UNPKG

@halsp/http

Version:

支持 Halsp HTTP 请求

166 lines 6.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parsePattern = exports.MapMatcher = void 0; const core_1 = require("@halsp/core"); const methods_1 = require("./methods.cjs"); class MapMatcher { ctx; options; constructor(ctx, options) { this.ctx = ctx; this.options = options; this.#parsedRegisters = ctx.startup.parsedRegisters; } #parsedRegisters; async match() { const register = this.getRegister(); if (!register) return; parseParams(this.ctx, register); if (register.handler) { await register.handler(this.ctx); } } getRegister() { const matchedPaths = this.#parsedRegisters .filter((r) => !!r.methods.length) .filter((r) => this.isPathMatched(r, true)); this.#parsedRegisters .filter((r) => !r.methods.length || r.methods.includes(methods_1.HttpMethods.any)) .filter((m) => this.isPathMatched(m, false)) .forEach((m) => matchedPaths.push(m)); const mapItem = this.getMostLikeRegister(matchedPaths); if (mapItem) return mapItem; const otherMethodPathCount = this.#parsedRegisters.filter((r) => this.isPathMatched(r, false)).length; if (otherMethodPathCount) { const method = this.ctx.req.method; this.ctx.res.methodNotAllowedMsg({ message: `method not allowed:${method}`, method: method, path: this.ctx.req.path, }); } else { this.ctx.res.notFoundMsg({ message: `Can't find the path:${this.ctx.req.path}`, path: this.ctx.req.path, }); } } isPathMatched(register, methodIncluded) { const reqUrl = this.ctx.req.path; const reqUrlStrs = reqUrl .toLowerCase() .split("/") .filter((item) => !!item); const mapUrlStrs = register.url .toLowerCase() .split("/") .filter((item) => !!item); if (reqUrlStrs.length != mapUrlStrs.length) return false; if (methodIncluded && !register.methods.includes(methods_1.HttpMethods.any)) { const matchedMethod = methods_1.HttpMethods.matched(this.ctx.req.method, this.options.customMethods); if (!matchedMethod || !register.methods.includes(matchedMethod)) { return false; } } for (let i = 0; i < mapUrlStrs.length; i++) { if (mapUrlStrs[i] != reqUrlStrs[i] && !mapUrlStrs[i].startsWith("^")) { return false; } } return true; } getMostLikeRegister(registers) { if (!registers || !registers.length) return; if (registers.length == 1) return registers[0]; const pathsParts = []; registers.forEach((register) => { pathsParts.push({ register: register, parts: register.url .toLowerCase() .split("/") .filter((item) => !!item), }); }); const minPartsCount = Math.min(...pathsParts.map((pp) => pp.parts.length)); for (let i = 0; i < minPartsCount; i++) { if (pathsParts.some((p) => p.parts[i].includes("^")) && pathsParts.some((p) => !p.parts[i].includes("^"))) { pathsParts .filter((p) => p.parts[i].includes("^")) .forEach((p) => pathsParts.splice(pathsParts.indexOf(p), 1)); } if (pathsParts.length == 1) return pathsParts[0].register; } if (pathsParts.some((pp) => pp.register.methods.includes(methods_1.HttpMethods.any)) && pathsParts.some((pp) => !pp.register.methods.includes(methods_1.HttpMethods.any))) { pathsParts .filter((pp) => pp.register.methods.includes(methods_1.HttpMethods.any)) .forEach((pp) => { pathsParts.splice(pathsParts.indexOf(pp), 1); }); } return pathsParts.sort((a, b) => a.parts.length - b.parts.length)[0] .register; } } exports.MapMatcher = MapMatcher; function parsePattern(register) { const strs = register.pattern.trim().split("//"); if (strs.length <= 1) { return { methods: [], url: (0, core_1.normalizePath)(strs[0]), handler: register.handler, }; } else { return { methods: strs[0] .split(",") .filter((m) => !!m) .map((m) => m.toUpperCase()), url: (0, core_1.normalizePath)(strs[1]), handler: register.handler, }; } } exports.parsePattern = parsePattern; function parseParams(ctx, register) { const params = {}; if (register.url.includes("^")) { const mapPathStrs = register.url.split("/").filter((item) => !!item); const reqPathStrs = ctx.req.path.split("/").filter((item) => !!item); for (let i = 0; i < Math.min(mapPathStrs.length, reqPathStrs.length); i++) { const mapPathStr = mapPathStrs[i]; if (!mapPathStr.startsWith("^")) continue; const reqPathStr = reqPathStrs[i]; const key = mapPathStr.substring(1, mapPathStr.length); const value = decodeURIComponent(reqPathStr); params[key] = value; } } Object.defineProperty(ctx.req, "params", { configurable: true, enumerable: true, get: () => { return params; }, }); Object.defineProperty(ctx.req, "param", { configurable: true, enumerable: true, get: () => { return params; }, }); } //# sourceMappingURL=map-matcher.js.map