hyapp-h5/guild/packages/core/product-context.js
2026-07-12 17:38:53 +08:00

112 lines
3.5 KiB
JavaScript

(function () {
'use strict';
var CONTEXT_QUERY_KEYS = [
'token',
'access_token',
'accessToken',
'env',
'language',
'lang',
'locale',
'app_lang',
'appLanguage',
'mock',
];
var product = null;
function normalizeSlug(value, field) {
var slug = String(value || '')
.trim()
.toLowerCase();
if (!/^[a-z][a-z0-9_-]*$/.test(slug)) {
throw new Error('Invalid guild product ' + field + ': ' + slug);
}
return slug;
}
function freezeArray(value) {
return Object.freeze(Array.isArray(value) ? value.slice() : []);
}
function defineProduct(config) {
var next = config || {};
var normalized = Object.freeze({
key: normalizeSlug(next.key, 'key'),
appCode: normalizeSlug(next.appCode, 'appCode'),
languages: freezeArray(next.languages),
features: Object.freeze(
Object.assign(
{
hostCenter: true,
agencyCenter: true,
bdCenter: true,
wallet: true,
},
next.features || {}
)
),
});
// 同一页面只能属于一个产品;静默覆盖会让后加载的品牌包改变请求租户,属于高风险串数据。
if (product && product.key !== normalized.key) {
throw new Error('Guild product already defined as ' + product.key);
}
product = normalized;
window.HyAppDefaultAppCode = normalized.appCode;
window.HyAppI18nSupported = normalized.languages;
document.documentElement.setAttribute(
'data-hy-product',
normalized.key
);
return product;
}
function getProduct() {
if (!product) throw new Error('Guild product is not defined');
return product;
}
function currentParams() {
var params = new URLSearchParams(window.location.search || '');
var hash = window.location.hash || '';
if (hash.indexOf('?') >= 0) {
new URLSearchParams(hash.split('?').slice(1).join('?')).forEach(
function (value, key) {
if (!params.has(key)) params.set(key, value);
}
);
}
return params;
}
function buildURL(path, extra) {
var target = new URL(path, window.location.href);
var source = currentParams();
// 页面跳转只继承认证、环境和语言上下文,不复制筛选、分页等页面状态,避免不同中心解释同名参数。
CONTEXT_QUERY_KEYS.forEach(function (key) {
if (source.has(key) && !target.searchParams.has(key)) {
target.searchParams.set(key, source.get(key));
}
});
target.searchParams.set('app_code', getProduct().appCode);
Object.keys(extra || {}).forEach(function (key) {
var value = extra[key];
if (value === undefined || value === null || value === '') {
target.searchParams.delete(key);
return;
}
target.searchParams.set(key, String(value));
});
return target.toString();
}
window.HyGuild = window.HyGuild || {};
window.HyGuild.product = {
define: defineProduct,
get: getProduct,
buildURL: buildURL,
};
})();