@heybox/hb-sdk 0.4.5 → 0.4.7

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.
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var index = require('./index-13_8m0Pw.cjs');
4
+ var node_crypto = require('node:crypto');
3
5
  var path = require('node:path');
4
- var index = require('./index-BYMTp2I6.cjs');
5
6
  var require$$0$2 = require('fs');
6
7
  var require$$0 = require('constants');
7
8
  var require$$0$1 = require('stream');
@@ -66,6 +67,281 @@ function isTruthyEnvFlag(value) {
66
67
  .toLowerCase());
67
68
  }
68
69
 
70
+ const globalHeyboxCliRequestConfig = {};
71
+ function readHeyboxCliRequestConfig() {
72
+ return normalizeHeyboxRylaiServiceTagConfig(globalHeyboxCliRequestConfig);
73
+ }
74
+ function resolveHeyboxRylaiServiceTag(pathWithQuery, config = readHeyboxCliRequestConfig()) {
75
+ const normalized = normalizeHeyboxRylaiServiceTagConfig(config);
76
+ const pathname = pathWithQuery ? getPathname(pathWithQuery) : '';
77
+ const specialTag = normalized.special_tag;
78
+ if (pathname && specialTag?.path_prefix_list.some((prefix) => pathname.startsWith(prefix))) {
79
+ return specialTag.tag_name;
80
+ }
81
+ return normalized.default_tag;
82
+ }
83
+ function normalizeHeyboxRylaiServiceTagConfig(config) {
84
+ const defaultTag = normalizeHeyboxRylaiServiceTag(config.default_tag);
85
+ const specialTagName = normalizeHeyboxRylaiServiceTag(config.special_tag?.tag_name);
86
+ const pathPrefixList = config.special_tag?.path_prefix_list?.filter(isValidPathPrefix) || [];
87
+ return {
88
+ ...(defaultTag ? { default_tag: defaultTag } : {}),
89
+ ...(specialTagName && pathPrefixList.length
90
+ ? {
91
+ special_tag: {
92
+ tag_name: specialTagName,
93
+ path_prefix_list: pathPrefixList,
94
+ },
95
+ }
96
+ : {}),
97
+ };
98
+ }
99
+ function normalizeHeyboxRylaiServiceTag(value) {
100
+ const tag = String(value ?? '').trim();
101
+ if (!tag) {
102
+ return undefined;
103
+ }
104
+ if (/[\r\n]/.test(tag)) {
105
+ throw new Error('x-rylai-service-tag 不允许包含换行符');
106
+ }
107
+ return tag;
108
+ }
109
+ function isValidPathPrefix(value) {
110
+ return typeof value === 'string' && value.startsWith('/') && !/[\r\n]/.test(value);
111
+ }
112
+ function getPathname(pathWithQuery) {
113
+ try {
114
+ return new URL(pathWithQuery, 'https://api.xiaoheihe.cn').pathname;
115
+ }
116
+ catch {
117
+ return '';
118
+ }
119
+ }
120
+
121
+ const SIGN_VERSION = '999.0.4';
122
+ const SIGN_CHARSET = 'AB45STUVWZEFGJ6CH01D237IXYPQRKLMN89';
123
+ function createHeyboxOpenPlatformSignParams(pathname, options = {}) {
124
+ const now = options.now ?? new Date();
125
+ const time = Math.trunc(now.getTime() / 1000);
126
+ const nonce = options.nonce ?? md5(`${time}${Date.now()}${node_crypto.randomBytes(16).toString('hex')}`).toUpperCase();
127
+ return {
128
+ version: SIGN_VERSION,
129
+ hkey: generateSignature(pathname, time + 1, nonce),
130
+ _time: time,
131
+ nonce,
132
+ };
133
+ }
134
+ function generateSignature(path, time, nonce) {
135
+ const normalizedPath = `/${path
136
+ .split('/')
137
+ .filter(Boolean)
138
+ .join('/')}/`;
139
+ const transformedTime = transformWithOffset(String(time), SIGN_CHARSET, -2);
140
+ const transformedPath = transform(normalizedPath, SIGN_CHARSET);
141
+ const transformedNonce = transform(nonce, SIGN_CHARSET);
142
+ const combined = interleave([transformedTime, transformedPath, transformedNonce]).slice(0, 20);
143
+ const hash = md5(combined);
144
+ let sign = `${mixColumns(hash.slice(-6).split('').map((char) => char.charCodeAt(0))).reduce((sum, value) => sum + value, 0) % 100}`;
145
+ sign = sign.length < 2 ? `0${sign}` : sign;
146
+ return `${transformWithOffset(hash.substring(0, 5), SIGN_CHARSET, -4)}${sign}`;
147
+ }
148
+ function transformWithOffset(str, charset, offset) {
149
+ return transform(str, charset.slice(0, offset));
150
+ }
151
+ function transform(str, charset) {
152
+ let output = '';
153
+ for (let index = 0; index < str.length; index += 1) {
154
+ output += charset[str.charCodeAt(index) % charset.length];
155
+ }
156
+ return output;
157
+ }
158
+ function interleave(strings) {
159
+ let output = '';
160
+ const maxLength = Math.max(...strings.map((str) => str.length));
161
+ for (let index = 0; index < maxLength; index += 1) {
162
+ for (const str of strings) {
163
+ if (index < str.length) {
164
+ output += str[index];
165
+ }
166
+ }
167
+ }
168
+ return output;
169
+ }
170
+ function mixColumns(column) {
171
+ const output = [...column];
172
+ output[0] = multiplyE(column[0]) ^ multiply4(column[1]) ^ multiply3(column[2]) ^ multiply2(column[3]);
173
+ output[1] = multiply2(column[0]) ^ multiplyE(column[1]) ^ multiply4(column[2]) ^ multiply3(column[3]);
174
+ output[2] = multiply3(column[0]) ^ multiply2(column[1]) ^ multiplyE(column[2]) ^ multiply4(column[3]);
175
+ output[3] = multiply4(column[0]) ^ multiply3(column[1]) ^ multiply2(column[2]) ^ multiplyE(column[3]);
176
+ return output;
177
+ }
178
+ function multiply1(value) {
179
+ if (value & 0x80) {
180
+ return ((value << 1) ^ 0x1b) & 0xff;
181
+ }
182
+ return value << 1;
183
+ }
184
+ function multiply2(value) {
185
+ return multiply1(value) ^ value;
186
+ }
187
+ function multiply3(value) {
188
+ return multiply2(multiply1(value));
189
+ }
190
+ function multiply4(value) {
191
+ return multiply3(multiply2(multiply1(value)));
192
+ }
193
+ function multiplyE(value) {
194
+ return multiply4(value) ^ multiply3(value) ^ multiply2(value);
195
+ }
196
+ function md5(input) {
197
+ return node_crypto.createHash('md5').update(input).digest('hex');
198
+ }
199
+
200
+ const DEFAULT_PLATFORM_PARAMS = {
201
+ os_type: 'web',
202
+ app: 'heybox',
203
+ x_client_type: 'web',
204
+ x_os_type: 'Mac',
205
+ x_app: 'heybox',
206
+ x_client_version: '999.999.999',
207
+ };
208
+ const HEYBOX_WEB_REFERER = 'https://www.xiaoheihe.cn/';
209
+ function resolveHeyboxId(session) {
210
+ if (session.heyboxId.trim()) {
211
+ return session.heyboxId.trim();
212
+ }
213
+ return session.cookieHeader
214
+ .split(';')
215
+ .map((part) => part.trim())
216
+ .find((part) => part.startsWith('heybox_id='))
217
+ ?.slice('heybox_id='.length);
218
+ }
219
+ function createHeyboxAuthHeaders(session, options = {}) {
220
+ const serviceTag = resolveHeyboxRylaiServiceTag(options.pathWithQuery);
221
+ return {
222
+ Cookie: session.cookieHeader,
223
+ Referer: HEYBOX_WEB_REFERER,
224
+ ...(options.contentType ? { 'Content-Type': options.contentType } : {}),
225
+ ...(serviceTag ? { 'x-rylai-service-tag': serviceTag } : {}),
226
+ };
227
+ }
228
+ function createHeyboxRequestContext(session, options = {}) {
229
+ const heyboxId = resolveHeyboxId(session);
230
+ const serviceTag = resolveHeyboxRylaiServiceTag(options.pathWithQuery);
231
+ return {
232
+ baseUrl: HEYBOX_API_BASE_URL,
233
+ headers: createHeyboxAuthHeaders(session, options),
234
+ platformParams: {
235
+ ...DEFAULT_PLATFORM_PARAMS,
236
+ ...options.platformParams,
237
+ ...(heyboxId ? { heybox_id: heyboxId } : {}),
238
+ ...(serviceTag ? { special_tag: serviceTag } : {}),
239
+ },
240
+ };
241
+ }
242
+ function createHeyboxOpenPlatformRequestContext(session, pathWithQuery, options = {}) {
243
+ return createHeyboxRequestContext(session, {
244
+ ...options,
245
+ pathWithQuery,
246
+ platformParams: {
247
+ x_app: 'heybox_website',
248
+ ...createHeyboxOpenPlatformSignParams(getApiPathname(pathWithQuery)),
249
+ ...options.platformParams,
250
+ },
251
+ });
252
+ }
253
+ function createHeyboxApiUrl(baseUrl, pathWithQuery, params) {
254
+ const url = new URL(pathWithQuery, baseUrl);
255
+ for (const [key, value] of Object.entries(params)) {
256
+ if (value !== '') {
257
+ url.searchParams.set(key, String(value));
258
+ }
259
+ }
260
+ return url.toString();
261
+ }
262
+ function getApiPathname(pathWithQuery) {
263
+ return new URL(pathWithQuery, HEYBOX_API_BASE_URL).pathname;
264
+ }
265
+ const ENVELOPE_BODY_PREVIEW_LENGTH = 1000;
266
+ async function readHeyboxApiEnvelope(response, options) {
267
+ const rawBody = await response.text();
268
+ let envelope = null;
269
+ let parseError = null;
270
+ if (rawBody) {
271
+ try {
272
+ envelope = JSON.parse(rawBody);
273
+ }
274
+ catch (error) {
275
+ parseError = error;
276
+ }
277
+ }
278
+ const envelopeOk = envelope?.status === 'ok' && (!options.requireResult || envelope?.result !== undefined);
279
+ if (response.ok && envelopeOk) {
280
+ return envelope.result;
281
+ }
282
+ const { message, verboseMessage } = formatHeyboxEnvelopeError({
283
+ response,
284
+ envelope,
285
+ parseError,
286
+ rawBody,
287
+ pathWithQuery: options.pathWithQuery,
288
+ });
289
+ throw new index.CliError(message, verboseMessage);
290
+ }
291
+ function formatHeyboxEnvelopeError(input) {
292
+ const parts = [`Heybox API ${input.pathWithQuery} failed`, `HTTP ${input.response.status}`];
293
+ if (input.envelope) {
294
+ const msg = typeof input.envelope.msg === 'string' ? input.envelope.msg.trim() : '';
295
+ const sbeUserMessage = readSbeUserMessage(input.envelope.result);
296
+ parts.push(`msg=${msg || '(empty)'}`);
297
+ if (typeof input.envelope.status === 'string') {
298
+ parts.push(`envelope.status=${input.envelope.status}`);
299
+ }
300
+ const { status: _s, msg: _m, result: _r, ...extras } = input.envelope;
301
+ if (Object.keys(extras).length > 0) {
302
+ parts.push(`extras=${truncate(safeJsonStringify(extras), ENVELOPE_BODY_PREVIEW_LENGTH)}`);
303
+ }
304
+ if (input.envelope.result !== undefined) {
305
+ parts.push(`result=${truncate(safeJsonStringify(input.envelope.result), ENVELOPE_BODY_PREVIEW_LENGTH)}`);
306
+ }
307
+ return {
308
+ message: sbeUserMessage || msg || `Heybox API ${input.pathWithQuery} 请求失败`,
309
+ verboseMessage: parts.join(' '),
310
+ };
311
+ }
312
+ if (input.parseError) {
313
+ const parseMsg = input.parseError instanceof Error ? input.parseError.message : String(input.parseError);
314
+ parts.push(`parseError=${parseMsg}`);
315
+ }
316
+ parts.push(input.rawBody ? `body=${truncate(input.rawBody, ENVELOPE_BODY_PREVIEW_LENGTH)}` : 'body=(empty)');
317
+ return {
318
+ message: `Heybox API ${input.pathWithQuery} 请求失败`,
319
+ verboseMessage: parts.join(' '),
320
+ };
321
+ }
322
+ function readSbeUserMessage(result) {
323
+ if (!result || typeof result !== 'object') {
324
+ return '';
325
+ }
326
+ const sbe = result.sbe;
327
+ if (!sbe || typeof sbe !== 'object') {
328
+ return '';
329
+ }
330
+ const userMessage = sbe.user_message;
331
+ return typeof userMessage === 'string' ? userMessage.trim() : '';
332
+ }
333
+ function truncate(value, max) {
334
+ return value.length > max ? `${value.slice(0, max)}...(+${value.length - max} chars)` : value;
335
+ }
336
+ function safeJsonStringify(value) {
337
+ try {
338
+ return JSON.stringify(value);
339
+ }
340
+ catch {
341
+ return String(value);
342
+ }
343
+ }
344
+
69
345
  var fs$1 = {};
