UNPKG

@qiniu/miku-delivery-mp-ks

Version:

Kuaishou Mini Program SDK for Miku Delivery

76 lines (75 loc) 2.65 kB
/** * @file 域名缓存规则相关逻辑 * @desc 详见 https://github.com/qbox/mikud/blob/main/docs/httpdns.md */ import { parseQuery, stringifyQuery } from '../utils/index'; import { Polyfilled_URL } from '../utils/url'; export function getCacheKey( /** 请求原 URL */ url, /** 缓存 Key 生成规则 */ cacheKeyConfig, /** bucket ID,值可能为空字符串,代表没有 bucket ID */ bucket) { const host = bucket || new Polyfilled_URL(url).hostname; // 获取 URL 中 path & query(不带 `?`)的简单实现 // 不直接使用 class URL 解析的结果,是因为其结果不能区分 path: "" 或 "/" let path, query; url = url.replace(/^\w+:\/\//, '').split('#')[0]; // 干掉 protocol & hash const queryIndex = url.indexOf('?'); if (queryIndex >= 0) { query = url.slice(queryIndex + 1); url = url.slice(0, queryIndex); } else { query = ''; } const pathIndex = url.indexOf('/'); path = pathIndex >= 0 ? url.slice(pathIndex) : ''; path = applyRewrites(cacheKeyConfig.rewrites, path); query = applyQueryStringConfig(cacheKeyConfig.queryString, query); let cacheKey = host + path; if (query !== '') cacheKey = cacheKey + '?' + query; return cacheKey; } export function applyRewrites(rewrites, path) { for (const rewrite of rewrites) { const matched = matchRewrite(rewrite, path); if (matched != null) { path = applyRewriteMatched(rewrite, matched); break; } } return path; } function matchRewrite(rewrite, pathQuery) { const re = new RegExp(rewrite.pattern); const matched = re.exec(pathQuery); return matched; } const replIndexedCapturingGroupPattern = /\${(\d+)}/g; function applyRewriteMatched(rewrite, matched) { return rewrite.repl.replace(replIndexedCapturingGroupPattern, (str, indexStr) => { var _a; const index = parseInt(indexStr, 10); return index >= matched.length ? str : ((_a = matched[index]) !== null && _a !== void 0 ? _a : ''); }); } export function applyQueryStringConfig({ type, values }, querystring) { if (type === 'none') return ''; if (type === 'all') return querystring; const source = parseQuery(querystring); const target = values !== null && values !== void 0 ? values : []; const result = {}; Object.keys(source).forEach(k => { if (type === 'include' && !target.includes(k)) return; if (type === 'exclude' && target.includes(k)) return; result[k] = source[k]; }); return stringifyQuery(result); }