@heybox/hb-sdk-protocol 0.7.4-alpha.1

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.
@@ -0,0 +1,259 @@
1
+ import type {
2
+ ClosePayload,
3
+ CloseResult,
4
+ DeleteCurrentUserLeaderboardEntryPayload,
5
+ DeleteCurrentUserLeaderboardEntryResult,
6
+ GetCurrentUserLeaderboardEntryPayload,
7
+ GetCurrentUserLeaderboardEntryResult,
8
+ GetLeaderboardInfoPayload,
9
+ GetLeaderboardInfoResult,
10
+ GetLeaderboardListPayload,
11
+ GetLeaderboardListResult,
12
+ GetStoragePayload,
13
+ GetStorageResult,
14
+ GetSteamGameListPayload,
15
+ GetSteamGameListResult,
16
+ GetUserInfoPayload,
17
+ GetUserInfoResult,
18
+ GetWindowInfoPayload,
19
+ GetWindowInfoResult,
20
+ HideLoadingPayload,
21
+ HideLoadingResult,
22
+ LoginPayload,
23
+ LoginResult,
24
+ NetworkRequestPayload,
25
+ NetworkResponsePayload,
26
+ OpenAppPagePayload,
27
+ OpenAppPageResult,
28
+ ReloadPayload,
29
+ ReloadResult,
30
+ ScreenshotPayload,
31
+ ScreenshotResult,
32
+ SetClipboardPayload,
33
+ SetClipboardResult,
34
+ SetNavigationBarStylePayload,
35
+ SetNavigationBarStyleResult,
36
+ SetStoragePayload,
37
+ ShowLoadingPayload,
38
+ ShowLoadingResult,
39
+ ShowShareMenuPayload,
40
+ ShowShareMenuResult,
41
+ ShowToastPayload,
42
+ ShowToastResult,
43
+ SubmitLeaderboardEntryPayload,
44
+ SubmitLeaderboardEntryResult,
45
+ VibratePayload,
46
+ VibrateResult,
47
+ } from './payloads';
48
+
49
+ export const AUTH_LOGIN_METHOD = 'auth.login' as const;
50
+ export const USER_GET_INFO_METHOD = 'user.getInfo' as const;
51
+ export const USER_REVOKE_AUTHORIZATION_METHOD = 'user.revokeAuthorization' as const;
52
+ export const USER_GET_STEAM_GAME_LIST_METHOD = 'user.getSteamGameList' as const;
53
+ export const SHARE_SHOW_SHARE_MENU_METHOD = 'share.showShareMenu' as const;
54
+ export const SHARE_SCREENSHOT_METHOD = 'share.screenshot' as const;
55
+ export const VIEWPORT_GET_WINDOW_INFO_METHOD = 'viewport.getWindowInfo' as const;
56
+ export const VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD = 'viewport.setNavigationBarStyle' as const;
57
+ export const STORAGE_GET_STORAGE_METHOD = 'storage.getStorage' as const;
58
+ export const STORAGE_SET_STORAGE_METHOD = 'storage.setStorage' as const;
59
+ export const NETWORK_REQUEST_METHOD = 'network.request' as const;
60
+ export const UI_SHOW_TOAST_METHOD = 'ui.showToast' as const;
61
+ export const UI_SHOW_LOADING_METHOD = 'ui.showLoading' as const;
62
+ export const UI_HIDE_LOADING_METHOD = 'ui.hideLoading' as const;
63
+ export const DEVICE_VIBRATE_METHOD = 'device.vibrate' as const;
64
+ export const DEVICE_SET_CLIPBOARD_METHOD = 'device.setClipboard' as const;
65
+ export const NAVIGATION_CLOSE_METHOD = 'navigation.close' as const;
66
+ export const NAVIGATION_RELOAD_METHOD = 'navigation.reload' as const;
67
+ export const NAVIGATION_OPEN_APP_PAGE_METHOD = 'navigation.openAppPage' as const;
68
+ export const CLOUD_LEADERBOARD_SUBMIT_METHOD = 'cloud.leaderboard.submit' as const;
69
+ export const CLOUD_LEADERBOARD_GET_LIST_METHOD = 'cloud.leaderboard.getList' as const;
70
+ export const CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.getCurrentUserEntry' as const;
71
+ export const CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.deleteCurrentUserEntry' as const;
72
+ export const CLOUD_LEADERBOARD_GET_INFO_METHOD = 'cloud.leaderboard.getInfo' as const;
73
+
74
+ export type MiniProgramAuthMethod = typeof AUTH_LOGIN_METHOD;
75
+ export type MiniProgramUserMethod = typeof USER_GET_INFO_METHOD | typeof USER_REVOKE_AUTHORIZATION_METHOD | typeof USER_GET_STEAM_GAME_LIST_METHOD;
76
+ export type MiniProgramShareMethod = typeof SHARE_SHOW_SHARE_MENU_METHOD | typeof SHARE_SCREENSHOT_METHOD;
77
+ export type MiniProgramViewportMethod = typeof VIEWPORT_GET_WINDOW_INFO_METHOD | typeof VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD;
78
+ export type MiniProgramStorageMethod = typeof STORAGE_GET_STORAGE_METHOD | typeof STORAGE_SET_STORAGE_METHOD;
79
+ export type MiniProgramNetworkMethod = typeof NETWORK_REQUEST_METHOD;
80
+ export type MiniProgramUiMethod = typeof UI_SHOW_TOAST_METHOD | typeof UI_SHOW_LOADING_METHOD | typeof UI_HIDE_LOADING_METHOD;
81
+ export type MiniProgramDeviceMethod = typeof DEVICE_VIBRATE_METHOD | typeof DEVICE_SET_CLIPBOARD_METHOD;
82
+ export type MiniProgramNavigationMethod = typeof NAVIGATION_CLOSE_METHOD | typeof NAVIGATION_RELOAD_METHOD | typeof NAVIGATION_OPEN_APP_PAGE_METHOD;
83
+ export type MiniProgramCloudMethod =
84
+ | typeof CLOUD_LEADERBOARD_SUBMIT_METHOD
85
+ | typeof CLOUD_LEADERBOARD_GET_LIST_METHOD
86
+ | typeof CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD
87
+ | typeof CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD
88
+ | typeof CLOUD_LEADERBOARD_GET_INFO_METHOD;
89
+ export type MiniProgramBridgeMethod =
90
+ | MiniProgramAuthMethod
91
+ | MiniProgramUserMethod
92
+ | MiniProgramShareMethod
93
+ | MiniProgramViewportMethod
94
+ | MiniProgramStorageMethod
95
+ | MiniProgramNetworkMethod
96
+ | MiniProgramUiMethod
97
+ | MiniProgramDeviceMethod
98
+ | MiniProgramNavigationMethod
99
+ | MiniProgramCloudMethod;
100
+ export type MiniProgramCapabilityModule = 'auth' | 'user' | 'share' | 'viewport' | 'storage' | 'network' | 'ui' | 'device' | 'navigation' | 'cloud';
101
+ export type MiniProgramCapabilityRisk = 'low' | 'medium' | 'high';
102
+
103
+ export interface MiniProgramCapabilityDefinition {
104
+ method: MiniProgramBridgeMethod;
105
+ module: MiniProgramCapabilityModule;
106
+ capability: MiniProgramBridgeMethod;
107
+ permission: string;
108
+ risk: MiniProgramCapabilityRisk;
109
+ }
110
+
111
+ export const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
112
+ { method: AUTH_LOGIN_METHOD, module: 'auth', capability: AUTH_LOGIN_METHOD, permission: 'auth.login', risk: 'medium' },
113
+ { method: USER_GET_INFO_METHOD, module: 'user', capability: USER_GET_INFO_METHOD, permission: 'user.getInfo', risk: 'medium' },
114
+ {
115
+ method: USER_REVOKE_AUTHORIZATION_METHOD,
116
+ module: 'user',
117
+ capability: USER_REVOKE_AUTHORIZATION_METHOD,
118
+ permission: 'user.revokeAuthorization',
119
+ risk: 'high',
120
+ },
121
+ {
122
+ method: USER_GET_STEAM_GAME_LIST_METHOD,
123
+ module: 'user',
124
+ capability: USER_GET_STEAM_GAME_LIST_METHOD,
125
+ permission: 'user.platformAccount.steam',
126
+ risk: 'high',
127
+ },
128
+ { method: SHARE_SHOW_SHARE_MENU_METHOD, module: 'share', capability: SHARE_SHOW_SHARE_MENU_METHOD, permission: 'share.basic', risk: 'low' },
129
+ { method: SHARE_SCREENSHOT_METHOD, module: 'share', capability: SHARE_SCREENSHOT_METHOD, permission: 'share.screenshot', risk: 'medium' },
130
+ {
131
+ method: VIEWPORT_GET_WINDOW_INFO_METHOD,
132
+ module: 'viewport',
133
+ capability: VIEWPORT_GET_WINDOW_INFO_METHOD,
134
+ permission: 'viewport.windowInfo',
135
+ risk: 'low',
136
+ },
137
+ {
138
+ method: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
139
+ module: 'viewport',
140
+ capability: VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD,
141
+ permission: 'viewport.navigationBarStyle',
142
+ risk: 'low',
143
+ },
144
+ { method: STORAGE_GET_STORAGE_METHOD, module: 'storage', capability: STORAGE_GET_STORAGE_METHOD, permission: 'storage.read', risk: 'low' },
145
+ { method: STORAGE_SET_STORAGE_METHOD, module: 'storage', capability: STORAGE_SET_STORAGE_METHOD, permission: 'storage.write', risk: 'medium' },
146
+ { method: NETWORK_REQUEST_METHOD, module: 'network', capability: NETWORK_REQUEST_METHOD, permission: 'network.request', risk: 'high' },
147
+ { method: UI_SHOW_TOAST_METHOD, module: 'ui', capability: UI_SHOW_TOAST_METHOD, permission: 'ui.toast', risk: 'low' },
148
+ { method: UI_SHOW_LOADING_METHOD, module: 'ui', capability: UI_SHOW_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
149
+ { method: UI_HIDE_LOADING_METHOD, module: 'ui', capability: UI_HIDE_LOADING_METHOD, permission: 'ui.loading', risk: 'low' },
150
+ { method: DEVICE_VIBRATE_METHOD, module: 'device', capability: DEVICE_VIBRATE_METHOD, permission: 'device.vibrate', risk: 'low' },
151
+ {
152
+ method: DEVICE_SET_CLIPBOARD_METHOD,
153
+ module: 'device',
154
+ capability: DEVICE_SET_CLIPBOARD_METHOD,
155
+ permission: 'device.clipboard.write',
156
+ risk: 'medium',
157
+ },
158
+ { method: NAVIGATION_CLOSE_METHOD, module: 'navigation', capability: NAVIGATION_CLOSE_METHOD, permission: 'navigation.close', risk: 'medium' },
159
+ { method: NAVIGATION_RELOAD_METHOD, module: 'navigation', capability: NAVIGATION_RELOAD_METHOD, permission: 'navigation.reload', risk: 'medium' },
160
+ {
161
+ method: NAVIGATION_OPEN_APP_PAGE_METHOD,
162
+ module: 'navigation',
163
+ capability: NAVIGATION_OPEN_APP_PAGE_METHOD,
164
+ permission: 'navigation.openAppPage',
165
+ risk: 'medium',
166
+ },
167
+ {
168
+ method: CLOUD_LEADERBOARD_SUBMIT_METHOD,
169
+ module: 'cloud',
170
+ capability: CLOUD_LEADERBOARD_SUBMIT_METHOD,
171
+ permission: 'cloud.leaderboard.write',
172
+ risk: 'medium',
173
+ },
174
+ {
175
+ method: CLOUD_LEADERBOARD_GET_LIST_METHOD,
176
+ module: 'cloud',
177
+ capability: CLOUD_LEADERBOARD_GET_LIST_METHOD,
178
+ permission: 'cloud.leaderboard.read',
179
+ risk: 'low',
180
+ },
181
+ {
182
+ method: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
183
+ module: 'cloud',
184
+ capability: CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD,
185
+ permission: 'cloud.leaderboard.currentUserEntry.read',
186
+ risk: 'medium',
187
+ },
188
+ {
189
+ method: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
190
+ module: 'cloud',
191
+ capability: CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD,
192
+ permission: 'cloud.leaderboard.currentUserEntry.delete',
193
+ risk: 'medium',
194
+ },
195
+ {
196
+ method: CLOUD_LEADERBOARD_GET_INFO_METHOD,
197
+ module: 'cloud',
198
+ capability: CLOUD_LEADERBOARD_GET_INFO_METHOD,
199
+ permission: 'cloud.leaderboard.info.read',
200
+ risk: 'low',
201
+ },
202
+ ] as const satisfies readonly MiniProgramCapabilityDefinition[];
203
+
204
+ export interface MiniProgramCapabilityPayloadMap {
205
+ [AUTH_LOGIN_METHOD]: LoginPayload;
206
+ [USER_GET_INFO_METHOD]: GetUserInfoPayload;
207
+ [USER_REVOKE_AUTHORIZATION_METHOD]: void;
208
+ [USER_GET_STEAM_GAME_LIST_METHOD]: GetSteamGameListPayload;
209
+ [SHARE_SHOW_SHARE_MENU_METHOD]: ShowShareMenuPayload;
210
+ [SHARE_SCREENSHOT_METHOD]: ScreenshotPayload;
211
+ [VIEWPORT_GET_WINDOW_INFO_METHOD]: GetWindowInfoPayload;
212
+ [VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD]: SetNavigationBarStylePayload;
213
+ [STORAGE_GET_STORAGE_METHOD]: GetStoragePayload;
214
+ [STORAGE_SET_STORAGE_METHOD]: SetStoragePayload;
215
+ [NETWORK_REQUEST_METHOD]: NetworkRequestPayload;
216
+ [UI_SHOW_TOAST_METHOD]: ShowToastPayload;
217
+ [UI_SHOW_LOADING_METHOD]: ShowLoadingPayload;
218
+ [UI_HIDE_LOADING_METHOD]: HideLoadingPayload;
219
+ [DEVICE_VIBRATE_METHOD]: VibratePayload;
220
+ [DEVICE_SET_CLIPBOARD_METHOD]: SetClipboardPayload;
221
+ [NAVIGATION_CLOSE_METHOD]: ClosePayload;
222
+ [NAVIGATION_RELOAD_METHOD]: ReloadPayload;
223
+ [NAVIGATION_OPEN_APP_PAGE_METHOD]: OpenAppPagePayload;
224
+ [CLOUD_LEADERBOARD_SUBMIT_METHOD]: SubmitLeaderboardEntryPayload;
225
+ [CLOUD_LEADERBOARD_GET_LIST_METHOD]: GetLeaderboardListPayload | undefined;
226
+ [CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD]: GetCurrentUserLeaderboardEntryPayload | undefined;
227
+ [CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD]: DeleteCurrentUserLeaderboardEntryPayload | undefined;
228
+ [CLOUD_LEADERBOARD_GET_INFO_METHOD]: GetLeaderboardInfoPayload | undefined;
229
+ }
230
+
231
+ export interface MiniProgramCapabilityResultMap {
232
+ [AUTH_LOGIN_METHOD]: LoginResult;
233
+ [USER_GET_INFO_METHOD]: GetUserInfoResult;
234
+ [USER_REVOKE_AUTHORIZATION_METHOD]: void;
235
+ [USER_GET_STEAM_GAME_LIST_METHOD]: GetSteamGameListResult;
236
+ [SHARE_SHOW_SHARE_MENU_METHOD]: ShowShareMenuResult;
237
+ [SHARE_SCREENSHOT_METHOD]: ScreenshotResult;
238
+ [VIEWPORT_GET_WINDOW_INFO_METHOD]: GetWindowInfoResult;
239
+ [VIEWPORT_SET_NAVIGATION_BAR_STYLE_METHOD]: SetNavigationBarStyleResult;
240
+ [STORAGE_GET_STORAGE_METHOD]: GetStorageResult;
241
+ [STORAGE_SET_STORAGE_METHOD]: void;
242
+ [NETWORK_REQUEST_METHOD]: NetworkResponsePayload;
243
+ [UI_SHOW_TOAST_METHOD]: ShowToastResult;
244
+ [UI_SHOW_LOADING_METHOD]: ShowLoadingResult;
245
+ [UI_HIDE_LOADING_METHOD]: HideLoadingResult;
246
+ [DEVICE_VIBRATE_METHOD]: VibrateResult;
247
+ [DEVICE_SET_CLIPBOARD_METHOD]: SetClipboardResult;
248
+ [NAVIGATION_CLOSE_METHOD]: CloseResult;
249
+ [NAVIGATION_RELOAD_METHOD]: ReloadResult;
250
+ [NAVIGATION_OPEN_APP_PAGE_METHOD]: OpenAppPageResult;
251
+ [CLOUD_LEADERBOARD_SUBMIT_METHOD]: SubmitLeaderboardEntryResult;
252
+ [CLOUD_LEADERBOARD_GET_LIST_METHOD]: GetLeaderboardListResult;
253
+ [CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD]: GetCurrentUserLeaderboardEntryResult;
254
+ [CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD]: DeleteCurrentUserLeaderboardEntryResult;
255
+ [CLOUD_LEADERBOARD_GET_INFO_METHOD]: GetLeaderboardInfoResult;
256
+ }
257
+
258
+ export type MiniProgramCapabilityPayload<T extends MiniProgramBridgeMethod> = MiniProgramCapabilityPayloadMap[T];
259
+ export type MiniProgramCapabilityResult<T extends MiniProgramBridgeMethod> = MiniProgramCapabilityResultMap[T];
@@ -0,0 +1,7 @@
1
+ export const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram' as const;
2
+ export const MINI_PROGRAM_MESSAGE_VERSION = 2 as const;
3
+ export const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce' as const;
4
+ export const SDK_HANDSHAKE_METHOD = 'sdk.handshake' as const;
5
+ export const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe' as const;
6
+ export const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report' as const;
7
+ export const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation' as const;
package/src/guards.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { MINI_PROGRAM_MESSAGE_NAMESPACE } from './constants';
2
+ import type { MiniProgramBridgeMessage } from './bridge';
3
+
4
+ export function isMiniProgramBridgeMessage(value: unknown): value is MiniProgramBridgeMessage {
5
+ if (!value || typeof value !== 'object') return false;
6
+ const message = value as Partial<MiniProgramBridgeMessage>;
7
+ return (
8
+ message.namespace === MINI_PROGRAM_MESSAGE_NAMESPACE &&
9
+ (message.version === 1 || message.version === 2) &&
10
+ typeof message.nonce === 'string' &&
11
+ typeof message.type === 'string'
12
+ );
13
+ }
package/src/index.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './bridge';
2
+ export * from './capabilities';
3
+ export * from './constants';
4
+ export * from './guards';
5
+ export * from './payloads';
6
+ export * from './permissions';
@@ -0,0 +1,280 @@
1
+ /** 当前用户信息与登录能力支持的完整 scope 目录。 */
2
+ export const USER_INFO_AUTHORIZATION_SCOPES = ['identity', 'profile'] as const;
3
+
4
+ /** 用户信息授权 scope。 */
5
+ export type UserInfoAuthorizationScope = (typeof USER_INFO_AUTHORIZATION_SCOPES)[number];
6
+
7
+ /** 登录请求使用与用户信息授权相同的 canonical scope。 */
8
+ export type LoginScope = UserInfoAuthorizationScope;
9
+ export type LoginPayload = { scopes?: LoginScope[] } | undefined;
10
+ export interface LoginResult {
11
+ code: string;
12
+ expiresIn: number;
13
+ scopes: LoginScope[];
14
+ }
15
+
16
+ /** 用户资料授权状态。 */
17
+ export type UserInfoAuthorizationStatus = 'not_required' | 'not_requested' | 'granted' | 'denied';
18
+
19
+ type CanonicalUserInfoAuthorization = Record<UserInfoAuthorizationScope, UserInfoAuthorizationStatus>;
20
+
21
+ /** 当前小程序对 canonical 用户信息 scope 的授权状态。 */
22
+ export interface UserInfoAuthorization extends CanonicalUserInfoAuthorization {}
23
+
24
+ /**
25
+ * 已获准向当前小程序披露的用户资料。
26
+ *
27
+ * @remarks
28
+ * 未开通网络权限且当前黑盒 APP 用户已登录时,Runtime 会隐式授予 `identity` 与
29
+ * `profile`,静默建立或读取隔离身份,并由 `user.getInfo()` 返回该对象。撤销授权后
30
+ * 旧身份失效,调用方应停止使用并清理本地缓存;再次调用 `user.getInfo()` 会静默建立
31
+ * 新的隔离身份。
32
+ */
33
+ export interface AuthorizedUserInfo {
34
+ /**
35
+ * 当前黑盒用户在当前小程序内稳定且不可逆的关联标识。
36
+ *
37
+ * @remarks
38
+ * 同一用户在不同小程序中的值不同。它不是黑盒用户 ID、登录凭据或主站私有接口凭据,
39
+ * 只应作为当前小程序自己的业务关联键使用。示例:
40
+ * `au_1_x7K9mQ2pL4vN8cR3tY6wB1zD5fH`。调用方必须把完整值视为不透明字符串,
41
+ * 不应解析格式或依赖固定长度。
42
+ */
43
+ app_user_id: string;
44
+ /** `profile` 已授权时返回昵称与头像;当前 Heybox Runtime 在无网络模式下隐式授予该 scope。 */
45
+ profile: { nickname: string; avatar: string } | null;
46
+ }
47
+
48
+ /**
49
+ * 当前黑盒 APP 登录态、授权状态和已获准披露的用户资料。
50
+ *
51
+ * @remarks
52
+ * 未登录时 `isHeyboxAppLoggedIn` 为 `false`,授权状态和用户资料均为 `null`。
53
+ * 当前 Heybox Runtime 在无网络模式且已登录时会隐式授予 `identity` 与 `profile`,
54
+ * 静默建立身份并返回 `userInfo`;Host 在已登录但身份暂不可用时仍可返回 `null`,
55
+ * 调用方必须进行空值判断。
56
+ */
57
+ export type MiniProgramUserInfoResult =
58
+ | { isHeyboxAppLoggedIn: false; authorization: null; userInfo: null }
59
+ | { isHeyboxAppLoggedIn: true; authorization: UserInfoAuthorization; userInfo: AuthorizedUserInfo | null };
60
+ export type GetUserInfoPayload = void;
61
+ export type GetUserInfoResult = MiniProgramUserInfoResult;
62
+ export type RevokeAuthorizationPayload = void;
63
+ export type RevokeAuthorizationResult = void;
64
+ export type SteamGameListSort = 'weeks' | 'all' | 'achieved';
65
+ interface GetSteamGameListRequest {
66
+ steamId?: string;
67
+ limit?: number;
68
+ offset?: number;
69
+ sort?: SteamGameListSort;
70
+ q?: string;
71
+ includeHidden?: boolean;
72
+ }
73
+ export type GetSteamGameListPayload = GetSteamGameListRequest | undefined;
74
+ export type SteamGamePrice = {
75
+ current?: string;
76
+ initial?: string;
77
+ discount?: number;
78
+ lowestPrice?: number;
79
+ deadlineDate?: string;
80
+ deadlineTimestamp?: number;
81
+ };
82
+ export interface SteamGameListItem {
83
+ appid: number;
84
+ steamAppid: number;
85
+ name: string;
86
+ image?: string;
87
+ icon?: string;
88
+ playtimeForever?: number;
89
+ playtime2Weeks?: number;
90
+ tags?: string[];
91
+ price?: SteamGamePrice;
92
+ }
93
+ export interface SteamGameListData {
94
+ gameList: SteamGameListItem[];
95
+ total?: number;
96
+ hasMore: boolean;
97
+ nextOffset: number;
98
+ isMe?: boolean;
99
+ }
100
+ export type GetSteamGameListResult =
101
+ | { isLogin: false; isBound: false; data: null }
102
+ | { isLogin: true; isBound: false; data: null }
103
+ | { isLogin: true; isBound: true; data: SteamGameListData };
104
+
105
+ export type MiniProgramShareChannel = 'wechatSession' | 'wechatTimeline' | 'qqFriend' | 'qzone' | 'weibo';
106
+ export interface MiniProgramSharePostOptions {
107
+ topicIds?: (string | number)[];
108
+ topics?: string[];
109
+ }
110
+ export interface MiniProgramScreenshotRect {
111
+ left: number;
112
+ top: number;
113
+ width: number;
114
+ height: number;
115
+ }
116
+ export type ShowShareMenuPayload = {
117
+ title: string;
118
+ desc: string;
119
+ url?: string;
120
+ imageUrl?: string;
121
+ channel?: MiniProgramShareChannel;
122
+ post?: MiniProgramSharePostOptions | null;
123
+ };
124
+ export type ShowShareMenuResult = unknown;
125
+ export type ScreenshotPayload =
126
+ | {
127
+ rect?: MiniProgramScreenshotRect;
128
+ delay?: number;
129
+ saveToAlbum?: boolean;
130
+ post?: MiniProgramSharePostOptions | null;
131
+ }
132
+ | undefined;
133
+ export type ScreenshotResult = unknown;
134
+
135
+ export interface GetStoragePayload {
136
+ key: string;
137
+ }
138
+ export interface GetStorageResult<T = unknown> {
139
+ data: T | undefined;
140
+ }
141
+ export interface SetStoragePayload {
142
+ key: string;
143
+ data: unknown;
144
+ }
145
+
146
+ export interface MiniProgramSafeArea {
147
+ left: number;
148
+ right: number;
149
+ top: number;
150
+ bottom: number;
151
+ width: number;
152
+ height: number;
153
+ }
154
+ export interface MiniProgramWindowInfoResult {
155
+ pixelRatio: number;
156
+ screenWidth: number;
157
+ screenHeight: number;
158
+ windowWidth: number;
159
+ windowHeight: number;
160
+ statusBarHeight: number;
161
+ safeArea: MiniProgramSafeArea;
162
+ screenTop: number;
163
+ }
164
+ export type GetWindowInfoPayload = void;
165
+ export type GetWindowInfoResult = MiniProgramWindowInfoResult;
166
+ export type MiniProgramNavigationBarForegroundStyle = 'light' | 'dark';
167
+ export type SetNavigationBarStylePayload = { foregroundStyle: MiniProgramNavigationBarForegroundStyle };
168
+ export type SetNavigationBarStyleResult = void;
169
+
170
+ export type MiniProgramNetworkHeaders = Record<string, string>;
171
+ export type MiniProgramNetworkParams = Record<string, unknown>;
172
+ export type MiniProgramNetworkRequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
173
+ export interface NetworkRequestPayload {
174
+ url: string;
175
+ method?: MiniProgramNetworkRequestMethod;
176
+ params?: MiniProgramNetworkParams;
177
+ data?: unknown;
178
+ headers?: MiniProgramNetworkHeaders;
179
+ timeout?: number;
180
+ withCredentials?: boolean;
181
+ }
182
+ export interface NetworkResponsePayload<T = unknown> {
183
+ data: T;
184
+ status: number;
185
+ statusText?: string;
186
+ headers: MiniProgramNetworkHeaders;
187
+ }
188
+
189
+ export type MiniProgramToastStatus = 'success' | 'error';
190
+ export interface ShowToastPayload {
191
+ message: string;
192
+ status?: MiniProgramToastStatus;
193
+ }
194
+ export type ShowToastResult = void;
195
+ export interface ShowLoadingPayload {
196
+ dismissible?: boolean;
197
+ }
198
+ export type ShowLoadingResult = void;
199
+ export type HideLoadingPayload = void;
200
+ export type HideLoadingResult = void;
201
+ export type MiniProgramVibrateIntensity = 'light' | 'medium' | 'heavy';
202
+ export interface VibratePayload {
203
+ intensity?: MiniProgramVibrateIntensity;
204
+ delay?: number;
205
+ }
206
+ export type VibrateResult = void;
207
+ export interface SetClipboardPayload {
208
+ text: string;
209
+ }
210
+ export type SetClipboardResult = void;
211
+
212
+ export type ClosePayload = void;
213
+ export type CloseResult = void;
214
+ export type ReloadPayload = void;
215
+ export type ReloadResult = void;
216
+ export type MiniProgramAppPageTarget = 'game_detail' | 'user_detail' | 'post_detail';
217
+ export type MiniProgramGameDetailGameType = 'pc' | 'console' | 'mobile';
218
+ export type MiniProgramGameDetailPage = 'game' | 'wiki';
219
+ export type OpenGameDetailAppPagePayload = {
220
+ target: 'game_detail';
221
+ appId: string;
222
+ gameType: MiniProgramGameDetailGameType;
223
+ page?: MiniProgramGameDetailPage;
224
+ hSrc?: string;
225
+ skuId?: string;
226
+ };
227
+ export type OpenUserDetailAppPagePayload = { target: 'user_detail'; userId: string };
228
+ export type OpenPostDetailAppPagePayload = {
229
+ target: 'post_detail';
230
+ linkId: string;
231
+ rootCommentId?: string;
232
+ commentId?: string;
233
+ };
234
+ export type OpenAppPagePayload = OpenGameDetailAppPagePayload | OpenUserDetailAppPagePayload | OpenPostDetailAppPagePayload;
235
+ export type OpenAppPageResult = void;
236
+
237
+ export type LeaderboardOrder = 'asc' | 'desc';
238
+ export interface LeaderboardEntry {
239
+ rank: number;
240
+ ranked: boolean;
241
+ appUserId: string;
242
+ score: number;
243
+ extra: Record<string, unknown>;
244
+ createdAt: number;
245
+ updatedAt: number;
246
+ }
247
+ export interface SubmitLeaderboardEntryPayload {
248
+ key?: string;
249
+ score: number;
250
+ extra?: Record<string, unknown>;
251
+ }
252
+ export type SubmitLeaderboardEntryResult = LeaderboardEntry;
253
+ export interface GetLeaderboardListPayload {
254
+ key?: string;
255
+ limit?: number;
256
+ cursor?: string;
257
+ }
258
+ export interface GetLeaderboardListResult {
259
+ entries: LeaderboardEntry[];
260
+ cursor?: string;
261
+ hasMore: boolean;
262
+ }
263
+ export interface GetCurrentUserLeaderboardEntryPayload {
264
+ key?: string;
265
+ }
266
+ export type GetCurrentUserLeaderboardEntryResult = LeaderboardEntry | undefined;
267
+ export interface DeleteCurrentUserLeaderboardEntryPayload {
268
+ key?: string;
269
+ }
270
+ export interface DeleteCurrentUserLeaderboardEntryResult {
271
+ deleted: boolean;
272
+ }
273
+ export interface GetLeaderboardInfoPayload {
274
+ key?: string;
275
+ }
276
+ export interface GetLeaderboardInfoResult {
277
+ key: string;
278
+ order: LeaderboardOrder;
279
+ rankLimit: number;
280
+ }
@@ -0,0 +1,56 @@
1
+ const MANAGED_RUNTIME_PERMISSION_KEYS = new Set(['network.request']);
2
+
3
+ export function isManagedMiniProgramRuntimePermissionKey(key: string) {
4
+ return MANAGED_RUNTIME_PERMISSION_KEYS.has(key);
5
+ }
6
+ export type MiniProgramRuntimePermissionStatus = 'enabled' | 'disabled';
7
+ export interface MiniProgramRuntimePermissionEntry {
8
+ key: string;
9
+ status: MiniProgramRuntimePermissionStatus;
10
+ config: Record<string, unknown>;
11
+ }
12
+ export interface MiniProgramRuntimePermissionsSnapshot {
13
+ schema_version: 1;
14
+ revision?: number;
15
+ entries: MiniProgramRuntimePermissionEntry[];
16
+ }
17
+ export interface ParsedMiniProgramRuntimePermissions {
18
+ valid: boolean;
19
+ permissions: Record<string, MiniProgramRuntimePermissionEntry>;
20
+ }
21
+
22
+ export function parseMiniProgramRuntimePermissions(snapshot: unknown): ParsedMiniProgramRuntimePermissions {
23
+ if (!isRecord(snapshot) || snapshot.schema_version !== 1 || !Array.isArray(snapshot.entries)) {
24
+ return { valid: false, permissions: {} };
25
+ }
26
+ if (snapshot.revision !== undefined && (typeof snapshot.revision !== 'number' || !Number.isInteger(snapshot.revision) || snapshot.revision < 0)) {
27
+ return { valid: false, permissions: {} };
28
+ }
29
+
30
+ const seenKeys = new Set<string>();
31
+ const permissions: Record<string, MiniProgramRuntimePermissionEntry> = {};
32
+ for (const rawEntry of snapshot.entries) {
33
+ if (!isRecord(rawEntry) || typeof rawEntry.key !== 'string' || !rawEntry.key.trim()) {
34
+ return { valid: false, permissions: {} };
35
+ }
36
+ const key = rawEntry.key.trim();
37
+ if (seenKeys.has(key) || (rawEntry.status !== 'enabled' && rawEntry.status !== 'disabled') || !isRecord(rawEntry.config)) {
38
+ return { valid: false, permissions: {} };
39
+ }
40
+ seenKeys.add(key);
41
+ if (!isManagedMiniProgramRuntimePermissionKey(key)) continue;
42
+ if (key === 'network.request' && typeof rawEntry.config.useOfficialDomain !== 'boolean') {
43
+ return { valid: false, permissions: {} };
44
+ }
45
+ permissions[key] = {
46
+ key,
47
+ status: rawEntry.status,
48
+ config: { useOfficialDomain: rawEntry.config.useOfficialDomain },
49
+ };
50
+ }
51
+ return { valid: true, permissions };
52
+ }
53
+
54
+ function isRecord(value: unknown): value is Record<string, unknown> {
55
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
56
+ }