70
346
 
71
347
  var universalify = {};
@@ -2959,20 +3235,39 @@ async function requireHeyboxAuthSession(options = {}) {
2959
3235
  return session;
2960
3236
  }
2961
3237
  async function writeHeyboxAuthSession(session, options = {}) {
2962
- const cacheFile = getAuthCacheFilePath(options);
2963
3238
  const cache = {
2964
3239
  version: AUTH_CACHE_VERSION,
2965
3240
  updatedAt: (options.now?.() ?? new Date()).toISOString(),
2966
3241
  heybox: session,
2967
3242
  };
2968
- await fs.ensureDir(path.dirname(cacheFile));
2969
- await fs.writeJson(cacheFile, cache, { spaces: 2 });
2970
- await fs.chmod(cacheFile, 0o600);
2971
- return cache;
3243
+ return writeAuthCache(cache, options);
2972
3244
  }
2973
3245
  async function clearHeyboxAuthSession(options = {}) {
2974
3246
  await fs.remove(getAuthCacheFilePath(options));
2975
3247
  }
3248
+ function createSelectedDeveloperEntitySnapshot(input, options = {}) {
3249
+ return {
3250
+ entityId: input.entityId,
3251
+ entityName: input.entityName,
3252
+ ...(input.ownerHeyboxId === undefined ? {} : { ownerHeyboxId: input.ownerHeyboxId }),
3253
+ selectedAt: (options.now?.() ?? new Date()).toISOString(),
3254
+ };
3255
+ }
3256
+ async function setSelectedDeveloperEntitySnapshot(input, options = {}) {
3257
+ const cache = await readAuthCache(options);
3258
+ if (!cache.heybox) {
3259
+ throw new Error('未发现 Heybox 登录态,请先运行 hb-sdk login');
3260
+ }
3261
+ const selectedEntity = createSelectedDeveloperEntitySnapshot(input, options);
3262
+ return writeAuthCache({
3263
+ version: AUTH_CACHE_VERSION,
3264
+ updatedAt: (options.now?.() ?? new Date()).toISOString(),
3265
+ heybox: {
3266
+ ...cache.heybox,
3267
+ selectedEntity,
3268
+ },
3269
+ }, options);
3270
+ }
2976
3271
  async function readRedactedHeyboxAuthStatus(options = {}) {
2977
3272
  const cacheFile = getAuthCacheFilePath(options);
2978
3273
  const session = await readHeyboxAuthSession(options);
@@ -2988,8 +3283,16 @@ async function readRedactedHeyboxAuthStatus(options = {}) {
2988
3283
  loginBaseUrl: session.loginBaseUrl,
2989
3284
  loggedIn: true,
2990
3285
  loggedInAt: session.loggedInAt,
3286
+ ...(session.selectedEntity ? { selectedEntity: session.selectedEntity } : {}),
2991
3287
  };
2992
3288
  }
