UNPKG

cloudflare-email-router

Version:

Support advanced email routing on Cloudflare Workers.

97 lines (95 loc) 2.86 kB
// src/router.ts var _router_counter = 0; var EmailRouter = class _EmailRouter { constructor(config = { name: `router-${_router_counter++}` }) { this.config = config; } rules = []; get name() { return this.config.name; } /** * Matches the given email message against the defined rules and returns the first matching rule. * @param message The email message to match against the rules. * @returns The first matching rule or null if no rule matches the message. */ async checkout(message) { for (const rule of this.rules) { const matched = await rule.match(message); if (matched) { return rule; } } return null; } /** * Processes the email message and returns the result of the matching route handle. * @param ctx - The email context object. * @param next - The next middleware function. * @returns An object containing the matched route handle or null if no match was found. */ async process(ctx, next) { const matched = await this.checkout(ctx.message); if (matched) { await matched.handle(ctx, next || (() => Promise.resolve())); return { matched }; } return { matched: null }; } async handle(ctx, next) { await this.process(ctx, next); } match(matcher, handler_subrouter) { let name = ""; if (typeof matcher === "string") { name = matcher; matcher = (message) => new RegExp(`^${matcher}$`).test(message.to); } else if (matcher instanceof RegExp) { const regex = matcher; name = regex.source; matcher = (message) => regex.test(message.to); } else if (typeof matcher === "function") { name = matcher.name; } if (handler_subrouter instanceof _EmailRouter) { const precondition = matcher; const subrouter = handler_subrouter; name = `${name} (${subrouter.config.name})`; matcher = async (message) => { if (await precondition(message)) { return subrouter.checkout(message) !== null; } return false; }; } else if (typeof handler_subrouter === "function") { const handler = handler_subrouter; const anonymous_middleware = { name: handler_subrouter.name, async handle(ctx, next) { await handler(ctx.message); await next(); } }; handler_subrouter = anonymous_middleware; } this.rules.push({ name, match: matcher, handle: handler_subrouter.handle.bind(handler_subrouter) }); return this; } }; // src/utils.ts var CATCH_ALL = () => true; function REJECT_ALL(reason = "Sorry, we don't accept emails to this address.") { return [CATCH_ALL, (message) => { var _a; return (_a = message.reject) == null ? void 0 : _a.call(message, reason); }]; } export { CATCH_ALL, EmailRouter, REJECT_ALL };