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 package/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nimpl/middleware-chain",
"version": "0.3.0",
"version": "0.4.0",
"description": "",
"main": "./dist/chain.js",
"files": [
Expand Down
18 changes: 11 additions & 7 deletions package/src/chain.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import type { NextRequest, NextFetchEvent } from "next/server";
import { type NextRequest, type NextFetchEvent } from "next/server";
import { type ChainItem, type ChainConfig } from "./lib/types";
import { collectData } from "./lib/collect-data";
import { ChainItem } from "./lib/types";
import { formatResponse } from "./lib/format-response";
import { Logger } from "./lib/logger";

export { FinalNextResponse } from "./lib/final-next-response";

export const chain = (middlewares: ChainItem[]) => async (req: NextRequest, event: NextFetchEvent) => {
const summary = await collectData(req, event, middlewares);
const next = formatResponse(summary);
export const chain =
(middlewares: ChainItem[], config?: ChainConfig) => async (req: NextRequest, event: NextFetchEvent) => {
const logger = new Logger(config?.logger);
const summary = await collectData(req, event, middlewares, logger);
const next = formatResponse(summary);

return next;
};
return next;
};

export default chain;
17 changes: 9 additions & 8 deletions package/src/lib/collect-data.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { NextResponse, type NextRequest, type NextFetchEvent } from "next/server";
import { ChainItem, Middleware, type ChainNextResponse, type Summary } from "./types";
import { type Logger } from "./logger";
import { type ChainItem, type Middleware, type ChainNextResponse, type Summary } from "./types";
import { FinalSymbol } from "./final-next-response";
import { INTERNAL_HEADERS } from "./constants";

export const collectData = async (req: NextRequest, event: NextFetchEvent, chainItems: ChainItem[]) => {
export const collectData = async (req: NextRequest, event: NextFetchEvent, chainItems: ChainItem[], logger: Logger) => {
const summary: Summary = {
type: "none",
destination: req.nextUrl,
Expand Down Expand Up @@ -44,11 +45,11 @@ export const collectData = async (req: NextRequest, event: NextFetchEvent, chain
if (next.headers.has("Location")) {
const destination = next.headers.get("Location") as string;
if (summary.destination !== destination || summary.type === "rewrite") {
console.log(
logger.log(
`Changing destination between middlewares: ${summary.destination} (${summary.type}) -> ${destination} (redirect)`,
);
} else if (summary.type === "json") {
console.log(`Changing response type between middlewares: json -> redirect`);
logger.log(`Changing response type between middlewares: json -> redirect`);
}
Object.assign(summary, {
type: "redirect",
Expand All @@ -60,11 +61,11 @@ export const collectData = async (req: NextRequest, event: NextFetchEvent, chain
} else if (next.headers.has("x-middleware-rewrite")) {
const destination = next.headers.get("x-middleware-rewrite") as string;
if (summary.destination !== destination || summary.type === "redirect") {
console.log(
logger.log(
`Changing destination between middlewares: ${summary.destination} (${summary.type}) -> ${destination} (rewrite)`,
);
} else if (summary.type === "json") {
console.log(`Changing response type between middlewares: json -> rewrite`);
logger.log(`Changing response type between middlewares: json -> rewrite`);
}
Object.assign(summary, {
type: "rewrite",
Expand All @@ -75,9 +76,9 @@ export const collectData = async (req: NextRequest, event: NextFetchEvent, chain
});
} else if (next.body) {
if (summary.type === "json") {
console.log(`Changing body between middlewares`);
logger.log(`Changing body between middlewares`);
} else {
console.log(`Changing response type between middlewares: ${summary.type} -> json`);
logger.log(`Changing response type between middlewares: ${summary.type} -> json`);
}
Object.assign(summary, {
type: "custom",
Expand Down
25 changes: 25 additions & 0 deletions package/src/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export class Logger {
private logger?: Logger | null;

constructor(logger?: Logger | boolean | null) {
if (logger && logger !== true) {
this.logger = logger;
} else if (logger === false || logger === null) {
this.logger = null;
} else {
this.logger = console;
}
}

log(message: string) {
this.logger?.log(message);
}

warn(message: string) {
this.logger?.warn(message);
}

error(message: string) {
this.logger?.error(message);
}
}
9 changes: 7 additions & 2 deletions package/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { type ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies";
import { type NextURL } from "next/dist/server/web/next-url";
import { NextResponse, type NextRequest, type NextFetchEvent } from "next/server";
import { FinalNextResponse, FinalSymbol } from "./final-next-response";
import { type NextResponse, type NextRequest, type NextFetchEvent } from "next/server";
import { type FinalNextResponse, type FinalSymbol } from "./final-next-response";
import { type Logger } from "./logger";

export type NextType = "rewrite" | "redirect" | "json" | "none" | undefined;

Expand All @@ -26,3 +27,7 @@ export type MiddlewareResult = ChainNextResponse | Response | void | undefined |
export type Middleware = (req: ChainNextRequest, event: NextFetchEvent) => MiddlewareResult;

export type ChainItem = Middleware | [Middleware, { include?: RegExp; exclude?: RegExp }?];

export type ChainConfig = {
logger?: Logger | boolean | null;
};