Skip to content

Commit 542d3bc

Browse files
authored
Merge pull request #395 from 2chanhaeng/next/fix
2 parents a6cb8d4 + 1d27e9b commit 542d3bc

File tree

1 file changed

+1
-162
lines changed

1 file changed

+1
-162
lines changed

packages/next/README.md

Lines changed: 1 addition & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This package provides a simple way to integrate [Fedify] with [Next.js].
2727
Usage
2828
-----
2929

30-
~~~~ typescript
30+
~~~~ typescript ignore
3131
// --- middleware.ts ---
3232
import { fedifyWith } from "@fedify/next";
3333
import { federation } from "./federation";
@@ -63,164 +63,3 @@ export const config = {
6363
],
6464
};
6565
~~~~
66-
67-
The integration code looks like this:
68-
69-
~~~~ typescript
70-
/**
71-
* Fedify with Next.js
72-
* ===================
73-
*
74-
* This module provides a [Next.js] middleware to integrate with the Fedify.
75-
*
76-
* [Next.js]: https://nextjs.org/
77-
*
78-
* @module
79-
* @since 1.9.0
80-
*/
81-
import type { Federation, FederationFetchOptions } from "@fedify/fedify";
82-
import { notFound } from "next/navigation";
83-
import { NextResponse } from "next/server";
84-
import { getXForwardedRequest } from "x-forwarded-fetch";
85-
86-
interface ContextDataFactory<TContextData> {
87-
(request: Request):
88-
| TContextData
89-
| Promise<TContextData>;
90-
}
91-
type ErrorHandlers = Omit<FederationFetchOptions<unknown>, "contextData">;
92-
93-
/**
94-
* Wrapper function for Next.js middleware to integrate with the
95-
* {@link Federation} object.
96-
*
97-
* @template TContextData A type of the context data for the
98-
* {@link Federation} object.
99-
* @param federation A {@link Federation} object to integrate with Next.js.
100-
* @param contextDataFactory A function to create a context data for the
101-
* {@link Federation} object.
102-
* @param errorHandlers A set of error handlers to handle errors during
103-
* the federation fetch.
104-
* @returns A Next.js middleware function to integrate with the
105-
* {@link Federation} object.
106-
*
107-
* @example
108-
* ```ts
109-
* import { fedifyWith } from "@fedify/next";
110-
* import { federation } from "./federation";
111-
*
112-
* export default fedifyWith(federation)(
113-
* function (request: Request) {
114-
* // You can add custom logic here for other requests
115-
* // except federation requests. If there is no custom logic,
116-
* // you can omit this function.
117-
* }
118-
* )
119-
*
120-
* // This config makes middleware process only requests with the
121-
* // "Accept" header matching the federation accept regex.
122-
* // More details: https://nextjs.org/docs/app/api-reference/file-conventions/middleware#config-object-optional.
123-
* export const config = {
124-
* runtime: "nodejs",
125-
* matcher: [
126-
* {
127-
* source: "/:path*",
128-
* has: [
129-
* {
130-
* type: "header",
131-
* key: "Accept",
132-
* value: ".*application\\/((jrd|activity|ld)\\+json|xrd\\+xml).*",
133-
* },
134-
* ],
135-
* },
136-
* {
137-
* source: "/:path*",
138-
* has: [
139-
* {
140-
* type: "header",
141-
* key: "content-type",
142-
* value: ".*application\\/((jrd|activity|ld)\\+json|xrd\\+xml).*",
143-
* },
144-
* ],
145-
* },
146-
* { source: "/.well-known/nodeinfo" },
147-
* { source: "/.well-known/x-nodeinfo2" },
148-
* ],
149-
* };
150-
* ```
151-
*/
152-
export const fedifyWith = <TContextData>(
153-
federation: Federation<TContextData>,
154-
contextDataFactory?: ContextDataFactory<TContextData>,
155-
errorHandlers?: Partial<ErrorHandlers>,
156-
) =>
157-
(
158-
middleware: (request: Request) => unknown =
159-
((_: Request) => NextResponse.next()),
160-
): (request: Request) => unknown =>
161-
async (request: Request) => {
162-
if (hasFederationAcceptHeader(request)) {
163-
return await integrateFederation(
164-
federation,
165-
contextDataFactory,
166-
errorHandlers,
167-
)(request);
168-
}
169-
return await middleware(request);
170-
};
171-
172-
/**
173-
* Check if the request has the "Accept" header matching the federation
174-
* accept regex.
175-
*
176-
* @param {Request} request The request to check.
177-
* @returns {boolean} `true` if the request has the "Accept" header matching
178-
* the federation accept regex, `false` otherwise.
179-
*/
180-
export const hasFederationAcceptHeader = (request: Request): boolean => {
181-
const acceptHeader = request.headers.get("Accept");
182-
// Check if the Accept header matches the federation accept regex.
183-
// If the header is not present, return false.
184-
return acceptHeader ? FEDERATION_ACCEPT_REGEX.test(acceptHeader) : false;
185-
};
186-
const FEDERATION_ACCEPT_REGEX =
187-
/.*application\/((jrd|activity|ld)\+json|xrd\+xml).*/;
188-
189-
/**
190-
* Create a Next.js handler to integrate with the {@link Federation} object.
191-
*
192-
* @template TContextData A type of the context data for the
193-
* {@link Federation} object.
194-
* @param federation A {@link Federation} object to integrate with Next.js.
195-
* @param contextDataFactory A function to create a context data for the
196-
* {@link Federation} object.
197-
* @param errorHandlers A set of error handlers to handle errors during
198-
* the federation fetch.
199-
* @returns A Next.js handler.
200-
*/
201-
export function integrateFederation<TContextData>(
202-
federation: Federation<TContextData>,
203-
contextDataFactory: ContextDataFactory<TContextData> = () =>
204-
undefined as TContextData,
205-
errorHandlers?: Partial<ErrorHandlers>,
206-
) {
207-
return async (request: Request) => {
208-
const forwardedRequest = await getXForwardedRequest(request);
209-
const contextData = await contextDataFactory(forwardedRequest);
210-
return await federation.fetch(
211-
forwardedRequest,
212-
{
213-
contextData,
214-
onNotFound: notFound,
215-
onNotAcceptable,
216-
...errorHandlers,
217-
},
218-
);
219-
};
220-
}
221-
const onNotAcceptable = () =>
222-
new Response("Not acceptable", {
223-
status: 406,
224-
headers: { "Content-Type": "text/plain", Vary: "Accept" },
225-
});
226-
~~~~

0 commit comments

Comments
 (0)