@mearl/app-profiles 3.0.0-beta.3 → 3.0.0-beta.5
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 +26 -5
- package/dist/metadata.d.ts +2 -2
- package/dist/metadata.js +2 -3
- package/dist/profiles.d.ts +3 -1
- package/dist/profiles.js +11 -34
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,15 +1,36 @@
|
|
|
1
1
|
# @mearl/app-profiles
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
核心不内置 App 档案。App UA、版本、桥对象、设置、scheme 路由、业务响应和容器实现均由安装的能力包提供;本包负责声明式档案校验、编译与设置覆盖。
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import { resolveAppProfileDefinition, type AppProfile } from '@mearl/app-profiles';
|
|
7
|
+
|
|
8
|
+
export function compileInstalledApp(definition: AppProfile) {
|
|
9
|
+
return resolveAppProfileDefinition(definition, { os: 'android' });
|
|
10
|
+
}
|
|
9
11
|
```
|
|
10
12
|
|
|
11
13
|
宿主可以向 resolveAppProfile 或 resolveAppProfileDefinition 提供已校验的动态定义;编译器保留桥、设置及 pageRuntime 描述,不执行能力代码。定义与选项被复制并绑定 revision,插件升级不直接改写活动文档。
|
|
12
14
|
|
|
13
15
|
resolveAppProfileUpdate、rebuildAppProfileConfig 和 updateAppProfileSetting 保持显式选项、设备外观及方法覆盖的优先级。preset 默认值由宿主传入,用户已有选择继续优先;能力包安装成功不等于默认配置已经应用。
|
|
14
16
|
|
|
15
|
-
完整 App
|
|
17
|
+
完整 App 行为由能力包声明并安装到受控页面;真实设备授权仍由相应宿主能力执行。拆分与验收进度见 [迁移说明](../../docs/migration.md)。
|
|
18
|
+
|
|
19
|
+
## Agent 能力发现
|
|
20
|
+
|
|
21
|
+
`mearl get_capabilities`、SDK `getCapabilities()`、MCP `browser_get_capabilities` 查询当前目标浏览器,沿用 browser/session 路由。默认返回动作、设备预设和 App 摘要;传 `{ "app": "package/app" }` 按需展开桥方法、可调设置和默认版本。目录为 partial 或 unsupported 时不能据此断言 App 未安装,available=false 的条目不可启用。方法按声明组分类:responses 为固定回包,noop 为成功空实现,behaviors 为模拟行为;这些都不证明真实业务操作可用。
|
|
22
|
+
|
|
23
|
+
能力包可在每份 App 定义中声明可选 `usage`,浏览器包与 Node/Skill 插件共用同一格式:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"usage": {
|
|
28
|
+
"description": "WebView 与桥接行为模拟",
|
|
29
|
+
"limitations": ["真实设备授权需要对应的宿主能力"],
|
|
30
|
+
"skills": ["example-skill"],
|
|
31
|
+
"documentation": [{ "title": "使用说明", "url": "https://example.com/docs" }]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
usage 最大 4 KiB;description 最多 512 字符,limitations/skills/documentation 各最多 8 项。文档只接受无凭据的 HTTPS URL。查询只读取已安装元数据,不执行插件刷新、不打开文档、不安装或加载 Skill,也不输出桥接脚本、全局变量值及固定回包内容。Skill 名称是作者提供的入口,不代表该 Skill 已安装;通用调用继续使用 set_app_profile/tab_open,特殊流程才读取配套说明。
|
package/dist/metadata.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const BUILTIN_APP_PROFILE_LABELS: Record<
|
|
1
|
+
/** App labels are supplied by installed capability definitions. */
|
|
2
|
+
export declare const BUILTIN_APP_PROFILE_LABELS: Readonly<Record<string, string>>;
|
package/dist/metadata.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
};
|
|
1
|
+
/** App labels are supplied by installed capability definitions. */
|
|
2
|
+
export const BUILTIN_APP_PROFILE_LABELS = Object.freeze({});
|
package/dist/profiles.d.ts
CHANGED
|
@@ -8,7 +8,9 @@ export declare function validateAppBridgeConfig(value: unknown): AppBridgeConfig
|
|
|
8
8
|
export declare function mergeAppBridgeConfigs(...configs: Array<AppBridgeConfig | undefined>): AppBridgeConfig | undefined;
|
|
9
9
|
/** 将声明式方法覆盖编译进运行时动作表,不修改档案的静态数据。 */
|
|
10
10
|
export declare function applyAppBridgeConfig(actions: BridgeActionMap, config?: AppBridgeConfig): BridgeActionMap;
|
|
11
|
-
|
|
11
|
+
/** Built-ins provide UA/version identity; full environments come from capability packages. */
|
|
12
|
+
/** Profiles are supplied by installed capabilities; the core has no App defaults. */
|
|
13
|
+
export declare const APP_PROFILES: Readonly<Partial<Record<BuiltinAppProfileName, AppProfile>>>;
|
|
12
14
|
export interface ResolveAppProfileOptions extends AppProfileOptions {
|
|
13
15
|
os?: AppProfileOs;
|
|
14
16
|
appVersion?: string;
|
package/dist/profiles.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { DEVICE_PRESETS, APP_BRIDGE_BEHAVIORS, appProfileRevision, validateAppProfileDefinition, resolveEmulationConfig, } from '@mearl/browser-core';
|
|
2
|
-
import { BUILTIN_APP_PROFILE_LABELS } from './metadata.js';
|
|
3
2
|
function emptyActions() {
|
|
4
3
|
return {
|
|
5
4
|
open: [],
|
|
@@ -174,16 +173,8 @@ export function applyAppBridgeConfig(actions, config) {
|
|
|
174
173
|
return out;
|
|
175
174
|
}
|
|
176
175
|
/** Built-ins provide UA/version identity; full environments come from capability packages. */
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
...(uaFamily && { uaFamily }), globals: {}, bridges: [], activeEvents: [], actions: emptyActions(), schemes: [] };
|
|
180
|
-
}
|
|
181
|
-
export const APP_PROFILES = {
|
|
182
|
-
fliggy: basicProfile('fliggy', 'LX', '10.0.9', ['AliTrip/{v}', 'WindVane/8.7.0']),
|
|
183
|
-
taobao: basicProfile('taobao', 'TB', '10.65.0', ['WindVane/8.7.0']),
|
|
184
|
-
wechat: basicProfile('wechat', 'WeChat', '8.0.58', [], 'wechatMiniProgram'),
|
|
185
|
-
alipay: { ...basicProfile('alipay', 'AP', '10.8.0', ['AlipayClient/{v}']), policies: { navigatorLanguage: true, defaultLanguage: 'zh-CN' } },
|
|
186
|
-
};
|
|
176
|
+
/** Profiles are supplied by installed capabilities; the core has no App defaults. */
|
|
177
|
+
export const APP_PROFILES = Object.freeze({});
|
|
187
178
|
/** 构造容器 UA。os 默认 ios;uaTokens 中的 {v} 替换为 appVersion */
|
|
188
179
|
export function buildAppProfileUa(profile, options = {}) {
|
|
189
180
|
const os = options.os ??
|
|
@@ -199,36 +190,21 @@ export function buildAppProfileUa(profile, options = {}) {
|
|
|
199
190
|
.replaceAll('{deviceModel}', deviceModel)
|
|
200
191
|
.replaceAll('{language}', options.language ?? profile.policies?.defaultLanguage ?? 'zh-Hans');
|
|
201
192
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
return `Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/${version} NetType/WIFI Language/zh_CN miniProgram`;
|
|
207
|
-
}
|
|
208
|
-
const tokens = profile.uaTokens.map(t => t.replaceAll('{v}', version)).filter(Boolean);
|
|
209
|
-
const tail = `${tokens.length > 0 ? ` ${tokens.join(' ')}` : ''}${profile.policies?.navigatorLanguage ? ` Language/${options.language ?? profile.policies.defaultLanguage ?? 'zh-CN'}` : ''}`;
|
|
210
|
-
if (os === 'android') {
|
|
211
|
-
return `Mozilla/5.0 (Linux; Android 17; ${deviceModel}) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/152.0.0.0 Mobile Safari/537.36 AliApp(${profile.appName}/${version})${tail}`;
|
|
212
|
-
}
|
|
213
|
-
return `Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) AliApp(${profile.appName}/${version})${tail}`;
|
|
193
|
+
return os === 'android'
|
|
194
|
+
? `Mozilla/5.0 (Linux; Android 17; ${deviceModel}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Mobile Safari/537.36`
|
|
195
|
+
: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1';
|
|
214
196
|
}
|
|
215
197
|
/**
|
|
216
198
|
* 解析容器档案为可下发配置。
|
|
217
199
|
* @throws profile 名不存在时抛错,错误信息列出全部可用档案
|
|
218
200
|
*/
|
|
219
201
|
export function listBuiltinAppProfiles() {
|
|
220
|
-
return
|
|
221
|
-
id: definition.name,
|
|
222
|
-
label: definition.label,
|
|
223
|
-
source: 'builtin',
|
|
224
|
-
revision: appProfileRevision(definition),
|
|
225
|
-
definition,
|
|
226
|
-
}));
|
|
202
|
+
return [];
|
|
227
203
|
}
|
|
228
204
|
export function resolveAppProfile(name, options = {}, pinnedDefinition) {
|
|
229
205
|
const definition = pinnedDefinition ?? APP_PROFILES[name];
|
|
230
206
|
if (!definition || definition.name !== name) {
|
|
231
|
-
throw new Error(`Unknown app profile "${name}".
|
|
207
|
+
throw new Error(`Unknown app profile "${name}". Install an App simulation capability first.`);
|
|
232
208
|
}
|
|
233
209
|
return resolveAppProfileDefinition(definition, options);
|
|
234
210
|
}
|
|
@@ -257,7 +233,7 @@ export function resolveAppProfileDefinition(definition, options = {}) {
|
|
|
257
233
|
if (options.language !== undefined &&
|
|
258
234
|
profile.policies?.languages &&
|
|
259
235
|
!profile.policies.languages.includes(options.language)) {
|
|
260
|
-
throw new Error(`Unsupported ${profile.
|
|
236
|
+
throw new Error(`Unsupported ${profile.label} language. Use ${profile.policies.languages.join(', ')}.`);
|
|
261
237
|
}
|
|
262
238
|
const os = options.os ??
|
|
263
239
|
(options.devicePreset ? DEVICE_PRESETS[options.devicePreset]?.appProfileOs : undefined) ??
|
|
@@ -272,10 +248,9 @@ export function resolveAppProfileDefinition(definition, options = {}) {
|
|
|
272
248
|
});
|
|
273
249
|
const deviceModel = options.deviceModel ?? DEVICE_PRESETS[devicePreset].appProfileModel;
|
|
274
250
|
const globals = profile.pageRuntime || profile.bridges.length > 0 || Object.keys(profile.globals).length > 0 ? {
|
|
275
|
-
...profile.globals,
|
|
251
|
+
...Object.fromEntries(Object.entries(profile.globals).map(([key, value]) => [key, value.replaceAll('{deviceModel}', deviceModel).replaceAll('{v}', version)])),
|
|
276
252
|
__APP_NAME__: profile.appName,
|
|
277
253
|
__APP_VERSION__: version,
|
|
278
|
-
__FLI_DEVICE_MODEL__: deviceModel,
|
|
279
254
|
__DEVICE_MODEL__: deviceModel,
|
|
280
255
|
} : {};
|
|
281
256
|
const ua = buildAppProfileUa(profile, { ...options, os, deviceModel });
|
|
@@ -294,6 +269,8 @@ export function resolveAppProfileDefinition(definition, options = {}) {
|
|
|
294
269
|
},
|
|
295
270
|
policies: profile.policies ?? {},
|
|
296
271
|
settings: profile.settings ?? [],
|
|
272
|
+
settingsUi: profile.settingsUi,
|
|
273
|
+
settingsGroup: profile.settingsGroup,
|
|
297
274
|
profile: profile.name,
|
|
298
275
|
label: profile.label,
|
|
299
276
|
globals,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/app-profiles",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
|
+
"description": "Declarative App profile compilation for installed capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@mearl/browser-core": "3.0.0-beta.
|
|
27
|
+
"@mearl/browser-core": "3.0.0-beta.5"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"typescript": "^5.8.3"
|