@heybox/hb-sdk 0.6.5 → 0.6.6-alpha.0
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 +5 -1
- package/dist/cli-chunks/{context-DjepdCaa.cjs → context-Do5YcZPw.cjs} +1 -1
- package/dist/cli-chunks/{create-D3BBKay9.cjs → create-CG36zW_8.cjs} +1 -1
- package/dist/cli-chunks/dev-BjlyFzNU.cjs +1976 -0
- package/dist/cli-chunks/{doctor-DEgZa2qC.cjs → doctor-OIjeEwrd.cjs} +1 -1
- package/dist/cli-chunks/{index-CKat0ExC.cjs → index-Ck6a9STO.cjs} +13 -13
- package/dist/cli-chunks/{index-B5gEl9ow.cjs → index-NrjOOQMK.cjs} +2 -2
- package/dist/cli-chunks/{login-B6gERpSX.cjs → login-CqXRKZgq.cjs} +2 -2
- package/dist/cli-chunks/{remote-BfQiZzeJ.cjs → remote-vquOa1cT.cjs} +4 -4
- package/dist/cli-chunks/{session-DPEq__gB.cjs → session-DUM4KQHQ.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/mock-host/index.html +1 -0
- package/dist/devtools/mock-host/main.js +258 -20
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.esm.js +1 -1
- package/package.json +4 -3
- package/skill/SKILL.md +3 -1
- package/skill/references/api-root.md +6 -2
- package/skill/references/cli.md +4 -2
- package/skill/skill.json +4 -4
- package/types/protocol/dev-session.d.ts +25 -0
- package/dist/cli-chunks/dev-C3u5FXIy.cjs +0 -1122
|
@@ -4,7 +4,7 @@ var fs$1 = require('node:fs');
|
|
|
4
4
|
var fs = require('node:fs/promises');
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var index = require('./index-
|
|
7
|
+
var index = require('./index-Ck6a9STO.cjs');
|
|
8
8
|
require('node:module');
|
|
9
9
|
require('path');
|
|
10
10
|
require('os');
|
|
@@ -234,19 +234,19 @@ function requireArgument () {
|
|
|
234
234
|
|
|
235
235
|
var command = {};
|
|
236
236
|
|
|
237
|
-
const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
237
|
+
const require$5 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-Ck6a9STO.cjs', document.baseURI).href)));
|
|
238
238
|
function __require$4() { return require$5("node:events"); }
|
|
239
239
|
|
|
240
|
-
const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
240
|
+
const require$4 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-Ck6a9STO.cjs', document.baseURI).href)));
|
|
241
241
|
function __require$3() { return require$4("node:child_process"); }
|
|
242
242
|
|
|
243
|
-
const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
243
|
+
const require$3 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-Ck6a9STO.cjs', document.baseURI).href)));
|
|
244
244
|
function __require$2() { return require$3("node:path"); }
|
|
245
245
|
|
|
246
|
-
const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
246
|
+
const require$2 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-Ck6a9STO.cjs', document.baseURI).href)));
|
|
247
247
|
function __require$1() { return require$2("node:fs"); }
|
|
248
248
|
|
|
249
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-
|
|
249
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli-chunks/index-Ck6a9STO.cjs', document.baseURI).href)));
|
|
250
250
|
function __require() { return require$1("node:process"); }
|
|
251
251
|
|
|
252
252
|
var help = {};
|
|
@@ -13347,7 +13347,7 @@ function getPathname(pathWithQuery) {
|
|
|
13347
13347
|
}
|
|
13348
13348
|
|
|
13349
13349
|
const CLI_VERSION_PLACEHOLDER = ['__HB', 'SDK', 'CLI', 'VERSION__'].join('_');
|
|
13350
|
-
const BUILT_CLI_VERSION = '0.6.
|
|
13350
|
+
const BUILT_CLI_VERSION = '0.6.6-alpha.0';
|
|
13351
13351
|
const PACKAGE_JSON_CANDIDATES = [
|
|
13352
13352
|
path.resolve(__dirname, '..', '..', 'package.json'),
|
|
13353
13353
|
path.resolve(__dirname, '..', 'package.json'),
|
|
@@ -13668,31 +13668,31 @@ function createCommandLoggerResolver(options) {
|
|
|
13668
13668
|
};
|
|
13669
13669
|
}
|
|
13670
13670
|
const defaultClearLoginStatus = async (...args) => {
|
|
13671
|
-
const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-
|
|
13671
|
+
const { clearLoginStatus } = await Promise.resolve().then(function () { return require('./login-CqXRKZgq.cjs'); });
|
|
13672
13672
|
return clearLoginStatus(...args);
|
|
13673
13673
|
};
|
|
13674
13674
|
const defaultLoginToHeybox = async (...args) => {
|
|
13675
|
-
const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-
|
|
13675
|
+
const { loginToHeybox } = await Promise.resolve().then(function () { return require('./login-CqXRKZgq.cjs'); });
|
|
13676
13676
|
return loginToHeybox(...args);
|
|
13677
13677
|
};
|
|
13678
13678
|
const defaultPrintLoginStatus = async (...args) => {
|
|
13679
|
-
const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-
|
|
13679
|
+
const { printLoginStatus } = await Promise.resolve().then(function () { return require('./login-CqXRKZgq.cjs'); });
|
|
13680
13680
|
return printLoginStatus(...args);
|
|
13681
13681
|
};
|
|
13682
13682
|
const defaultRunCreateCommand = async (...args) => {
|
|
13683
|
-
const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-
|
|
13683
|
+
const { runCreateCommand } = await Promise.resolve().then(function () { return require('./create-CG36zW_8.cjs'); });
|
|
13684
13684
|
return runCreateCommand(...args);
|
|
13685
13685
|
};
|
|
13686
13686
|
const defaultRunDevCommand = async (...args) => {
|
|
13687
|
-
const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-
|
|
13687
|
+
const { runDevCommand } = await Promise.resolve().then(function () { return require('./dev-BjlyFzNU.cjs'); });
|
|
13688
13688
|
return runDevCommand(...args);
|
|
13689
13689
|
};
|
|
13690
13690
|
const defaultRunDoctorCommand = async (...args) => {
|
|
13691
|
-
const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-
|
|
13691
|
+
const { runDoctorCommand } = await Promise.resolve().then(function () { return require('./doctor-OIjeEwrd.cjs'); });
|
|
13692
13692
|
return runDoctorCommand(...args);
|
|
13693
13693
|
};
|
|
13694
13694
|
const defaultRunRemoteCommand = async (...args) => {
|
|
13695
|
-
const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-
|
|
13695
|
+
const { runRemoteCommand } = await Promise.resolve().then(function () { return require('./remote-vquOa1cT.cjs'); });
|
|
13696
13696
|
return runRemoteCommand(...args);
|
|
13697
13697
|
};
|
|
13698
13698
|
function resolveStandaloneLogger(options, verbose) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index$2 = require('./index-
|
|
3
|
+
var index$2 = require('./index-Ck6a9STO.cjs');
|
|
4
4
|
var require$$0$2 = require('fs');
|
|
5
5
|
var require$$2$1 = require('crypto');
|
|
6
6
|
var require$$1$2 = require('path');
|
|
7
7
|
var require$$0$3 = require('assert');
|
|
8
8
|
var require$$4$2 = require('events');
|
|
9
9
|
var require$$1$1 = require('util');
|
|
10
|
-
var context$1 = require('./context-
|
|
10
|
+
var context$1 = require('./context-Do5YcZPw.cjs');
|
|
11
11
|
var require$$0$5 = require('net');
|
|
12
12
|
var require$$0$4 = require('url');
|
|
13
13
|
var require$$2$2 = require('http');
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var promises = require('node:readline/promises');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
5
|
var node_http = require('node:http');
|
|
6
|
-
var session = require('./session-
|
|
6
|
+
var session = require('./session-DUM4KQHQ.cjs');
|
|
7
7
|
var browser = require('./browser-RAy8e8cV.cjs');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-Ck6a9STO.cjs');
|
|
9
9
|
require('node:path');
|
|
10
10
|
require('fs');
|
|
11
11
|
require('constants');
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var promises = require('node:readline/promises');
|
|
4
|
-
var index = require('./index-
|
|
5
|
-
var session = require('./session-
|
|
4
|
+
var index = require('./index-Ck6a9STO.cjs');
|
|
5
|
+
var session = require('./session-DUM4KQHQ.cjs');
|
|
6
6
|
var childProcess = require('node:child_process');
|
|
7
7
|
var fs = require('node:fs');
|
|
8
8
|
var fs$1 = require('node:fs/promises');
|
|
9
9
|
var path = require('node:path');
|
|
10
|
-
var context = require('./context-
|
|
10
|
+
var context = require('./context-Do5YcZPw.cjs');
|
|
11
11
|
require('node:module');
|
|
12
12
|
require('path');
|
|
13
13
|
require('os');
|
|
@@ -264,7 +264,7 @@ async function createDefaultCosClient(uploadToken) {
|
|
|
264
264
|
};
|
|
265
265
|
}
|
|
266
266
|
async function loadCosConstructor() {
|
|
267
|
-
const cosModule = await Promise.resolve().then(function () { return require('./index-
|
|
267
|
+
const cosModule = await Promise.resolve().then(function () { return require('./index-NrjOOQMK.cjs'); }).then(function (n) { return n.index; });
|
|
268
268
|
return cosModule.default;
|
|
269
269
|
}
|
|
270
270
|
function formatSize(bytes) {
|
package/dist/cli.cjs
CHANGED
|
@@ -384,6 +384,7 @@
|
|
|
384
384
|
<div class="actions" style="margin-top: 10px">
|
|
385
385
|
<button id="reset-permissions-button" type="button">恢复初始权限</button>
|
|
386
386
|
</div>
|
|
387
|
+
<div class="mac-app-status" id="permission-persistence-status"></div>
|
|
387
388
|
<ul class="release-diagnostics" id="release-diagnostics"></ul>
|
|
388
389
|
</section>
|
|
389
390
|
|
|
@@ -3427,6 +3427,11 @@ function requireBrowser () {
|
|
|
3427
3427
|
|
|
3428
3428
|
var browserExports = requireBrowser();
|
|
3429
3429
|
|
|
3430
|
+
/** Dev Shell 读取局域网 Dev Session endpoint 的 query 参数。 */
|
|
3431
|
+
const MINI_PROGRAM_DEV_CONTEXT_QUERY_PARAM = 'dev_context_url';
|
|
3432
|
+
/** Mock Host 创建和读取 Dev Session 的固定路径。 */
|
|
3433
|
+
const MINI_PROGRAM_DEV_CONTEXT_PATH = '/__hb_sdk__/dev-context';
|
|
3434
|
+
|
|
3430
3435
|
function createCSPViolationPanel(container) {
|
|
3431
3436
|
const seen = new Set();
|
|
3432
3437
|
const list = document.createElement('ol');
|
|
@@ -6385,6 +6390,7 @@ function isPlainRecord(value) {
|
|
|
6385
6390
|
|
|
6386
6391
|
const NETWORK_PROXY_PATH = '/__hb_sdk_mock_network__';
|
|
6387
6392
|
const MOCK_HOST_BOOTSTRAP_PATH = '/__hb_sdk_bootstrap__';
|
|
6393
|
+
const DEV_PERMISSIONS_PATH = '/__hb_sdk__/dev-permissions';
|
|
6388
6394
|
const RUNTIME_GATE_PROBE_METHOD = 'runtime.gate.probe';
|
|
6389
6395
|
const params = new URL(location.href).searchParams;
|
|
6390
6396
|
const miniUrl = params.get('mini_url');
|
|
@@ -6397,6 +6403,9 @@ const storage = new Map();
|
|
|
6397
6403
|
const logs = [];
|
|
6398
6404
|
let handshaken = false;
|
|
6399
6405
|
let navigationBarStyle = 'dark';
|
|
6406
|
+
let mobileQrGeneration = 0;
|
|
6407
|
+
let mobileQrRefreshTimer;
|
|
6408
|
+
let mobileDevSessionCreation = Promise.resolve();
|
|
6400
6409
|
let currentUser = {
|
|
6401
6410
|
heybox_id: 'debug_user',
|
|
6402
6411
|
nickname: 'PC Debug User',
|
|
@@ -6419,6 +6428,7 @@ const elements = {
|
|
|
6419
6428
|
mobileQrStatus: queryElement('#mobile-qr-status'),
|
|
6420
6429
|
nicknameInput: queryElement('#nickname-input'),
|
|
6421
6430
|
networkPermissionSelect: queryElement('#network-permission-select'),
|
|
6431
|
+
permissionPersistenceStatus: queryElement('#permission-persistence-status'),
|
|
6422
6432
|
releaseDiagnostics: queryElement('#release-diagnostics'),
|
|
6423
6433
|
resetPermissionsButton: queryElement('#reset-permissions-button'),
|
|
6424
6434
|
storageSnapshot: queryElement('#storage-snapshot'),
|
|
@@ -6431,9 +6441,12 @@ if (!miniUrl) {
|
|
|
6431
6441
|
}
|
|
6432
6442
|
const miniProgramUrl = miniUrl;
|
|
6433
6443
|
const bootstrap = await loadMockHostBootstrap();
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
let permissionState = clonePermissionState(
|
|
6444
|
+
let devContext = bootstrap.devContext;
|
|
6445
|
+
let remotePermissionState = createMiniProgramMockPermissionState(devContext);
|
|
6446
|
+
let permissionState = clonePermissionState(remotePermissionState);
|
|
6447
|
+
let hasPermissionOverride = false;
|
|
6448
|
+
let permissionActionMessage = '';
|
|
6449
|
+
await loadPersistedPermissionConfiguration();
|
|
6437
6450
|
const iframe = document.createElement('iframe');
|
|
6438
6451
|
iframe.src = appendNonce(miniProgramUrl, nonce);
|
|
6439
6452
|
iframe.allow = 'clipboard-read; clipboard-write';
|
|
@@ -6468,6 +6481,7 @@ updateStorageSnapshot();
|
|
|
6468
6481
|
updatePermissionControls();
|
|
6469
6482
|
window.addEventListener('message', handleMessage);
|
|
6470
6483
|
window.addEventListener('beforeunload', () => {
|
|
6484
|
+
clearMobileQrRefreshTimer();
|
|
6471
6485
|
postEvent('unload', { timestamp: Date.now() });
|
|
6472
6486
|
});
|
|
6473
6487
|
queryElement('#login-button').addEventListener('click', () => {
|
|
@@ -6494,13 +6508,10 @@ elements.mobileLanSelect.addEventListener('change', () => {
|
|
|
6494
6508
|
void updateMobileQrCode();
|
|
6495
6509
|
});
|
|
6496
6510
|
elements.networkPermissionSelect.addEventListener('change', () => {
|
|
6497
|
-
|
|
6498
|
-
elements.networkPermissionSelect.value === 'enabled' ? 'enabled' : 'disabled';
|
|
6499
|
-
rebuildRuntimeWithPermissions();
|
|
6511
|
+
void savePermissionOverride(elements.networkPermissionSelect.value === 'enabled' ? 'enabled' : 'disabled');
|
|
6500
6512
|
});
|
|
6501
6513
|
elements.resetPermissionsButton.addEventListener('click', () => {
|
|
6502
|
-
|
|
6503
|
-
rebuildRuntimeWithPermissions();
|
|
6514
|
+
void resetPermissionOverride();
|
|
6504
6515
|
});
|
|
6505
6516
|
const mobileAppQrReady = setupMobileAppQr();
|
|
6506
6517
|
function createRuntime() {
|
|
@@ -6515,14 +6526,149 @@ function rebuildRuntimeWithPermissions() {
|
|
|
6515
6526
|
}
|
|
6516
6527
|
function updatePermissionControls() {
|
|
6517
6528
|
elements.devContextStatus.textContent =
|
|
6518
|
-
devContext.source === 'remote'
|
|
6519
|
-
? `已连接线上配置${devContext.miniProgramId ? ` · ${devContext.miniProgramId}` : ''}`
|
|
6520
|
-
: '匿名本地沙箱';
|
|
6529
|
+
devContext.source === 'remote' ? `已连接线上配置${devContext.miniProgramId ? ` · ${devContext.miniProgramId}` : ''}` : '匿名本地沙箱';
|
|
6521
6530
|
elements.networkPermissionSelect.value = permissionState.networkRequest.status;
|
|
6531
|
+
const remoteLabel = readPermissionStatusLabel(remotePermissionState.networkRequest.status);
|
|
6532
|
+
const localLabel = readPermissionStatusLabel(permissionState.networkRequest.status);
|
|
6533
|
+
const sourceDescription = hasPermissionOverride
|
|
6534
|
+
? `远端基线:${remoteLabel} · 本地覆盖:${localLabel}`
|
|
6535
|
+
: `${devContext.source === 'remote' ? '当前使用远端权限' : '当前使用匿名默认权限'}:${remoteLabel}`;
|
|
6536
|
+
elements.permissionPersistenceStatus.textContent = permissionActionMessage
|
|
6537
|
+
? `${sourceDescription} · ${permissionActionMessage}`
|
|
6538
|
+
: sourceDescription;
|
|
6522
6539
|
const diagnostics = createMiniProgramDevReleaseDiagnostics(devContext, permissionState);
|
|
6523
|
-
elements.releaseDiagnostics.innerHTML = diagnostics
|
|
6524
|
-
|
|
6525
|
-
|
|
6540
|
+
elements.releaseDiagnostics.innerHTML = diagnostics.map((diagnostic) => `<li>${escapeHtml(diagnostic.message)}</li>`).join('');
|
|
6541
|
+
}
|
|
6542
|
+
async function loadPersistedPermissionConfiguration() {
|
|
6543
|
+
try {
|
|
6544
|
+
const response = await fetch(DEV_PERMISSIONS_PATH, { cache: 'no-store' });
|
|
6545
|
+
const payload = await response.json();
|
|
6546
|
+
const configuration = readPermissionConfiguration(payload);
|
|
6547
|
+
if (!response.ok || !configuration) {
|
|
6548
|
+
throw new Error('权限持久化配置加载失败');
|
|
6549
|
+
}
|
|
6550
|
+
applyPermissionConfiguration(configuration);
|
|
6551
|
+
}
|
|
6552
|
+
catch {
|
|
6553
|
+
permissionActionMessage = '权限持久化暂不可用,刷新或重启后可能丢失本页修改。';
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
async function savePermissionOverride(status) {
|
|
6557
|
+
elements.networkPermissionSelect.disabled = true;
|
|
6558
|
+
elements.resetPermissionsButton.disabled = true;
|
|
6559
|
+
permissionState = {
|
|
6560
|
+
networkRequest: {
|
|
6561
|
+
...permissionState.networkRequest,
|
|
6562
|
+
status,
|
|
6563
|
+
},
|
|
6564
|
+
};
|
|
6565
|
+
hasPermissionOverride = true;
|
|
6566
|
+
permissionActionMessage = '正在保存本地权限覆盖...';
|
|
6567
|
+
rebuildRuntimeWithPermissions();
|
|
6568
|
+
void updateMobileQrCode();
|
|
6569
|
+
try {
|
|
6570
|
+
const response = await fetch(DEV_PERMISSIONS_PATH, {
|
|
6571
|
+
body: JSON.stringify({
|
|
6572
|
+
runtime_permissions: createMiniProgramMockRuntimePermissions(permissionState),
|
|
6573
|
+
}),
|
|
6574
|
+
headers: { 'content-type': 'application/json' },
|
|
6575
|
+
method: 'PUT',
|
|
6576
|
+
});
|
|
6577
|
+
const payload = await response.json();
|
|
6578
|
+
const configuration = readPermissionConfiguration(payload);
|
|
6579
|
+
if (!response.ok || !configuration) {
|
|
6580
|
+
throw new Error(readResponseMessage(payload) ?? '保存失败');
|
|
6581
|
+
}
|
|
6582
|
+
applyPermissionConfiguration(configuration, configuration.persistenceError || '本地权限覆盖已保存。');
|
|
6583
|
+
rebuildRuntimeWithPermissions();
|
|
6584
|
+
}
|
|
6585
|
+
catch (error) {
|
|
6586
|
+
permissionActionMessage = `${readErrorText(error)},当前页面仍会应用该权限,但刷新或重启后会丢失。`;
|
|
6587
|
+
updatePermissionControls();
|
|
6588
|
+
}
|
|
6589
|
+
finally {
|
|
6590
|
+
elements.networkPermissionSelect.disabled = false;
|
|
6591
|
+
elements.resetPermissionsButton.disabled = false;
|
|
6592
|
+
}
|
|
6593
|
+
}
|
|
6594
|
+
async function resetPermissionOverride() {
|
|
6595
|
+
elements.networkPermissionSelect.disabled = true;
|
|
6596
|
+
elements.resetPermissionsButton.disabled = true;
|
|
6597
|
+
try {
|
|
6598
|
+
const response = await fetch(DEV_PERMISSIONS_PATH, {
|
|
6599
|
+
method: 'DELETE',
|
|
6600
|
+
});
|
|
6601
|
+
const payload = await response.json();
|
|
6602
|
+
const configuration = readPermissionConfiguration(payload);
|
|
6603
|
+
if (!response.ok || !configuration) {
|
|
6604
|
+
throw new Error(readResponseMessage(payload) ?? '重置失败');
|
|
6605
|
+
}
|
|
6606
|
+
else {
|
|
6607
|
+
applyPermissionConfiguration(configuration, configuration.source === 'remote' ? '已重新读取远端权限并清除本地覆盖。' : '已清除本地权限覆盖。');
|
|
6608
|
+
}
|
|
6609
|
+
rebuildRuntimeWithPermissions();
|
|
6610
|
+
void updateMobileQrCode();
|
|
6611
|
+
}
|
|
6612
|
+
catch (error) {
|
|
6613
|
+
permissionActionMessage = `重置失败:${readErrorText(error)}`;
|
|
6614
|
+
updatePermissionControls();
|
|
6615
|
+
}
|
|
6616
|
+
finally {
|
|
6617
|
+
elements.networkPermissionSelect.disabled = false;
|
|
6618
|
+
elements.resetPermissionsButton.disabled = false;
|
|
6619
|
+
}
|
|
6620
|
+
}
|
|
6621
|
+
function readPermissionConfiguration(value) {
|
|
6622
|
+
if (!isRecord(value) || (value.source !== 'anonymous' && value.source !== 'remote')) {
|
|
6623
|
+
return undefined;
|
|
6624
|
+
}
|
|
6625
|
+
const remotePermissions = value.remote_permissions;
|
|
6626
|
+
const remoteParsed = parseMiniProgramRuntimePermissions(remotePermissions);
|
|
6627
|
+
const overridePermissions = value.override_permissions;
|
|
6628
|
+
const overrideParsed = parseMiniProgramRuntimePermissions(overridePermissions);
|
|
6629
|
+
if (remotePermissions !== undefined && !remoteParsed.valid) {
|
|
6630
|
+
return undefined;
|
|
6631
|
+
}
|
|
6632
|
+
if (overridePermissions !== undefined && !overrideParsed.valid) {
|
|
6633
|
+
return undefined;
|
|
6634
|
+
}
|
|
6635
|
+
const source = value.source;
|
|
6636
|
+
const fallbackContext = { };
|
|
6637
|
+
return {
|
|
6638
|
+
source,
|
|
6639
|
+
miniProgramId: typeof value.mini_program_id === 'string' ? value.mini_program_id : undefined,
|
|
6640
|
+
remotePermissions,
|
|
6641
|
+
remoteState: createMiniProgramMockPermissionState(remotePermissions === undefined ? fallbackContext : { runtimePermissions: remotePermissions }),
|
|
6642
|
+
...(overridePermissions === undefined
|
|
6643
|
+
? {}
|
|
6644
|
+
: {
|
|
6645
|
+
overrideState: createMiniProgramMockPermissionState({ runtimePermissions: overridePermissions }),
|
|
6646
|
+
}),
|
|
6647
|
+
persistenceError: typeof value.persistence_error === 'string' ? value.persistence_error : undefined,
|
|
6648
|
+
};
|
|
6649
|
+
}
|
|
6650
|
+
function applyPermissionConfiguration(configuration, message) {
|
|
6651
|
+
devContext =
|
|
6652
|
+
configuration.source === 'remote'
|
|
6653
|
+
? {
|
|
6654
|
+
source: 'remote',
|
|
6655
|
+
miniProgramId: configuration.miniProgramId,
|
|
6656
|
+
runtimePermissions: configuration.remotePermissions,
|
|
6657
|
+
}
|
|
6658
|
+
: { source: 'anonymous', warning: devContext.warning };
|
|
6659
|
+
remotePermissionState = clonePermissionState(configuration.remoteState);
|
|
6660
|
+
permissionState = clonePermissionState(configuration.overrideState ?? configuration.remoteState);
|
|
6661
|
+
hasPermissionOverride = Boolean(configuration.overrideState);
|
|
6662
|
+
permissionActionMessage = message ?? configuration.persistenceError ?? '';
|
|
6663
|
+
}
|
|
6664
|
+
function readPermissionStatusLabel(status) {
|
|
6665
|
+
return status === 'enabled' ? '允许' : '拒绝';
|
|
6666
|
+
}
|
|
6667
|
+
function readResponseMessage(value) {
|
|
6668
|
+
return isRecord(value) && typeof value.message === 'string' ? value.message : undefined;
|
|
6669
|
+
}
|
|
6670
|
+
function readErrorText(error) {
|
|
6671
|
+
return error instanceof Error && error.message ? error.message : '操作失败';
|
|
6526
6672
|
}
|
|
6527
6673
|
function clonePermissionState(state) {
|
|
6528
6674
|
return {
|
|
@@ -6754,9 +6900,7 @@ async function loadMockHostBootstrap() {
|
|
|
6754
6900
|
devContext: readDevContext(payload.devContext, payload.runtimePermissions),
|
|
6755
6901
|
lanAddresses: Array.isArray(payload.lanAddresses) ? payload.lanAddresses.filter(isLanAddress) : [],
|
|
6756
6902
|
macAppProtocol: typeof payload.macAppProtocol === 'string' ? payload.macAppProtocol : undefined,
|
|
6757
|
-
nativeAppLaunchUnavailableReason: typeof payload.nativeAppLaunchUnavailableReason === 'string'
|
|
6758
|
-
? payload.nativeAppLaunchUnavailableReason
|
|
6759
|
-
: undefined,
|
|
6903
|
+
nativeAppLaunchUnavailableReason: typeof payload.nativeAppLaunchUnavailableReason === 'string' ? payload.nativeAppLaunchUnavailableReason : undefined,
|
|
6760
6904
|
runtimePermissions: payload.runtimePermissions,
|
|
6761
6905
|
};
|
|
6762
6906
|
}
|
|
@@ -6805,6 +6949,8 @@ function setupMobileLanSelect() {
|
|
|
6805
6949
|
elements.mobileLanSelect.disabled = !hasLanAddress;
|
|
6806
6950
|
}
|
|
6807
6951
|
async function updateMobileQrCode() {
|
|
6952
|
+
const generation = ++mobileQrGeneration;
|
|
6953
|
+
clearMobileQrRefreshTimer();
|
|
6808
6954
|
if (nativeAppLaunchUnavailableReason) {
|
|
6809
6955
|
elements.mobileQrImage.removeAttribute('src');
|
|
6810
6956
|
elements.mobileQrImage.hidden = true;
|
|
@@ -6818,8 +6964,8 @@ async function updateMobileQrCode() {
|
|
|
6818
6964
|
elements.mobileQrStatus.textContent = '';
|
|
6819
6965
|
return;
|
|
6820
6966
|
}
|
|
6821
|
-
const
|
|
6822
|
-
if (!
|
|
6967
|
+
const basePayload = selected.mobileAppQrPayload;
|
|
6968
|
+
if (!basePayload) {
|
|
6823
6969
|
elements.mobileQrImage.removeAttribute('src');
|
|
6824
6970
|
elements.mobileQrImage.hidden = true;
|
|
6825
6971
|
elements.mobileQrStatus.textContent = '真机调试配置不可用,请重启 hb-sdk dev 后重试。';
|
|
@@ -6827,20 +6973,112 @@ async function updateMobileQrCode() {
|
|
|
6827
6973
|
}
|
|
6828
6974
|
elements.mobileQrStatus.textContent = '正在生成二维码...';
|
|
6829
6975
|
try {
|
|
6830
|
-
|
|
6976
|
+
const devSession = await createMobileDevSession(selected);
|
|
6977
|
+
if (generation !== mobileQrGeneration) {
|
|
6978
|
+
return;
|
|
6979
|
+
}
|
|
6980
|
+
const payload = applyDevContextToMobileQrPayload(basePayload, devSession.url);
|
|
6981
|
+
const imageUrl = await browserExports.toDataURL(payload, {
|
|
6831
6982
|
errorCorrectionLevel: 'M',
|
|
6832
6983
|
margin: 1,
|
|
6833
6984
|
width: 176,
|
|
6834
6985
|
});
|
|
6986
|
+
if (generation !== mobileQrGeneration) {
|
|
6987
|
+
return;
|
|
6988
|
+
}
|
|
6989
|
+
elements.mobileQrImage.src = imageUrl;
|
|
6835
6990
|
elements.mobileQrImage.hidden = false;
|
|
6836
6991
|
elements.mobileQrStatus.textContent = '';
|
|
6992
|
+
scheduleMobileQrRefresh(devSession.expiresAt, generation);
|
|
6837
6993
|
}
|
|
6838
6994
|
catch {
|
|
6995
|
+
if (generation !== mobileQrGeneration) {
|
|
6996
|
+
return;
|
|
6997
|
+
}
|
|
6839
6998
|
elements.mobileQrImage.removeAttribute('src');
|
|
6840
6999
|
elements.mobileQrImage.hidden = true;
|
|
6841
7000
|
elements.mobileQrStatus.textContent = '二维码生成失败';
|
|
6842
7001
|
}
|
|
6843
7002
|
}
|
|
7003
|
+
async function createMobileDevSession(selected) {
|
|
7004
|
+
const creation = mobileDevSessionCreation.then(() => requestMobileDevSession(selected));
|
|
7005
|
+
mobileDevSessionCreation = creation.then(() => undefined, () => undefined);
|
|
7006
|
+
return creation;
|
|
7007
|
+
}
|
|
7008
|
+
async function requestMobileDevSession(selected) {
|
|
7009
|
+
const miniUrl = new URL(selected.appUrl);
|
|
7010
|
+
const response = await fetch(MINI_PROGRAM_DEV_CONTEXT_PATH, {
|
|
7011
|
+
body: JSON.stringify({
|
|
7012
|
+
mini_url_origin: miniUrl.origin,
|
|
7013
|
+
runtime_permissions: createMiniProgramMockRuntimePermissions({
|
|
7014
|
+
...permissionState,
|
|
7015
|
+
networkRequest: {
|
|
7016
|
+
...permissionState.networkRequest,
|
|
7017
|
+
useOfficialDomain: false,
|
|
7018
|
+
},
|
|
7019
|
+
}),
|
|
7020
|
+
}),
|
|
7021
|
+
headers: { 'content-type': 'application/json' },
|
|
7022
|
+
method: 'POST',
|
|
7023
|
+
});
|
|
7024
|
+
if (!response.ok) {
|
|
7025
|
+
throw new Error('Failed to create mobile Dev Session');
|
|
7026
|
+
}
|
|
7027
|
+
const result = await response.json();
|
|
7028
|
+
if (!isRecord(result) ||
|
|
7029
|
+
typeof result.token !== 'string' ||
|
|
7030
|
+
!/^[a-f0-9]{64}$/.test(result.token) ||
|
|
7031
|
+
typeof result.expires_at !== 'number' ||
|
|
7032
|
+
!Number.isFinite(result.expires_at) ||
|
|
7033
|
+
result.expires_at <= Date.now()) {
|
|
7034
|
+
throw new Error('Invalid mobile Dev Session response');
|
|
7035
|
+
}
|
|
7036
|
+
const devContextUrl = new URL(`${MINI_PROGRAM_DEV_CONTEXT_PATH}/${result.token}`, location.origin);
|
|
7037
|
+
devContextUrl.hostname = miniUrl.hostname;
|
|
7038
|
+
return {
|
|
7039
|
+
expiresAt: result.expires_at,
|
|
7040
|
+
url: devContextUrl.toString(),
|
|
7041
|
+
};
|
|
7042
|
+
}
|
|
7043
|
+
function scheduleMobileQrRefresh(expiresAt, generation) {
|
|
7044
|
+
mobileQrRefreshTimer = window.setTimeout(() => {
|
|
7045
|
+
if (generation !== mobileQrGeneration) {
|
|
7046
|
+
return;
|
|
7047
|
+
}
|
|
7048
|
+
elements.mobileQrImage.removeAttribute('src');
|
|
7049
|
+
elements.mobileQrImage.hidden = true;
|
|
7050
|
+
elements.mobileQrStatus.textContent = '二维码已过期,正在重新生成...';
|
|
7051
|
+
void updateMobileQrCode();
|
|
7052
|
+
}, Math.max(0, expiresAt - Date.now()));
|
|
7053
|
+
}
|
|
7054
|
+
function clearMobileQrRefreshTimer() {
|
|
7055
|
+
if (mobileQrRefreshTimer === undefined) {
|
|
7056
|
+
return;
|
|
7057
|
+
}
|
|
7058
|
+
window.clearTimeout(mobileQrRefreshTimer);
|
|
7059
|
+
mobileQrRefreshTimer = undefined;
|
|
7060
|
+
}
|
|
7061
|
+
function applyDevContextToMobileQrPayload(payload, devContextUrl) {
|
|
7062
|
+
const protocolMarker = '#heybox://';
|
|
7063
|
+
const protocolIndex = payload.indexOf(protocolMarker);
|
|
7064
|
+
if (protocolIndex < 0) {
|
|
7065
|
+
throw new Error('Invalid mobile App QR payload');
|
|
7066
|
+
}
|
|
7067
|
+
const encodedPayload = payload.slice(protocolIndex + protocolMarker.length);
|
|
7068
|
+
const openWindowPayload = JSON.parse(decodeURIComponent(encodedPayload));
|
|
7069
|
+
if (!isRecord(openWindowPayload) || !isRecord(openWindowPayload.webview)) {
|
|
7070
|
+
throw new Error('Invalid mobile App openWindow payload');
|
|
7071
|
+
}
|
|
7072
|
+
const devShellUrlValue = openWindowPayload.webview.url;
|
|
7073
|
+
if (typeof devShellUrlValue !== 'string') {
|
|
7074
|
+
throw new Error('Missing mobile App dev shell URL');
|
|
7075
|
+
}
|
|
7076
|
+
const devShellUrl = new URL(devShellUrlValue);
|
|
7077
|
+
devShellUrl.searchParams.delete('dev_network_request');
|
|
7078
|
+
devShellUrl.searchParams.set(MINI_PROGRAM_DEV_CONTEXT_QUERY_PARAM, devContextUrl);
|
|
7079
|
+
openWindowPayload.webview.url = devShellUrl.toString();
|
|
7080
|
+
return `${payload.slice(0, protocolIndex)}${protocolMarker}${encodeURIComponent(JSON.stringify(openWindowPayload))}`;
|
|
7081
|
+
}
|
|
6844
7082
|
function updateNativeAppLaunchAvailability() {
|
|
6845
7083
|
const isUnavailable = Boolean(nativeAppLaunchUnavailableReason);
|
|
6846
7084
|
elements.macAppButton.disabled = isUnavailable;
|
package/dist/index.cjs.js
CHANGED
package/dist/index.esm.js
CHANGED
package/dist/vite.cjs.js
CHANGED
package/dist/vite.esm.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heybox/hb-sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6-alpha.0",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"./src/index.ts",
|
|
6
6
|
"./src/core/singleton.ts",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"author": "",
|
|
52
52
|
"license": "ISC",
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"parse5": "^7.3.0"
|
|
54
|
+
"parse5": "^7.3.0",
|
|
55
|
+
"undici": "^7.28.0"
|
|
55
56
|
},
|
|
56
57
|
"peerDependencies": {
|
|
57
58
|
"vite": ">=5"
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
"vue": "^2.7.16",
|
|
93
94
|
"vite": "^8.0.12",
|
|
94
95
|
"vitest": "^3.2.4",
|
|
95
|
-
"@heybox/hb-api": "~1.25.
|
|
96
|
+
"@heybox/hb-api": "~1.25.4"
|
|
96
97
|
},
|
|
97
98
|
"publishConfig": {
|
|
98
99
|
"registry": "https://registry.npmjs.org/",
|
package/skill/SKILL.md
CHANGED
|
@@ -80,7 +80,9 @@ For CLI and local development:
|
|
|
80
80
|
2. Do not use `hb-sdk login` as a workaround for mini-program user authentication.
|
|
81
81
|
3. Use the built-in local debugging page instead of creating another browser Mock.
|
|
82
82
|
4. Keep the Vite `miniappManifest()` plugin enabled.
|
|
83
|
-
5. Treat
|
|
83
|
+
5. Treat Dev Context permission changes as persistent local overrides, not online configuration changes. `hb-sdk` scopes them by real project path and `miniProgramId`, restores them after page refresh or `hb-sdk dev` restart, and clears them only after an explicit reset successfully refetches remote permissions. A regenerated Mobile App QR code may carry only a `dev_context_url` backed by a 256-bit token that expires after 5 minutes; it must not embed a permission snapshot.
|
|
84
|
+
6. Require the Runtime Host to fetch the immutable Dev Session snapshot before startup. Dev Session `network.request` must use the token-bound local proxy, never a native credential adapter, and must force `useOfficialDomain: false`.
|
|
85
|
+
7. Do not treat the legacy `dev_network_request` query as authorization or as a fallback. This Web-only flow must preserve existing Android/iOS URL pass-through behavior without requiring client changes.
|
|
84
86
|
|
|
85
87
|
For host/runtime/protocol-maintenance code:
|
|
86
88
|
|