UNPKG

next-mw

Version:

A middleware manager for Next.js

171 lines (169 loc) 4.86 kB
// src/index.ts import { NextResponse } from "next/server"; // src/matcher.ts import { match as pathMatch } from "path-to-regexp"; var matcherCache = /* @__PURE__ */ new Map(); var regexCache = /* @__PURE__ */ new Map(); function getMatcherFunction(pattern) { if (matcherCache.has(pattern)) { return matcherCache.get(pattern); } const fn = pathMatch(pattern, { decode: decodeURIComponent }); matcherCache.set(pattern, fn); return fn; } function getRegex(regexStr) { if (regexCache.has(regexStr)) return regexCache.get(regexStr); const re = new RegExp(regexStr); regexCache.set(regexStr, re); return re; } function matchPath(path, pattern) { const matcherFn = getMatcherFunction(pattern); return matcherFn(path) !== false; } function checkHasConditions(req, conditions) { for (const condition of conditions) { switch (condition.type) { case "header": { const headerValue = req.headers.get(condition.key); if (headerValue === null) return false; if (condition.value !== void 0 && headerValue !== condition.value) return false; break; } case "query": { const queryValue = req.nextUrl.searchParams.get(condition.key); if (queryValue === null) return false; if (condition.value !== void 0 && queryValue !== condition.value) return false; break; } case "cookie": { const cookie = req.cookies.get(condition.key); if (!cookie) return false; if (condition.value !== void 0 && cookie.value !== condition.value) return false; break; } default: return false; } } return true; } function checkMissingConditions(req, conditions) { for (const condition of conditions) { switch (condition.type) { case "header": { const headerValue = req.headers.get(condition.key); if (headerValue !== null) { if (condition.value === void 0 || headerValue === condition.value) return false; } break; } case "query": { const queryValue = req.nextUrl.searchParams.get(condition.key); if (queryValue !== null) { if (condition.value === void 0 || queryValue === condition.value) return false; } break; } case "cookie": { const cookie = req.cookies.get(condition.key); if (cookie) { if (condition.value === void 0 || cookie.value === condition.value) return false; } break; } default: return false; } } return true; } function matchMatcherCondition(req, condition) { let pathToMatch = req.nextUrl.pathname; if (condition.locale === false && req.nextUrl.locale) { const localePrefix = "/" + req.nextUrl.locale; if (pathToMatch.startsWith(localePrefix)) { pathToMatch = pathToMatch.slice(localePrefix.length) || "/"; } } if (!matchPath(pathToMatch, condition.source)) { return false; } if (condition.regexp) { const re = getRegex(condition.regexp); if (!re.test(pathToMatch)) { return false; } } if (condition.has && !checkHasConditions(req, condition.has)) { return false; } if (condition.missing && !checkMissingConditions(req, condition.missing)) { return false; } return true; } function matchRequest(req, matcher) { if (!matcher) return true; const matchers = Array.isArray(matcher) ? matcher : [matcher]; for (const m of matchers) { if (typeof m === "string") { if (matchPath(req.nextUrl.pathname, m)) { return true; } } else { if (matchMatcherCondition(req, m)) { return true; } } } return false; } // src/index.ts function middlewares(...modules) { for (const module of modules) { if (module.config) { if (module.config.matcher !== void 0 && (module.config.include !== void 0 || module.config.exclude !== void 0)) { throw new Error( "Cannot define both 'matcher' and 'include/exclude' in middleware config." ); } } } return async function(req, ev) { for (const module of modules) { if (module.config) { if (module.config.matcher !== void 0) { if (!matchRequest(req, module.config.matcher)) { continue; } } else { if (module.config.include !== void 0 && !matchRequest(req, module.config.include)) { continue; } if (module.config.exclude !== void 0 && matchRequest(req, module.config.exclude)) { continue; } } } const result = await module.middleware(req, ev); if (result) { return result; } } return NextResponse.next(); }; } export { middlewares }; //# sourceMappingURL=index.mjs.map