@mearl/browser-core 3.0.0-beta.1 → 3.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/README.zh-CN.md +13 -0
- package/dist/agentChat.d.ts +10 -1
- package/dist/agentChat.js +8 -0
- package/dist/agentServiceProtocol.d.ts +23 -0
- package/dist/agentServiceProtocol.js +3 -0
- package/dist/agentSkills.d.ts +1 -1
- package/dist/app-profile-runtime/types.d.ts +10 -12
- package/dist/appProfileDefinition.d.ts +32 -14
- package/dist/appProfileDefinition.js +63 -69
- package/dist/axSnapshot.js +1 -1
- package/dist/boundedRequestBuffer.d.ts +4 -4
- package/dist/browserActionProtocol.d.ts +55 -45
- package/dist/browserActionProtocol.js +12 -15
- package/dist/browserCapabilities.d.ts +47 -0
- package/dist/browserCapabilities.js +63 -0
- package/dist/browserDiscovery.d.ts +3 -0
- package/dist/browserDiscovery.js +20 -0
- package/dist/browserEnhancement.d.ts +161 -0
- package/dist/browserEnhancement.js +80 -0
- package/dist/cookie.d.ts +6 -0
- package/dist/cookie.js +20 -5
- package/dist/dataStructure.d.ts +8 -0
- package/dist/dataStructure.js +58 -0
- package/dist/deviceEmulation.d.ts +6 -0
- package/dist/deviceEmulation.js +13 -0
- package/dist/deviceEnvironmentObservation.d.ts +48 -0
- package/dist/deviceEnvironmentObservation.js +77 -0
- package/dist/domClicking.d.ts +14 -0
- package/dist/domClicking.js +98 -10
- package/dist/domInspection.js +13 -1
- package/dist/extensionServiceProtocol.d.ts +7 -0
- package/dist/extensionServiceProtocol.js +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +8 -0
- package/dist/pageAct.d.ts +2 -0
- package/dist/pageAct.js +42 -10
- package/dist/pageDialog.d.ts +66 -0
- package/dist/pageDialog.js +175 -0
- package/dist/pageObserver.js +16 -5
- package/dist/pagePressing.d.ts +1 -1
- package/dist/pluginPageHost.js +2 -2
- package/dist/providerAppResources.d.ts +39 -0
- package/dist/providerAppResources.js +2 -0
- package/dist/proxyPermissions.js +3 -3
- package/dist/requestMetadata.d.ts +9 -0
- package/dist/requestMetadata.js +8 -0
- package/dist/requestSerializer.d.ts +2 -2
- package/dist/requestSerializer.js +1 -29
- package/dist/requestStreamCapture.d.ts +5 -3
- package/dist/requestStreamCapture.js +2 -0
- package/dist/runActions.js +1 -1
- package/dist/types.d.ts +4 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# @mearl/browser-core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Page control logic and protocols shared by browsers and Node: DOM/AX snapshots, action observation, input, scrolling, navigation, request serialization, capture cursors, device simulation, generic device appearance, Cookie/domain permissions, and plugin task, page, and state contracts. Modules have no browser extension or native process installation side effects.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The core includes no preset App identities. The host validates profile IDs against its active capability catalog. App profile schemas, explicit options, revisions, and page runtime bindings are data contracts; independent capability packages supply complete bridge implementations.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The built-in installer at `@mearl/browser-core/appProfileRuntime` synchronizes only UA, navigator.appVersion, navigator.platform, and touch points. It does not install App bridges, business globals, container stacks, or authorization handlers. With a pageRuntime binding, the host must prepare the exact code from the installed capability package and execute it through the page runtime dispatcher; the base installer cannot substitute for this. See [browser bundles](../../docs/browser-bundles.md#page-runtimes) for resource preparation and dispatch.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The default proxy authorization addresses are localhost and 127.0.0.1. Hosts obtain permission for other sites and pass them in the authorization list. The core includes Aplus/RUM/ARMS event parsers; additional parsers register through capability packages.
|
|
12
|
+
|
|
13
|
+
Agent contracts are defined in agentChat.ts, agentSkills.ts, and pluginModels.ts and exported through the corresponding subpaths. agent-runtime uses these contracts to avoid duplicate definitions. Serializable page functions remain self-contained for shared use by the Extension and CDP.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @mearl/browser-core
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
浏览器与 Node 可共享的页面控制逻辑和协议:DOM/AX 快照、动作观察、输入、滚动、导航、请求序列化、捕获游标、设备模拟、通用设备外观、Cookie/域名权限和插件任务、页面、状态合同。模块没有浏览器扩展或本机进程的安装副作用。
|
|
6
|
+
|
|
7
|
+
核心不预置 App 身份;档案 ID 由宿主的已激活能力目录校验。App 档案 schema、显式选项、revision 和页面运行时绑定是数据合同,完整桥实现由独立能力包提供。
|
|
8
|
+
|
|
9
|
+
`@mearl/browser-core/appProfileRuntime` 的内置安装器只同步 UA、navigator.appVersion、navigator.platform 和触摸点,不安装 App 桥、业务全局变量、容器栈或授权处理。有 pageRuntime 绑定时,宿主必须先从已安装的能力包准备确切代码,再通过页面运行时派发器执行;不能调用基础安装器代替。资源准备和派发见 [能力包](../../docs/browser-bundles.zh-CN.md#页面运行时)。
|
|
10
|
+
|
|
11
|
+
默认代理授权地址为 localhost 与 127.0.0.1。其余站点由宿主取得权限后传入授权列表。核心内置 Aplus/RUM/ARMS 事件解析;扩展解析器通过能力包注册。
|
|
12
|
+
|
|
13
|
+
Agent 合同源在本包的 agentChat.ts、agentSkills.ts 和 pluginModels.ts;分别通过同名子路径导出,agent-runtime 使用这些合同,避免并行维护副本。可序列化的页面函数保持自包含,便于 Extension 与 CDP 共同使用。
|
package/dist/agentChat.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type AgentChatEventKind = 'lifecycle' | 'notification' | 'request' | 'error';
|
|
2
2
|
export type AgentChatSessionStatus = 'idle' | 'running' | 'waiting' | 'error';
|
|
3
|
+
export declare function isQoderAuthenticationError(message: unknown): boolean;
|
|
4
|
+
export declare function isQoderMissingSessionError(message: unknown): boolean;
|
|
3
5
|
export type AgentChatCapabilitySupport = boolean | 'runtime';
|
|
4
6
|
export declare const AGENT_CHAT_MAX_PAGE_URL_CHARS = 16384;
|
|
5
7
|
export declare const AGENT_CHAT_MAX_PAGE_TITLE_CHARS = 2048;
|
|
@@ -15,6 +17,8 @@ export interface AgentChatProviderDescriptor {
|
|
|
15
17
|
id: string;
|
|
16
18
|
name: string;
|
|
17
19
|
available: boolean;
|
|
20
|
+
/** False while accepted conversations retain a removed or superseded runtime. */
|
|
21
|
+
acceptsNewSessions?: boolean;
|
|
18
22
|
capabilities: {
|
|
19
23
|
streaming: boolean;
|
|
20
24
|
resume: boolean;
|
|
@@ -26,7 +30,8 @@ export interface AgentChatProviderDescriptor {
|
|
|
26
30
|
};
|
|
27
31
|
error?: string;
|
|
28
32
|
setup?: {
|
|
29
|
-
installCommand
|
|
33
|
+
installCommand?: string;
|
|
34
|
+
canInstall?: boolean;
|
|
30
35
|
loginCommand?: string;
|
|
31
36
|
docsUrl?: string;
|
|
32
37
|
};
|
|
@@ -89,6 +94,7 @@ export interface AgentChatSendOptions {
|
|
|
89
94
|
message: string;
|
|
90
95
|
images?: AgentChatImageInput[];
|
|
91
96
|
displayMessage?: string;
|
|
97
|
+
hasAdditionalContext?: boolean;
|
|
92
98
|
clientMessageId?: string;
|
|
93
99
|
}
|
|
94
100
|
export interface AgentChatRunOptions {
|
|
@@ -155,6 +161,9 @@ export interface AgentChatStatus {
|
|
|
155
161
|
sessions: AgentChatSession[];
|
|
156
162
|
}
|
|
157
163
|
export interface AgentChatKnownEventParams {
|
|
164
|
+
'session/reconnected': {
|
|
165
|
+
providerSessionId: string;
|
|
166
|
+
};
|
|
158
167
|
'turn/started': {
|
|
159
168
|
turn: {
|
|
160
169
|
id: string;
|
package/dist/agentChat.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export function isQoderAuthenticationError(message) {
|
|
2
|
+
return (typeof message === 'string' &&
|
|
3
|
+
/^(?:Authentication (?:is )?required|Unauthenticated|Sign-in required)(?:[:.\s]|$)/i.test(message));
|
|
4
|
+
}
|
|
5
|
+
export function isQoderMissingSessionError(message) {
|
|
6
|
+
return typeof message === 'string' && /^(?:Invalid params:\s*)?Invalid session identifier\b/i.test(message);
|
|
7
|
+
}
|
|
1
8
|
export const AGENT_CHAT_MAX_PAGE_URL_CHARS = 16_384;
|
|
2
9
|
export const AGENT_CHAT_MAX_PAGE_TITLE_CHARS = 2_048;
|
|
3
10
|
export const AGENT_CHAT_MAX_TOOLBOX_CONTEXT_CHARS = 65_536;
|
|
@@ -123,6 +130,7 @@ function readAgentChatRequestParams(params) {
|
|
|
123
130
|
return { ...params, requestId: params.requestId };
|
|
124
131
|
}
|
|
125
132
|
const AGENT_CHAT_EVENT_PARAM_READERS = {
|
|
133
|
+
'session/reconnected': params => typeof params.providerSessionId === 'string' ? { providerSessionId: params.providerSessionId } : null,
|
|
126
134
|
'turn/started': readAgentChatTurnParams,
|
|
127
135
|
'turn/completed': readAgentChatTurnParams,
|
|
128
136
|
'session/model/updated': readAgentChatModelParams,
|
|
@@ -11,6 +11,18 @@ export interface AgentServiceActionMap {
|
|
|
11
11
|
request: undefined;
|
|
12
12
|
response: AgentChatStatus;
|
|
13
13
|
};
|
|
14
|
+
agent_chat_install_provider: {
|
|
15
|
+
request: {
|
|
16
|
+
providerId: string;
|
|
17
|
+
};
|
|
18
|
+
response: AgentChatStatus;
|
|
19
|
+
};
|
|
20
|
+
agent_chat_login_qoder: {
|
|
21
|
+
request: undefined;
|
|
22
|
+
response: {
|
|
23
|
+
url: string | null;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
14
26
|
agent_chat_prepare: {
|
|
15
27
|
request: AgentChatPrepareOptions;
|
|
16
28
|
response: {
|
|
@@ -51,6 +63,14 @@ export interface AgentServiceActionMap {
|
|
|
51
63
|
request: AgentChatEventsOptions;
|
|
52
64
|
response: AgentChatEventsResult;
|
|
53
65
|
};
|
|
66
|
+
agent_chat_read_visualization: {
|
|
67
|
+
request: {
|
|
68
|
+
path: string;
|
|
69
|
+
};
|
|
70
|
+
response: {
|
|
71
|
+
html: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
54
74
|
agent_chat_refresh: {
|
|
55
75
|
request: AgentChatEventsOptions;
|
|
56
76
|
response: AgentChatRefreshResult;
|
|
@@ -112,6 +132,8 @@ export type AgentServiceHandlerMap = {
|
|
|
112
132
|
export declare const AGENT_SERVICE_ACTIONS: {
|
|
113
133
|
readonly agent_chat_pick_directory: true;
|
|
114
134
|
readonly agent_chat_status: true;
|
|
135
|
+
readonly agent_chat_install_provider: true;
|
|
136
|
+
readonly agent_chat_login_qoder: true;
|
|
115
137
|
readonly agent_chat_prepare: true;
|
|
116
138
|
readonly agent_chat_list_sessions: true;
|
|
117
139
|
readonly agent_chat_start: true;
|
|
@@ -120,6 +142,7 @@ export declare const AGENT_SERVICE_ACTIONS: {
|
|
|
120
142
|
readonly agent_chat_interrupt: true;
|
|
121
143
|
readonly agent_chat_close: true;
|
|
122
144
|
readonly agent_chat_events: true;
|
|
145
|
+
readonly agent_chat_read_visualization: true;
|
|
123
146
|
readonly agent_chat_refresh: true;
|
|
124
147
|
readonly agent_chat_open_app: true;
|
|
125
148
|
readonly agent_chat_open_workspace: true;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const AGENT_SERVICE_ACTIONS = {
|
|
2
2
|
agent_chat_pick_directory: true,
|
|
3
3
|
agent_chat_status: true,
|
|
4
|
+
agent_chat_install_provider: true,
|
|
5
|
+
agent_chat_login_qoder: true,
|
|
4
6
|
agent_chat_prepare: true,
|
|
5
7
|
agent_chat_list_sessions: true,
|
|
6
8
|
agent_chat_start: true,
|
|
@@ -9,6 +11,7 @@ export const AGENT_SERVICE_ACTIONS = {
|
|
|
9
11
|
agent_chat_interrupt: true,
|
|
10
12
|
agent_chat_close: true,
|
|
11
13
|
agent_chat_events: true,
|
|
14
|
+
agent_chat_read_visualization: true,
|
|
12
15
|
agent_chat_refresh: true,
|
|
13
16
|
agent_chat_open_app: true,
|
|
14
17
|
agent_chat_open_workspace: true,
|
package/dist/agentSkills.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type AgentSkillProviderId =
|
|
1
|
+
export type AgentSkillProviderId = string;
|
|
2
2
|
export type AgentSkillScope = 'project' | 'global';
|
|
3
3
|
export type AgentInstalledSkillScope = AgentSkillScope | 'system' | 'admin' | 'built-in' | 'unknown';
|
|
4
4
|
export interface AgentInstalledSkill {
|
|
@@ -2,15 +2,16 @@ import type { AppProfileBinding, AppProfilePolicies, AppProfileSetting } from '.
|
|
|
2
2
|
import type { BrowserDevicePresetName } from '../browserActionProtocol.js';
|
|
3
3
|
import type { DeviceCutout } from '../deviceEmulation.js';
|
|
4
4
|
/** 桥调用风格,与页面适配器使用的端内调用约定一一对应。 */
|
|
5
|
-
export type AppBridgeStyle =
|
|
5
|
+
export type AppBridgeStyle = string;
|
|
6
6
|
export interface AppBridgeSpec {
|
|
7
7
|
global: string;
|
|
8
8
|
style: AppBridgeStyle;
|
|
9
9
|
/** 页面脚本重设全局对象时仍保留桥叶子,同时接纳页面对象上的其他 API。 */
|
|
10
10
|
persistent?: boolean;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/** Provider-defined identifier, interpreted by its installed page runtime. */
|
|
13
|
+
export type AppBridgeBehavior = string;
|
|
14
|
+
/** 桥方法名到标准化动作的映射。命名空间桥使用 `Class.method`,其余使用 api 名。 */
|
|
14
15
|
export interface BridgeActionMap {
|
|
15
16
|
open: string[];
|
|
16
17
|
close: string[];
|
|
@@ -18,7 +19,7 @@ export interface BridgeActionMap {
|
|
|
18
19
|
navigationBar?: string[];
|
|
19
20
|
statusBar?: string[];
|
|
20
21
|
systemInfo: string[];
|
|
21
|
-
|
|
22
|
+
protocol: string[];
|
|
22
23
|
kvGet?: string[];
|
|
23
24
|
kvSet?: string[];
|
|
24
25
|
kvDelete?: string[];
|
|
@@ -68,14 +69,14 @@ export interface AppMiniProgramMessageRule {
|
|
|
68
69
|
}
|
|
69
70
|
export type AppMiniProgramNativeAction = 'navigateMiniProgram' | 'subscribeMessage';
|
|
70
71
|
export interface AppMiniProgramNativeRoute {
|
|
71
|
-
/**
|
|
72
|
+
/** 承接原生能力的小程序页面 pathname。 */
|
|
72
73
|
pathname: string;
|
|
73
74
|
/** 该页面允许模拟的固定原生动作,动作名读取 URL 的 action 参数。 */
|
|
74
75
|
actions: AppMiniProgramNativeAction[];
|
|
75
76
|
/** 限制业务根域,避免其他小程序的同名页面被接管。 */
|
|
76
77
|
hostSuffixes?: string[];
|
|
77
78
|
}
|
|
78
|
-
/**
|
|
79
|
+
/** 小程序容器相关规则统一收口,避免为每种业务页增加顶层配置。 */
|
|
79
80
|
export interface AppMiniProgramConfig {
|
|
80
81
|
paymentRoutes?: AppMiniProgramPaymentRoute[];
|
|
81
82
|
nativeRoutes?: AppMiniProgramNativeRoute[];
|
|
@@ -187,6 +188,8 @@ export interface InjectedAppProfileConfig {
|
|
|
187
188
|
binding?: AppProfileBinding;
|
|
188
189
|
policies?: AppProfilePolicies;
|
|
189
190
|
settings?: AppProfileSetting[];
|
|
191
|
+
settingsUi?: 'runtime';
|
|
192
|
+
settingsGroup?: string;
|
|
190
193
|
profile: string;
|
|
191
194
|
label: string;
|
|
192
195
|
globals: Record<string, string>;
|
|
@@ -207,11 +210,6 @@ export interface InjectedAppProfileConfig {
|
|
|
207
210
|
schemes: AppSchemeRule[];
|
|
208
211
|
miniProgram?: AppMiniProgramConfig;
|
|
209
212
|
imagePicker?: AppImagePickerConfig;
|
|
210
|
-
/** 原生定位返回地址时使用的逆地理编码服务,复用容器的 MTop 传输。 */
|
|
211
|
-
geolocation?: {
|
|
212
|
-
reverseGeocodeApi: string;
|
|
213
|
-
version: string;
|
|
214
|
-
};
|
|
215
213
|
overlay?: AppOverlayConfig;
|
|
216
214
|
/** URL 参数为真时以新 WebView 替换当前业务层。 */
|
|
217
215
|
popBeforeOpenParam?: string;
|
|
@@ -221,7 +219,7 @@ export interface InjectedAppProfileConfig {
|
|
|
221
219
|
layerUrlProxy?: AppLayerUrlProxyConfig;
|
|
222
220
|
urlSyncHostSuffixes?: string[];
|
|
223
221
|
animationMs?: number;
|
|
224
|
-
|
|
222
|
+
runtimeOptions?: Record<string, unknown>;
|
|
225
223
|
titleBar?: AppTitleBarConfig;
|
|
226
224
|
rootContainer?: AppRootContainerConfig;
|
|
227
225
|
simulateSystemBars?: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { BrowserDevicePresetName, AppBridgeConfig } from './browserActionProtocol.js';
|
|
2
2
|
import type { AppBridgeSpec, AppImagePickerConfig, AppLayerUrlProxyConfig, AppMiniProgramConfig, AppNativeBackConfig, AppOverlayConfig, AppSchemeRule, AppTitleBarHostStyle, BridgeActionMap } from './app-profile-runtime/types.js';
|
|
3
3
|
export interface AppProfilePolicies {
|
|
4
|
-
titleBar?:
|
|
4
|
+
titleBar?: string;
|
|
5
5
|
navigatorLanguage?: boolean;
|
|
6
|
-
networkResult?:
|
|
6
|
+
networkResult?: string;
|
|
7
7
|
languages?: string[];
|
|
8
8
|
defaultLanguage?: string;
|
|
9
9
|
}
|
|
@@ -56,28 +56,49 @@ export interface AppProfileCatalogEntry {
|
|
|
56
56
|
revision: string;
|
|
57
57
|
definition: AppProfileDefinition;
|
|
58
58
|
}
|
|
59
|
+
/** Short, author-supplied guidance; discovery does not load Skills or follow links. */
|
|
60
|
+
export interface AppProfileUsage {
|
|
61
|
+
description?: string;
|
|
62
|
+
limitations?: string[];
|
|
63
|
+
skills?: string[];
|
|
64
|
+
documentation?: Array<{
|
|
65
|
+
title: string;
|
|
66
|
+
url: string;
|
|
67
|
+
}>;
|
|
68
|
+
}
|
|
59
69
|
/** 单容器档案(纯数据) */
|
|
60
70
|
export interface AppProfileDefinition {
|
|
61
71
|
name: string;
|
|
72
|
+
usage?: AppProfileUsage;
|
|
62
73
|
/** Content-addressed installer supplied by the selected browser capability package. */
|
|
63
74
|
pageRuntime?: {
|
|
64
75
|
id: string;
|
|
65
76
|
sha256: string;
|
|
66
77
|
};
|
|
67
78
|
label: string;
|
|
68
|
-
|
|
79
|
+
actionIcon?: string;
|
|
80
|
+
labels?: {
|
|
81
|
+
en: string;
|
|
82
|
+
zh_CN?: string;
|
|
83
|
+
};
|
|
84
|
+
/** 容器的应用标识,由能力包定义 */
|
|
69
85
|
appName: string;
|
|
70
86
|
defaultAppVersion: string;
|
|
71
|
-
/** UA
|
|
72
|
-
uaFamily?:
|
|
87
|
+
/** UA 主体格式;未提供时使用标准浏览器 UA */
|
|
88
|
+
uaFamily?: string;
|
|
73
89
|
uaTemplate?: {
|
|
74
90
|
ios: string;
|
|
75
91
|
android: string;
|
|
76
92
|
};
|
|
77
93
|
policies?: AppProfilePolicies;
|
|
78
94
|
settings?: AppProfileSetting[];
|
|
79
|
-
|
|
80
|
-
|
|
95
|
+
authorization?: {
|
|
96
|
+
hook: string;
|
|
97
|
+
method: string;
|
|
98
|
+
};
|
|
99
|
+
settingsUi?: 'runtime';
|
|
100
|
+
settingsGroup?: string;
|
|
101
|
+
/** UA 主体之后追加的 token,{v} 占位会被替换为 appVersion */
|
|
81
102
|
uaTokens: string[];
|
|
82
103
|
/** 额外注入到 window 的变量(公共变量由 resolve 统一生成) */
|
|
83
104
|
globals: Record<string, string>;
|
|
@@ -90,10 +111,6 @@ export interface AppProfileDefinition {
|
|
|
90
111
|
miniProgram?: AppMiniProgramConfig;
|
|
91
112
|
/** 原生图片页 scheme 的浏览器选图与上传配置 */
|
|
92
113
|
imagePicker?: AppImagePickerConfig;
|
|
93
|
-
geolocation?: {
|
|
94
|
-
reverseGeocodeApi: string;
|
|
95
|
-
version: string;
|
|
96
|
-
};
|
|
97
114
|
/**
|
|
98
115
|
* 地址栏借位同步的可选 host 白名单:容器栈顶 URL 的 host 命中时,地址栏借 top
|
|
99
116
|
* 域名同步其 path+query+hash(pushState 同源约束下保持域名不变只改 path);
|
|
@@ -124,10 +141,11 @@ export interface AppProfileDefinition {
|
|
|
124
141
|
statusBarBackgroundColors?: Record<string, string>;
|
|
125
142
|
/** 按业务根域配置标题栏与状态栏样式。 */
|
|
126
143
|
titleBarHostStyles?: AppTitleBarHostStyle[];
|
|
127
|
-
/**
|
|
128
|
-
|
|
144
|
+
/** Opaque configuration owned by the installed page runtime. */
|
|
145
|
+
runtimeOptions?: Record<string, unknown>;
|
|
129
146
|
}
|
|
130
|
-
|
|
147
|
+
/** Behavior IDs belong to the installed page runtime, never to a host-side enum. */
|
|
148
|
+
export declare function isAppBridgeBehavior(value: unknown): value is string;
|
|
131
149
|
/** Validate plain data before registration or compiling a document-start configuration. */
|
|
132
150
|
export declare function validateAppProfileDefinition(value: unknown): AppProfileDefinition;
|
|
133
151
|
export declare function validateAppProfileContribution(value: unknown): AppProfileContribution | undefined;
|
|
@@ -1,57 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
'
|
|
4
|
-
|
|
5
|
-
'callback',
|
|
6
|
-
'btrip',
|
|
7
|
-
'invoke',
|
|
8
|
-
'callHandler',
|
|
9
|
-
'amap',
|
|
10
|
-
'didi',
|
|
11
|
-
'easybikeNative',
|
|
12
|
-
'mega',
|
|
13
|
-
'wechat',
|
|
14
|
-
'wechatMiniProgram',
|
|
15
|
-
]);
|
|
16
|
-
export const APP_BRIDGE_BEHAVIORS = [
|
|
17
|
-
'navigate',
|
|
18
|
-
'closeAll',
|
|
19
|
-
'closeBackData',
|
|
20
|
-
'postMessage',
|
|
21
|
-
'notifySubscribe',
|
|
22
|
-
'notifyUnsubscribe',
|
|
23
|
-
'notifyPost',
|
|
24
|
-
'sharedFileRead',
|
|
25
|
-
'sharedFileWrite',
|
|
26
|
-
'sharedDataGet',
|
|
27
|
-
'sharedDataSet',
|
|
28
|
-
'legacyBroadcastCreate',
|
|
29
|
-
'legacyBroadcastPost',
|
|
30
|
-
'legacyBroadcastClose',
|
|
31
|
-
'memoryGet',
|
|
32
|
-
'memorySet',
|
|
33
|
-
'memoryDelete',
|
|
34
|
-
'availabilityMap',
|
|
35
|
-
'userInfo',
|
|
36
|
-
'authCode',
|
|
37
|
-
'networkInfo',
|
|
38
|
-
'geolocation',
|
|
39
|
-
'permission',
|
|
40
|
-
'imagePicker',
|
|
41
|
-
'prefetch',
|
|
42
|
-
'fptTrack',
|
|
43
|
-
'mtopStream',
|
|
44
|
-
'previewFile',
|
|
45
|
-
'toast',
|
|
46
|
-
'unsupportedNativeInput',
|
|
47
|
-
'payment',
|
|
48
|
-
'userTrack',
|
|
49
|
-
'calendar',
|
|
50
|
-
'networkQualityMonitor',
|
|
51
|
-
'beaconRequest',
|
|
52
|
-
'voiceRecognition',
|
|
53
|
-
];
|
|
54
|
-
const BEHAVIORS = new Set(APP_BRIDGE_BEHAVIORS);
|
|
1
|
+
/** Behavior IDs belong to the installed page runtime, never to a host-side enum. */
|
|
2
|
+
export function isAppBridgeBehavior(value) {
|
|
3
|
+
return typeof value === 'string' && /^[a-zA-Z][a-zA-Z0-9_.:-]{0,95}$/.test(value);
|
|
4
|
+
}
|
|
55
5
|
function record(value) {
|
|
56
6
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
57
7
|
}
|
|
@@ -95,7 +45,7 @@ function validateActions(value) {
|
|
|
95
45
|
'navigationBar',
|
|
96
46
|
'statusBar',
|
|
97
47
|
'systemInfo',
|
|
98
|
-
'
|
|
48
|
+
'protocol',
|
|
99
49
|
'kvGet',
|
|
100
50
|
'kvSet',
|
|
101
51
|
'kvDelete',
|
|
@@ -103,7 +53,7 @@ function validateActions(value) {
|
|
|
103
53
|
'noop',
|
|
104
54
|
'silent',
|
|
105
55
|
];
|
|
106
|
-
fields(value, ['open', 'close', 'title', 'systemInfo', '
|
|
56
|
+
fields(value, ['open', 'close', 'title', 'systemInfo', 'protocol', 'noop'], [...arrays, 'responses', 'behaviors'], 'actions');
|
|
107
57
|
for (const key of arrays)
|
|
108
58
|
if (value[key] !== undefined && !strings(value[key]))
|
|
109
59
|
invalid(`actions.${key}`);
|
|
@@ -111,7 +61,7 @@ function validateActions(value) {
|
|
|
111
61
|
invalid('actions.responses');
|
|
112
62
|
if (value.behaviors !== undefined &&
|
|
113
63
|
(!stringMap(value.behaviors) ||
|
|
114
|
-
!Object.values(value.behaviors).every(item =>
|
|
64
|
+
!Object.values(value.behaviors).every(item => isAppBridgeBehavior(item))))
|
|
115
65
|
invalid('actions.behaviors');
|
|
116
66
|
}
|
|
117
67
|
/** Validate plain data before registration or compiling a document-start configuration. */
|
|
@@ -133,15 +83,19 @@ export function validateAppProfileDefinition(value) {
|
|
|
133
83
|
'schemes',
|
|
134
84
|
];
|
|
135
85
|
const optional = [
|
|
86
|
+
'usage',
|
|
87
|
+
'actionIcon',
|
|
88
|
+
'labels',
|
|
136
89
|
'pageRuntime',
|
|
137
90
|
'uaFamily',
|
|
138
91
|
'uaTemplate',
|
|
139
92
|
'policies',
|
|
140
93
|
'settings',
|
|
141
94
|
'settingsGroup',
|
|
95
|
+
'settingsUi',
|
|
96
|
+
'authorization',
|
|
142
97
|
'miniProgram',
|
|
143
98
|
'imagePicker',
|
|
144
|
-
'geolocation',
|
|
145
99
|
'urlSyncHostSuffixes',
|
|
146
100
|
'overlay',
|
|
147
101
|
'popBeforeOpenParam',
|
|
@@ -152,7 +106,7 @@ export function validateAppProfileDefinition(value) {
|
|
|
152
106
|
'titleBarHiddenPathnames',
|
|
153
107
|
'statusBarBackgroundColors',
|
|
154
108
|
'titleBarHostStyles',
|
|
155
|
-
'
|
|
109
|
+
'runtimeOptions',
|
|
156
110
|
];
|
|
157
111
|
fields(value, required, optional, 'definition');
|
|
158
112
|
for (const key of ['name', 'label', 'appName', 'defaultAppVersion'])
|
|
@@ -160,6 +114,37 @@ export function validateAppProfileDefinition(value) {
|
|
|
160
114
|
invalid(key);
|
|
161
115
|
if (!/^[a-z][a-z0-9-]*(?:\/[a-z][a-z0-9-]*)?$/.test(value.name))
|
|
162
116
|
invalid('name');
|
|
117
|
+
if (value.usage !== undefined) {
|
|
118
|
+
const usage = value.usage;
|
|
119
|
+
fields(usage, [], ['description', 'limitations', 'skills', 'documentation'], 'usage');
|
|
120
|
+
if (new TextEncoder().encode(JSON.stringify(usage)).byteLength > 4096)
|
|
121
|
+
invalid('usage exceeds 4 KiB');
|
|
122
|
+
if (usage.description !== undefined && (!text(usage.description) || usage.description.length > 512))
|
|
123
|
+
invalid('usage.description');
|
|
124
|
+
for (const key of ['limitations', 'skills']) {
|
|
125
|
+
const items = usage[key];
|
|
126
|
+
if (items !== undefined && (!Array.isArray(items) || items.length > 8 || items.some(item => !text(item) || !item || item.length > 256)))
|
|
127
|
+
invalid(`usage.${key}`);
|
|
128
|
+
}
|
|
129
|
+
if (usage.documentation !== undefined) {
|
|
130
|
+
if (!Array.isArray(usage.documentation) || usage.documentation.length > 8)
|
|
131
|
+
invalid('usage.documentation');
|
|
132
|
+
for (const link of usage.documentation) {
|
|
133
|
+
fields(link, ['title', 'url'], [], 'usage.documentation');
|
|
134
|
+
if (!text(link.title) || !link.title || link.title.length > 128 || !text(link.url) || link.url.length > 1024)
|
|
135
|
+
invalid('usage.documentation');
|
|
136
|
+
let url;
|
|
137
|
+
try {
|
|
138
|
+
url = new URL(link.url);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
invalid('usage.documentation.url');
|
|
142
|
+
}
|
|
143
|
+
if (url.protocol !== 'https:' || url.username || url.password)
|
|
144
|
+
invalid('usage.documentation.url');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
163
148
|
if (value.pageRuntime !== undefined) {
|
|
164
149
|
fields(value.pageRuntime, ['id', 'sha256'], [], 'pageRuntime');
|
|
165
150
|
const runtime = value.pageRuntime;
|
|
@@ -191,17 +176,28 @@ export function validateAppProfileDefinition(value) {
|
|
|
191
176
|
.split('.')
|
|
192
177
|
.some(part => ['__proto__', 'prototype', 'constructor'].includes(part)) ||
|
|
193
178
|
globals.has(bridge.global) ||
|
|
194
|
-
|
|
179
|
+
(typeof bridge.style !== 'string' || !/^[a-zA-Z][a-zA-Z0-9-]{0,63}$/.test(bridge.style)) ||
|
|
195
180
|
(bridge.persistent !== undefined && typeof bridge.persistent !== 'boolean'))
|
|
196
181
|
invalid('bridge');
|
|
197
182
|
globals.add(bridge.global);
|
|
198
183
|
}
|
|
199
184
|
validateActions(value.actions);
|
|
185
|
+
if (value.labels !== undefined) {
|
|
186
|
+
fields(value.labels, ['en'], ['zh_CN'], 'labels');
|
|
187
|
+
if (!text(value.labels.en) || !value.labels.en || value.labels.en.length > 120 || value.labels.zh_CN !== undefined && (!text(value.labels.zh_CN) || value.labels.zh_CN.length > 120))
|
|
188
|
+
invalid('labels');
|
|
189
|
+
}
|
|
190
|
+
if (value.actionIcon !== undefined && (typeof value.actionIcon !== 'string' || value.actionIcon.length > 32768 || !/^data:image\/png;base64,iVBORw0KGgo[A-Za-z0-9+/]*={0,2}$/.test(value.actionIcon)))
|
|
191
|
+
invalid('actionIcon');
|
|
192
|
+
if (value.authorization !== undefined && (!record(value.authorization) || Object.keys(value.authorization).sort().join(',') !== 'hook,method' || typeof value.authorization.hook !== 'string' || !/^[a-z][a-zA-Z0-9_.-]{0,95}$/.test(value.authorization.hook) || typeof value.authorization.method !== 'string' || !value.authorization.method || value.authorization.method.length > 200))
|
|
193
|
+
invalid('authorization');
|
|
194
|
+
if (value.settingsUi !== undefined && value.settingsUi !== 'runtime')
|
|
195
|
+
throw new Error('Invalid App settings UI');
|
|
200
196
|
if (value.settingsGroup !== undefined &&
|
|
201
|
-
|
|
197
|
+
(typeof value.settingsGroup !== 'string' || value.settingsGroup.length > 64))
|
|
202
198
|
invalid('settingsGroup');
|
|
203
199
|
if (value.uaFamily !== undefined &&
|
|
204
|
-
|
|
200
|
+
(typeof value.uaFamily !== 'string' || value.uaFamily.length > 64))
|
|
205
201
|
invalid('uaFamily');
|
|
206
202
|
if (value.uaTemplate !== undefined) {
|
|
207
203
|
fields(value.uaTemplate, ['ios', 'android'], [], 'uaTemplate');
|
|
@@ -212,9 +208,9 @@ export function validateAppProfileDefinition(value) {
|
|
|
212
208
|
fields(value.policies, [], ['titleBar', 'navigatorLanguage', 'networkResult', 'languages', 'defaultLanguage'], 'policies');
|
|
213
209
|
const p = value.policies;
|
|
214
210
|
if (p.titleBar !== undefined &&
|
|
215
|
-
|
|
211
|
+
(typeof p.titleBar !== 'string' || p.titleBar.length > 64))
|
|
216
212
|
invalid('policies.titleBar');
|
|
217
|
-
if (p.networkResult !== undefined &&
|
|
213
|
+
if (p.networkResult !== undefined && (typeof p.networkResult !== 'string' || p.networkResult.length > 64))
|
|
218
214
|
invalid('policies.networkResult');
|
|
219
215
|
if (p.navigatorLanguage !== undefined && typeof p.navigatorLanguage !== 'boolean')
|
|
220
216
|
invalid('policies.navigatorLanguage');
|
|
@@ -281,7 +277,7 @@ export function validateAppProfileDefinition(value) {
|
|
|
281
277
|
'navigationBar',
|
|
282
278
|
'statusBar',
|
|
283
279
|
'systemInfo',
|
|
284
|
-
'
|
|
280
|
+
'protocol',
|
|
285
281
|
'kvGet',
|
|
286
282
|
'kvSet',
|
|
287
283
|
'kvDelete',
|
|
@@ -307,9 +303,8 @@ export function validateAppProfileDefinition(value) {
|
|
|
307
303
|
invalid('setting.option type');
|
|
308
304
|
}
|
|
309
305
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
invalid(key);
|
|
306
|
+
if (value.runtimeOptions !== undefined && (!record(value.runtimeOptions) || !json(value.runtimeOptions)))
|
|
307
|
+
invalid('runtimeOptions');
|
|
313
308
|
for (const key of ['popBeforeOpenParam', 'messageEvent'])
|
|
314
309
|
if (value[key] !== undefined && !text(value[key]))
|
|
315
310
|
invalid(key);
|
|
@@ -321,7 +316,6 @@ export function validateAppProfileDefinition(value) {
|
|
|
321
316
|
function validateStructuredOptions(value) {
|
|
322
317
|
const shapes = {
|
|
323
318
|
nativeBack: [[], ['event', 'controlFunction', 'handler']],
|
|
324
|
-
geolocation: [['reverseGeocodeApi', 'version'], []],
|
|
325
319
|
layerUrlProxy: [
|
|
326
320
|
['sourceHostPrefix', 'pathPrefix', 'targetHostSuffixes'],
|
|
327
321
|
['defaultTargetHost'],
|
package/dist/axSnapshot.js
CHANGED
|
@@ -290,7 +290,7 @@ export function resolvePageSnapshotQuery(query) {
|
|
|
290
290
|
if (query === undefined)
|
|
291
291
|
return undefined;
|
|
292
292
|
if (!query || typeof query !== 'object' || Array.isArray(query)) {
|
|
293
|
-
throw new Error('page_snapshot: query must be an object');
|
|
293
|
+
throw new Error('page_snapshot: query must be an object, for example {"query":{"text":"提交","exact":false}}.');
|
|
294
294
|
}
|
|
295
295
|
const { text, role, exact } = query;
|
|
296
296
|
if (text !== undefined && (typeof text !== 'string' || !text.trim())) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CapturedRequest } from './types.js';
|
|
2
2
|
export declare const REQUEST_BUFFER_MAX_ENTRIES = 500;
|
|
3
3
|
export declare const REQUEST_BUFFER_MAX_BYTES: number;
|
|
4
4
|
export declare const REQUEST_BUFFER_MAX_FIELD_BYTES: number;
|
|
@@ -12,7 +12,7 @@ export interface RequestBufferLimits {
|
|
|
12
12
|
maxFieldBytes?: number;
|
|
13
13
|
}
|
|
14
14
|
export declare function limitBufferedField(value: any, maxBytes: number): any;
|
|
15
|
-
export declare function estimateRequestBufferBytes(request:
|
|
15
|
+
export declare function estimateRequestBufferBytes(request: CapturedRequest): number;
|
|
16
16
|
export declare function createRequestBufferAccounting(): RequestBufferAccounting;
|
|
17
|
-
export declare function appendRequestToBuffer(requests:
|
|
18
|
-
export declare function refreshRequestInBuffer(requests:
|
|
17
|
+
export declare function appendRequestToBuffer(requests: CapturedRequest[], accounting: RequestBufferAccounting, request: CapturedRequest, limits?: RequestBufferLimits): CapturedRequest[];
|
|
18
|
+
export declare function refreshRequestInBuffer(requests: CapturedRequest[], accounting: RequestBufferAccounting, request: CapturedRequest, limits?: RequestBufferLimits): CapturedRequest[];
|