Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove support for simple objects in endpoints #9181

Merged
merged 5 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/clever-beds-notice.md
Original file line number Diff line number Diff line change
@@ -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 are also cleaned up. 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.
matthewp marked this conversation as resolved.
Show resolved Hide resolved
34 changes: 8 additions & 26 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -2059,8 +2058,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
Expand Down Expand Up @@ -2217,7 +2214,6 @@ export interface APIContext<
* ```
*/
locals: App.Locals;
ResponseWithEncoding: typeof ResponseWithEncoding;

/**
* Available only when `experimental.i18n` enabled and in SSR.
Expand Down Expand Up @@ -2253,22 +2249,12 @@ export interface APIContext<
currentLocale: string | undefined;
}

export type EndpointOutput =
| {
body: Body;
encoding?: BufferEncoding;
}
| {
body: Uint8Array;
encoding: 'binary';
};

export type APIRoute<Props extends Record<string, any> = Record<string, any>> = (
context: APIContext<Props>
) => EndpointOutput | Response | Promise<EndpointOutput | Response>;
) => Response | Promise<Response>;

export interface EndpointHandler {
[method: string]: APIRoute | ((params: Params, request: Request) => EndpointOutput | Response);
[method: string]: APIRoute | ((params: Params, request: Request) => Response);
}

export type Props = Record<string, unknown>;
Expand Down Expand Up @@ -2373,20 +2359,16 @@ export interface AstroIntegration {
};
}

export type MiddlewareNext<R> = () => Promise<R>;
export type MiddlewareHandler<R> = (
export type MiddlewareNext = () => Promise<Response>;
export type MiddlewareHandler = (
context: APIContext,
next: MiddlewareNext<R>
) => Promise<R> | R | Promise<void> | void;

export type MiddlewareResponseHandler = MiddlewareHandler<Response>;
export type MiddlewareEndpointHandler = MiddlewareHandler<Response | EndpointOutput>;
export type MiddlewareNextResponse = MiddlewareNext<Response>;
next: MiddlewareNext
) => Promise<Response> | Response | Promise<void> | 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<R> = {
onRequest?: MiddlewareHandler<R>;
export type AstroMiddlewareInstance = {
onRequest?: MiddlewareHandler;
};

export type AstroIntegrationMiddleware = {
Expand Down
13 changes: 5 additions & 8 deletions packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
EndpointHandler,
ManifestData,
MiddlewareEndpointHandler,
RouteData,
SSRElement,
SSRManifest,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
30 changes: 11 additions & 19 deletions packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type {
AstroSettings,
ComponentInstance,
GetStaticPathsItem,
MiddlewareEndpointHandler,
RouteData,
RouteType,
SSRError,
Expand Down Expand Up @@ -244,10 +243,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn

await queue.onIdle();
const assetsTimeEnd = performance.now();
logger.info(
null,
green(`✓ Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.\n`)
);
logger.info(null, green(`✓ Completed in ${getTimeStat(assetsTimer, assetsTimeEnd)}.\n`));

delete globalThis?.astroAsset?.addStaticImage;
}
Expand Down Expand Up @@ -286,15 +282,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(
Expand Down Expand Up @@ -390,13 +384,13 @@ async function getPathsForRoute(
throw err;
});

const label = staticPaths.length === 1 ? 'page' : 'pages';
logger.debug(
'build',
`├── ${bold(green('✔'))} ${route.component} → ${magenta(
`[${staticPaths.length} ${label}]`
)}`
);
const label = staticPaths.length === 1 ? 'page' : 'pages';
logger.debug(
'build',
`├── ${bold(green('✔'))} ${route.component} → ${magenta(
`[${staticPaths.length} ${label}]`
)}`
);

paths.push(
...staticPaths
Expand Down Expand Up @@ -587,7 +581,6 @@ async function generatePath(pathname: string, gopts: GeneratePathOptions, pipeli
});

let body: string | Uint8Array;
let encoding: BufferEncoding | undefined;

let response: Response;
try {
Expand Down Expand Up @@ -630,15 +623,14 @@ 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);
const outFile = getOutFile(pipeline.getConfig(), outFolder, pathname, route.type);
route.distURL = outFile;

await fs.promises.mkdir(outFolder, { recursive: true });
await fs.promises.writeFile(outFile, body, encoding);
await fs.promises.writeFile(outFile, body);
}
}

Expand Down
28 changes: 1 addition & 27 deletions packages/astro/src/core/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class AstroBuilder {
this.logger.info('build', `output: ${blue('"' + this.settings.config.output + '"')}`);
this.logger.info('build', `directory: ${blue(fileURLToPath(this.settings.config.outDir))}`);
if (this.settings.adapter) {
this.logger.info('build', `adapter: ${green(this.settings.adapter.name)}`);
this.logger.info('build', `adapter: ${green(this.settings.adapter.name)}`);
}
this.logger.info('build', 'Collecting build info...');
this.timer.loadStart = performance.now();
Expand Down Expand Up @@ -253,32 +253,6 @@ class AstroBuilder {
`the outDir cannot be the root folder. Please build to a folder such as dist.`
);
}

// TODO: Remove in Astro 4.0
if (config.build.split === true) {
if (config.output === 'static') {
this.logger.warn(
'config',
'The option `build.split` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.'
);
}
this.logger.warn(
'deprecated',
'The option `build.split` is deprecated. Use the adapter options.'
);
}
if (config.build.excludeMiddleware === true) {
if (config.output === 'static') {
this.logger.warn(
'config',
'The option `build.excludeMiddleware` won\'t take effect, because `output` is not `"server"` or `"hybrid"`.'
);
}
this.logger.warn(
'deprecated',
'The option `build.excludeMiddleware` is deprecated. Use the adapter options.'
);
}
}

/** Stats */
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface SinglePageBuiltModule {
/**
* The `onRequest` hook exported by the middleware
*/
onRequest?: MiddlewareHandler<unknown>;
onRequest?: MiddlewareHandler;
renderers: SSRLoadedRenderer[];
}

Expand Down
Loading
Loading