@wevu/web-apis
Version:
Web API polyfills and global installers for mini-program runtimes
667 lines (666 loc) • 22.2 kB
JavaScript
import { URLPolyfill, URLSearchParamsPolyfill } from "./url.mjs";
//#region ../../@weapp-core/shared/dist/index.js
var __create = Object.create;
var __defProp$1 = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp$1(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
function isPlainObject(value) {
if (value === null || typeof value !== "object") return false;
const prototype = Object.getPrototypeOf(value);
if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) return false;
if (Symbol.iterator in value) return false;
if (Symbol.toStringTag in value) return Object.prototype.toString.call(value) === "[object Module]";
return true;
}
function _defu(baseObject, defaults, namespace = ".", merger) {
if (!isPlainObject(defaults)) return _defu(baseObject, {}, namespace, merger);
const object = { ...defaults };
for (const key of Object.keys(baseObject)) {
if (key === "__proto__" || key === "constructor") continue;
const value = baseObject[key];
if (value === null || value === void 0) continue;
if (merger && merger(object, key, value, namespace)) continue;
if (Array.isArray(value) && Array.isArray(object[key])) object[key] = [...value, ...object[key]];
else if (isPlainObject(value) && isPlainObject(object[key])) object[key] = _defu(value, object[key], (namespace ? `${namespace}.` : "") + key.toString(), merger);
else object[key] = value;
}
return object;
}
const DEFAULT_PROJECT_CONFIG_ROOT_KEYS = ["miniprogramRoot", "srcMiniprogramRoot"];
const DEFAULT_RUNTIME_CAPABILITIES = Object.freeze({
globalPageStack: true,
globalCreateSelectorQuery: true,
selectorQueryScopeByIn: true,
globalCreateIntersectionObserver: true,
intersectionObserverScopeByParameter: true,
pageShareMenu: true,
shareTimelineRequiresShareAppMessage: true,
pageScrollApi: true,
pullDownRefreshApi: true,
globalRouterApi: true,
appErrorListener: true,
appPageNotFoundListener: true,
appUnhandledRejectionListener: true,
appThemeChangeListener: true,
appMemoryWarningListener: true
});
const DEFAULT_PAGE_IDENTITY_RULES = [{
prefix: "route",
source: "route"
}];
/**
* @description 全仓库统一的小程序平台描述表。
*/
const MINI_PROGRAM_PLATFORM_DESCRIPTORS = [
{
id: "weapp",
displayName: "WeChat Mini Program",
family: "wechat",
aliases: [
"weapp",
"wechat",
"weixin",
"wx"
],
outputExtensions: {
js: "js",
json: "json",
wxml: "wxml",
wxss: "wxss",
wxs: "wxs"
},
projectConfigFileName: "project.config.json",
projectConfigRootKeys: DEFAULT_PROJECT_CONFIG_ROOT_KEYS,
ide: {},
build: {
autoTouchAppStyle: true,
defaultBuildTarget: "es2020"
},
resolvePreservedNpmDirNames: () => ["miniprogram_npm"],
json: {},
npm: { distDirName: () => "miniprogram_npm" },
wxml: {
eventBindingStyle: "default",
directivePrefix: "wx"
},
compiler: { templatePreset: "wechat" },
typescript: { appTypesPackage: "miniprogram-api-typings" },
runtime: {
globalObjectKey: "wx",
hostConfigKey: "__wxConfig",
globalResolvePriority: 1,
routeGlobalResolvePriority: 0,
capabilities: DEFAULT_RUNTIME_CAPABILITIES,
pageIdentityRules: [
{
prefix: "webview",
source: "field",
field: "__wxWebviewId__"
},
{
prefix: "exparser",
source: "field",
field: "__wxExparserNodeId__"
},
...DEFAULT_PAGE_IDENTITY_RULES
]
}
},
{
id: "alipay",
displayName: "Alipay Mini Program",
family: "alipay",
aliases: [
"alipay",
"ali",
"my"
],
outputExtensions: {
js: "js",
json: "json",
wxml: "axml",
wxss: "acss",
wxs: "sjs"
},
projectConfigFileName: "mini.project.json",
projectConfigRootKeys: DEFAULT_PROJECT_CONFIG_ROOT_KEYS,
scriptModuleTagByExtension: { sjs: "import-sjs" },
usesProjectRootNpmDir: true,
ide: {
requiresOpenPlatformArg: true,
defaultProjectRoot: "dist/alipay/dist"
},
build: {
autoTouchAppStyle: false,
defaultBuildTarget: "es2015"
},
resolvePreservedNpmDirNames: (options) => [options?.alipayNpmMode === "miniprogram_npm" ? "miniprogram_npm" : "node_modules"],
json: {
normalizeUsingComponents: true,
fillComponentGenericsDefault: true,
rewriteBundleNpmImports: true
},
npm: {
distDirName: (options) => options?.alipayNpmMode === "miniprogram_npm" ? "miniprogram_npm" : "node_modules",
normalizeImportPath: true,
normalizeMiniprogramPackage: true,
copyEsModuleDirectory: true,
hoistNestedDependencies: true,
shouldRebuildCachedPackage: true
},
wxml: {
eventBindingStyle: "alipay",
directivePrefix: "a",
normalizeComponentTagName: true,
normalizeVueTemplate: true,
emitGenericPlaceholder: true
},
compiler: { templatePreset: "alipay" },
typescript: { appTypesPackage: "@mini-types/alipay" },
runtime: {
globalObjectKey: "my",
hostConfigKey: "__wxConfig",
globalResolvePriority: 0,
routeGlobalResolvePriority: 2,
capabilities: {
...DEFAULT_RUNTIME_CAPABILITIES,
pageShareMenu: false,
appThemeChangeListener: false
},
pageIdentityRules: DEFAULT_PAGE_IDENTITY_RULES
}
},
{
id: "swan",
displayName: "Baidu Smart Program",
family: "swan",
aliases: [
"swan",
"baidu",
"bd"
],
outputExtensions: {
js: "js",
json: "json",
wxml: "swan",
wxss: "css",
wxs: "sjs"
},
projectConfigFileName: "project.swan.json",
projectConfigRootKeys: ["smartProgramRoot", ...DEFAULT_PROJECT_CONFIG_ROOT_KEYS],
ide: {},
build: { autoTouchAppStyle: false },
resolvePreservedNpmDirNames: () => ["miniprogram_npm"],
json: {},
npm: { distDirName: () => "miniprogram_npm" },
wxml: {
eventBindingStyle: "default",
directivePrefix: "s"
},
compiler: { templatePreset: "swan" },
typescript: { appTypesPackage: "miniprogram-api-typings" },
runtime: {
globalObjectKey: "swan",
hostConfigKey: "__wxConfig",
capabilities: DEFAULT_RUNTIME_CAPABILITIES,
pageIdentityRules: DEFAULT_PAGE_IDENTITY_RULES
}
},
{
id: "tt",
displayName: "ByteDance / Douyin Mini Program",
family: "tt",
aliases: [
"tt",
"toutiao",
"bytedance",
"douyin"
],
outputExtensions: {
js: "js",
json: "json",
wxml: "ttml",
wxss: "ttss"
},
projectConfigFileName: "project.config.json",
projectConfigRootKeys: DEFAULT_PROJECT_CONFIG_ROOT_KEYS,
ide: {},
build: { autoTouchAppStyle: false },
resolvePreservedNpmDirNames: () => ["miniprogram_npm"],
json: {},
npm: { distDirName: () => "miniprogram_npm" },
wxml: {
eventBindingStyle: "default",
directivePrefix: "tt"
},
compiler: { templatePreset: "tt" },
typescript: { appTypesPackage: "@douyin-microapp/typings" },
runtime: {
globalObjectKey: "tt",
hostConfigKey: "__wxConfig",
globalResolvePriority: 2,
routeGlobalResolvePriority: 1,
capabilities: {
...DEFAULT_RUNTIME_CAPABILITIES,
appThemeChangeListener: false
},
pageIdentityRules: DEFAULT_PAGE_IDENTITY_RULES
}
},
{
id: "jd",
displayName: "JD Mini Program",
family: "wechat",
aliases: ["jd", "jingdong"],
outputExtensions: {
js: "js",
json: "json",
wxml: "jxml",
wxss: "jxss",
wxs: "wxs"
},
projectConfigFileName: "project.config.json",
projectConfigRootKeys: DEFAULT_PROJECT_CONFIG_ROOT_KEYS,
ide: {},
build: { autoTouchAppStyle: false },
resolvePreservedNpmDirNames: () => ["miniprogram_npm"],
json: {},
npm: { distDirName: () => "miniprogram_npm" },
wxml: {
eventBindingStyle: "default",
directivePrefix: "wx"
},
compiler: { templatePreset: "wechat" },
typescript: { appTypesPackage: "miniprogram-api-typings" },
runtime: {
globalObjectKey: "jd",
hostConfigKey: "__wxConfig",
capabilities: DEFAULT_RUNTIME_CAPABILITIES,
pageIdentityRules: DEFAULT_PAGE_IDENTITY_RULES
}
},
{
id: "xhs",
displayName: "Xiaohongshu Mini Program",
family: "wechat",
aliases: [
"xhs",
"xiaohongshu",
"little-red-book",
"red"
],
outputExtensions: {
js: "js",
json: "json",
wxml: "xhsml",
wxss: "css",
wxs: "wxs"
},
projectConfigFileName: "project.config.json",
projectConfigRootKeys: DEFAULT_PROJECT_CONFIG_ROOT_KEYS,
ide: {},
build: { autoTouchAppStyle: false },
resolvePreservedNpmDirNames: () => ["miniprogram_npm"],
json: {},
npm: { distDirName: () => "miniprogram_npm" },
wxml: {
eventBindingStyle: "default",
directivePrefix: "wx"
},
compiler: { templatePreset: "wechat" },
typescript: { appTypesPackage: "miniprogram-api-typings" },
runtime: {
globalObjectKey: "xhs",
hostConfigKey: "__wxConfig",
capabilities: DEFAULT_RUNTIME_CAPABILITIES,
pageIdentityRules: DEFAULT_PAGE_IDENTITY_RULES
}
}
];
function createMiniProgramPlatformRegistry(descriptors) {
const descriptorById = /* @__PURE__ */ new Map();
const aliasToId = /* @__PURE__ */ new Map();
const runtimeGlobalKeyToId = /* @__PURE__ */ new Map();
for (const descriptor of descriptors) {
descriptorById.set(descriptor.id, descriptor);
runtimeGlobalKeyToId.set(descriptor.runtime.globalObjectKey, descriptor.id);
aliasToId.set(descriptor.id, descriptor.id);
for (const alias of descriptor.aliases) {
const normalized = alias.trim().toLowerCase();
if (!normalized) continue;
aliasToId.set(normalized, descriptor.id);
}
}
return {
aliasToId,
descriptorById,
runtimeGlobalKeyToId
};
}
const { aliasToId: MINI_PROGRAM_PLATFORM_ALIAS_TO_ID, descriptorById: MINI_PROGRAM_PLATFORM_DESCRIPTOR_BY_ID, runtimeGlobalKeyToId: MINI_PROGRAM_RUNTIME_GLOBAL_KEY_TO_ID } = createMiniProgramPlatformRegistry(MINI_PROGRAM_PLATFORM_DESCRIPTORS);
Object.freeze(MINI_PROGRAM_PLATFORM_DESCRIPTORS.map((descriptor) => descriptor.id));
Object.freeze(Array.from(new Set(MINI_PROGRAM_PLATFORM_DESCRIPTORS.map((descriptor) => descriptor.wxml?.directivePrefix).filter((prefix) => Boolean(prefix)))));
const ORDERED_RUNTIME_GLOBAL_KEYS = Object.freeze(Array.from(new Set(MINI_PROGRAM_PLATFORM_DESCRIPTORS.map((descriptor) => descriptor.runtime.globalObjectKey))));
const MAX_RUNTIME_RESOLVE_PRIORITY = Number.MAX_SAFE_INTEGER;
function getOrderedRuntimeGlobalKeysByPriority(priorityKey) {
const ordered = [...MINI_PROGRAM_PLATFORM_DESCRIPTORS].sort((left, right) => {
const leftPriority = left.runtime[priorityKey] ?? MAX_RUNTIME_RESOLVE_PRIORITY;
const rightPriority = right.runtime[priorityKey] ?? MAX_RUNTIME_RESOLVE_PRIORITY;
if (leftPriority !== rightPriority) return leftPriority - rightPriority;
return MINI_PROGRAM_PLATFORM_DESCRIPTORS.indexOf(left) - MINI_PROGRAM_PLATFORM_DESCRIPTORS.indexOf(right);
});
return Object.freeze(Array.from(new Set(ordered.map((descriptor) => descriptor.runtime.globalObjectKey))));
}
getOrderedRuntimeGlobalKeysByPriority("globalResolvePriority");
getOrderedRuntimeGlobalKeysByPriority("routeGlobalResolvePriority");
Object.freeze(Object.fromEntries(MINI_PROGRAM_PLATFORM_ALIAS_TO_ID.entries()));
/**
* @description 获取平台描述。
*/
function getMiniProgramPlatformDescriptor(platform) {
const descriptor = MINI_PROGRAM_PLATFORM_DESCRIPTOR_BY_ID.get(platform);
if (!descriptor) throw new Error(`不支持的小程序平台 "${platform}"。`);
return descriptor;
}
/**
* @description 获取宿主全局对象 key。
*/
function getMiniProgramRuntimeGlobalKey(platform) {
return getMiniProgramPlatformDescriptor(platform).runtime.globalObjectKey;
}
/**
* @description 返回 runtime 全局对象 key 的扫描优先级。
*/
function getMiniProgramRuntimeGlobalKeys(platform) {
if (platform) return [getMiniProgramRuntimeGlobalKey(platform)];
return ORDERED_RUNTIME_GLOBAL_KEYS;
}
/*!
* get-value <https://github.com/jonschlinkert/get-value>
*
* Copyright (c) 2014-present, Jon Schlinkert.
* Released under the MIT License.
*/
/*!
* is-primitive <https://github.com/jonschlinkert/is-primitive>
*
* Copyright (c) 2014-present, Jon Schlinkert.
* Released under the MIT License.
*/
var require_is_primitive = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = function isPrimitive(val) {
if (typeof val === "object") return val === null;
return typeof val !== "function";
};
}));
/*!
* isobject <https://github.com/jonschlinkert/isobject>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
var require_isobject = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = function isObject(val) {
return val != null && typeof val === "object" && Array.isArray(val) === false;
};
}));
/*!
* is-plain-object <https://github.com/jonschlinkert/is-plain-object>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
var require_is_plain_object = /* @__PURE__ */ __commonJSMin(((exports, module) => {
var isObject = require_isobject();
function isObjectObject(o) {
return isObject(o) === true && Object.prototype.toString.call(o) === "[object Object]";
}
module.exports = function isPlainObject(o) {
var ctor, prot;
if (isObjectObject(o) === false) return false;
ctor = o.constructor;
if (typeof ctor !== "function") return false;
prot = ctor.prototype;
if (isObjectObject(prot) === false) return false;
if (prot.hasOwnProperty("isPrototypeOf") === false) return false;
return true;
};
}));
(/* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
const { deleteProperty } = Reflect;
const isPrimitive = require_is_primitive();
const isPlainObject = require_is_plain_object();
const isObject = (value) => {
return typeof value === "object" && value !== null || typeof value === "function";
};
const isUnsafeKey = (key) => {
return key === "__proto__" || key === "constructor" || key === "prototype";
};
const validateKey = (key) => {
if (!isPrimitive(key)) throw new TypeError("Object keys must be strings or symbols");
if (isUnsafeKey(key)) throw new Error(`Cannot set unsafe key: "${key}"`);
};
const toStringKey = (input) => {
return Array.isArray(input) ? input.flat().map(String).join(",") : input;
};
const createMemoKey = (input, options) => {
if (typeof input !== "string" || !options) return input;
let key = input + ";";
if (options.arrays !== void 0) key += `arrays=${options.arrays};`;
if (options.separator !== void 0) key += `separator=${options.separator};`;
if (options.split !== void 0) key += `split=${options.split};`;
if (options.merge !== void 0) key += `merge=${options.merge};`;
if (options.preservePaths !== void 0) key += `preservePaths=${options.preservePaths};`;
return key;
};
const memoize = (input, options, fn) => {
const key = toStringKey(options ? createMemoKey(input, options) : input);
validateKey(key);
const value = setValue.cache.get(key) || fn();
setValue.cache.set(key, value);
return value;
};
const splitString = (input, options = {}) => {
const sep = options.separator || ".";
const preserve = sep === "/" ? false : options.preservePaths;
if (typeof input === "string" && preserve !== false && /\//.test(input)) return [input];
const parts = [];
let part = "";
const push = (part) => {
let number;
if (part.trim() !== "" && Number.isInteger(number = Number(part))) parts.push(number);
else parts.push(part);
};
for (let i = 0; i < input.length; i++) {
const value = input[i];
if (value === "\\") {
part += input[++i];
continue;
}
if (value === sep) {
push(part);
part = "";
continue;
}
part += value;
}
if (part) push(part);
return parts;
};
const split = (input, options) => {
if (options && typeof options.split === "function") return options.split(input);
if (typeof input === "symbol") return [input];
if (Array.isArray(input)) return input;
return memoize(input, options, () => splitString(input, options));
};
const assignProp = (obj, prop, value, options) => {
validateKey(prop);
if (value === void 0) deleteProperty(obj, prop);
else if (options && options.merge) {
const merge = options.merge === "function" ? options.merge : Object.assign;
if (merge && isPlainObject(obj[prop]) && isPlainObject(value)) obj[prop] = merge(obj[prop], value);
else obj[prop] = value;
} else obj[prop] = value;
return obj;
};
const setValue = (target, path, value, options) => {
if (!path || !isObject(target)) return target;
const keys = split(path, options);
let obj = target;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const next = keys[i + 1];
validateKey(key);
if (next === void 0) {
assignProp(obj, key, value, options);
break;
}
if (typeof next === "number" && !Array.isArray(obj[key])) {
obj = obj[key] = [];
continue;
}
if (!isObject(obj[key])) obj[key] = {};
obj = obj[key];
}
return target;
};
setValue.split = split;
setValue.cache = /* @__PURE__ */ new Map();
setValue.clear = () => {
setValue.cache = /* @__PURE__ */ new Map();
};
module.exports = setValue;
})))(), 1)).default;
//#endregion
//#region src/constructors.ts
function resolveUrlConstructor() {
return typeof globalThis.URL === "function" ? globalThis.URL : void 0;
}
function isUrlInstance(value) {
const HostUrl = resolveUrlConstructor();
return Boolean(HostUrl && value instanceof HostUrl || value instanceof URLPolyfill);
}
function resolveUrlSearchParamsConstructor() {
return typeof globalThis.URLSearchParams === "function" ? globalThis.URLSearchParams : void 0;
}
function isUrlSearchParamsInstance(value) {
const HostUrlSearchParams = resolveUrlSearchParamsConstructor();
return Boolean(HostUrlSearchParams && value instanceof HostUrlSearchParams || value instanceof URLSearchParamsPolyfill);
}
function resolveTextEncoderConstructor() {
return typeof globalThis.TextEncoder === "function" ? globalThis.TextEncoder : void 0;
}
function resolveTextDecoderConstructor() {
return typeof globalThis.TextDecoder === "function" ? globalThis.TextDecoder : void 0;
}
//#endregion
//#region src/shared.ts
var RequestGlobalsEventTarget = class {
listeners = /* @__PURE__ */ new Map();
addEventListener(type, listener) {
const set = this.listeners.get(type) ?? /* @__PURE__ */ new Set();
set.add(listener);
this.listeners.set(type, set);
}
removeEventListener(type, listener) {
this.listeners.get(type)?.delete(listener);
}
dispatchEvent(event) {
const payload = {
...event,
target: event.target ?? this,
currentTarget: event.currentTarget ?? this
};
for (const listener of this.listeners.get(event.type) ?? []) listener(payload);
const handlerKey = `on${event.type}`;
const handler = this[handlerKey];
if (typeof handler === "function") handler(payload);
return true;
}
};
function resolveRequestGlobalsHost() {
if (typeof globalThis !== "undefined") return globalThis;
return {};
}
function isRequestGlobalsHostCandidate(value) {
return value != null && (typeof value === "object" || typeof value === "function");
}
function pushRequestGlobalsHost(hosts, candidate) {
if (!isRequestGlobalsHostCandidate(candidate)) return;
if (!hosts.includes(candidate)) hosts.push(candidate);
}
function resolveRequestGlobalsHosts() {
const hosts = [];
const primaryHost = resolveRequestGlobalsHost();
pushRequestGlobalsHost(hosts, primaryHost);
for (const name of [
"global",
"self",
"window"
]) pushRequestGlobalsHost(hosts, primaryHost[name]);
for (const key of getMiniProgramRuntimeGlobalKeys()) pushRequestGlobalsHost(hosts, primaryHost[key]);
return hosts;
}
function installRequestGlobalBinding(name, value) {
if (!name) return;
try {
const host = resolveRequestGlobalsHost();
host[name] = value;
} catch {}
}
function cloneArrayBuffer(buffer) {
return buffer.slice(0);
}
function cloneArrayBufferView(view) {
const copied = new Uint8Array(view.byteLength);
copied.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
return copied.buffer;
}
function encodeTextFallback(value) {
const binary = unescape(encodeURIComponent(String(value)));
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
return bytes.buffer;
}
function encodeText(value) {
const TextEncoderConstructor = resolveTextEncoderConstructor();
if (TextEncoderConstructor) return new TextEncoderConstructor().encode(value).buffer;
return encodeTextFallback(value);
}
function decodeTextFallback(value) {
const bytes = new Uint8Array(value);
let binary = "";
for (const byte of bytes) binary += String.fromCharCode(byte);
try {
return decodeURIComponent(escape(binary));
} catch {
return binary;
}
}
function decodeText(value) {
const TextDecoderConstructor = resolveTextDecoderConstructor();
if (TextDecoderConstructor) return new TextDecoderConstructor().decode(value);
return decodeTextFallback(value);
}
function normalizeHeaderName(name) {
return name.trim().toLowerCase();
}
//#endregion
export { decodeTextFallback as a, installRequestGlobalBinding as c, resolveRequestGlobalsHosts as d, isUrlInstance as f, getMiniProgramRuntimeGlobalKeys as g, resolveUrlConstructor as h, decodeText as i, normalizeHeaderName as l, resolveTextEncoderConstructor as m, cloneArrayBuffer as n, encodeText as o, isUrlSearchParamsInstance as p, cloneArrayBufferView as r, encodeTextFallback as s, RequestGlobalsEventTarget as t, resolveRequestGlobalsHost as u };