UNPKG

@fly/edge

Version:
166 lines 22.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PathPatternMatcher = exports.buildRules = exports.validateRule = void 0; /** * @module Config * @ignore * */ const text_replacements_1 = require("../text-replacements"); function validateRule(r) { if (typeof r !== "object") { throw new Error("must be an object"); } if (!r.actionType) { throw new Error("actionType must be defined"); } if (r.actionType !== "redirect" && r.actionType !== "rewrite") { throw new Error("actionType must be either `redirect` or `rewrite`"); } if (r.actionType === "rewrite" && !r.backendKey) { throw new Error("must inclue `backendKey` when actionType is set to `rewrite`"); } return true; } exports.validateRule = validateRule; function buildRules(backends, rules) { const compiled = rules.map(compileRule); return async function ruleFetch(req, init) { if (typeof req === "string") { req = new Request(req, init); } const match = compiled.find((r) => r(req)); if (!match) { return new Response("no routing rule found", { status: 404 }); } const rule = match.rule; // do the redirect if (rule.actionType === "redirect") { let original = new URL(req.url); let url = undefined; if (match.pathPattern && rule.redirectURLPattern) { url = match.pathPattern.replace(original.pathname, rule.redirectURLPattern); } else if (rule.redirectURLPattern) { url = rule.redirectURLPattern; } if (!url || original.toString() === url) { return new Response("Can't redirect to a bad URL", { status: 500 }); } const status = rule.redirectStatus || 302; const redirectTo = new URL(url, original); return new Response("Redirect", { status: status, headers: { location: redirectTo.toString() } }); } if (rule.actionType !== "rewrite") { return new Response("Invalid rule action", { status: 500 }); } const backend = rule.backendKey && backends ? backends.get(rule.backendKey) : undefined; if (!backend) { return new Response("No backend for rule", { status: 502 }); } // rewrite request if necessary if (match.pathPattern && rule.pathReplacementPattern) { let url = new URL(req.url); url = new URL(match.pathPattern.replace(url.pathname, rule.pathReplacementPattern), url); req = new Request(url.toString(), req); } if (!rule.responseReplacements || rule.responseReplacements.length === 0) { return await backend(req, init); } req.headers.delete("accept-encoding"); let resp = await backend(req, init); return text_replacements_1.applyReplacements(resp, rule.responseReplacements); }; } exports.buildRules = buildRules; function compileRule(rule) { const pathPattern = ensurePathPatternMatcher(rule.pathPattern); const httpHeaderValue = ensureRegExp(rule.httpHeaderValue); const fn = function compiledRule(req) { const url = new URL(req.url); if (rule.matchScheme === "http" || rule.matchScheme === "https") { const scheme = url.protocol.slice(0, -1); if (scheme !== rule.matchScheme) return false; } if (rule.hostname && rule.hostname !== "") { if (url.hostname !== rule.hostname) { return false; } } if (rule.httpHeaderKey && rule.httpHeaderKey !== "" && httpHeaderValue) { const header = req.headers.get(rule.httpHeaderKey); if (!header || !header.match(httpHeaderValue)) { return false; } } if (pathPattern && !pathPattern.match(url.pathname)) { return false; } return true; }; return Object.assign(fn, { rule: rule, pathPattern: pathPattern }); } function ensureRegExp(pattern) { if (!pattern || pattern == "") return null; if (typeof pattern === "string") return new RegExp(pattern); if (pattern instanceof RegExp) return pattern; throw new Error("Pattern must be a string or RegExp: " + typeof pattern); } function ensurePathPatternMatcher(pattern) { if (!pattern || pattern == "") return null; if (typeof pattern === "string") return new PathPatternMatcher(pattern); if (pattern instanceof RegExp) return new PathPatternMatcher(pattern); throw new Error("Pattern must be a string or RegExp: " + typeof pattern); } class PathPatternMatcher { constructor(pattern) { this.params = []; if (pattern instanceof RegExp) { this.regex = pattern; } else { const matches = pattern.match(/([:\*]\w+)/g); if (matches) { for (const match of matches) { this.params.push(match.substring(1)); if (match.startsWith(":")) { pattern = pattern.replace(match, "([^/.]+)"); } else if (match.startsWith("*")) { pattern = pattern.replace(match, "(.+)"); } } } this.regex = new RegExp(pattern); } } match(path) { return this.regex.test(path); } parse(path) { const params = {}; const match = this.regex.exec(path); if (!match) { return params; } for (const [paramIndex, paramName] of this.params.entries()) { params[paramName] = match[paramIndex + 1]; } return params; } replace(path, replacement) { const params = this.parse(path); for (const [name, value] of Object.entries(params)) { replacement = replacement.replace(`$${name}`, value); } return replacement; } } exports.PathPatternMatcher = PathPatternMatcher; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL3J1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7S0FHSztBQUNMLDREQUF5RDtBQW9CekQsU0FBZ0IsWUFBWSxDQUFDLENBQU07SUFDakMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0tBQ3JDO0lBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUU7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO0tBQzlDO0lBQ0QsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFVBQVUsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRTtRQUM3RCxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7S0FDckU7SUFDRCxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRTtRQUMvQyxNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUE7S0FDaEY7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFkRCxvQ0FjQztBQUVELFNBQWdCLFVBQVUsQ0FBQyxRQUF3QixFQUFFLEtBQWlCO0lBQ3BFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDdkMsT0FBTyxLQUFLLFVBQVUsU0FBUyxDQUFDLEdBQWdCLEVBQUUsSUFBa0I7UUFDbEUsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUU7WUFDM0IsR0FBRyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtTQUM3QjtRQUNELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBVSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ25ELElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDVixPQUFPLElBQUksUUFBUSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7U0FDOUQ7UUFDRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFBO1FBQ3ZCLGtCQUFrQjtRQUNsQixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO1lBQ2xDLElBQUksUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUMvQixJQUFJLEdBQUcsR0FBdUIsU0FBUyxDQUFBO1lBQ3ZDLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7Z0JBQ2hELEdBQUcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO2FBQzVFO2lCQUFNLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUNsQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFBO2FBQzlCO1lBQ0QsSUFBSSxDQUFDLEdBQUcsSUFBSSxRQUFRLENBQUMsUUFBUSxFQUFFLEtBQUssR0FBRyxFQUFFO2dCQUN2QyxPQUFPLElBQUksUUFBUSxDQUFDLDZCQUE2QixFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7YUFDcEU7WUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxJQUFJLEdBQUcsQ0FBQTtZQUN6QyxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDekMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUE7U0FDbEc7UUFDRCxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFO1lBQ2pDLE9BQU8sSUFBSSxRQUFRLENBQUMscUJBQXFCLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQTtTQUM1RDtRQUNELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO1FBQ3ZGLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDWixPQUFPLElBQUksUUFBUSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7U0FDNUQ7UUFDRCwrQkFBK0I7UUFDL0IsSUFBSSxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtZQUNwRCxJQUFJLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDMUIsR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUE7WUFDeEYsR0FBRyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBZSxHQUFHLENBQUMsQ0FBQTtTQUNwRDtRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDeEUsT0FBTyxNQUFNLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUE7U0FDaEM7UUFFRCxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQ3JDLElBQUksSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUNuQyxPQUFPLHFDQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtJQUMzRCxDQUFDLENBQUE7QUFDSCxDQUFDO0FBaERELGdDQWdEQztBQUVELFNBQVMsV0FBVyxDQUFDLElBQWM7SUFDakMsTUFBTSxXQUFXLEdBQUcsd0JBQXdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQzlELE1BQU0sZUFBZSxHQUFHLFlBQVksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUE7SUFDMUQsTUFBTSxFQUFFLEdBQUcsU0FBUyxZQUFZLENBQUMsR0FBWTtRQUMzQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDNUIsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLE9BQU8sRUFBRTtZQUMvRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN4QyxJQUFJLE1BQU0sS0FBSyxJQUFJLENBQUMsV0FBVztnQkFBRSxPQUFPLEtBQUssQ0FBQTtTQUM5QztRQUNELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLEVBQUUsRUFBRTtZQUN6QyxJQUFJLEdBQUcsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDbEMsT0FBTyxLQUFLLENBQUE7YUFDYjtTQUNGO1FBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssRUFBRSxJQUFJLGVBQWUsRUFBRTtZQUN0RSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUE7WUFDbEQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQUU7Z0JBQzdDLE9BQU8sS0FBSyxDQUFBO2FBQ2I7U0FDRjtRQUNELElBQUksV0FBVyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDbkQsT0FBTyxLQUFLLENBQUE7U0FDYjtRQUNELE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQyxDQUFBO0lBQ0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUE7QUFDcEUsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLE9BQXlCO0lBQzdDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxJQUFJLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUMxQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVE7UUFBRSxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzNELElBQUksT0FBTyxZQUFZLE1BQU07UUFBRSxPQUFPLE9BQU8sQ0FBQTtJQUU3QyxNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxHQUFHLE9BQU8sT0FBTyxDQUFDLENBQUE7QUFDMUUsQ0FBQztBQUVELFNBQVMsd0JBQXdCLENBQUMsT0FBeUI7SUFDekQsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLElBQUksRUFBRTtRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQzFDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtRQUFFLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN2RSxJQUFJLE9BQU8sWUFBWSxNQUFNO1FBQUUsT0FBTyxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBRXJFLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLEdBQUcsT0FBTyxPQUFPLENBQUMsQ0FBQTtBQUMxRSxDQUFDO0FBR0QsTUFBYSxrQkFBa0I7SUFJN0IsWUFBWSxPQUF3QjtRQUY1QixXQUFNLEdBQWEsRUFBRSxDQUFBO1FBRzNCLElBQUksT0FBTyxZQUFZLE1BQU0sRUFBRTtZQUM3QixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQTtTQUNyQjthQUFNO1lBQ0wsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQTtZQUM1QyxJQUFJLE9BQU8sRUFBRTtnQkFDWCxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRTtvQkFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO29CQUNwQyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7d0JBQ3pCLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQTtxQkFDN0M7eUJBQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO3dCQUNoQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUE7cUJBQ3pDO2lCQUNGO2FBQ0Y7WUFDRCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1NBQ2pDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFZO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDOUIsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFZO1FBQ2hCLE1BQU0sTUFBTSxHQUErQixFQUFFLENBQUE7UUFFN0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbkMsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNWLE9BQU8sTUFBTSxDQUFBO1NBQ2Q7UUFDRCxLQUFLLE1BQU0sQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUMzRCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUMzQztRQUNELE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUFZLEVBQUUsV0FBbUI7UUFDdkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNsRCxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFBO1NBQ3JEO1FBQ0QsT0FBTyxXQUFXLENBQUE7SUFDcEIsQ0FBQztDQUNGO0FBL0NELGdEQStDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBDb25maWdcbiAqIEBpZ25vcmVcbiAqICovXG5pbXBvcnQgeyBhcHBseVJlcGxhY2VtZW50cyB9IGZyb20gXCIuLi90ZXh0LXJlcGxhY2VtZW50c1wiO1xuaW1wb3J0IHsgQmFja2VuZFByb3hpZXMgfSBmcm9tIFwiLi9pbmRleFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bGVJbmZvIHtcbiAgYWN0aW9uVHlwZTogXCJyZWRpcmVjdFwiIHwgXCJyZXdyaXRlXCIsXG4gIGJhY2tlbmRLZXk/OiBzdHJpbmcsXG4gIG1hdGNoU2NoZW1lPzogc3RyaW5nLFxuICBob3N0bmFtZT86IHN0cmluZyxcbiAgcGF0aE1hdGNoTW9kZT86IFwicHJlZml4XCIgfCBcImZ1bGxcIixcbiAgaHR0cEhlYWRlcktleT86IHN0cmluZyxcbiAgaHR0cEhlYWRlclZhbHVlPzogUmVnRXhwIHwgc3RyaW5nLFxuICBwYXRoUGF0dGVybj86IFJlZ0V4cCB8IHN0cmluZyxcbiAgcGF0aFJlcGxhY2VtZW50UGF0dGVybj86IHN0cmluZyxcbiAgcmVkaXJlY3RVUkxQYXR0ZXJuPzogc3RyaW5nLFxuICByZWRpcmVjdFN0YXR1cz86IG51bWJlcixcbiAgcmVzcG9uc2VSZXBsYWNlbWVudHM/OiBbc3RyaW5nLCBzdHJpbmddW10sXG59XG5cbmRlY2xhcmUgdmFyIGFwcDogYW55XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVJ1bGUocjogYW55KTogciBpcyBSdWxlSW5mbyB7XG4gIGlmICh0eXBlb2YgciAhPT0gXCJvYmplY3RcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm11c3QgYmUgYW4gb2JqZWN0XCIpXG4gIH1cbiAgaWYgKCFyLmFjdGlvblR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJhY3Rpb25UeXBlIG11c3QgYmUgZGVmaW5lZFwiKVxuICB9XG4gIGlmIChyLmFjdGlvblR5cGUgIT09IFwicmVkaXJlY3RcIiAmJiByLmFjdGlvblR5cGUgIT09IFwicmV3cml0ZVwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiYWN0aW9uVHlwZSBtdXN0IGJlIGVpdGhlciBgcmVkaXJlY3RgIG9yIGByZXdyaXRlYFwiKVxuICB9XG4gIGlmIChyLmFjdGlvblR5cGUgPT09IFwicmV3cml0ZVwiICYmICFyLmJhY2tlbmRLZXkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJtdXN0IGluY2x1ZSBgYmFja2VuZEtleWAgd2hlbiBhY3Rpb25UeXBlIGlzIHNldCB0byBgcmV3cml0ZWBcIilcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSdWxlcyhiYWNrZW5kczogQmFja2VuZFByb3hpZXMsIHJ1bGVzOiBSdWxlSW5mb1tdKSB7XG4gIGNvbnN0IGNvbXBpbGVkID0gcnVsZXMubWFwKGNvbXBpbGVSdWxlKVxuICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gcnVsZUZldGNoKHJlcTogUmVxdWVzdEluZm8sIGluaXQ/OiBSZXF1ZXN0SW5pdCkge1xuICAgIGlmICh0eXBlb2YgcmVxID09PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXEgPSBuZXcgUmVxdWVzdChyZXEsIGluaXQpXG4gICAgfVxuICAgIGNvbnN0IG1hdGNoID0gY29tcGlsZWQuZmluZCgocikgPT4gcig8UmVxdWVzdD5yZXEpKVxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJubyByb3V0aW5nIHJ1bGUgZm91bmRcIiwgeyBzdGF0dXM6IDQwNCB9KVxuICAgIH1cbiAgICBjb25zdCBydWxlID0gbWF0Y2gucnVsZVxuICAgIC8vIGRvIHRoZSByZWRpcmVjdFxuICAgIGlmIChydWxlLmFjdGlvblR5cGUgPT09IFwicmVkaXJlY3RcIikge1xuICAgICAgbGV0IG9yaWdpbmFsID0gbmV3IFVSTChyZXEudXJsKVxuICAgICAgbGV0IHVybDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG4gICAgICBpZiAobWF0Y2gucGF0aFBhdHRlcm4gJiYgcnVsZS5yZWRpcmVjdFVSTFBhdHRlcm4pIHtcbiAgICAgICAgdXJsID0gbWF0Y2gucGF0aFBhdHRlcm4ucmVwbGFjZShvcmlnaW5hbC5wYXRobmFtZSwgcnVsZS5yZWRpcmVjdFVSTFBhdHRlcm4pXG4gICAgICB9IGVsc2UgaWYgKHJ1bGUucmVkaXJlY3RVUkxQYXR0ZXJuKSB7XG4gICAgICAgIHVybCA9IHJ1bGUucmVkaXJlY3RVUkxQYXR0ZXJuXG4gICAgICB9XG4gICAgICBpZiAoIXVybCB8fCBvcmlnaW5hbC50b1N0cmluZygpID09PSB1cmwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIkNhbid0IHJlZGlyZWN0IHRvIGEgYmFkIFVSTFwiLCB7IHN0YXR1czogNTAwIH0pXG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBydWxlLnJlZGlyZWN0U3RhdHVzIHx8IDMwMlxuICAgICAgY29uc3QgcmVkaXJlY3RUbyA9IG5ldyBVUkwodXJsLCBvcmlnaW5hbClcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJSZWRpcmVjdFwiLCB7IHN0YXR1czogc3RhdHVzLCBoZWFkZXJzOiB7IGxvY2F0aW9uOiByZWRpcmVjdFRvLnRvU3RyaW5nKCkgfSB9KVxuICAgIH1cbiAgICBpZiAocnVsZS5hY3Rpb25UeXBlICE9PSBcInJld3JpdGVcIikge1xuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIkludmFsaWQgcnVsZSBhY3Rpb25cIiwgeyBzdGF0dXM6IDUwMCB9KVxuICAgIH1cbiAgICBjb25zdCBiYWNrZW5kID0gcnVsZS5iYWNrZW5kS2V5ICYmIGJhY2tlbmRzID8gYmFja2VuZHMuZ2V0KHJ1bGUuYmFja2VuZEtleSkgOiB1bmRlZmluZWRcbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJObyBiYWNrZW5kIGZvciBydWxlXCIsIHsgc3RhdHVzOiA1MDIgfSlcbiAgICB9XG4gICAgLy8gcmV3cml0ZSByZXF1ZXN0IGlmIG5lY2Vzc2FyeVxuICAgIGlmIChtYXRjaC5wYXRoUGF0dGVybiAmJiBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pIHtcbiAgICAgIGxldCB1cmwgPSBuZXcgVVJMKHJlcS51cmwpXG4gICAgICB1cmwgPSBuZXcgVVJMKG1hdGNoLnBhdGhQYXR0ZXJuLnJlcGxhY2UodXJsLnBhdGhuYW1lLCBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pLCB1cmwpXG4gICAgICByZXEgPSBuZXcgUmVxdWVzdCh1cmwudG9TdHJpbmcoKSwgPFJlcXVlc3RJbml0PnJlcSlcbiAgICB9XG4gICAgaWYgKCFydWxlLnJlc3BvbnNlUmVwbGFjZW1lbnRzIHx8IHJ1bGUucmVzcG9uc2VSZXBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmFja2VuZChyZXEsIGluaXQpXG4gICAgfVxuXG4gICAgcmVxLmhlYWRlcnMuZGVsZXRlKFwiYWNjZXB0LWVuY29kaW5nXCIpXG4gICAgbGV0IHJlc3AgPSBhd2FpdCBiYWNrZW5kKHJlcSwgaW5pdClcbiAgICByZXR1cm4gYXBwbHlSZXBsYWNlbWVudHMocmVzcCwgcnVsZS5yZXNwb25zZVJlcGxhY2VtZW50cylcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21waWxlUnVsZShydWxlOiBSdWxlSW5mbykge1xuICBjb25zdCBwYXRoUGF0dGVybiA9IGVuc3VyZVBhdGhQYXR0ZXJuTWF0Y2hlcihydWxlLnBhdGhQYXR0ZXJuKVxuICBjb25zdCBodHRwSGVhZGVyVmFsdWUgPSBlbnN1cmVSZWdFeHAocnVsZS5odHRwSGVhZGVyVmFsdWUpXG4gIGNvbnN0IGZuID0gZnVuY3Rpb24gY29tcGlsZWRSdWxlKHJlcTogUmVxdWVzdCkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybClcbiAgICBpZiAocnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwXCIgfHwgcnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwc1wiKSB7XG4gICAgICBjb25zdCBzY2hlbWUgPSB1cmwucHJvdG9jb2wuc2xpY2UoMCwgLTEpXG4gICAgICBpZiAoc2NoZW1lICE9PSBydWxlLm1hdGNoU2NoZW1lKSByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgaWYgKHJ1bGUuaG9zdG5hbWUgJiYgcnVsZS5ob3N0bmFtZSAhPT0gXCJcIikge1xuICAgICAgaWYgKHVybC5ob3N0bmFtZSAhPT0gcnVsZS5ob3N0bmFtZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJ1bGUuaHR0cEhlYWRlcktleSAmJiBydWxlLmh0dHBIZWFkZXJLZXkgIT09IFwiXCIgJiYgaHR0cEhlYWRlclZhbHVlKSB7XG4gICAgICBjb25zdCBoZWFkZXIgPSByZXEuaGVhZGVycy5nZXQocnVsZS5odHRwSGVhZGVyS2V5KVxuICAgICAgaWYgKCFoZWFkZXIgfHwgIWhlYWRlci5tYXRjaChodHRwSGVhZGVyVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAocGF0aFBhdHRlcm4gJiYgIXBhdGhQYXR0ZXJuLm1hdGNoKHVybC5wYXRobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIHJldHVybiBPYmplY3QuYXNzaWduKGZuLCB7IHJ1bGU6IHJ1bGUsIHBhdGhQYXR0ZXJuOiBwYXRoUGF0dGVybiB9KVxufVxuXG5mdW5jdGlvbiBlbnN1cmVSZWdFeHAocGF0dGVybj86IHN0cmluZyB8IFJlZ0V4cCk6IFJlZ0V4cCB8IG51bGwge1xuICBpZiAoIXBhdHRlcm4gfHwgcGF0dGVybiA9PSBcIlwiKSByZXR1cm4gbnVsbFxuICBpZiAodHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIpIHJldHVybiBuZXcgUmVnRXhwKHBhdHRlcm4pXG4gIGlmIChwYXR0ZXJuIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gcGF0dGVyblxuXG4gIHRocm93IG5ldyBFcnJvcihcIlBhdHRlcm4gbXVzdCBiZSBhIHN0cmluZyBvciBSZWdFeHA6IFwiICsgdHlwZW9mIHBhdHRlcm4pXG59XG5cbmZ1bmN0aW9uIGVuc3VyZVBhdGhQYXR0ZXJuTWF0Y2hlcihwYXR0ZXJuPzogc3RyaW5nIHwgUmVnRXhwKTogUGF0aFBhdHRlcm5NYXRjaGVyIHwgbnVsbCB7XG4gIGlmICghcGF0dGVybiB8fCBwYXR0ZXJuID09IFwiXCIpIHJldHVybiBudWxsXG4gIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG5ldyBQYXRoUGF0dGVybk1hdGNoZXIocGF0dGVybilcbiAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiBuZXcgUGF0aFBhdHRlcm5NYXRjaGVyKHBhdHRlcm4pXG5cbiAgdGhyb3cgbmV3IEVycm9yKFwiUGF0dGVybiBtdXN0IGJlIGEgc3RyaW5nIG9yIFJlZ0V4cDogXCIgKyB0eXBlb2YgcGF0dGVybilcbn1cblxuXG5leHBvcnQgY2xhc3MgUGF0aFBhdHRlcm5NYXRjaGVyIHtcbiAgcHJpdmF0ZSByZWdleDogUmVnRXhwXG4gIHByaXZhdGUgcGFyYW1zOiBzdHJpbmdbXSA9IFtdXG5cbiAgY29uc3RydWN0b3IocGF0dGVybjogc3RyaW5nIHwgUmVnRXhwKSB7XG4gICAgaWYgKHBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgIHRoaXMucmVnZXggPSBwYXR0ZXJuXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSBwYXR0ZXJuLm1hdGNoKC8oWzpcXCpdXFx3KykvZylcbiAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgbWF0Y2hlcykge1xuICAgICAgICAgIHRoaXMucGFyYW1zLnB1c2gobWF0Y2guc3Vic3RyaW5nKDEpKVxuICAgICAgICAgIGlmIChtYXRjaC5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICAgICAgcGF0dGVybiA9IHBhdHRlcm4ucmVwbGFjZShtYXRjaCwgXCIoW14vLl0rKVwiKVxuICAgICAgICAgIH0gZWxzZSBpZiAobWF0Y2guc3RhcnRzV2l0aChcIipcIikpIHtcbiAgICAgICAgICAgIHBhdHRlcm4gPSBwYXR0ZXJuLnJlcGxhY2UobWF0Y2gsIFwiKC4rKVwiKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZWdleCA9IG5ldyBSZWdFeHAocGF0dGVybilcbiAgICB9XG4gIH1cblxuICBtYXRjaChwYXRoOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZWdleC50ZXN0KHBhdGgpXG4gIH1cblxuICBwYXJzZShwYXRoOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0ge31cblxuICAgIGNvbnN0IG1hdGNoID0gdGhpcy5yZWdleC5leGVjKHBhdGgpXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgcmV0dXJuIHBhcmFtc1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtwYXJhbUluZGV4LCBwYXJhbU5hbWVdIG9mIHRoaXMucGFyYW1zLmVudHJpZXMoKSkge1xuICAgICAgcGFyYW1zW3BhcmFtTmFtZV0gPSBtYXRjaFtwYXJhbUluZGV4ICsgMV07XG4gICAgfVxuICAgIHJldHVybiBwYXJhbXNcbiAgfVxuXG4gIHJlcGxhY2UocGF0aDogc3RyaW5nLCByZXBsYWNlbWVudDogc3RyaW5nKSB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5wYXJzZShwYXRoKVxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhwYXJhbXMpKSB7XG4gICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnJlcGxhY2UoYCQke25hbWV9YCwgdmFsdWUpXG4gICAgfVxuICAgIHJldHVybiByZXBsYWNlbWVudFxuICB9XG59XG4iXX0=