@heybox/hb-sdk 0.8.0 → 0.8.1-alpha.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +80 -7
  3. package/dist/cli-chunks/{build-PYCNacya.cjs → build-CtqIXxDL.cjs} +16 -10
  4. package/dist/cli-chunks/{context-m2W2XbL0.cjs → context-t57bMfbr.cjs} +17 -3
  5. package/dist/cli-chunks/{create-BdAg3WGA.cjs → create-BDOPSacf.cjs} +1 -1
  6. package/dist/cli-chunks/{dev-CyZuw7Yn.cjs → dev-VxjconYc.cjs} +628 -147
  7. package/dist/cli-chunks/{doctor-DU8rCfUF.cjs → doctor-BkfYdlnZ.cjs} +1 -1
  8. package/dist/cli-chunks/{index-MMW2ibQm.cjs → index-DDrytLTX.cjs} +87 -15
  9. package/dist/cli-chunks/{index-DATObqzK.cjs → index-lLaHzwfT.cjs} +2 -2
  10. package/dist/cli-chunks/{index.esm-BiAaAUFC.cjs → index.esm-Dy4qRhuo.cjs} +9 -8
  11. package/dist/cli-chunks/{login-B3TThMss.cjs → login-D2EX4R5_.cjs} +2 -2
  12. package/dist/cli-chunks/{project-vite-BQj8YLI4.cjs → project-vite-CFhz2THK.cjs} +1 -1
  13. package/dist/cli-chunks/{remote-DNvI7tHH.cjs → remote-CfESZxO2.cjs} +41 -28
  14. package/dist/cli-chunks/{runtime-gate-BEFp1w_s.cjs → runtime-gate-BWb8QIcX.cjs} +0 -107
  15. package/dist/cli-chunks/{runtime-permission-env-CtL8rsjB.cjs → runtime-permission-env-BtTDFqEL.cjs} +304 -23
  16. package/dist/cli-chunks/{session-DjBkjaF8.cjs → session-Dkhwjqhm.cjs} +1 -1
  17. package/dist/cli-chunks/{skill-cR_wnaw2.cjs → skill-DOveC5jt.cjs} +83 -27
  18. package/dist/cli-chunks/{version-yEn1E2Bg.cjs → version-C4nE66sX.cjs} +1 -1
  19. package/dist/cli.cjs +1 -1
  20. package/dist/devtools/browser-dev-host/assets/browser-dev-host-BM9Qo_Ta.js +101 -0
  21. package/dist/devtools/browser-dev-host/assets/desktop-app-launch-C2I333Yn.js +6 -0
  22. package/dist/devtools/browser-dev-host/assets/index-Bnb6MMTv.js +567 -0
  23. package/dist/devtools/browser-dev-host/assets/index-D-aNERAr.css +1 -0
  24. package/dist/devtools/browser-dev-host/index.html +3 -3
  25. package/dist/index.cjs.js +1970 -1567
  26. package/dist/index.esm.js +1969 -1568
  27. package/dist/miniapp-publish.cjs.js +61 -0
  28. package/dist/miniapp-publish.esm.js +59 -1
  29. package/dist/protocol.cjs.js +64 -13
  30. package/dist/protocol.esm.js +64 -13
  31. package/dist/templates/vanilla-vite-js/README.md.ejs +1 -1
  32. package/dist/templates/vanilla-vite-js/package.json.ejs +1 -0
  33. package/dist/templates/vanilla-vite-js/vite.config.js +1 -1
  34. package/dist/vite.cjs.js +1333 -18
  35. package/dist/vite.esm.js +1334 -20
  36. package/package.json +9 -11
  37. package/skill/SKILL.md +11 -3
  38. package/skill/references/api-protocol.md +8 -4
  39. package/skill/references/api-root.md +328 -210
  40. package/skill/references/cli.md +11 -3
  41. package/skill/references/examples.md +13 -1
  42. package/skill/references/recipes.md +162 -0
  43. package/skill/references/safety-boundaries.md +9 -3
  44. package/skill/skill.json +5 -5
  45. package/types/core/client.d.ts +9 -1
  46. package/types/core/sdk.d.ts +6 -0
  47. package/types/core/singleton.d.ts +6 -0
  48. package/types/devtools/device-logs.d.ts +48 -0
  49. package/types/index.d.ts +5 -1
  50. package/types/miniapp-manifest/companion-directory.d.ts +2 -0
  51. package/types/miniapp-manifest/companion-executable.d.ts +4 -0
  52. package/types/miniapp-manifest/companion-types.d.ts +38 -0
  53. package/types/miniapp-manifest/companions.d.ts +17 -0
  54. package/types/miniapp-manifest/index.d.ts +2 -0
  55. package/types/miniapp-manifest/node.d.ts +9 -0
  56. package/types/miniapp-manifest/permissions.d.ts +1 -1
  57. package/types/miniapp-manifest/schema.d.ts +5 -1
  58. package/types/miniapp-publish/index.d.ts +17 -2
  59. package/types/modules/companion/index.d.ts +57 -0
  60. package/types/modules/environment/index.d.ts +70 -0
  61. package/types/modules/network/index.d.ts +1 -4
  62. package/types/modules/network/observability.d.ts +0 -1
  63. package/types/protocol/dev-session.d.ts +8 -1
  64. package/types/protocol.d.ts +1 -1
  65. package/types/vite/index.d.ts +11 -4
  66. package/dist/devtools/browser-dev-host/assets/browser-dev-host-TzYf9L6C.js +0 -99
  67. package/dist/devtools/browser-dev-host/assets/index-C5MZZDa5.js +0 -567
  68. package/dist/devtools/browser-dev-host/assets/index-P-ra4m1y.css +0 -1
  69. package/dist/devtools/browser-dev-host/assets/workbench-state-BwV7bm4n.js +0 -5
