From cdabf6ef02be7220fd2b6bdcef924ceca089381e Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Tue, 28 Nov 2023 01:51:57 +0800 Subject: [PATCH] Remove support for simple objects in endpoints (#9181) * Deprecate simple object from endpoints * Update changeset * Add missing Response return Co-authored-by: Happydev <81974850+MoustaphaDev@users.noreply.github.com> * Update .changeset/clever-beds-notice.md Co-authored-by: Sarah Rainsberger --------- Co-authored-by: Happydev <81974850+MoustaphaDev@users.noreply.github.com> Co-authored-by: Matthew Phillips Co-authored-by: Sarah Rainsberger --- .changeset/clever-beds-notice.md | 9 ++ packages/astro/src/@types/astro.ts | 34 +---- packages/astro/src/core/app/index.ts | 13 +- packages/astro/src/core/build/generate.ts | 11 +- packages/astro/src/core/build/types.ts | 2 +- packages/astro/src/core/endpoint/index.ts | 142 +----------------- .../src/core/middleware/callMiddleware.ts | 43 ++---- packages/astro/src/core/middleware/index.ts | 4 +- .../astro/src/core/middleware/sequence.ts | 6 +- packages/astro/src/core/pipeline.ts | 37 ++--- packages/astro/src/core/render/index.ts | 2 +- packages/astro/src/i18n/middleware.ts | 4 +- .../src/vite-plugin-astro-server/route.ts | 4 +- .../src/pages/context/data/[param].json.js | 6 +- .../src/pages/data/[slug].json.ts | 10 +- .../src/pages/glob.json.js | 4 +- .../src/pages/headings-glob.json.js | 8 +- .../src/pages/raw-content.json.js | 10 +- .../src/pages/vite-env-vars-glob.json.js | 4 +- .../src/pages/collections.json.js | 6 +- .../src/pages/entries.json.js | 15 +- .../fixtures/core-image-ssr/src/pages/api.ts | 5 +- .../src/pages/authors/[id].json.js | 12 +- .../src/pages/authors/all.json.js | 5 +- .../src/pages/translations/[lang].json.js | 12 +- .../src/pages/translations/all.json.js | 5 +- .../src/pages/translations/by-id.json.js | 5 +- .../src/pages/api/catch/[...slug].ts | 14 +- .../src/pages/about-object.json.ts | 12 -- .../src/pages/placeholder-object.png.ts | 18 --- .../src/pages/placeholder.png.ts | 5 +- .../src/pages/api/catch/[...slug].json.ts | 8 +- .../src/pages/api/catch/[foo]-[bar].json.ts | 10 +- .../src/pages/context/[param].js | 26 ++-- .../src/pages/food-object.json.js | 10 -- .../src/pages/api/products/[id].js | 5 +- .../src/pages/data/[slug].json.ts | 10 +- .../static-build/src/pages/company.json.ts | 12 +- .../src/pages/data/[slug].json.ts | 12 +- .../static-build/src/pages/posts.json.js | 5 +- .../src/pages/[slug].json.ts | 10 +- .../src/pages/data/[slug].json.ts | 10 +- .../src/pages/home.json.ts | 6 +- .../src/pages/images/[image].svg.ts | 18 ++- .../src/pages/images/hex.ts | 11 +- .../src/pages/images/static.svg.ts | 15 +- packages/astro/test/non-html-pages.test.js | 23 --- packages/astro/test/ssr-api-route.test.js | 18 --- .../src/pages/collection.json.js | 4 +- .../src/pages/entry.json.js | 4 +- .../src/pages/glob.json.js | 6 +- .../mdx-frontmatter/src/pages/glob.json.js | 9 +- .../mdx-get-headings/src/pages/pages.json.js | 13 +- .../mdx-url-export/src/pages/pages.json.js | 9 +- .../src/pages/frontmatter.json.js | 4 +- .../fixtures/node-middleware/src/pages/ssr.ts | 10 +- 56 files changed, 206 insertions(+), 529 deletions(-) create mode 100644 .changeset/clever-beds-notice.md delete mode 100644 packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts delete mode 100644 packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts delete mode 100644 packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js diff --git a/.changeset/clever-beds-notice.md b/.changeset/clever-beds-notice.md new file mode 100644 index 000000000000..6be65bde1157 --- /dev/null +++ b/.changeset/clever-beds-notice.md @@ -0,0 +1,9 @@ +--- +'astro': major +--- + +Removes support for returning simple objects from endpoints (deprecated since Astro 3.0). You should return a `Response` instead. + +`ResponseWithEncoding` is also removed. You can refactor the code to return a response with an array buffer instead, which is encoding agnostic. + +The types for middlewares have also been revised. To type a middleware function, you should now use `MiddlewareHandler` instead of `MiddlewareResponseHandler`. If you used `defineMiddleware()` to type the function, no changes are needed. diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index a769bcdf48b6..e77222c0c165 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -19,7 +19,6 @@ import type { AstroConfigType } from '../core/config/index.js'; import type { AstroTimer } from '../core/config/timer.js'; import type { TSConfig } from '../core/config/tsconfig.js'; import type { AstroCookies } from '../core/cookies/index.js'; -import type { ResponseWithEncoding } from '../core/endpoint/index.js'; import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger/core.js'; import type { AstroDevOverlay, DevOverlayCanvas } from '../runtime/client/dev-overlay/overlay.js'; import type { DevOverlayHighlight } from '../runtime/client/dev-overlay/ui-library/highlight.js'; @@ -2005,8 +2004,6 @@ export interface AstroAdapter { supportedAstroFeatures: AstroFeatureMap; } -type Body = string; - export type ValidRedirectStatus = 300 | 301 | 302 | 303 | 304 | 307 | 308; // Shared types between `Astro` global and API context object @@ -2163,7 +2160,6 @@ export interface APIContext< * ``` */ locals: App.Locals; - ResponseWithEncoding: typeof ResponseWithEncoding; /** * Available only when `experimental.i18n` enabled and in SSR. @@ -2199,22 +2195,12 @@ export interface APIContext< currentLocale: string | undefined; } -export type EndpointOutput = - | { - body: Body; - encoding?: BufferEncoding; - } - | { - body: Uint8Array; - encoding: 'binary'; - }; - export type APIRoute = Record> = ( context: APIContext -) => EndpointOutput | Response | Promise; +) => Response | Promise; export interface EndpointHandler { - [method: string]: APIRoute | ((params: Params, request: Request) => EndpointOutput | Response); + [method: string]: APIRoute | ((params: Params, request: Request) => Response); } export type Props = Record; @@ -2319,20 +2305,16 @@ export interface AstroIntegration { }; } -export type MiddlewareNext = () => Promise; -export type MiddlewareHandler = ( +export type MiddlewareNext = () => Promise; +export type MiddlewareHandler = ( context: APIContext, - next: MiddlewareNext -) => Promise | R | Promise | void; - -export type MiddlewareResponseHandler = MiddlewareHandler; -export type MiddlewareEndpointHandler = MiddlewareHandler; -export type MiddlewareNextResponse = MiddlewareNext; + next: MiddlewareNext +) => Promise | Response | Promise | void; // NOTE: when updating this file with other functions, // remember to update `plugin-page.ts` too, to add that function as a no-op function. -export type AstroMiddlewareInstance = { - onRequest?: MiddlewareHandler; +export type AstroMiddlewareInstance = { + onRequest?: MiddlewareHandler; }; export type AstroIntegrationMiddleware = { diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index 23ecba8371ed..3e72c3810e21 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -1,7 +1,6 @@ import type { EndpointHandler, ManifestData, - MiddlewareEndpointHandler, RouteData, SSRElement, SSRManifest, @@ -181,16 +180,14 @@ export class App { ); if (i18nMiddleware) { if (mod.onRequest) { - this.#pipeline.setMiddlewareFunction( - sequence(i18nMiddleware, mod.onRequest as MiddlewareEndpointHandler) - ); + this.#pipeline.setMiddlewareFunction(sequence(i18nMiddleware, mod.onRequest)); } else { this.#pipeline.setMiddlewareFunction(i18nMiddleware); } this.#pipeline.onBeforeRenderRoute(i18nPipelineHook); } else { if (mod.onRequest) { - this.#pipeline.setMiddlewareFunction(mod.onRequest as MiddlewareEndpointHandler); + this.#pipeline.setMiddlewareFunction(mod.onRequest); } } response = await this.#pipeline.renderRoute(renderContext, pageModule); @@ -322,7 +319,7 @@ export class App { ); const page = (await mod.page()) as any; if (skipMiddleware === false && mod.onRequest) { - this.#pipeline.setMiddlewareFunction(mod.onRequest as MiddlewareEndpointHandler); + this.#pipeline.setMiddlewareFunction(mod.onRequest); } if (skipMiddleware) { // make sure middleware set by other requests is cleared out @@ -367,8 +364,8 @@ export class App { const status = override?.status ? override.status : oldResponse.status === 200 - ? newResponse.status - : oldResponse.status; + ? newResponse.status + : oldResponse.status; return new Response(newResponse.body, { status, diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 4750f2afc89c..a7d286b4054c 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -8,7 +8,6 @@ import type { AstroSettings, ComponentInstance, GetStaticPathsItem, - MiddlewareEndpointHandler, RouteData, RouteType, SSRError, @@ -269,15 +268,13 @@ async function generatePage( ); if (config.experimental.i18n && i18nMiddleware) { if (onRequest) { - pipeline.setMiddlewareFunction( - sequence(i18nMiddleware, onRequest as MiddlewareEndpointHandler) - ); + pipeline.setMiddlewareFunction(sequence(i18nMiddleware, onRequest)); } else { pipeline.setMiddlewareFunction(i18nMiddleware); } pipeline.onBeforeRenderRoute(i18nPipelineHook); } else if (onRequest) { - pipeline.setMiddlewareFunction(onRequest as MiddlewareEndpointHandler); + pipeline.setMiddlewareFunction(onRequest); } if (!pageModulePromise) { throw new Error( @@ -560,7 +557,6 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli }); let body: string | Uint8Array; - let encoding: BufferEncoding | undefined; let response: Response; try { @@ -603,7 +599,6 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli // If there's no body, do nothing if (!response.body) return; body = Buffer.from(await response.arrayBuffer()); - encoding = (response.headers.get('X-Astro-Encoding') as BufferEncoding | null) ?? 'utf-8'; } const outFolder = getOutFolder(pipeline.getConfig(), pathname, route.type); @@ -611,7 +606,7 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli route.distURL = outFile; await fs.promises.mkdir(outFolder, { recursive: true }); - await fs.promises.writeFile(outFile, body, encoding); + await fs.promises.writeFile(outFile, body); } } diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index 59fa06f6b47f..0722a293dcad 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -54,7 +54,7 @@ export interface SinglePageBuiltModule { /** * The `onRequest` hook exported by the middleware */ - onRequest?: MiddlewareHandler; + onRequest?: MiddlewareHandler; renderers: SSRLoadedRenderer[]; } diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index f9c61d053fe6..c0490a7404f2 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -1,12 +1,4 @@ -import mime from 'mime'; -import type { - APIContext, - EndpointHandler, - EndpointOutput, - MiddlewareEndpointHandler, - MiddlewareHandler, - Params, -} from '../../@types/astro.js'; +import type { APIContext, EndpointHandler, MiddlewareHandler, Params } from '../../@types/astro.js'; import { renderEndpoint } from '../../runtime/server/index.js'; import { ASTRO_VERSION } from '../constants.js'; import { AstroCookies, attachCookiesToResponse } from '../cookies/index.js'; @@ -19,8 +11,6 @@ import { } from '../render/context.js'; import { type Environment, type RenderContext } from '../render/index.js'; -const encoder = new TextEncoder(); - const clientAddressSymbol = Symbol.for('astro.clientAddress'); const clientLocalsSymbol = Symbol.for('astro.locals'); @@ -69,7 +59,6 @@ export function createAPIContext({ }, }); }, - ResponseWithEncoding, get preferredLocale(): string | undefined { if (preferredLocale) { return preferredLocale; @@ -143,36 +132,11 @@ export function createAPIContext({ return context; } -type ResponseParameters = ConstructorParameters; - -export class ResponseWithEncoding extends Response { - constructor(body: ResponseParameters[0], init: ResponseParameters[1], encoding?: BufferEncoding) { - // If a body string is given, try to encode it to preserve the behaviour as simple objects. - // We don't do the full handling as simple objects so users can control how headers are set instead. - if (typeof body === 'string') { - // In NodeJS, we can use Buffer.from which supports all BufferEncoding - if (typeof Buffer !== 'undefined' && Buffer.from) { - body = Buffer.from(body, encoding); - } - // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings - else if (encoding == null || encoding === 'utf8' || encoding === 'utf-8') { - body = encoder.encode(body); - } - } - - super(body, init); - - if (encoding) { - this.headers.set('X-Astro-Encoding', encoding); - } - } -} - -export async function callEndpoint( +export async function callEndpoint( mod: EndpointHandler, env: Environment, ctx: RenderContext, - onRequest: MiddlewareHandler | undefined + onRequest: MiddlewareHandler | undefined ): Promise { const context = createAPIContext({ request: ctx.request, @@ -187,107 +151,13 @@ export async function callEndpoint let response; if (onRequest) { - response = await callMiddleware( - env.logger, - onRequest as MiddlewareEndpointHandler, - context, - async () => { - return await renderEndpoint(mod, context, env.ssr, env.logger); - } - ); + response = await callMiddleware(onRequest, context, async () => { + return await renderEndpoint(mod, context, env.ssr, env.logger); + }); } else { response = await renderEndpoint(mod, context, env.ssr, env.logger); } - const isEndpointSSR = env.ssr && !ctx.route?.prerender; - - if (response instanceof Response) { - if (isEndpointSSR && response.headers.get('X-Astro-Encoding')) { - env.logger.warn( - null, - '`ResponseWithEncoding` is ignored in SSR. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - attachCookiesToResponse(response, context.cookies); - return response; - } - - // The endpoint returned a simple object, convert it to a Response - - // TODO: Remove in Astro 4.0 - env.logger.warn( - null, - `${ctx.route.component} returns a simple object which is deprecated. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.` - ); - - if (isEndpointSSR) { - if (response.hasOwnProperty('headers')) { - env.logger.warn( - null, - 'Setting headers is not supported when returning an object. Please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - - if (response.encoding) { - env.logger.warn( - null, - '`encoding` is ignored in SSR. To return a charset other than UTF-8, please return an instance of Response. See https://docs.astro.build/en/core-concepts/endpoints/#server-endpoints-api-routes for more information.' - ); - } - } - - let body: BodyInit; - const headers = new Headers(); - - // Try to get the MIME type for this route - const pathname = ctx.route - ? // Try the static route `pathname` - ctx.route.pathname ?? - // Dynamic routes don't include `pathname`, so synthesize a path for these (e.g. 'src/pages/[slug].svg') - ctx.route.segments.map((s) => s.map((p) => p.content).join('')).join('/') - : // Fallback to pathname of the request - ctx.pathname; - const mimeType = mime.getType(pathname) || 'text/plain'; - headers.set('Content-Type', `${mimeType};charset=utf-8`); - - // Save encoding to X-Astro-Encoding to be used later during SSG with `fs.writeFile`. - // It won't work in SSR and is already warned above. - if (response.encoding) { - headers.set('X-Astro-Encoding', response.encoding); - } - - // For Uint8Array (binary), it can passed to Response directly - if (response.body instanceof Uint8Array) { - body = response.body; - headers.set('Content-Length', body.byteLength.toString()); - } - // In NodeJS, we can use Buffer.from which supports all BufferEncoding - else if (typeof Buffer !== 'undefined' && Buffer.from) { - body = Buffer.from(response.body, response.encoding); - headers.set('Content-Length', body.byteLength.toString()); - } - // In non-NodeJS, use the web-standard TextEncoder for utf-8 strings only - // to calculate the content length - else if ( - response.encoding == null || - response.encoding === 'utf8' || - response.encoding === 'utf-8' - ) { - body = encoder.encode(response.body); - headers.set('Content-Length', body.byteLength.toString()); - } - // Fallback pass it to Response directly. It will mainly rely on X-Astro-Encoding - // to be further processed in SSG. - else { - body = response.body; - // NOTE: Can't calculate the content length as we can't encode to figure out the real length. - // But also because we don't need the length for SSG as it's only being written to disk. - } - - response = new Response(body, { - status: 200, - headers, - }); attachCookiesToResponse(response, context.cookies); return response; } diff --git a/packages/astro/src/core/middleware/callMiddleware.ts b/packages/astro/src/core/middleware/callMiddleware.ts index d0a6ceca201a..4d79cd566364 100644 --- a/packages/astro/src/core/middleware/callMiddleware.ts +++ b/packages/astro/src/core/middleware/callMiddleware.ts @@ -1,13 +1,6 @@ -import { bold } from 'kleur/colors'; -import type { - APIContext, - EndpointOutput, - MiddlewareHandler, - MiddlewareNext, -} from '../../@types/astro.js'; +import type { APIContext, MiddlewareHandler, MiddlewareNext } from '../../@types/astro.js'; import { attachCookiesToResponse, responseHasCookies } from '../cookies/index.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Environment } from '../render/index.js'; /** * Utility function that is in charge of calling the middleware. @@ -43,15 +36,14 @@ import type { Environment } from '../render/index.js'; * @param apiContext The API context * @param responseFunction A callback function that should return a promise with the response */ -export async function callMiddleware( - logger: Environment['logger'], - onRequest: MiddlewareHandler, +export async function callMiddleware( + onRequest: MiddlewareHandler, apiContext: APIContext, - responseFunction: () => Promise -): Promise { + responseFunction: () => Promise +): Promise { let nextCalled = false; - let responseFunctionPromise: Promise | undefined = undefined; - const next: MiddlewareNext = async () => { + let responseFunctionPromise: Promise | undefined = undefined; + const next: MiddlewareNext = async () => { nextCalled = true; responseFunctionPromise = responseFunction(); return responseFunctionPromise; @@ -60,15 +52,6 @@ export async function callMiddleware( let middlewarePromise = onRequest(apiContext, next); return await Promise.resolve(middlewarePromise).then(async (value) => { - if (isEndpointOutput(value)) { - logger.warn( - null, - apiContext.url.pathname + - ' Using simple endpoints can cause unexpected issues in the chain of middleware functions.' + - `\nIt's strongly suggested to use full ${bold('Response')} objects.` - ); - } - // first we check if `next` was called if (nextCalled) { /** @@ -84,7 +67,7 @@ export async function callMiddleware( if (value instanceof Response === false) { throw new AstroError(AstroErrorData.MiddlewareNotAResponse); } - return ensureCookiesAttached(apiContext, value as Response); + return ensureCookiesAttached(apiContext, value); } else { /** * Here we handle the case where `next` was called and returned nothing. @@ -107,7 +90,7 @@ export async function callMiddleware( throw new AstroError(AstroErrorData.MiddlewareNotAResponse); } else { // Middleware did not call resolve and returned a value - return ensureCookiesAttached(apiContext, value as Response); + return ensureCookiesAttached(apiContext, value); } }); } @@ -118,11 +101,3 @@ function ensureCookiesAttached(apiContext: APIContext, response: Response): Resp } return response; } - -function isEndpointOutput(endpointResult: any): endpointResult is EndpointOutput { - return ( - !(endpointResult instanceof Response) && - typeof endpointResult === 'object' && - typeof endpointResult.body === 'string' - ); -} diff --git a/packages/astro/src/core/middleware/index.ts b/packages/astro/src/core/middleware/index.ts index c02761351d3c..ffaafb3e56b2 100644 --- a/packages/astro/src/core/middleware/index.ts +++ b/packages/astro/src/core/middleware/index.ts @@ -1,8 +1,8 @@ -import type { MiddlewareEndpointHandler, Params } from '../../@types/astro.js'; +import type { MiddlewareHandler, Params } from '../../@types/astro.js'; import { createAPIContext } from '../endpoint/index.js'; import { sequence } from './sequence.js'; -function defineMiddleware(fn: MiddlewareEndpointHandler) { +function defineMiddleware(fn: MiddlewareHandler) { return fn; } diff --git a/packages/astro/src/core/middleware/sequence.ts b/packages/astro/src/core/middleware/sequence.ts index d20641ee3169..9a68963945ec 100644 --- a/packages/astro/src/core/middleware/sequence.ts +++ b/packages/astro/src/core/middleware/sequence.ts @@ -1,4 +1,4 @@ -import type { APIContext, MiddlewareEndpointHandler } from '../../@types/astro.js'; +import type { APIContext, MiddlewareHandler } from '../../@types/astro.js'; import { defineMiddleware } from './index.js'; // From SvelteKit: https://github.com/sveltejs/kit/blob/master/packages/kit/src/exports/hooks/sequence.js @@ -6,11 +6,11 @@ import { defineMiddleware } from './index.js'; * * It accepts one or more middleware handlers and makes sure that they are run in sequence. */ -export function sequence(...handlers: MiddlewareEndpointHandler[]): MiddlewareEndpointHandler { +export function sequence(...handlers: MiddlewareHandler[]): MiddlewareHandler { const filtered = handlers.filter((h) => !!h); const length = filtered.length; if (!length) { - const handler: MiddlewareEndpointHandler = defineMiddleware((context, next) => { + const handler: MiddlewareHandler = defineMiddleware((context, next) => { return next(); }); return handler; diff --git a/packages/astro/src/core/pipeline.ts b/packages/astro/src/core/pipeline.ts index 87f833ee5cc4..b3493b7c0437 100644 --- a/packages/astro/src/core/pipeline.ts +++ b/packages/astro/src/core/pipeline.ts @@ -1,10 +1,4 @@ -import type { - ComponentInstance, - EndpointHandler, - MiddlewareEndpointHandler, - MiddlewareHandler, - MiddlewareResponseHandler, -} from '../@types/astro.js'; +import type { ComponentInstance, EndpointHandler, MiddlewareHandler } from '../@types/astro.js'; import { callEndpoint, createAPIContext } from './endpoint/index.js'; import { callMiddleware } from './middleware/callMiddleware.js'; import { renderPage } from './render/core.js'; @@ -28,7 +22,7 @@ export type PipelineHookFunction = (ctx: RenderContext, mod: ComponentInstance | */ export class Pipeline { env: Environment; - #onRequest?: MiddlewareEndpointHandler; + #onRequest?: MiddlewareHandler; #hooks: PipelineHooks = { before: [], }; @@ -60,7 +54,7 @@ export class Pipeline { /** * A middleware function that will be called before each request. */ - setMiddlewareFunction(onRequest: MiddlewareEndpointHandler) { + setMiddlewareFunction(onRequest: MiddlewareHandler) { this.#onRequest = onRequest; } @@ -115,11 +109,11 @@ export class Pipeline { * * It throws an error if the page can't be rendered. */ - async #tryRenderRoute( + async #tryRenderRoute( renderContext: Readonly, env: Readonly, mod: Readonly | undefined, - onRequest?: MiddlewareHandler + onRequest?: MiddlewareHandler ): Promise { const apiContext = createAPIContext({ request: renderContext.request, @@ -137,19 +131,14 @@ export class Pipeline { case 'fallback': case 'redirect': { if (onRequest) { - return await callMiddleware( - env.logger, - onRequest as MiddlewareResponseHandler, - apiContext, - () => { - return renderPage({ - mod, - renderContext, - env, - cookies: apiContext.cookies, - }); - } - ); + return await callMiddleware(onRequest, apiContext, () => { + return renderPage({ + mod, + renderContext, + env, + cookies: apiContext.cookies, + }); + }); } else { return await renderPage({ mod, diff --git a/packages/astro/src/core/render/index.ts b/packages/astro/src/core/render/index.ts index 6d466c4117d8..5f3a702a3083 100644 --- a/packages/astro/src/core/render/index.ts +++ b/packages/astro/src/core/render/index.ts @@ -24,5 +24,5 @@ export interface SSROptions { /** * Optional middlewares */ - middleware?: AstroMiddlewareInstance; + middleware?: AstroMiddlewareInstance; } diff --git a/packages/astro/src/i18n/middleware.ts b/packages/astro/src/i18n/middleware.ts index 854a39b77cda..79ac2c962464 100644 --- a/packages/astro/src/i18n/middleware.ts +++ b/packages/astro/src/i18n/middleware.ts @@ -1,5 +1,5 @@ import { appendForwardSlash, joinPaths } from '@astrojs/internal-helpers/path'; -import type { MiddlewareEndpointHandler, RouteData, SSRManifest } from '../@types/astro.js'; +import type { MiddlewareHandler, RouteData, SSRManifest } from '../@types/astro.js'; import type { PipelineHookFunction } from '../core/pipeline.js'; const routeDataSymbol = Symbol.for('astro.routeData'); @@ -19,7 +19,7 @@ export function createI18nMiddleware( i18n: SSRManifest['i18n'], base: SSRManifest['base'], trailingSlash: SSRManifest['trailingSlash'] -): MiddlewareEndpointHandler | undefined { +): MiddlewareHandler | undefined { if (!i18n) { return undefined; } diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index f87c4e1478c1..4c49525e7593 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url'; import type { ComponentInstance, ManifestData, - MiddlewareEndpointHandler, + MiddlewareHandler, RouteData, SSRElement, SSRManifest, @@ -288,7 +288,7 @@ export async function handleRoute({ }); } - const onRequest = middleware?.onRequest as MiddlewareEndpointHandler | undefined; + const onRequest = middleware?.onRequest as MiddlewareHandler | undefined; if (config.experimental.i18n) { const i18Middleware = createI18nMiddleware( config.experimental.i18n, diff --git a/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js index d18eb086f9a5..cb9308ba4554 100644 --- a/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js +++ b/packages/astro/test/fixtures/api-routes/src/pages/context/data/[param].json.js @@ -15,10 +15,10 @@ export function getStaticPaths() { } export function GET({ params, request }) { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ param: params.param, pathname: new URL(request.url).pathname }) - }; + ); } diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts index 32a0fd140f12..21df537cd4a2 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/data/[slug].json.ts @@ -1,14 +1,12 @@ export async function getStaticPaths() { - return [ + return [ { params: { slug: 'thing1' } }, { params: { slug: 'thing2' } } ]; } export async function GET() { - return { - body: JSON.stringify({ - title: '[slug]' - }, null, 4) - }; + return Response.json({ + title: '[slug]', + }); } diff --git a/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js b/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js index 3aae6d89a8a9..1916378c93c0 100644 --- a/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown-frontmatter-injection/src/pages/glob.json.js @@ -1,6 +1,4 @@ export async function GET() { const docs = await import.meta.glob('./*.md', { eager: true }); - return { - body: JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)), - } + return Response.json(Object.values(docs).map((doc) => doc.frontmatter)); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js index b2c9ea6ea25f..3cc852c6f565 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/headings-glob.json.js @@ -1,9 +1,7 @@ import { getHeadings } from './with-layout.md'; export async function GET() { - return { - body: JSON.stringify({ - headings: getHeadings(), - }), - } + return Response.json({ + headings: getHeadings(), + }); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js index 82977443dc11..cf499bb39c01 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/raw-content.json.js @@ -1,10 +1,8 @@ import { rawContent, compiledContent } from './basic.md'; export async function GET() { - return { - body: JSON.stringify({ - raw: rawContent(), - compiled: await compiledContent(), - }), - } + return Response.json({ + raw: rawContent(), + compiled: await compiledContent(), + }); } diff --git a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js index 7a5d00f47ac0..7dfe96294701 100644 --- a/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js +++ b/packages/astro/test/fixtures/astro-markdown/src/pages/vite-env-vars-glob.json.js @@ -1,7 +1,5 @@ import { frontmatter } from './vite-env-vars.md'; export async function GET() { - return { - body: JSON.stringify(frontmatter), - } + return Response.json(frontmatter); } diff --git a/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js b/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js index e335d2b05d7c..b7b7d847253e 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js +++ b/packages/astro/test/fixtures/content-collections/src/pages/collections.json.js @@ -8,7 +8,7 @@ export async function GET() { const withSlugConfig = stripAllRenderFn(await getCollection('with-custom-slugs')); const withUnionSchema = stripAllRenderFn(await getCollection('with-union-schema')); - return { - body: devalue.stringify({withoutConfig, withSchemaConfig, withSlugConfig, withUnionSchema}), - } + return new Response( + devalue.stringify({ withoutConfig, withSchemaConfig, withSlugConfig, withUnionSchema }) + ); } diff --git a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js index 311b76cc8bca..a05a9138b1d8 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js +++ b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js @@ -5,10 +5,17 @@ import { stripRenderFn } from '../utils.js'; export async function GET() { const columbiaWithoutConfig = stripRenderFn(await getEntryBySlug('without-config', 'columbia')); const oneWithSchemaConfig = stripRenderFn(await getEntryBySlug('with-schema-config', 'one')); - const twoWithSlugConfig = stripRenderFn(await getEntryBySlug('with-custom-slugs', 'interesting-two')); + const twoWithSlugConfig = stripRenderFn( + await getEntryBySlug('with-custom-slugs', 'interesting-two') + ); const postWithUnionSchema = stripRenderFn(await getEntryBySlug('with-union-schema', 'post')); - return { - body: devalue.stringify({columbiaWithoutConfig, oneWithSchemaConfig, twoWithSlugConfig, postWithUnionSchema}), - } + return new Response( + devalue.stringify({ + columbiaWithoutConfig, + oneWithSchemaConfig, + twoWithSlugConfig, + postWithUnionSchema, + }) + ); } diff --git a/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts b/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts index 7847baf62cb8..261fb6bb7dc7 100644 --- a/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts +++ b/packages/astro/test/fixtures/core-image-ssr/src/pages/api.ts @@ -3,8 +3,5 @@ import type { APIRoute } from "../../../../../src/@types/astro"; export const GET = (async ({ params, request }) => { const url = new URL(request.url); const src = url.searchParams.get("src"); - - return { - body: "An image: " + JSON.stringify(src), - }; + return new Response("An image: " + JSON.stringify(src)); }) satisfies APIRoute; diff --git a/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js b/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js index 76f4d57606d2..8d5365a2eb2d 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/authors/[id].json.js @@ -1,9 +1,9 @@ import { getEntry } from 'astro:content'; -const ids = ['Ben Holmes', 'Fred K Schott', 'Nate Moore'] +const ids = ['Ben Holmes', 'Fred K Schott', 'Nate Moore']; export function getStaticPaths() { - return ids.map(id => ({ params: { id } })) + return ids.map((id) => ({ params: { id } })); } /** @param {import('astro').APIContext} params */ @@ -11,12 +11,8 @@ export async function GET({ params }) { const { id } = params; const author = await getEntry('authors-without-config', id); if (!author) { - return { - body: JSON.stringify({ error: `Author ${id} Not found` }), - } + return Response.json({ error: `Author ${id} Not found` }); } else { - return { - body: JSON.stringify(author), - } + return Response.json(author); } } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js b/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js index 5b5007fedb70..79dd8cd9dd3c 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/authors/all.json.js @@ -2,8 +2,5 @@ import { getCollection } from 'astro:content'; export async function GET() { const authors = await getCollection('authors-without-config'); - - return { - body: JSON.stringify(authors), - } + return Response.json(authors); } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js index ab8cc764e353..c6b0cfff669b 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/[lang].json.js @@ -1,9 +1,9 @@ import { getEntry } from 'astro:content'; -const langs = ['en', 'es', 'fr'] +const langs = ['en', 'es', 'fr']; export function getStaticPaths() { - return langs.map(lang => ({ params: { lang } })) + return langs.map((lang) => ({ params: { lang } })); } /** @param {import('astro').APIContext} params */ @@ -11,12 +11,8 @@ export async function GET({ params }) { const { lang } = params; const translations = await getEntry('i18n', lang); if (!translations) { - return { - body: JSON.stringify({ error: `Translation ${lang} Not found` }), - } + return Response.json({ error: `Translation ${lang} Not found` }); } else { - return { - body: JSON.stringify(translations), - } + return Response.json(translations); } } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js index e8a1fee92908..f1ebb15b761e 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/all.json.js @@ -2,8 +2,5 @@ import { getCollection } from 'astro:content'; export async function GET() { const translations = await getCollection('i18n'); - - return { - body: JSON.stringify(translations), - } + return Response.json(translations); } diff --git a/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js b/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js index f7b84752dd3f..5f71c80e9f7b 100644 --- a/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js +++ b/packages/astro/test/fixtures/data-collections/src/pages/translations/by-id.json.js @@ -2,8 +2,5 @@ import { getDataEntryById } from 'astro:content'; export async function GET() { const item = await getDataEntryById('i18n', 'en'); - - return { - body: JSON.stringify(item), - } + return Response.json(item); } diff --git a/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts b/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts index 8fccd6695a8c..96a9d56f6cb4 100644 --- a/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts +++ b/packages/astro/test/fixtures/dynamic-endpoint-collision/src/pages/api/catch/[...slug].ts @@ -1,15 +1,13 @@ -import type { APIRoute } from "astro"; +import type { APIRoute } from 'astro'; -const slugs = ["one", undefined]; +const slugs = ['one', undefined]; export const GET: APIRoute = ({ params }) => { - return { - body: JSON.stringify({ - slug: params.slug || "index", - }), - }; + return Response.json({ + slug: params.slug || 'index', + }); }; export function getStaticPaths() { - return slugs.map((u) => ({ params: { slug: u } })); + return slugs.map((u) => ({ params: { slug: u } })); } diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts deleted file mode 100644 index 3936cbe85ba7..000000000000 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/about-object.json.ts +++ /dev/null @@ -1,12 +0,0 @@ -// NOTE: test deprecated object form -// Returns the file body for this non-HTML file. -// The content type is based off of the extension in the filename, -// in this case: about.json. -export async function GET() { - return { - body: JSON.stringify({ - name: 'Astro', - url: 'https://astro.build/', - }), - }; -} diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts deleted file mode 100644 index 11415900400c..000000000000 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder-object.png.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { promises as fs } from 'node:fs'; - -import type { APIRoute } from 'astro'; - -// NOTE: test deprecated object form -export const GET: APIRoute = async function get() { - try { - // Image is in the public domain. Sourced from - // https://en.wikipedia.org/wiki/File:Portrait_placeholder.png - const buffer = await fs.readFile('./test/fixtures/non-html-pages/src/images/placeholder.png'); - return { - body: buffer.toString('binary'), - encoding: 'binary', - } as const; - } catch (error: unknown) { - throw new Error(`Something went wrong in placeholder.png route!: ${error as string}`); - } -}; diff --git a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts index 50c6b877b09f..1ac93597e62b 100644 --- a/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts +++ b/packages/astro/test/fixtures/non-html-pages/src/pages/placeholder.png.ts @@ -2,12 +2,13 @@ import { promises as fs } from 'node:fs'; import type { APIRoute } from 'astro'; -export const GET: APIRoute = async function get({ ResponseWithEncoding }) { +export const GET: APIRoute = async function get() { try { // Image is in the public domain. Sourced from // https://en.wikipedia.org/wiki/File:Portrait_placeholder.png const buffer = await fs.readFile('./test/fixtures/non-html-pages/src/images/placeholder.png'); - return new ResponseWithEncoding(buffer.toString('binary'), undefined, 'binary') + // NOTE: SSG only so not Content-Type needed + return new Response(buffer.buffer) } catch (error: unknown) { throw new Error(`Something went wrong in placeholder.png route!: ${error as string}`); } diff --git a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts index bc7e1b774698..4b26f41e56a0 100644 --- a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts +++ b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[...slug].json.ts @@ -1,11 +1,11 @@ import type { APIRoute } from 'astro'; export const GET: APIRoute = async ({ params }) => { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ path: params.slug, - }), - }; + }) + ); }; export function getStaticPaths() { diff --git a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts index b06efff6f213..b9d2f0cabff1 100644 --- a/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts +++ b/packages/astro/test/fixtures/routing-priority/src/pages/api/catch/[foo]-[bar].json.ts @@ -1,12 +1,12 @@ import type { APIRoute } from 'astro'; export const GET: APIRoute = async ({ params }) => { - return { - body: JSON.stringify({ + return new Response( + JSON.stringify({ foo: params.foo, - bar: params.bar, - }), - }; + bar: params.bar, + }) + ); }; export function getStaticPaths() { diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js b/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js index ba110ee13f4d..d5c9f4033d67 100644 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js +++ b/packages/astro/test/fixtures/ssr-api-route/src/pages/context/[param].js @@ -1,18 +1,16 @@ /** - * @param {import('astro').APIContext} api + * @param {import('astro').APIContext} api */ export function GET(ctx) { - return { - body: JSON.stringify({ - cookiesExist: !!ctx.cookies, - requestExist: !!ctx.request, - redirectExist: !!ctx.redirect, - propsExist: !!ctx.props, - params: ctx.params, - site: ctx.site?.toString(), - generator: ctx.generator, - url: ctx.url.toString(), - clientAddress: ctx.clientAddress, - }) - }; + return Response.json({ + cookiesExist: !!ctx.cookies, + requestExist: !!ctx.request, + redirectExist: !!ctx.redirect, + propsExist: !!ctx.props, + params: ctx.params, + site: ctx.site?.toString(), + generator: ctx.generator, + url: ctx.url.toString(), + clientAddress: ctx.clientAddress, + }); } diff --git a/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js b/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js deleted file mode 100644 index 7992e697aacc..000000000000 --- a/packages/astro/test/fixtures/ssr-api-route/src/pages/food-object.json.js +++ /dev/null @@ -1,10 +0,0 @@ -// NOTE: test deprecated object form -export function GET() { - return { - body: JSON.stringify([ - { name: 'lettuce' }, - { name: 'broccoli' }, - { name: 'pizza' } - ]) - }; -} diff --git a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js index 8c7c393029c1..8956f0d4ccc3 100644 --- a/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js +++ b/packages/astro/test/fixtures/ssr-dynamic/src/pages/api/products/[id].js @@ -1,6 +1,3 @@ - export function GET({ params }) { - return { - body: JSON.stringify(params) - }; + return Response.json(params); } diff --git a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts index d969873c54d1..7a1b6af28241 100644 --- a/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/ssr-prerender-get-static-paths/src/pages/data/[slug].json.ts @@ -1,16 +1,14 @@ export const prerender = true; export async function getStaticPaths() { - return [ + return [ { params: { slug: 'thing1' } }, { params: { slug: 'thing2' } } ]; } export async function GET() { - return { - body: JSON.stringify({ - title: '[slug]' - }, null, 4) - }; + return Response.json({ + title: '[slug]', + }); } diff --git a/packages/astro/test/fixtures/static-build/src/pages/company.json.ts b/packages/astro/test/fixtures/static-build/src/pages/company.json.ts index 08f45a7b87f8..6a08cc9399bb 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/company.json.ts +++ b/packages/astro/test/fixtures/static-build/src/pages/company.json.ts @@ -1,8 +1,6 @@ -export async function GET() { - return { - body: JSON.stringify({ - name: 'Astro Technology Company', - url: 'https://astro.build/' - }) - } +export function GET() { + return Response.json({ + name: 'Astro Technology Company', + url: 'https://astro.build/', + }); } diff --git a/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts index 2fa13ac1820e..2c78812ec107 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/static-build/src/pages/data/[slug].json.ts @@ -6,11 +6,9 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - name: 'Astro Technology Company', - url: 'https://astro.build/' - }) - } + return Response.json({ + slug: params.slug, + name: 'Astro Technology Company', + url: 'https://astro.build/' + }); } diff --git a/packages/astro/test/fixtures/static-build/src/pages/posts.json.js b/packages/astro/test/fixtures/static-build/src/pages/posts.json.js index aefbbffff72c..b72a000d9638 100644 --- a/packages/astro/test/fixtures/static-build/src/pages/posts.json.js +++ b/packages/astro/test/fixtures/static-build/src/pages/posts.json.js @@ -15,8 +15,5 @@ async function fetchPosts() { export async function GET() { const posts = await fetchPosts(); - - return { - body: JSON.stringify(posts, null, 4), - }; + return Response.json(posts); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts index 783031605467..3c1408300f25 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/[slug].json.ts @@ -6,10 +6,8 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - title: '[slug]' - }) - }; + return Response.json({ + slug: params.slug, + title: '[slug]' + }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts index 707c39fa9c9c..26cd9b065c34 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/data/[slug].json.ts @@ -6,10 +6,8 @@ export async function getStaticPaths() { } export async function GET({ params }) { - return { - body: JSON.stringify({ - slug: params.slug, - title: 'data [slug]' - }) - }; + return Response.json({ + slug: params.slug, + title: 'data [slug]' + }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts index 5eaac42f1d57..2bee50a8e328 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/home.json.ts @@ -1,7 +1,3 @@ export async function GET() { - return { - body: JSON.stringify({ - title: 'home' - }) - }; + return Response.json({ title: 'home' }); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts index c6fa88711671..cef9dd60855d 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/[image].svg.ts @@ -1,14 +1,16 @@ export async function getStaticPaths() { - return [ - { params: { image: 1 } }, - { params: { image: 2 } }, - ]; + return [{ params: { image: 1 } }, { params: { image: 2 } }]; } export async function GET({ params }) { - return { - body: ` + return new Response( + ` ${params.image} -` - }; +`, + { + headers: { + 'content-type': 'image/svg+xml', + }, + } + ); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts index 84dd6dcaa19a..c258c3091c2d 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/hex.ts @@ -1,9 +1,6 @@ -import { readFileSync } from "node:fs"; +import { readFile } from 'node:fs/promises'; -export async function GET({ params, request }) { - const buffer = readFileSync(new URL('../../astro.png', import.meta.url)); - return { - body: buffer.toString('hex'), - encoding: 'hex', - }; +export async function GET() { + const buffer = await readFile(new URL('../../astro.png', import.meta.url)); + return new Response(buffer.buffer); } diff --git a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts index 93fcf40228bc..423f258f8c17 100644 --- a/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts +++ b/packages/astro/test/fixtures/with-endpoint-routes/src/pages/images/static.svg.ts @@ -1,7 +1,12 @@ -export async function GET() { - return { - body: ` +export function GET() { + return new Response( + ` Static SVG -` - }; +`, + { + headers: { + 'content-type': 'image/svg+xml', + }, + } + ); } diff --git a/packages/astro/test/non-html-pages.test.js b/packages/astro/test/non-html-pages.test.js index 2cf5811041bc..9f050ae96f35 100644 --- a/packages/astro/test/non-html-pages.test.js +++ b/packages/astro/test/non-html-pages.test.js @@ -15,12 +15,6 @@ describe('Non-HTML Pages', () => { expect(json).to.have.property('name', 'Astro'); expect(json).to.have.property('url', 'https://astro.build/'); }); - - it('should match contents (deprecated object form)', async () => { - const json = JSON.parse(await fixture.readFile('/about-object.json')); - expect(json).to.have.property('name', 'Astro'); - expect(json).to.have.property('url', 'https://astro.build/'); - }); }); describe('png', () => { @@ -40,22 +34,5 @@ describe('Non-HTML Pages', () => { 'iVBORw0KGgoAAAANSUhEUgAAAGQAAACWCAMAAAAfZt10AAAABlBMVEXd3d3+/v7B/CFgAAAA3UlEQVR42u3ZMQ7DIBQFQeb+l06bNgUbG/5eYApLFjzWNE3TNE3TNE035av9AhAQEBBQGAQEFAaFQWFQGBQGhUGCKAwKgwQpDJ6JECgCRYIEikH8YAyCRyEGyRCDvBWRIPNNBpm/8G6kUM45EhXKlQfuFSHFpbFH+jt2j/S7xwqUYvBaCRIozZy6X2km7v1K8uwQIIWBwkBAQEBg3Tyj3z4LnzRBKgwKg8KgMEgQhaEwSBCFQWBEiMIgQQqDBCkMEqQw+APixYgcsa0TERs7D/F6xGmIAxCD/Iw4AvEB92Ec3ZAPdlMAAAAASUVORK5CYII=' ); }); - - it('should not have had its encoding mangled (deprecated object form)', async () => { - const buffer = await fixture.readFile('/placeholder-object.png', 'base64'); - - // Sanity check the first byte - const hex = Buffer.from(buffer, 'base64').toString('hex'); - const firstHexByte = hex.slice(0, 2); - // If we accidentally utf8 encode the png, the first byte (in hex) will be 'c2' - expect(firstHexByte).to.not.equal('c2'); - // and if correctly encoded in binary, it should be '89' - expect(firstHexByte).to.equal('89'); - - // Make sure the whole buffer (in base64) matches this snapshot - expect(buffer).to.equal( - 'iVBORw0KGgoAAAANSUhEUgAAAGQAAACWCAMAAAAfZt10AAAABlBMVEXd3d3+/v7B/CFgAAAA3UlEQVR42u3ZMQ7DIBQFQeb+l06bNgUbG/5eYApLFjzWNE3TNE3TNE035av9AhAQEBBQGAQEFAaFQWFQGBQGhUGCKAwKgwQpDJ6JECgCRYIEikH8YAyCRyEGyRCDvBWRIPNNBpm/8G6kUM45EhXKlQfuFSHFpbFH+jt2j/S7xwqUYvBaCRIozZy6X2km7v1K8uwQIIWBwkBAQEBg3Tyj3z4LnzRBKgwKg8KgMEgQhaEwSBCFQWBEiMIgQQqDBCkMEqQw+APixYgcsa0TERs7D/F6xGmIAxCD/Iw4AvEB92Ec3ZAPdlMAAAAASUVORK5CYII=' - ); - }); }); }); diff --git a/packages/astro/test/ssr-api-route.test.js b/packages/astro/test/ssr-api-route.test.js index fbaafc82275c..e15993b88681 100644 --- a/packages/astro/test/ssr-api-route.test.js +++ b/packages/astro/test/ssr-api-route.test.js @@ -33,17 +33,6 @@ describe('API routes in SSR', () => { expect(body.length).to.equal(3); }); - it('Can load the API route too (deprecated object form)', async () => { - const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/food-object.json'); - const response = await app.render(request); - expect(response.status).to.equal(200); - expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8'); - expect(response.headers.get('Content-Length')).to.not.be.empty; - const body = await response.json(); - expect(body.length).to.equal(3); - }); - it('Has valid api context', async () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/context/any'); @@ -96,13 +85,6 @@ describe('API routes in SSR', () => { expect(res.status).to.equal(200); }); - it('Infer content type with charset for { body } shorthand (deprecated object form)', async () => { - const response = await fixture.fetch('/food-object.json', { - method: 'GET', - }); - expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8'); - }); - it('Can set multiple headers of the same type', async () => { const response = await new Promise((resolve) => { let { port } = devServer.address; diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js index 6f389f0a7235..cb3c84652622 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js @@ -4,7 +4,5 @@ import { stripAllRenderFn } from '../../utils.js'; export async function GET() { const posts = await getCollection('blog'); - return { - body: stringify(stripAllRenderFn(posts)) - }; + return new Response(stringify(stripAllRenderFn(posts))); } diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js index aa24117ab88d..53dd17013ba7 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js @@ -4,7 +4,5 @@ import { stripRenderFn } from '../../utils.js'; export async function GET() { const post = await getEntryBySlug('blog', 'post-1'); - return { - body: stringify(stripRenderFn(post)), - }; + return new Response(stringify(stripRenderFn(post))); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js b/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js index 3423bc634446..63248dc56f88 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-frontmatter-injection/src/pages/glob.json.js @@ -1,6 +1,6 @@ export async function GET() { const docs = await import.meta.glob('./*.mdx', { eager: true }); - return { - body: JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)), - } + return new Response( + JSON.stringify(Object.values(docs).map(doc => doc.frontmatter)) + ); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js index 9a10127b7606..d82d9f770517 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-frontmatter/src/pages/glob.json.js @@ -1,9 +1,6 @@ export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - titles: Object.values(mdxPages ?? {}).map(v => v?.frontmatter?.title), - }) - } + return Response.json({ + titles: Object.values(mdxPages ?? {}).map((v) => v?.frontmatter?.title), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js b/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js index de65e50e0b90..e57192c6151d 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-get-headings/src/pages/pages.json.js @@ -1,11 +1,8 @@ export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - headingsByPage: Object.fromEntries( - Object.entries(mdxPages ?? {}).map(([k, v]) => [k, v?.getHeadings()]) - ), - }), - } + return Response.json({ + headingsByPage: Object.fromEntries( + Object.entries(mdxPages ?? {}).map(([k, v]) => [k, v?.getHeadings()]) + ), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js b/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js index 93bf31be29d7..02cff64a8af1 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-url-export/src/pages/pages.json.js @@ -1,9 +1,6 @@ export async function GET() { const mdxPages = await import.meta.glob('./*.mdx', { eager: true }); - - return { - body: JSON.stringify({ - urls: Object.values(mdxPages ?? {}).map(v => v?.url), - }) - } + return Response.json({ + urls: Object.values(mdxPages ?? {}).map((v) => v?.url), + }); } diff --git a/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js b/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js index 91654c3923f3..152285b9cf94 100644 --- a/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js +++ b/packages/integrations/mdx/test/fixtures/mdx-vite-env-vars/src/pages/frontmatter.json.js @@ -1,7 +1,5 @@ import { frontmatter } from './vite-env-vars.mdx'; export function GET() { - return { - body: JSON.stringify(frontmatter), - } + return Response.json(frontmatter); } diff --git a/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts index 67f32eafae14..423db341a46e 100644 --- a/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts +++ b/packages/integrations/node/test/fixtures/node-middleware/src/pages/ssr.ts @@ -1,9 +1,7 @@ export async function GET() { let number = Math.random(); - return { - body: JSON.stringify({ - number, - message: `Here's a random number: ${number}`, - }), - }; + return Response.json({ + number, + message: `Here's a random number: ${number}`, + }); }