@qiniu/miku-delivery-mp-ks
Version:
Kuaishou Mini Program SDK for Miku Delivery
76 lines (75 loc) • 2.65 kB
JavaScript
/**
* @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);
}