@@ -2813,6 +2813,8 @@ const MINIAPP_UPLOAD_SCOPE = 'activity';
2813
2813
  const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
2814
2814
  const MINIAPP_UPLOAD_BATCH_SIZE = 50;
2815
2815
  const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
2816
+ /** 与 Activity 上传后端合同一致的 Companion 归档总大小上限。 */
2817
+ const MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES = 500 * 1024 * 1024;
2816
2818
  const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
2817
2819
  const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
2818
2820
  const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
@@ -2918,6 +2920,18 @@ function validateUploadTotalSize(items, options = {}) {
2918
2920
  }
2919
2921
  return undefined;
2920
2922
  }
2923
+ function validateMiniappUploadSizeBudgets(items, options = {}) {
2924
+ const companionItems = items.filter((item) => normalizeRelativePath(item.relativePath).startsWith('companions/'));
2925
+ const webItems = items.filter((item) => !normalizeRelativePath(item.relativePath).startsWith('companions/'));
2926
+ const webError = validateUploadTotalSize(webItems, { limitBytes: options.webLimitBytes ?? MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES });
2927
+ if (webError)
2928
+ return webError;
2929
+ const companionTotal = companionItems.reduce((sum, item) => sum + (Number.isFinite(item.size) && item.size > 0 ? item.size : 0), 0);
2930
+ const companionLimit = options.companionLimitBytes ?? MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES;
2931
+ if (companionTotal > companionLimit)
2932
+ return 'Companion 归档总大小超过 500MiB 上限,请缩减归档后重新 deploy';
2933
+ return undefined;
2934
+ }
2921
2935
  function shouldUploadDistFile(relativePath) {
2922
2936
  const normalized = normalizeRelativePath(relativePath);
2923
2937
  if (!normalized) {
@@ -3016,6 +3030,7 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3016
3030
  }
3017
3031
  const mappings = new Map();
3018
3032
  const serverSizes = new Map();
3033
+ const serverHashes = new Map();
3019
3034
  const knownKeys = new Set();
3020
3035
  for (const serverFile of serverFiles) {
3021
3036
  const relativePath = normalizeMiniappArtifactRelativePath(serverFile.relative_path);
@@ -3033,8 +3048,13 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3033
3048
  if (!Number.isSafeInteger(size) || size < 0) {
3034
3049
  throw new Error(`上传会话返回文件大小异常:${relativePath}`);
3035
3050
  }
3051
+ const sha256 = String(serverFile.sha256 || '');
3052
+ if (!/^[a-f0-9]{64}$/.test(sha256)) {
3053
+ throw new Error(`上传会话返回文件 SHA-256 异常:${relativePath}`);
3054
+ }
3036
3055
  mappings.set(relativePath, key);
3037
3056
  serverSizes.set(relativePath, size);
3057
+ serverHashes.set(relativePath, sha256);
3038
3058
  knownKeys.add(key);
3039
3059
  }
3040
3060
  const files = preparedFiles.map((file) => {
@@ -3045,6 +3065,9 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3045
3065
  if (serverSizes.get(file.relativePath) !== file.size) {
3046
3066
  throw new Error(`上传会话文件大小与本地构建不一致:${file.relativePath}`);
3047
3067
  }
3068
+ if (!('sha256' in file) || serverHashes.get(file.relativePath) !== file.sha256) {
3069
+ throw new Error(`上传会话文件 SHA-256 与本地构建不一致:${file.relativePath}`);
3070
+ }
3048
3071
  return { file, key };
3049
3072
  });
3050
3073
  const completed = new Set();
@@ -3061,6 +3084,41 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3061
3084
  uploadedKeys: [...completed],
3062
3085
  };
3063
3086
  }
3087
+ /** 校验 Manifest 中所有 Companion 归档都精确属于当前上传 receipt。 */
3088
+ function validateMiniappCompanionFileReceipts(companions, files) {
3089
+ const companionFiles = new Map(files.filter((file) => file.relativePath.startsWith('companions/')).map((file) => [file.relativePath, file]));
3090
+ if (companions === undefined) {
3091
+ if (companionFiles.size > 0)
3092
+ throw new Error('dist 包含未被 manifest.companions 引用的 Companion 归档');
3093
+ return;
3094
+ }
3095
+ if (!isRecord(companions))
3096
+ throw new Error('manifest.companions 必须是对象');
3097
+ const referenced = new Set();
3098
+ for (const definition of Object.values(companions)) {
3099
+ if (!isRecord(definition) || !isRecord(definition.targets))
3100
+ throw new Error('manifest.companions targets 不合法');
3101
+ for (const artifact of Object.values(definition.targets)) {
3102
+ if (!isRecord(artifact) || typeof artifact.path !== 'string' || typeof artifact.size !== 'number' || typeof artifact.sha256 !== 'string') {
3103
+ throw new Error('manifest.companions artifact 不合法');
3104
+ }
3105
+ const file = companionFiles.get(artifact.path);
3106
+ if (!file)
3107
+ throw new Error(`manifest.companions 引用的归档不在当前上传 receipt:${artifact.path}`);
3108
+ if (file.size !== artifact.size)
3109
+ throw new Error(`Companion 归档大小与 manifest 不一致:${artifact.path}`);
3110
+ if (file.sha256 !== artifact.sha256)
3111
+ throw new Error(`Companion 归档 SHA-256 与 manifest 不一致:${artifact.path}`);
3112
+ referenced.add(artifact.path);
3113
+ }
3114
+ }
3115
+ const extra = [...companionFiles.keys()].find((relativePath) => !referenced.has(relativePath));
3116
+ if (extra)
3117
+ throw new Error(`Companion 归档未被 manifest.companions 引用:${extra}`);
3118
+ }
3119
+ function isRecord(value) {
3120
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
3121
+ }
3064
3122
  function normalizeMiniappArtifactRelativePath(relativePath) {
3065
3123
  const value = String(relativePath || '');
3066
3124
  if (!value) {
@@ -3143,6 +3201,7 @@ exports.DEVELOPER_ENTITY_SWITCH_API_PATH = DEVELOPER_ENTITY_SWITCH_API_PATH;
3143
3201
  exports.LIST_USER_MINIPROGRAM_API_PATH = LIST_USER_MINIPROGRAM_API_PATH;
3144
3202
  exports.LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH = LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH;
3145
3203
  exports.LIST_USER_MINIPROGRAM_VERSION_API_PATH = LIST_USER_MINIPROGRAM_VERSION_API_PATH;
3204
+ exports.MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES = MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES;
3146
3205
  exports.MINIAPP_UPLOAD_BATCH_SIZE = MINIAPP_UPLOAD_BATCH_SIZE;
3147
3206
  exports.MINIAPP_UPLOAD_SCOPE = MINIAPP_UPLOAD_SCOPE;
3148
3207
  exports.MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES;
@@ -3167,6 +3226,8 @@ exports.prepareMiniappArtifactFiles = prepareMiniappArtifactFiles;
3167
3226
  exports.relativePathContainsNodeModulesSegment = relativePathContainsNodeModulesSegment;
3168
3227
  exports.resolveMiniappUploadSessionFiles = resolveMiniappUploadSessionFiles;
3169
3228
  exports.shouldUploadDistFile = shouldUploadDistFile;
3229
+ exports.validateMiniappCompanionFileReceipts = validateMiniappCompanionFileReceipts;
3170
3230
  exports.validateMiniappUploadPathLengths = validateMiniappUploadPathLengths;
3231
+ exports.validateMiniappUploadSizeBudgets = validateMiniappUploadSizeBudgets;
3171
3232
  exports.validateUploadPaths = validateUploadPaths;
3172
3233
  exports.validateUploadTotalSize = validateUploadTotalSize;
@@ -2811,6 +2811,8 @@ const MINIAPP_UPLOAD_SCOPE = 'activity';
2811
2811
  const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
2812
2812
  const MINIAPP_UPLOAD_BATCH_SIZE = 50;
2813
2813
  const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
2814
+ /** 与 Activity 上传后端合同一致的 Companion 归档总大小上限。 */
2815
+ const MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES = 500 * 1024 * 1024;
2814
2816
  const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
2815
2817
  const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
2816
2818
  const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
@@ -2916,6 +2918,18 @@ function validateUploadTotalSize(items, options = {}) {
2916
2918
  }
2917
2919
  return undefined;
2918
2920
  }
2921
+ function validateMiniappUploadSizeBudgets(items, options = {}) {
2922
+ const companionItems = items.filter((item) => normalizeRelativePath(item.relativePath).startsWith('companions/'));
2923
+ const webItems = items.filter((item) => !normalizeRelativePath(item.relativePath).startsWith('companions/'));
2924
+ const webError = validateUploadTotalSize(webItems, { limitBytes: options.webLimitBytes ?? MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES });
2925
+ if (webError)
2926
+ return webError;
2927
+ const companionTotal = companionItems.reduce((sum, item) => sum + (Number.isFinite(item.size) && item.size > 0 ? item.size : 0), 0);
2928
+ const companionLimit = options.companionLimitBytes ?? MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES;
2929
+ if (companionTotal > companionLimit)
2930
+ return 'Companion 归档总大小超过 500MiB 上限,请缩减归档后重新 deploy';
2931
+ return undefined;
2932
+ }
2919
2933
  function shouldUploadDistFile(relativePath) {
2920
2934
  const normalized = normalizeRelativePath(relativePath);
2921
2935
  if (!normalized) {
@@ -3014,6 +3028,7 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3014
3028
  }
3015
3029
  const mappings = new Map();
3016
3030
  const serverSizes = new Map();
3031
+ const serverHashes = new Map();
3017
3032
  const knownKeys = new Set();
3018
3033
  for (const serverFile of serverFiles) {
3019
3034
  const relativePath = normalizeMiniappArtifactRelativePath(serverFile.relative_path);
@@ -3031,8 +3046,13 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3031
3046
  if (!Number.isSafeInteger(size) || size < 0) {
3032
3047
  throw new Error(`上传会话返回文件大小异常:${relativePath}`);
3033
3048
  }
3049
+ const sha256 = String(serverFile.sha256 || '');
3050
+ if (!/^[a-f0-9]{64}$/.test(sha256)) {
3051
+ throw new Error(`上传会话返回文件 SHA-256 异常:${relativePath}`);
3052
+ }
3034
3053
  mappings.set(relativePath, key);
3035
3054
  serverSizes.set(relativePath, size);
3055
+ serverHashes.set(relativePath, sha256);
3036
3056
  knownKeys.add(key);
3037
3057
  }
3038
3058
  const files = preparedFiles.map((file) => {
@@ -3043,6 +3063,9 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3043
3063
  if (serverSizes.get(file.relativePath) !== file.size) {
3044
3064
  throw new Error(`上传会话文件大小与本地构建不一致:${file.relativePath}`);
3045
3065
  }
3066
+ if (!('sha256' in file) || serverHashes.get(file.relativePath) !== file.sha256) {
3067
+ throw new Error(`上传会话文件 SHA-256 与本地构建不一致:${file.relativePath}`);
3068
+ }
3046
3069
  return { file, key };
3047
3070
  });
3048
3071
  const completed = new Set();
@@ -3059,6 +3082,41 @@ function resolveMiniappUploadSessionFiles(localFiles, serverFiles, uploadedKeys)
3059
3082
  uploadedKeys: [...completed],
3060
3083
  };
3061
3084
  }
3085
+ /** 校验 Manifest 中所有 Companion 归档都精确属于当前上传 receipt。 */
3086
+ function validateMiniappCompanionFileReceipts(companions, files) {
3087
+ const companionFiles = new Map(files.filter((file) => file.relativePath.startsWith('companions/')).map((file) => [file.relativePath, file]));
3088
+ if (companions === undefined) {
3089
+ if (companionFiles.size > 0)
3090
+ throw new Error('dist 包含未被 manifest.companions 引用的 Companion 归档');
3091
+ return;
3092
+ }
3093
+ if (!isRecord(companions))
3094
+ throw new Error('manifest.companions 必须是对象');
3095
+ const referenced = new Set();
3096
+ for (const definition of Object.values(companions)) {
3097
+ if (!isRecord(definition) || !isRecord(definition.targets))
3098
+ throw new Error('manifest.companions targets 不合法');
3099
+ for (const artifact of Object.values(definition.targets)) {
3100
+ if (!isRecord(artifact) || typeof artifact.path !== 'string' || typeof artifact.size !== 'number' || typeof artifact.sha256 !== 'string') {
3101
+ throw new Error('manifest.companions artifact 不合法');
3102
+ }
3103
+ const file = companionFiles.get(artifact.path);
3104
+ if (!file)
3105
+ throw new Error(`manifest.companions 引用的归档不在当前上传 receipt:${artifact.path}`);
3106
+ if (file.size !== artifact.size)
3107
+ throw new Error(`Companion 归档大小与 manifest 不一致:${artifact.path}`);
3108
+ if (file.sha256 !== artifact.sha256)
3109
+ throw new Error(`Companion 归档 SHA-256 与 manifest 不一致:${artifact.path}`);
3110
+ referenced.add(artifact.path);
3111
+ }
3112
+ }
3113
+ const extra = [...companionFiles.keys()].find((relativePath) => !referenced.has(relativePath));
3114
+ if (extra)
3115
+ throw new Error(`Companion 归档未被 manifest.companions 引用:${extra}`);
3116
+ }
3117
+ function isRecord(value) {
3118
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
3119
+ }
3062
3120
  function normalizeMiniappArtifactRelativePath(relativePath) {
3063
3121
  const value = String(relativePath || '');
3064
3122
  if (!value) {
@@ -3129,4 +3187,4 @@ function compareBytes(left, right) {
3129
3187
  return left.length - right.length;
3130
3188
  }
3131
3189
 
3132
- export { ACTIVITY_UPLOAD_KEY_MAX_LENGTH, CREATE_USER_MINIPROGRAM_API_PATH, CREATE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, CREATE_USER_MINIPROGRAM_LOCAL_DEV_LAUNCH_TOKEN_API_PATH, DELETE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, DETAIL_USER_MINIPROGRAM_API_PATH, DETAIL_USER_MINIPROGRAM_LEADERBOARD_API_PATH, DEVELOPER_ENTITY_LIST_API_PATH, DEVELOPER_ENTITY_SWITCH_API_PATH, LIST_USER_MINIPROGRAM_API_PATH, LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH, LIST_USER_MINIPROGRAM_VERSION_API_PATH, MINIAPP_UPLOAD_BATCH_SIZE, MINIAPP_UPLOAD_SCOPE, MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES, PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, RELEASE_USER_MINIPROGRAM_VERSION_API_PATH, REOPEN_USER_MINIPROGRAM_API_PATH, SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, TAKE_DOWN_USER_MINIPROGRAM_API_PATH, UPDATE_SQUARE_DISPLAY_API_PATH, UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, USER_MINIPROGRAM_ACCESS_STATUS_API_PATH, USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH, createMiniappArtifactFileHeader, createMiniappArtifactSignatureHeader, getMiniProgramUploadAlias, getMiniappUploadKey, isValidMiniappManifestVersion as isValidVersion, normalizeRelativePath, prepareMiniappArtifactFiles, relativePathContainsNodeModulesSegment, resolveMiniappUploadSessionFiles, shouldUploadDistFile, validateMiniappUploadPathLengths, validateUploadPaths, validateUploadTotalSize };
3190
+ export { ACTIVITY_UPLOAD_KEY_MAX_LENGTH, CREATE_USER_MINIPROGRAM_API_PATH, CREATE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, CREATE_USER_MINIPROGRAM_LOCAL_DEV_LAUNCH_TOKEN_API_PATH, DELETE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, DETAIL_USER_MINIPROGRAM_API_PATH, DETAIL_USER_MINIPROGRAM_LEADERBOARD_API_PATH, DEVELOPER_ENTITY_LIST_API_PATH, DEVELOPER_ENTITY_SWITCH_API_PATH, LIST_USER_MINIPROGRAM_API_PATH, LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH, LIST_USER_MINIPROGRAM_VERSION_API_PATH, MINIAPP_COMPANION_UPLOAD_TEMPORARY_SIZE_LIMIT_BYTES, MINIAPP_UPLOAD_BATCH_SIZE, MINIAPP_UPLOAD_SCOPE, MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES, PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, RELEASE_USER_MINIPROGRAM_VERSION_API_PATH, REOPEN_USER_MINIPROGRAM_API_PATH, SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, TAKE_DOWN_USER_MINIPROGRAM_API_PATH, UPDATE_SQUARE_DISPLAY_API_PATH, UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, USER_MINIPROGRAM_ACCESS_STATUS_API_PATH, USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH, createMiniappArtifactFileHeader, createMiniappArtifactSignatureHeader, getMiniProgramUploadAlias, getMiniappUploadKey, isValidMiniappManifestVersion as isValidVersion, normalizeRelativePath, prepareMiniappArtifactFiles, relativePathContainsNodeModulesSegment, resolveMiniappUploadSessionFiles, shouldUploadDistFile, validateMiniappCompanionFileReceipts, validateMiniappUploadPathLengths, validateMiniappUploadSizeBudgets, validateUploadPaths, validateUploadTotalSize };
@@ -1,5 +1,14 @@
1
1
  'use strict';
2
2
 
3
+ const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
4
+ const MINI_PROGRAM_MESSAGE_VERSION = 2;
5
+ const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
6
+ const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
7
+ const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
8
+ const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
9
+ const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
10
+ const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
11
+
3
12
  const AUTH_LOGIN_METHOD = 'auth.login';
4
13
  const USER_GET_INFO_METHOD = 'user.getInfo';
5
14
  const USER_REVOKE_AUTHORIZATION_METHOD = 'user.revokeAuthorization';
@@ -41,6 +50,18 @@ const CLOUD_LEADERBOARD_GET_LIST_METHOD = 'cloud.leaderboard.getList';
41
50
  const CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.getCurrentUserEntry';
42
51
  const CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.deleteCurrentUserEntry';
43
52
  const CLOUD_LEADERBOARD_GET_INFO_METHOD = 'cloud.leaderboard.getInfo';
53
+ const COMPANION_GET_INFO_METHOD = 'companion.getInfo';
54
+ const COMPANION_GET_PREPARATION_STATUS_METHOD = 'companion.getPreparationStatus';
55
+ const COMPANION_PREPARE_METHOD = 'companion.prepare';
56
+ const COMPANION_CANCEL_PREPARATION_METHOD = 'companion.cancelPreparation';
57
+ const COMPANION_GET_ACTIVE_SESSION_METHOD = 'companion.getActiveSession';
58
+ const COMPANION_LAUNCH_METHOD = 'companion.launch';
59
+ const COMPANION_SESSION_WRITE_METHOD = 'companion.session.write';
60
+ const COMPANION_SESSION_CLOSE_STDIN_METHOD = 'companion.session.closeStdin';
61
+ const COMPANION_SESSION_TERMINATE_METHOD = 'companion.session.terminate';
62
+ const COMPANION_SESSION_ACK_OUTPUT_METHOD = 'companion.session.ackOutput';
63
+ const COMPANION_OPEN_ATTACHMENT_METHOD = 'companion.openAttachment';
64
+ const COMPANION_SHOW_NOTIFICATION_METHOD = 'companion.showNotification';
44
65
  const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
45
66
  {
46
67
  method: AUTH_LOGIN_METHOD,
@@ -287,17 +308,28 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
287
308
  requirement: { kind: 'all', permissions: ['leaderboard'] },
288
309
  risk: 'low',
289
310
  },
311
+ ...[
312
+ COMPANION_GET_INFO_METHOD,
313
+ COMPANION_GET_PREPARATION_STATUS_METHOD,
314
+ COMPANION_PREPARE_METHOD,
315
+ COMPANION_CANCEL_PREPARATION_METHOD,
316
+ COMPANION_GET_ACTIVE_SESSION_METHOD,
317
+ COMPANION_LAUNCH_METHOD,
318
+ COMPANION_SESSION_WRITE_METHOD,
319
+ COMPANION_SESSION_CLOSE_STDIN_METHOD,
320
+ COMPANION_SESSION_TERMINATE_METHOD,
321
+ COMPANION_SESSION_ACK_OUTPUT_METHOD,
322
+ COMPANION_OPEN_ATTACHMENT_METHOD,
323
+ COMPANION_SHOW_NOTIFICATION_METHOD,
324
+ ].map((method) => ({
325
+ method,
326
+ module: 'companion',
327
+ capability: method,
328
+ requirement: { kind: 'all', permissions: ['companion'] },
329
+ risk: 'high',
330
+ })),
290
331
  ];
291
332
 
292
- const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
293
- const MINI_PROGRAM_MESSAGE_VERSION = 2;
294
- const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
295
- const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
296
- const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
297
- const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
298
- const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
299
- const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
300
-
301
333
  function isMiniProgramBridgeMessage(value) {
302
334
  if (!isRecord$1(value))
303
335
  return false;
@@ -319,7 +351,7 @@ function isMiniProgramBridgeMessage(value) {
319
351
  if (!isNonEmptyString(value.method) || value.error !== undefined)
320
352
  return false;
321
353
  if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
322
- return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
354
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramOperationProgressPayload(value.payload);
323
355
  }
324
356
  return value.id === undefined || isNonEmptyString(value.id);
325
357
  }
@@ -357,7 +389,7 @@ function isMiniProgramDirectoryRef(value) {
357
389
  if (isNonEmptyString(value.handleId)) {
358
390
  return hasOnlyKeys(value, ['kind', 'handleId']);
359
391
  }
360
- return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
392
+ return (isMiniProgramPathRootRef(value.root) && (value.relativePath === '.' || isMiniProgramRelativePath(value.relativePath)) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
361
393
  }
362
394
  function isMiniProgramFileDescriptor(value) {
363
395
  return (isRecord$1(value) &&
@@ -400,6 +432,24 @@ function isMiniProgramDownloadProgressPayload(value) {
400
432
  return value.total === undefined;
401
433
  return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
402
434
  }
435
+ function isMiniProgramCompanionPrepareProgress(value) {
436
+ if (!isRecord$1(value))
437
+ return false;
438
+ if (value.phase === 'downloading') {
439
+ return (isNonNegativeSafeInteger(value.loaded) &&
440
+ (value.total === undefined || (isNonNegativeSafeInteger(value.total) && value.loaded <= value.total)) &&
441
+ hasOnlyKeys(value, ['phase', 'loaded', 'total']));
442
+ }
443
+ if (value.phase !== 'verifying' && value.phase !== 'extracting')
444
+ return false;
445
+ return (isNonNegativeSafeInteger(value.processed) &&
446
+ isNonNegativeSafeInteger(value.total) &&
447
+ value.processed <= value.total &&
448
+ hasOnlyKeys(value, ['phase', 'processed', 'total']));
449
+ }
450
+ function isMiniProgramOperationProgressPayload(value) {
451
+ return isMiniProgramDownloadProgressPayload(value) || isMiniProgramCompanionPrepareProgress(value);
452
+ }
403
453
  function isSDKHandshakePayload(value) {
404
454
  return isRecord$1(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
405
455
  }
@@ -438,6 +488,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
438
488
  'clipboard',
439
489
  'leaderboard',
440
490
  'network',
491
+ 'companion',
441
492
  ];
442
493
  new Set(MINI_PROGRAM_PERMISSION_KEYS);
443
494
 
@@ -465,8 +516,8 @@ function parseMiniProgramRuntimePermissions(snapshot) {
465
516
  }
466
517
  seenKeys.add(key);
467
518
  if (!isManagedMiniProgramRuntimePermissionKey(key)) {
468
- if (!isRecord(rawEntry.config))
469
- return { valid: false, permissions: {} };
519
+ // 未知权限必须忽略,不能让 config:null / 缺字段把已认识的批准一起否掉。
520
+ // 服务端会对无 config message 字段输出 null(Rylai EmitUnpopulated)。
470
521
  continue;
471
522
  }
472
523
  if (key === 'network') {
@@ -1,3 +1,12 @@
1
+ const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
2
+ const MINI_PROGRAM_MESSAGE_VERSION = 2;
3
+ const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
4
+ const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
5
+ const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
6
+ const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
7
+ const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
8
+ const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
9
+
1
10
  const AUTH_LOGIN_METHOD = 'auth.login';
2
11
  const USER_GET_INFO_METHOD = 'user.getInfo';
3
12
  const USER_REVOKE_AUTHORIZATION_METHOD = 'user.revokeAuthorization';
@@ -39,6 +48,18 @@ const CLOUD_LEADERBOARD_GET_LIST_METHOD = 'cloud.leaderboard.getList';
39
48
  const CLOUD_LEADERBOARD_GET_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.getCurrentUserEntry';
40
49
  const CLOUD_LEADERBOARD_DELETE_CURRENT_USER_ENTRY_METHOD = 'cloud.leaderboard.deleteCurrentUserEntry';
41
50
  const CLOUD_LEADERBOARD_GET_INFO_METHOD = 'cloud.leaderboard.getInfo';
51
+ const COMPANION_GET_INFO_METHOD = 'companion.getInfo';
52
+ const COMPANION_GET_PREPARATION_STATUS_METHOD = 'companion.getPreparationStatus';
53
+ const COMPANION_PREPARE_METHOD = 'companion.prepare';
54
+ const COMPANION_CANCEL_PREPARATION_METHOD = 'companion.cancelPreparation';
55
+ const COMPANION_GET_ACTIVE_SESSION_METHOD = 'companion.getActiveSession';
56
+ const COMPANION_LAUNCH_METHOD = 'companion.launch';
57
+ const COMPANION_SESSION_WRITE_METHOD = 'companion.session.write';
58
+ const COMPANION_SESSION_CLOSE_STDIN_METHOD = 'companion.session.closeStdin';
59
+ const COMPANION_SESSION_TERMINATE_METHOD = 'companion.session.terminate';
60
+ const COMPANION_SESSION_ACK_OUTPUT_METHOD = 'companion.session.ackOutput';
61
+ const COMPANION_OPEN_ATTACHMENT_METHOD = 'companion.openAttachment';
62
+ const COMPANION_SHOW_NOTIFICATION_METHOD = 'companion.showNotification';
42
63
  const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
43
64
  {
44
65
  method: AUTH_LOGIN_METHOD,
@@ -285,17 +306,28 @@ const MINI_PROGRAM_PROTOCOL_CAPABILITIES = [
285
306
  requirement: { kind: 'all', permissions: ['leaderboard'] },
286
307
  risk: 'low',
287
308
  },
309
+ ...[
310
+ COMPANION_GET_INFO_METHOD,
311
+ COMPANION_GET_PREPARATION_STATUS_METHOD,
312
+ COMPANION_PREPARE_METHOD,
313
+ COMPANION_CANCEL_PREPARATION_METHOD,
314
+ COMPANION_GET_ACTIVE_SESSION_METHOD,
315
+ COMPANION_LAUNCH_METHOD,
316
+ COMPANION_SESSION_WRITE_METHOD,
317
+ COMPANION_SESSION_CLOSE_STDIN_METHOD,
318
+ COMPANION_SESSION_TERMINATE_METHOD,
319
+ COMPANION_SESSION_ACK_OUTPUT_METHOD,
320
+ COMPANION_OPEN_ATTACHMENT_METHOD,
321
+ COMPANION_SHOW_NOTIFICATION_METHOD,
322
+ ].map((method) => ({
323
+ method,
324
+ module: 'companion',
325
+ capability: method,
326
+ requirement: { kind: 'all', permissions: ['companion'] },
327
+ risk: 'high',
328
+ })),
288
329
  ];
289
330
 
290
- const MINI_PROGRAM_MESSAGE_NAMESPACE = 'heybox:miniprogram';
291
- const MINI_PROGRAM_MESSAGE_VERSION = 2;
292
- const MINI_PROGRAM_BRIDGE_NONCE_PARAM = 'hb_mini_bridge_nonce';
293
- const SDK_HANDSHAKE_METHOD = 'sdk.handshake';
294
- const RUNTIME_LOCATION_PROBE_METHOD = 'runtime.location.probe';
295
- const SDK_LOCATION_REPORT_METHOD = 'sdk.location.report';
296
- const SDK_CSP_VIOLATION_METHOD = 'sdk.csp.violation';
297
- const MINI_PROGRAM_OPERATION_PROGRESS_METHOD = 'operation.progress';
298
-
299
331
  function isMiniProgramBridgeMessage(value) {
300
332
  if (!isRecord$1(value))
301
333
  return false;
@@ -317,7 +349,7 @@ function isMiniProgramBridgeMessage(value) {
317
349
  if (!isNonEmptyString(value.method) || value.error !== undefined)
318
350
  return false;
319
351
  if (value.method === MINI_PROGRAM_OPERATION_PROGRESS_METHOD) {
320
- return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramDownloadProgressPayload(value.payload);
352
+ return value.version === 2 && isNonEmptyString(value.id) && isMiniProgramOperationProgressPayload(value.payload);
321
353
  }
322
354
  return value.id === undefined || isNonEmptyString(value.id);
323
355
  }
@@ -355,7 +387,7 @@ function isMiniProgramDirectoryRef(value) {
355
387
  if (isNonEmptyString(value.handleId)) {
356
388
  return hasOnlyKeys(value, ['kind', 'handleId']);
357
389
  }
358
- return (isMiniProgramPathRootRef(value.root) && isMiniProgramRelativePath(value.relativePath) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
390
+ return (isMiniProgramPathRootRef(value.root) && (value.relativePath === '.' || isMiniProgramRelativePath(value.relativePath)) && hasOnlyKeys(value, ['kind', 'root', 'relativePath']));
359
391
  }
360
392
  function isMiniProgramFileDescriptor(value) {
361
393
  return (isRecord$1(value) &&
@@ -398,6 +430,24 @@ function isMiniProgramDownloadProgressPayload(value) {
398
430
  return value.total === undefined;
399
431
  return isNonNegativeSafeInteger(value.total) && value.loaded <= value.total;
400
432
  }
433
+ function isMiniProgramCompanionPrepareProgress(value) {
434
+ if (!isRecord$1(value))
435
+ return false;
436
+ if (value.phase === 'downloading') {
437
+ return (isNonNegativeSafeInteger(value.loaded) &&
438
+ (value.total === undefined || (isNonNegativeSafeInteger(value.total) && value.loaded <= value.total)) &&
439
+ hasOnlyKeys(value, ['phase', 'loaded', 'total']));
440
+ }
441
+ if (value.phase !== 'verifying' && value.phase !== 'extracting')
442
+ return false;
443
+ return (isNonNegativeSafeInteger(value.processed) &&
444
+ isNonNegativeSafeInteger(value.total) &&
445
+ value.processed <= value.total &&
446
+ hasOnlyKeys(value, ['phase', 'processed', 'total']));
447
+ }
448
+ function isMiniProgramOperationProgressPayload(value) {
449
+ return isMiniProgramDownloadProgressPayload(value) || isMiniProgramCompanionPrepareProgress(value);
450
+ }
401
451
  function isSDKHandshakePayload(value) {
402
452
  return isRecord$1(value) && isNonEmptyString(value.href) && typeof value.userAgent === 'string' && isNonEmptyString(value.sdkVersion);
403
453
  }
@@ -436,6 +486,7 @@ const MINI_PROGRAM_PERMISSION_KEYS = [
436
486
  'clipboard',
437
487
  'leaderboard',
438
488
  'network',
489
+ 'companion',
439
490
  ];
440
491
  new Set(MINI_PROGRAM_PERMISSION_KEYS);
441
492
 
@@ -463,8 +514,8 @@ function parseMiniProgramRuntimePermissions(snapshot) {
463
514
  }
464
515
  seenKeys.add(key);
465
516
  if (!isManagedMiniProgramRuntimePermissionKey(key)) {
466
- if (!isRecord(rawEntry.config))
467
- return { valid: false, permissions: {} };
517
+ // 未知权限必须忽略,不能让 config:null / 缺字段把已认识的批准一起否掉。
518
+ // 服务端会对无 config message 字段输出 null(Rylai EmitUnpopulated)。
468
519
  continue;
469
520
  }
470
521
  if (key === 'network') {
@@ -9,6 +9,6 @@ npm run build
9
9
  npm run deploy -- --release-note "更新说明"
10
10
  ```
11
11
 
12
- `vite.config.js` 默认声明 `android`、`ios`、`ohos`。发布前请在每个声明的平台完成真机验收;需要支持桌面平台时,由项目自行加入并验收。
12
+ `package.json#heybox.platforms` 默认声明 `android`、`ios`、`ohos`。发布前请在每个声明的平台完成真机验收;需要支持桌面平台时,由项目自行加入并验收。
13
13
 
14
14
  更多内容见 [CLI 指南](https://docs.xiaoheihe.cn/hb_sdk/guide/cli) 和 [SDK 文档](https://docs.xiaoheihe.cn/hb_sdk/)。
@@ -5,6 +5,7 @@
5
5
  "type": "module",
6
6
  "heybox": {
7
7
  "miniProgramId": "",
8
+ "platforms": ["android", "ios", "ohos"],
8
9
  "permissions": {}
9
10
  },
10
11
  "scripts": {
@@ -3,5 +3,5 @@ import { defineConfig } from 'vite';
3
3
 
4
4
  export default defineConfig({
5
5
  base: './',
6
- plugins: [miniappManifest({ platforms: ['android', 'ios', 'ohos'] })],
6
+ plugins: [miniappManifest()],
7
7
  });