3289
+ async function writeAuthCache(cache, options = {}) {
3290
+ const cacheFile = getAuthCacheFilePath(options);
3291
+ await fs.ensureDir(path.dirname(cacheFile));
3292
+ await fs.writeJson(cacheFile, cache, { spaces: 2 });
3293
+ await fs.chmod(cacheFile, 0o600);
3294
+ return cache;
3295
+ }
2993
3296
  function createEmptyAuthCache(options = {}) {
2994
3297
  return {
2995
3298
  version: AUTH_CACHE_VERSION,
@@ -3020,21 +3323,56 @@ function isHeyboxAuthSession(value) {
3020
3323
  typeof value.loggedInAt === 'string');
3021
3324
  }
3022
3325
  function normalizeHeyboxAuthSession(session) {
3023
- return {
3024
- ...session,
3326
+ const normalized = {
3327
+ heyboxId: session.heyboxId,
3328
+ pkey: session.pkey,
3329
+ xXhhHeyboxId: session.xXhhHeyboxId,
3330
+ cookieHeader: session.cookieHeader,
3331
+ loggedInAt: session.loggedInAt,
3025
3332
  loginBaseUrl: resolveHeyboxLoginBaseUrl({ loginBaseUrl: session.loginBaseUrl }),
3026
3333
  };
3334
+ const selectedEntity = normalizeSelectedDeveloperEntitySnapshot(session.selectedEntity);
3335
+ if (selectedEntity) {
3336
+ normalized.selectedEntity = selectedEntity;
3337
+ }
3338
+ return normalized;
3339
+ }
3340
+ function normalizeSelectedDeveloperEntitySnapshot(value) {
3341
+ if (!isRecord(value)) {
3342
+ return undefined;
3343
+ }
3344
+ if (typeof value.entityId !== 'number' || !Number.isFinite(value.entityId)) {
3345
+ return undefined;
3346
+ }
3347
+ if (typeof value.entityName !== 'string' || value.entityName.length === 0) {
3348
+ return undefined;
3349
+ }
3350
+ if (value.ownerHeyboxId !== undefined && (typeof value.ownerHeyboxId !== 'number' || !Number.isFinite(value.ownerHeyboxId))) {
3351
+ return undefined;
3352
+ }
3353
+ if (typeof value.selectedAt !== 'string' || value.selectedAt.length === 0) {
3354
+ return undefined;
3355
+ }
3356
+ return {
3357
+ entityId: value.entityId,
3358
+ entityName: value.entityName,
3359
+ ...(value.ownerHeyboxId === undefined ? {} : { ownerHeyboxId: value.ownerHeyboxId }),
3360
+ selectedAt: value.selectedAt,
3361
+ };
3027
3362
  }
3028
3363
  function isRecord(value) {
3029
3364
  return Object.prototype.toString.call(value) === '[object Object]';
3030
3365
  }
3031
3366
 
3032
- exports.HEYBOX_API_BASE_URL = HEYBOX_API_BASE_URL;
3033
3367
  exports.clearHeyboxAuthSession = clearHeyboxAuthSession;
3368
+ exports.createHeyboxApiUrl = createHeyboxApiUrl;
3034
3369
  exports.createHeyboxAuthSession = createHeyboxAuthSession;
3370
+ exports.createHeyboxOpenPlatformRequestContext = createHeyboxOpenPlatformRequestContext;
3035
3371
  exports.getAuthCacheFilePath = getAuthCacheFilePath;
3372
+ exports.readHeyboxApiEnvelope = readHeyboxApiEnvelope;
3036
3373
  exports.readRedactedHeyboxAuthStatus = readRedactedHeyboxAuthStatus;
3037
3374
  exports.requireHeyboxAuthSession = requireHeyboxAuthSession;
3038
3375
  exports.resolveHeyboxApiBaseUrl = resolveHeyboxApiBaseUrl;
3039
3376
  exports.resolveHeyboxLoginBaseUrl = resolveHeyboxLoginBaseUrl;
3377
+ exports.setSelectedDeveloperEntitySnapshot = setSelectedDeveloperEntitySnapshot;
3040
3378
  exports.writeHeyboxAuthSession = writeHeyboxAuthSession;
package/dist/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./cli-chunks/index-BYMTp2I6.cjs');
3
+ var index = require('./cli-chunks/index-13_8m0Pw.cjs');
4
4
  require('node:module');
5
5
  require('node:fs');
6
6
  require('node:fs/promises');
@@ -3686,14 +3686,14 @@ function readScreenshotRect(value) {
3686
3686
  }
3687
3687
 
3688
3688
  /** 展示基础分享面板。 */
3689
- function showMiniProgramRuntimeShareMenu(payload, platformAdapter) {
3690
- return platformAdapter.share.showShareMenu(readMiniProgramShareMenuOptions(payload));
3689
+ function showMiniProgramRuntimeShareMenu(payload, platformAdapter, context = {}) {
3690
+ return platformAdapter.share.showShareMenu(readMiniProgramShareMenuOptions(payload, platformAdapter, context));
3691
3691
  }
3692
- function readMiniProgramShareMenuOptions(payload) {
3692
+ function readMiniProgramShareMenuOptions(payload, platformAdapter, context) {
3693
3693
  assertMiniProgramRuntimeRecord(payload, 'share.showShareMenu 参数必须是对象');
3694
3694
  const title = readMiniProgramRuntimeRequiredString(payload.title, 'share.showShareMenu title 必须是非空字符串');
3695
3695
  const desc = readMiniProgramRuntimeRequiredString(payload.desc, 'share.showShareMenu desc 必须是非空字符串');
3696
- const url = readMiniProgramRuntimeHttpUrl(payload.url, 'share.showShareMenu url 必须是 HTTP(S) URL');
3696
+ const url = readMiniProgramShareUrl(payload.url, platformAdapter, context);
3697
3697
  const imageUrl = payload.imageUrl === undefined
3698
3698
  ? undefined
3699
3699
  : readMiniProgramRuntimeHttpUrl(payload.imageUrl, 'share.showShareMenu imageUrl 必须是 HTTP(S) URL');
@@ -3709,6 +3709,33 @@ function readMiniProgramShareMenuOptions(payload) {
3709
3709
  channel,
3710
3710
  };
3711
3711
  }
3712
+ function readMiniProgramShareUrl(value, platformAdapter, context) {
3713
+ if (typeof value === 'string' && value.trim()) {
3714
+ return readMiniProgramRuntimeHttpUrl(value, 'share.showShareMenu url 必须是 HTTP(S) URL');
3715
+ }
3716
+ if (value !== undefined && value !== null && value !== '') {
3717
+ throw createMiniProgramRuntimeBridgeError('INVALID_PARAMS', 'share.showShareMenu url 必须是 HTTP(S) URL');
3718
+ }
3719
+ return createUserMiniprogramShareUrl(platformAdapter, context);
3720
+ }
3721
+ function createUserMiniprogramShareUrl(platformAdapter, context) {
3722
+ const miniProgramId = context.miniProgramId?.trim();
3723
+ if (!miniProgramId) {
3724
+ throw createMiniProgramRuntimeBridgeError('INVALID_PARAMS', 'share.showShareMenu url 必须是 HTTP(S) URL');
3725
+ }
3726
+ try {
3727
+ const shareUrl = new URL('/tools/common_share', platformAdapter.app.getCurrentHref());
3728
+ shareUrl.searchParams.set('user_miniprogram_id', miniProgramId);
3729
+ const miniProgramVersion = context.miniProgramVersion?.trim();
3730
+ if (miniProgramVersion) {
3731
+ shareUrl.searchParams.set('preview_version', miniProgramVersion);
3732
+ }
3733
+ return shareUrl.href;
3734
+ }
3735
+ catch {
3736
+ throw createMiniProgramRuntimeBridgeError('INVALID_PARAMS', 'share.showShareMenu url 必须是 HTTP(S) URL');
3737
+ }
3738
+ }
3712
3739
  function isShareChannel(value) {
3713
3740
  return (value === 'wechatSession' ||
3714
3741
  value === 'wechatTimeline' ||
@@ -2811,7 +2811,11 @@ function getMiniappManifestVersionError(version) {
2811
2811
 
2812
2812
  const MINIAPP_UPLOAD_SCOPE = 'activity';
2813
2813
  const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
2814
+ const MINIAPP_UPLOAD_BATCH_SIZE = 50;
2815
+ const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
2814
2816
  const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
2817
+ const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
2818
+ const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
2815
2819
  const LIST_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/list';
2816
2820
  const CREATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/create';
2817
2821
  const UPDATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/update';
@@ -2867,6 +2871,17 @@ function validateUploadPaths(items, options) {
2867
2871
  }
2868
2872
  return undefined;
2869
2873
  }
2874
+ function validateUploadTotalSize(items, options = {}) {
2875
+ const limit = options.limitBytes ?? MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES;
2876
+ const total = items.reduce((sum, item) => {
2877
+ const size = Number(item.size);
2878
+ return sum + (Number.isFinite(size) && size > 0 ? size : 0);
2879
+ }, 0);
2880
+ if (total > limit) {
2881
+ return '构建产物总大小超过 100MB,请删除未引用资源或压缩图片后重新 deploy';
2882
+ }
2883
+ return undefined;
2884
+ }
2870
2885
  function shouldUploadDistFile(relativePath) {
2871
2886
  const normalized = normalizeRelativePath(relativePath);
2872
2887
  if (!normalized) {
@@ -2887,9 +2902,13 @@ function shouldUploadDistFile(relativePath) {
2887
2902
  exports.ACTIVITY_UPLOAD_KEY_MAX_LENGTH = ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
2888
2903
  exports.CREATE_USER_MINIPROGRAM_API_PATH = CREATE_USER_MINIPROGRAM_API_PATH;
2889
2904
  exports.DETAIL_USER_MINIPROGRAM_API_PATH = DETAIL_USER_MINIPROGRAM_API_PATH;
2905
+ exports.DEVELOPER_ENTITY_LIST_API_PATH = DEVELOPER_ENTITY_LIST_API_PATH;
2906
+ exports.DEVELOPER_ENTITY_SWITCH_API_PATH = DEVELOPER_ENTITY_SWITCH_API_PATH;
2890
2907
  exports.LIST_USER_MINIPROGRAM_API_PATH = LIST_USER_MINIPROGRAM_API_PATH;
2891
2908
  exports.LIST_USER_MINIPROGRAM_VERSION_API_PATH = LIST_USER_MINIPROGRAM_VERSION_API_PATH;
2909
+ exports.MINIAPP_UPLOAD_BATCH_SIZE = MINIAPP_UPLOAD_BATCH_SIZE;
2892
2910
  exports.MINIAPP_UPLOAD_SCOPE = MINIAPP_UPLOAD_SCOPE;
2911
+ exports.MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES;
2893
2912
  exports.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH = PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH;
2894
2913
  exports.RELEASE_USER_MINIPROGRAM_VERSION_API_PATH = RELEASE_USER_MINIPROGRAM_VERSION_API_PATH;
2895
2914
  exports.REOPEN_USER_MINIPROGRAM_API_PATH = REOPEN_USER_MINIPROGRAM_API_PATH;
@@ -2908,3 +2927,4 @@ exports.normalizeRelativePath = normalizeRelativePath;
2908
2927
  exports.relativePathContainsNodeModulesSegment = relativePathContainsNodeModulesSegment;
2909
2928
  exports.shouldUploadDistFile = shouldUploadDistFile;
2910
2929
  exports.validateUploadPaths = validateUploadPaths;
2930
+ exports.validateUploadTotalSize = validateUploadTotalSize;
@@ -2809,7 +2809,11 @@ function getMiniappManifestVersionError(version) {
2809
2809
 
2810
2810
  const MINIAPP_UPLOAD_SCOPE = 'activity';
2811
2811
  const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
2812
+ const MINIAPP_UPLOAD_BATCH_SIZE = 50;
2813
+ const MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES = 100 * 1024 * 1024;
2812
2814
  const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
2815
+ const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
2816
+ const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
2813
2817
  const LIST_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/list';
2814
2818
  const CREATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/create';
2815
2819
  const UPDATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/update';
@@ -2865,6 +2869,17 @@ function validateUploadPaths(items, options) {
2865
2869
  }
2866
2870
  return undefined;
2867
2871
  }
2872
+ function validateUploadTotalSize(items, options = {}) {
2873
+ const limit = options.limitBytes ?? MINIAPP_UPLOAD_TOTAL_SIZE_LIMIT_BYTES;
2874
+ const total = items.reduce((sum, item) => {
2875
+ const size = Number(item.size);
2876
+ return sum + (Number.isFinite(size) && size > 0 ? size : 0);
2877
+ }, 0);
2878
+ if (total > limit) {
2879
+ return '构建产物总大小超过 100MB,请删除未引用资源或压缩图片后重新 deploy';
2880
+ }
2881
+ return undefined;
2882
+ }
2868
2883
  function shouldUploadDistFile(relativePath) {
2869
2884
  const normalized = normalizeRelativePath(relativePath);
2870
2885
  if (!normalized) {
@@ -2882,4 +2897,4 @@ function shouldUploadDistFile(relativePath) {
2882
2897
  return true;
2883
2898
  }
2884
2899
 
2885
- export { ACTIVITY_UPLOAD_KEY_MAX_LENGTH, CREATE_USER_MINIPROGRAM_API_PATH, DETAIL_USER_MINIPROGRAM_API_PATH, LIST_USER_MINIPROGRAM_API_PATH, LIST_USER_MINIPROGRAM_VERSION_API_PATH, MINIAPP_UPLOAD_SCOPE, 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_USER_MINIPROGRAM_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, getMiniProgramUploadAlias, getMiniappUploadKey, isValidMiniappManifestVersion as isValidVersion, normalizeRelativePath, relativePathContainsNodeModulesSegment, shouldUploadDistFile, validateUploadPaths };
2900
+ export { ACTIVITY_UPLOAD_KEY_MAX_LENGTH, CREATE_USER_MINIPROGRAM_API_PATH, DETAIL_USER_MINIPROGRAM_API_PATH, DEVELOPER_ENTITY_LIST_API_PATH, DEVELOPER_ENTITY_SWITCH_API_PATH, LIST_USER_MINIPROGRAM_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_USER_MINIPROGRAM_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, getMiniProgramUploadAlias, getMiniappUploadKey, isValidMiniappManifestVersion as isValidVersion, normalizeRelativePath, relativePathContainsNodeModulesSegment, shouldUploadDistFile, validateUploadPaths, validateUploadTotalSize };
@@ -21,7 +21,7 @@ npm run deploy
21
21
 
22
22
  - `npm run dev`:启动本地 Vite 服务和 `hb-sdk` 内置 mock runtime host,适合本地调试 SDK 能力;调试页内可点击按钮在 Mac 版 APP 中启动同一页面,也可以选择局域网网卡后用手机小黑盒 APP 扫码调试。手机需要与电脑处在同一局域网,并使用支持小程序调试壳的新版小黑盒 APP。Codex、VSCode 等内嵌浏览器可能无法唤起系统 APP,需要时请在系统浏览器中打开同一个调试页后重试。
23
23
  - `npm run build`:先执行 TypeScript 检查,再构建生产产物。
24
- - `npm run deploy -- --release-note "..."`:运行 `hb-sdk remote deploy`,构建、上传并提交当前小程序版本审核。部署前需要先通过 `hb-sdk remote create --name "..."` 创建并绑定远端小程序,或用 `hb-sdk remote bind <mini-program-id>` 绑定已有小程序,并执行过 `npx hb-sdk login`;默认审核通过后用 `hb-sdk remote versions` 查看状态,再用 `hb-sdk remote release <version>` 发布,如需审核通过后自动发布可追加 `--auto-publish`。顶层 `hb-sdk deploy` 已删除,不再作为兼容别名保留。
24
+ - `npm run deploy -- --release-note "..."`:运行 `hb-sdk remote deploy`,构建、上传并提交当前小程序版本审核。部署前需要先执行过 `npx hb-sdk login`;多主体账号还应通过 `npx hb-sdk remote entity current` 确认服务端 current entity。远端小程序可通过 `npx hb-sdk remote create --name "..."` current entity 下创建并绑定,或用 `npx hb-sdk remote bind <mini-program-id>` 绑定 current entity 可管理的已有小程序。`selectedEntity` 只是 CLI 登录缓存中的提示快照,实际 deploy/create/bind 以服务端 current entity 为准。默认审核通过后用 `hb-sdk remote versions` 查看状态,再用 `hb-sdk remote release <version>` 发布,如需审核通过后自动发布可追加 `--auto-publish`。顶层 `hb-sdk deploy` 已删除,不再作为兼容别名保留。
25
25
 
26
26
  ## 更多能力
27
27
 
@@ -33,7 +33,6 @@ import hbSDK from '@heybox/hb-sdk';
33
33
  await hbSDK.share.showShareMenu({
34
34
  title: '<%= projectName %>',
35
35
  desc: '分享描述',
36
- url: window.location.href,
37
36
  });
38
37
 
39
38
  await hbSDK.storage.setStorage({
@@ -46,3 +45,5 @@ const response = await hbSDK.network.request({
46
45
  url: 'https://jsonplaceholder.typicode.com/todos/1',
47
46
  });
48
47
  ```
48
+
49
+ 用户小程序通常不要传 `url`;宿主 runtime 会自动生成当前小程序的通用分享页。只有确实要分享外部 HTTP(S) 页面时才显式传 `url`。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heybox/hb-sdk",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {