Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"require": "./build/cjs/index.server.js"
},
"./middleware": {
"types": "./build/types/integration/middleware/index.types.d.ts",
"types": "./build/types/integration/middleware/index.d.ts",
"node": "./build/esm/integration/middleware/index.js",
"import": "./build/esm/integration/middleware/index.js",
"require": "./build/cjs/integration/middleware/index.js"
Expand Down
15 changes: 12 additions & 3 deletions packages/astro/src/integration/middleware/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { MiddlewareResponseHandler } from 'astro';
import { handleRequest } from '../../server/middleware';

type MiddlewareNext = () => Promise<Response>;
type MiddlewareHandler = (ctx: unknown, next: MiddlewareNext) => Promise<Response> | Response | Promise<void> | void;

/**
* This export is used by our integration to automatically add the middleware
* to astro ^3.5.0 projects.
Expand All @@ -10,6 +12,13 @@ import { handleRequest } from '../../server/middleware';
* middleware registration in our integration and manually add it in their own
* `/src/middleware.js` file.
*/
export const onRequest: MiddlewareResponseHandler = (ctx, next) => {
return handleRequest()(ctx, next);
export const onRequest: MiddlewareHandler = (ctx, next) => {
const middleware = handleRequest();

// `onRequest` deliberately uses framework-agnostic parameter types so the published
// `@sentry/astro/middleware` declaration does not reference Astro-version-specific types
// (e.g. `MiddlewareResponseHandler`, which is absent in some supported Astro versions).
// The handler returned by `handleRequest()` is typed against Astro's own types, so we cast
// back to its expected parameter types here – the runtime shapes are identical.
return middleware(ctx as Parameters<typeof middleware>[0], next as Parameters<typeof middleware>[1]);
};
18 changes: 18 additions & 0 deletions packages/astro/test/integration/middleware/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, expectTypeOf, it } from 'vitest';
import { onRequest } from '../../../src/integration/middleware';

describe('Integration middleware types', () => {
// Regression test for #21413: the published `@sentry/astro/middleware` declaration must stay
// framework-agnostic. Typing `onRequest` against Astro-version-specific aliases (such as
// `MiddlewareResponseHandler`) made the public type depend on an export that is absent in some
// supported Astro versions. The assertions below fail on that previous typing and pass with the fix.
it('exposes onRequest as a framework-agnostic middleware handler', () => {
expectTypeOf(onRequest).toBeFunction();
expectTypeOf(onRequest).parameters.toEqualTypeOf<[unknown, () => Promise<Response>]>();
expectTypeOf(onRequest).returns.toEqualTypeOf<Promise<Response> | Response | Promise<void> | void>();
});

it('is callable with a minimal context and a zero-argument next', () => {
expectTypeOf(onRequest).toBeCallableWith({}, () => Promise.resolve(new Response()));
});
});
2 changes: 1 addition & 1 deletion packages/astro/test/integration/middleware/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Integration middleware', () => {
id: '123',
},
};
// @ts-expect-error - a partial ctx object is fine here
// `onRequest` accepts a framework-agnostic `ctx`, so a partial Astro context is fine here.
const res = await onRequest(ctx, next);

expect(res).toBeDefined();
Expand Down
Loading