@heybox/hb-sdk 0.9.4-alpha.0 → 0.9.4-alpha.2

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 (31) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +2 -0
  3. package/dist/cli-chunks/{runtime-gate-alLUP4_C.cjs → artifact-BTi9i7N4.cjs} +136 -65
  4. package/dist/cli-chunks/{build-BHfbvke-.cjs → build-CScc5bgz.cjs} +34 -83
  5. package/dist/cli-chunks/{create-B-KOcThY.cjs → create-BybyVKxB.cjs} +1 -1
  6. package/dist/cli-chunks/{deploy-lock-DY7E8TFw.cjs → deploy-lock-CtJXBtKK.cjs} +1 -1
  7. package/dist/cli-chunks/{dev-BC_oKKzT.cjs → dev-BVZ9yV84.cjs} +15469 -15357
  8. package/dist/cli-chunks/{context-DZldyzoT.cjs → dev-context-BjwOy-fF.cjs} +299 -299
  9. package/dist/cli-chunks/{doctor-l9Gd1Rhf.cjs → doctor-CTEun30u.cjs} +1 -1
  10. package/dist/cli-chunks/{games-DDoaQ_KF.cjs → games-Bp6gkkgb.cjs} +2 -2
  11. package/dist/cli-chunks/{index-Czupnh5A.cjs → index-CxelQqdy.cjs} +17 -17
  12. package/dist/cli-chunks/{index-COzyQErL.cjs → index-DF8KQKoa.cjs} +1 -1
  13. package/dist/cli-chunks/{index.esm-BX-KdUxn.cjs → index.esm-vr3yuZ2Q.cjs} +6 -6
  14. package/dist/cli-chunks/{login-Dy-um6Ka.cjs → login-BPyX2p9v.cjs} +1 -1
  15. package/dist/cli-chunks/{project-vite-CTWRejM4.cjs → project-vite-DBId94T0.cjs} +1 -1
  16. package/dist/cli-chunks/{remote-BKIgszJS.cjs → remote-C1n11VWk.cjs} +66 -144
  17. package/dist/cli-chunks/{runtime-permission-env-DFFgIfoX.cjs → runtime-permission-env-Beurz19O.cjs} +127 -128
  18. package/dist/cli-chunks/{skill-WQPin-5N.cjs → skill-C33zgdJF.cjs} +2 -2
  19. package/dist/cli-chunks/{version-BQVBVZPA.cjs → version-BKjLEHsb.cjs} +1 -1
  20. package/dist/cli.cjs +1 -1
  21. package/dist/devtools/browser-dev-host/assets/{browser-dev-host-j00ZN_C-.js → browser-dev-host-DedSMBMn.js} +15 -15
  22. package/dist/devtools/browser-dev-host/assets/{desktop-app-launch-BTmNqUZA.js → desktop-app-launch-BBIYbjgT.js} +1 -1
  23. package/dist/devtools/browser-dev-host/assets/{index-D3cBjlwQ.js → index-CnC7wDP_.js} +3 -3
  24. package/dist/devtools/browser-dev-host/index.html +2 -2
  25. package/dist/index.cjs.js +1 -1
  26. package/dist/index.esm.js +1 -1
  27. package/dist/vite.cjs.js +79 -13
  28. package/dist/vite.esm.js +79 -13
  29. package/package.json +6 -6
  30. package/skill/skill.json +4 -4
  31. package/types/vite/index.d.ts +35 -7
@@ -1,82 +1,171 @@
1
1
  'use strict';
2
2
 
3
+ var index = require('./index-CxelQqdy.cjs');
4
+ var runtimePermissionEnv = require('./runtime-permission-env-Beurz19O.cjs');
3
5
  var node_crypto = require('node:crypto');
4
6
  var fs = require('node:fs/promises');
5
7
  var path = require('node:path');
6
- var runtimePermissionEnv = require('./runtime-permission-env-DFFgIfoX.cjs');
7
8
  var fs$1 = require('node:fs');
8
9
  var sharp = require('sharp');
9
- var index = require('./index-Czupnh5A.cjs');
10
10
 
11
- async function inspectBasicInfoImage(bytes, sourcePath, kind) {
12
- const inspected = await inspectDecodedBasicInfoImage(bytes, kind);
13
- const extensions = { jpg: ['jpg', 'jpeg'], png: ['png'], gif: ['gif'], webp: ['webp'] };
14
- const ext = sourcePath.split('.').pop().toLowerCase();
15
- if (!extensions[inspected.extension]?.includes(ext))
16
- throw new Error('资料图片格式与扩展名不一致');
17
- return inspected;
11
+ function createRemoteApiClient(options) {
12
+ return {
13
+ listPermissionApplications: (request) => remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_PERMISSION_APPLICATION_API_PATH, request, options),
14
+ submitPermissionApplication: (request) => remotePostForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_PERMISSION_APPLICATION_API_PATH, request, options),
15
+ listDeveloperEntities: () => listDeveloperEntities(options),
16
+ switchDeveloperEntity: (requestOptions) => switchDeveloperEntity(requestOptions, options),
17
+ getDeveloperAccessStatus: () => getDeveloperAccessStatus(options),
18
+ listUserMiniprograms: (requestOptions = {}) => listUserMiniprograms(requestOptions, options),
19
+ createUserMiniprogram: () => createUserMiniprogram(options),
20
+ getUserMiniprogramDetail: (requestOptions) => getUserMiniprogramDetail(requestOptions, options),
21
+ createLocalDevLaunchToken: (requestOptions) => createLocalDevLaunchToken$1(requestOptions, options),
22
+ getPreviewAllowlist: (requestOptions) => getPreviewAllowlist(requestOptions, options),
23
+ updatePreviewAllowlist: (requestOptions) => updatePreviewAllowlist(requestOptions, options),
24
+ createUserMiniprogramLeaderboard: (requestOptions) => createUserMiniprogramLeaderboard(requestOptions, options),
25
+ getUserMiniprogramLeaderboard: (requestOptions) => getUserMiniprogramLeaderboard(requestOptions, options),
26
+ listUserMiniprogramLeaderboards: (requestOptions) => listUserMiniprogramLeaderboards(requestOptions, options),
27
+ deleteUserMiniprogramLeaderboard: (requestOptions) => deleteUserMiniprogramLeaderboard(requestOptions, options),
28
+ precheckUserMiniprogramVersion: (requestOptions) => precheckUserMiniprogramVersion(requestOptions, options),
29
+ submitUserMiniprogramAudit: (requestOptions) => submitUserMiniprogramAudit(requestOptions, options),
30
+ getVersionPreviewInfo: (requestOptions) => getVersionPreviewInfo(requestOptions, options),
31
+ withdrawUserMiniprogramVersion: (requestOptions) => withdrawUserMiniprogramVersion(requestOptions, options),
32
+ releaseUserMiniprogramVersion: (requestOptions) => releaseUserMiniprogramVersion(requestOptions, options),
33
+ takeDownUserMiniprogram: (requestOptions) => takeDownUserMiniprogram(requestOptions, options),
34
+ reopenUserMiniprogram: (requestOptions) => reopenUserMiniprogram(requestOptions, options),
35
+ updateSquareDisplay: (requestOptions) => updateSquareDisplay(requestOptions, options),
36
+ listUserMiniprogramVersions: (requestOptions) => listUserMiniprogramVersions(requestOptions, options),
37
+ };
18
38
  }
19
- async function inspectRemoteBasicInfoImage(bytes, kind) {
20
- return inspectDecodedBasicInfoImage(bytes, kind);
39
+ async function listDeveloperEntities(runtime) {
40
+ return remoteGet(runtimePermissionEnv.DEVELOPER_ENTITY_LIST_API_PATH, {}, runtime);
21
41
  }
22
- async function inspectDecodedBasicInfoImage(bytes, kind) {
23
- if (!bytes.length || bytes.length > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
24
- throw new Error('资料图片不得为空或超过 10 MiB');
25
- const decoder = sharp(bytes, { limitInputPixels: runtimePermissionEnv.BASIC_INFO_MAX_PIXELS, failOn: 'warning' });
26
- const metadata = await decoder.metadata();
27
- const extensions = { jpeg: 'jpg', png: 'png', gif: 'gif', webp: 'webp' };
28
- if (!metadata.format || !extensions[metadata.format])
29
- throw new Error('资料图片格式不支持');
30
- const width = metadata.width ?? 0;
31
- const height = metadata.pageHeight ?? metadata.height ?? 0;
32
- if (!width || !height || width * height > runtimePermissionEnv.BASIC_INFO_MAX_PIXELS)
33
- throw new Error('资料图片不得超过 4000 万像素');
34
- if (kind === 'icon' && (width !== 200 || height !== 200))
35
- throw new Error('icon 必须是 200×200');
36
- // 强制解码而非只信任图片头;不将解码结果写回图片。
37
- await decoder.stats();
38
- return { sha256: node_crypto.createHash('sha256').update(bytes).digest('hex'), extension: extensions[metadata.format] };
42
+ async function switchDeveloperEntity(options, runtime) {
43
+ return (await remotePostForm(runtimePermissionEnv.DEVELOPER_ENTITY_SWITCH_API_PATH, options, runtime, { requireResult: false })) ?? {};
39
44
  }
40
- async function readBasicInfoSource(projectRoot, relative, kind) {
41
- runtimePermissionEnv.validateBasicInfoPath(relative);
42
- const root = await fs.realpath(projectRoot);
43
- const target = await fs.realpath(path.join(root, relative));
44
- const resolvedRelative = path.relative(root, target).split(path.sep).join('/');
45
- runtimePermissionEnv.validateBasicInfoPath(resolvedRelative);
46
- if (resolvedRelative.startsWith('../') || path.isAbsolute(resolvedRelative))
47
- throw new Error('资料图片不能逃逸项目目录');
48
- const info = await fs.stat(target);
49
- if (!info.isFile() || info.size > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
50
- throw new Error('资料图片必须为不超过 10 MiB 的普通文件');
51
- const file = await fs.open(target, fs$1.constants.O_RDONLY | fs$1.constants.O_NOFOLLOW);
52
- try {
53
- const actual = await file.stat();
54
- if (!actual.isFile() || actual.size > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
55
- throw new Error('资料图片文件已变化');
56
- const bytes = await file.readFile();
57
- return { bytes, ...(await inspectBasicInfoImage(bytes, relative, kind)) };
45
+ async function getDeveloperAccessStatus(runtime) {
46
+ return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_ACCESS_STATUS_API_PATH, {}, runtime);
47
+ }
48
+ async function listUserMiniprograms(options, runtime) {
49
+ return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_API_PATH, options, runtime);
50
+ }
51
+ async function createUserMiniprogram(runtime) {
52
+ return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_API_PATH, {}, runtime);
53
+ }
54
+ async function getUserMiniprogramDetail(options, runtime) {
55
+ return remoteGet(runtimePermissionEnv.DETAIL_USER_MINIPROGRAM_API_PATH, options, runtime);
56
+ }
57
+ async function createLocalDevLaunchToken$1(options, runtime) {
58
+ return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_LOCAL_DEV_LAUNCH_TOKEN_API_PATH, options, runtime);
59
+ }
60
+ async function getPreviewAllowlist(options, runtime) {
61
+ return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
62
+ }
63
+ async function updatePreviewAllowlist(options, runtime) {
64
+ return remotePostForm(runtimePermissionEnv.UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
65
+ }
66
+ async function createUserMiniprogramLeaderboard(options, runtime) {
67
+ return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
68
+ }
69
+ async function getUserMiniprogramLeaderboard(options, runtime) {
70
+ return remoteGet(runtimePermissionEnv.DETAIL_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
71
+ }
72
+ async function listUserMiniprogramLeaderboards(options, runtime) {
73
+ return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
74
+ }
75
+ async function deleteUserMiniprogramLeaderboard(options, runtime) {
76
+ return ((await remotePostForm(runtimePermissionEnv.DELETE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime, { requireResult: false })) ?? {});
77
+ }
78
+ async function precheckUserMiniprogramVersion(options, runtime) {
79
+ return remotePostForm(runtimePermissionEnv.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
80
+ }
81
+ async function submitUserMiniprogramAudit(options, runtime) {
82
+ return remotePostForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, {
83
+ mini_program_id: options.mini_program_id, session_id: options.session_id, preflight_token: options.preflight_token,
84
+ }, runtime);
85
+ }
86
+ async function getVersionPreviewInfo(options, runtime) {
87
+ return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, {
88
+ mini_program_id: options.mini_program_id,
89
+ preview_version: options.version,
90
+ }, runtime);
91
+ }
92
+ async function withdrawUserMiniprogramVersion(options, runtime) {
93
+ return remotePostForm(runtimePermissionEnv.WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
94
+ }
95
+ async function releaseUserMiniprogramVersion(options, runtime) {
96
+ return remotePostForm(runtimePermissionEnv.RELEASE_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
97
+ }
98
+ async function takeDownUserMiniprogram(options, runtime) {
99
+ return remotePostForm(runtimePermissionEnv.TAKE_DOWN_USER_MINIPROGRAM_API_PATH, options, runtime);
100
+ }
101
+ async function reopenUserMiniprogram(options, runtime) {
102
+ return remotePostForm(runtimePermissionEnv.REOPEN_USER_MINIPROGRAM_API_PATH, options, runtime);
103
+ }
104
+ async function updateSquareDisplay(options, runtime) {
105
+ return remotePostForm(runtimePermissionEnv.UPDATE_SQUARE_DISPLAY_API_PATH, options, runtime);
106
+ }
107
+ async function listUserMiniprogramVersions(options, runtime) {
108
+ return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
109
+ }
110
+ async function remoteGet(path, query, runtime) {
111
+ const pathWithQuery = createPathWithQuery(path, query);
112
+ const context = index.createHeyboxOpenPlatformRequestContext(runtime.session, pathWithQuery);
113
+ const fetchImpl = runtime.fetchImpl ?? fetch;
114
+ const response = await fetchImpl(index.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, pathWithQuery, context.platformParams), {
115
+ method: 'GET',
116
+ headers: context.headers,
117
+ });
118
+ return readRequiredResult(response, pathWithQuery);
119
+ }
120
+ async function remotePostForm(path, fields, runtime, options = {}) {
121
+ const context = index.createHeyboxOpenPlatformRequestContext(runtime.session, path, {
122
+ contentType: 'application/x-www-form-urlencoded',
123
+ });
124
+ const fetchImpl = runtime.fetchImpl ?? fetch;
125
+ const response = await fetchImpl(index.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, path, context.platformParams), {
126
+ method: 'POST',
127
+ headers: context.headers,
128
+ body: createFormBody(fields),
129
+ });
130
+ if (options.requireResult === false) {
131
+ return readOptionalResult(response, path);
58
132
  }
59
- finally {
60
- await file.close();
133
+ return readRequiredResult(response, path);
134
+ }
135
+ async function readRequiredResult(response, pathWithQuery) {
136
+ const result = await index.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: true });
137
+ return result;
138
+ }
139
+ async function readOptionalResult(response, pathWithQuery) {
140
+ return index.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: false });
141
+ }
142
+ function createPathWithQuery(path, query) {
143
+ const params = new URLSearchParams();
144
+ for (const [key, value] of Object.entries(query)) {
145
+ if (value !== undefined && value !== null && value !== '') {
146
+ params.set(key, String(value));
147
+ }
61
148
  }
149
+ const queryString = params.toString();
150
+ return queryString ? `${path}?${queryString}` : path;
62
151
  }
63
- /** 逐级校验真实目录,避免保留目录或迁移目录中的符号链接将写入带到项目外。 */
64
- async function ensureBasicInfoDirectory(rootPath, relative) {
65
- const root = await fs.realpath(rootPath);
66
- let current = root;
67
- for (const part of relative.split('/')) {
68
- if (!part || part === '.' || part === '..')
69
- throw new Error('资料目录不合法');
70
- current = path.join(current, part);
71
- await fs.mkdir(current).catch((error) => {
72
- if (error.code !== 'EEXIST')
73
- throw error;
74
- });
75
- const resolved = await fs.realpath(current);
76
- const within = path.relative(root, resolved);
77
- if (within.startsWith('..') || path.isAbsolute(within))
78
- throw new Error('资料目录不能逃逸项目');
152
+ function createFormBody(fields) {
153
+ const body = new URLSearchParams();
154
+ for (const [key, value] of Object.entries(fields)) {
155
+ if (value === undefined || value === null) {
156
+ continue;
157
+ }
158
+ if (Array.isArray(value)) {
159
+ body.set(key, value.join(','));
160
+ continue;
161
+ }
162
+ if (typeof value === 'object') {
163
+ body.set(key, JSON.stringify(value));
164
+ continue;
165
+ }
166
+ body.set(key, String(value));
79
167
  }
168
+ return body.toString();
80
169
  }
81
170
 
82
171
  class MiniProgramProjectBindingError extends Error {
@@ -153,26 +242,154 @@ async function writeBoundMiniProgramId(startDir, miniProgramId, options = {}) {
153
242
  miniProgramId: normalizedMiniProgramId,
154
243
  };
155
244
  }
156
- if (context.packageJson.heybox !== undefined && !isPlainObject(context.packageJson.heybox)) {
157
- throw new MiniProgramProjectBindingError('package.json heybox 字段必须是对象,不能写入 miniProgramId', 'PACKAGE_JSON_HEYBOX_INVALID');
245
+ if (context.packageJson.heybox !== undefined && !isPlainObject(context.packageJson.heybox)) {
246
+ throw new MiniProgramProjectBindingError('package.json heybox 字段必须是对象,不能写入 miniProgramId', 'PACKAGE_JSON_HEYBOX_INVALID');
247
+ }
248
+ context.packageJson.heybox = {
249
+ ...(context.packageJson.heybox ?? {}),
250
+ miniProgramId: normalizedMiniProgramId,
251
+ };
252
+ await fs.writeFile(context.packageJsonPath, `${JSON.stringify(context.packageJson, null, context.indent)}${context.trailingNewline || '\n'}`, 'utf8');
253
+ return {
254
+ ...context,
255
+ changed: true,
256
+ miniProgramId: normalizedMiniProgramId,
257
+ };
258
+ }
259
+ function detectJsonIndent(raw) {
260
+ const match = raw.match(/\n(\s+)"[^"]+":/);
261
+ return match?.[1] ?? 2;
262
+ }
263
+ function isPlainObject(value) {
264
+ return Object.prototype.toString.call(value) === '[object Object]';
265
+ }
266
+
267
+ async function resolveRemoteEnvironment(options = {}, runtime = {}) {
268
+ const env = options.env ?? process.env;
269
+ const apiBaseUrl = index.resolveHeyboxApiBaseUrl({ ...options, env });
270
+ const loginBaseUrl = index.resolveHeyboxLoginBaseUrl({ ...options, env });
271
+ const session = options.session ?? (await (runtime.requireAuthSession ?? index.requireHeyboxAuthSession)({ loginBaseUrl }));
272
+ return {
273
+ apiBaseUrl,
274
+ loginBaseUrl,
275
+ allowUnsafeApiBaseUrl: options.allowUnsafeApiBaseUrl === true || isTruthyEnvFlag(env.HB_SDK_ALLOW_UNSAFE_API_BASE_URL),
276
+ env,
277
+ fetchImpl: runtime.fetchImpl ?? options.fetchImpl ?? fetch,
278
+ session,
279
+ };
280
+ }
281
+ function createRemoteApiClientForEnvironment(environment) {
282
+ return createRemoteApiClient({
283
+ baseUrl: environment.apiBaseUrl,
284
+ fetchImpl: environment.fetchImpl,
285
+ session: environment.session,
286
+ });
287
+ }
288
+ async function getBoundMiniProgram(options = {}, runtime = {}) {
289
+ const cwd = options.cwd ?? process.cwd();
290
+ const binding = await requireBoundMiniProgramId(cwd);
291
+ const api = await resolveRemoteApiClient(options, runtime);
292
+ const detail = await api.getUserMiniprogramDetail({ mini_program_id: binding.miniProgramId });
293
+ return {
294
+ ...binding,
295
+ detail,
296
+ };
297
+ }
298
+ async function createLocalDevLaunchToken(options, runtime = {}) {
299
+ const miniProgramId = options.miniProgramId.trim();
300
+ if (!miniProgramId) {
301
+ throw new Error('mini-program-id 不能为空');
302
+ }
303
+ const api = await resolveRemoteApiClient(options, runtime);
304
+ return api.createLocalDevLaunchToken({
305
+ mini_program_id: miniProgramId,
306
+ ...(options.developmentSnapshot ? { development_snapshot: options.developmentSnapshot } : {}),
307
+ ...(options.companionManifestSha256
308
+ ? { companion_manifest_sha256: options.companionManifestSha256 }
309
+ : {}),
310
+ });
311
+ }
312
+ async function resolveRemoteApiClient(options, runtime) {
313
+ if (runtime.apiClient) {
314
+ return runtime.apiClient;
315
+ }
316
+ return createRemoteApiClientForEnvironment(await resolveRemoteEnvironment(options, runtime));
317
+ }
318
+ function isTruthyEnvFlag(value) {
319
+ return ['1', 'true', 'yes', 'on'].includes(String(value ?? '')
320
+ .trim()
321
+ .toLowerCase());
322
+ }
323
+
324
+ async function inspectBasicInfoImage(bytes, sourcePath, kind) {
325
+ const inspected = await inspectDecodedBasicInfoImage(bytes, kind);
326
+ const extensions = { jpg: ['jpg', 'jpeg'], png: ['png'], gif: ['gif'], webp: ['webp'] };
327
+ const ext = sourcePath.split('.').pop().toLowerCase();
328
+ if (!extensions[inspected.extension]?.includes(ext))
329
+ throw new Error('资料图片格式与扩展名不一致');
330
+ return inspected;
331
+ }
332
+ async function inspectRemoteBasicInfoImage(bytes, kind) {
333
+ return inspectDecodedBasicInfoImage(bytes, kind);
334
+ }
335
+ async function inspectDecodedBasicInfoImage(bytes, kind) {
336
+ if (!bytes.length || bytes.length > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
337
+ throw new Error('资料图片不得为空或超过 10 MiB');
338
+ const decoder = sharp(bytes, { limitInputPixels: runtimePermissionEnv.BASIC_INFO_MAX_PIXELS, failOn: 'warning' });
339
+ const metadata = await decoder.metadata();
340
+ const extensions = { jpeg: 'jpg', png: 'png', gif: 'gif', webp: 'webp' };
341
+ if (!metadata.format || !extensions[metadata.format])
342
+ throw new Error('资料图片格式不支持');
343
+ const width = metadata.width ?? 0;
344
+ const height = metadata.pageHeight ?? metadata.height ?? 0;
345
+ if (!width || !height || width * height > runtimePermissionEnv.BASIC_INFO_MAX_PIXELS)
346
+ throw new Error('资料图片不得超过 4000 万像素');
347
+ if (kind === 'icon' && (width !== 200 || height !== 200))
348
+ throw new Error('icon 必须是 200×200');
349
+ // 强制解码而非只信任图片头;不将解码结果写回图片。
350
+ await decoder.stats();
351
+ return { sha256: node_crypto.createHash('sha256').update(bytes).digest('hex'), extension: extensions[metadata.format] };
352
+ }
353
+ async function readBasicInfoSource(projectRoot, relative, kind) {
354
+ runtimePermissionEnv.validateBasicInfoPath(relative);
355
+ const root = await fs.realpath(projectRoot);
356
+ const target = await fs.realpath(path.join(root, relative));
357
+ const resolvedRelative = path.relative(root, target).split(path.sep).join('/');
358
+ runtimePermissionEnv.validateBasicInfoPath(resolvedRelative);
359
+ if (resolvedRelative.startsWith('../') || path.isAbsolute(resolvedRelative))
360
+ throw new Error('资料图片不能逃逸项目目录');
361
+ const info = await fs.stat(target);
362
+ if (!info.isFile() || info.size > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
363
+ throw new Error('资料图片必须为不超过 10 MiB 的普通文件');
364
+ const file = await fs.open(target, fs$1.constants.O_RDONLY | fs$1.constants.O_NOFOLLOW);
365
+ try {
366
+ const actual = await file.stat();
367
+ if (!actual.isFile() || actual.size > runtimePermissionEnv.BASIC_INFO_MAX_BYTES)
368
+ throw new Error('资料图片文件已变化');
369
+ const bytes = await file.readFile();
370
+ return { bytes, ...(await inspectBasicInfoImage(bytes, relative, kind)) };
371
+ }
372
+ finally {
373
+ await file.close();
158
374
  }
159
- context.packageJson.heybox = {
160
- ...(context.packageJson.heybox ?? {}),
161
- miniProgramId: normalizedMiniProgramId,
162
- };
163
- await fs.writeFile(context.packageJsonPath, `${JSON.stringify(context.packageJson, null, context.indent)}${context.trailingNewline || '\n'}`, 'utf8');
164
- return {
165
- ...context,
166
- changed: true,
167
- miniProgramId: normalizedMiniProgramId,
168
- };
169
375
  }
170
- function detectJsonIndent(raw) {
171
- const match = raw.match(/\n(\s+)"[^"]+":/);
172
- return match?.[1] ?? 2;
173
- }
174
- function isPlainObject(value) {
175
- return Object.prototype.toString.call(value) === '[object Object]';
376
+ /** 逐级校验真实目录,避免保留目录或迁移目录中的符号链接将写入带到项目外。 */
377
+ async function ensureBasicInfoDirectory(rootPath, relative) {
378
+ const root = await fs.realpath(rootPath);
379
+ let current = root;
380
+ for (const part of relative.split('/')) {
381
+ if (!part || part === '.' || part === '..')
382
+ throw new Error('资料目录不合法');
383
+ current = path.join(current, part);
384
+ await fs.mkdir(current).catch((error) => {
385
+ if (error.code !== 'EEXIST')
386
+ throw error;
387
+ });
388
+ const resolved = await fs.realpath(current);
389
+ const within = path.relative(root, resolved);
390
+ if (within.startsWith('..') || path.isAbsolute(within))
391
+ throw new Error('资料目录不能逃逸项目');
392
+ }
176
393
  }
177
394
 
178
395
  function trustedProfileUrl(raw) {
@@ -428,223 +645,6 @@ function isPlainRecord(value) {
428
645
  return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
429
646
  }
430
647
 
431
- function createRemoteApiClient(options) {
432
- return {
433
- listPermissionApplications: (request) => remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_PERMISSION_APPLICATION_API_PATH, request, options),
434
- submitPermissionApplication: (request) => remotePostForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_PERMISSION_APPLICATION_API_PATH, request, options),
435
- listDeveloperEntities: () => listDeveloperEntities(options),
436
- switchDeveloperEntity: (requestOptions) => switchDeveloperEntity(requestOptions, options),
437
- getDeveloperAccessStatus: () => getDeveloperAccessStatus(options),
438
- listUserMiniprograms: (requestOptions = {}) => listUserMiniprograms(requestOptions, options),
439
- createUserMiniprogram: () => createUserMiniprogram(options),
440
- getUserMiniprogramDetail: (requestOptions) => getUserMiniprogramDetail(requestOptions, options),
441
- createLocalDevLaunchToken: (requestOptions) => createLocalDevLaunchToken$1(requestOptions, options),
442
- getPreviewAllowlist: (requestOptions) => getPreviewAllowlist(requestOptions, options),
443
- updatePreviewAllowlist: (requestOptions) => updatePreviewAllowlist(requestOptions, options),
444
- createUserMiniprogramLeaderboard: (requestOptions) => createUserMiniprogramLeaderboard(requestOptions, options),
445
- getUserMiniprogramLeaderboard: (requestOptions) => getUserMiniprogramLeaderboard(requestOptions, options),
446
- listUserMiniprogramLeaderboards: (requestOptions) => listUserMiniprogramLeaderboards(requestOptions, options),
447
- deleteUserMiniprogramLeaderboard: (requestOptions) => deleteUserMiniprogramLeaderboard(requestOptions, options),
448
- precheckUserMiniprogramVersion: (requestOptions) => precheckUserMiniprogramVersion(requestOptions, options),
449
- submitUserMiniprogramAudit: (requestOptions) => submitUserMiniprogramAudit(requestOptions, options),
450
- getVersionPreviewInfo: (requestOptions) => getVersionPreviewInfo(requestOptions, options),
451
- withdrawUserMiniprogramVersion: (requestOptions) => withdrawUserMiniprogramVersion(requestOptions, options),
452
- releaseUserMiniprogramVersion: (requestOptions) => releaseUserMiniprogramVersion(requestOptions, options),
453
- takeDownUserMiniprogram: (requestOptions) => takeDownUserMiniprogram(requestOptions, options),
454
- reopenUserMiniprogram: (requestOptions) => reopenUserMiniprogram(requestOptions, options),
455
- updateSquareDisplay: (requestOptions) => updateSquareDisplay(requestOptions, options),
456
- listUserMiniprogramVersions: (requestOptions) => listUserMiniprogramVersions(requestOptions, options),
457
- };
458
- }
459
- async function listDeveloperEntities(runtime) {
460
- return remoteGet(runtimePermissionEnv.DEVELOPER_ENTITY_LIST_API_PATH, {}, runtime);
461
- }
462
- async function switchDeveloperEntity(options, runtime) {
463
- return (await remotePostForm(runtimePermissionEnv.DEVELOPER_ENTITY_SWITCH_API_PATH, options, runtime, { requireResult: false })) ?? {};
464
- }
465
- async function getDeveloperAccessStatus(runtime) {
466
- return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_ACCESS_STATUS_API_PATH, {}, runtime);
467
- }
468
- async function listUserMiniprograms(options, runtime) {
469
- return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_API_PATH, options, runtime);
470
- }
471
- async function createUserMiniprogram(runtime) {
472
- return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_API_PATH, {}, runtime);
473
- }
474
- async function getUserMiniprogramDetail(options, runtime) {
475
- return remoteGet(runtimePermissionEnv.DETAIL_USER_MINIPROGRAM_API_PATH, options, runtime);
476
- }
477
- async function createLocalDevLaunchToken$1(options, runtime) {
478
- return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_LOCAL_DEV_LAUNCH_TOKEN_API_PATH, options, runtime);
479
- }
480
- async function getPreviewAllowlist(options, runtime) {
481
- return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
482
- }
483
- async function updatePreviewAllowlist(options, runtime) {
484
- return remotePostForm(runtimePermissionEnv.UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
485
- }
486
- async function createUserMiniprogramLeaderboard(options, runtime) {
487
- return remotePostForm(runtimePermissionEnv.CREATE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
488
- }
489
- async function getUserMiniprogramLeaderboard(options, runtime) {
490
- return remoteGet(runtimePermissionEnv.DETAIL_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
491
- }
492
- async function listUserMiniprogramLeaderboards(options, runtime) {
493
- return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
494
- }
495
- async function deleteUserMiniprogramLeaderboard(options, runtime) {
496
- return ((await remotePostForm(runtimePermissionEnv.DELETE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime, { requireResult: false })) ?? {});
497
- }
498
- async function precheckUserMiniprogramVersion(options, runtime) {
499
- return remotePostForm(runtimePermissionEnv.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
500
- }
501
- async function submitUserMiniprogramAudit(options, runtime) {
502
- return remotePostForm(runtimePermissionEnv.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, {
503
- mini_program_id: options.mini_program_id, session_id: options.session_id, preflight_token: options.preflight_token,
504
- }, runtime);
505
- }
506
- async function getVersionPreviewInfo(options, runtime) {
507
- return remoteGet(runtimePermissionEnv.USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, {
508
- mini_program_id: options.mini_program_id,
509
- preview_version: options.version,
510
- }, runtime);
511
- }
512
- async function withdrawUserMiniprogramVersion(options, runtime) {
513
- return remotePostForm(runtimePermissionEnv.WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
514
- }
515
- async function releaseUserMiniprogramVersion(options, runtime) {
516
- return remotePostForm(runtimePermissionEnv.RELEASE_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
517
- }
518
- async function takeDownUserMiniprogram(options, runtime) {
519
- return remotePostForm(runtimePermissionEnv.TAKE_DOWN_USER_MINIPROGRAM_API_PATH, options, runtime);
520
- }
521
- async function reopenUserMiniprogram(options, runtime) {
522
- return remotePostForm(runtimePermissionEnv.REOPEN_USER_MINIPROGRAM_API_PATH, options, runtime);
523
- }
524
- async function updateSquareDisplay(options, runtime) {
525
- return remotePostForm(runtimePermissionEnv.UPDATE_SQUARE_DISPLAY_API_PATH, options, runtime);
526
- }
527
- async function listUserMiniprogramVersions(options, runtime) {
528
- return remoteGet(runtimePermissionEnv.LIST_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
529
- }
530
- async function remoteGet(path, query, runtime) {
531
- const pathWithQuery = createPathWithQuery(path, query);
532
- const context = index.createHeyboxOpenPlatformRequestContext(runtime.session, pathWithQuery);
533
- const fetchImpl = runtime.fetchImpl ?? fetch;
534
- const response = await fetchImpl(index.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, pathWithQuery, context.platformParams), {
535
- method: 'GET',
536
- headers: context.headers,
537
- });
538
- return readRequiredResult(response, pathWithQuery);
539
- }
540
- async function remotePostForm(path, fields, runtime, options = {}) {
541
- const context = index.createHeyboxOpenPlatformRequestContext(runtime.session, path, {
542
- contentType: 'application/x-www-form-urlencoded',
543
- });
544
- const fetchImpl = runtime.fetchImpl ?? fetch;
545
- const response = await fetchImpl(index.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, path, context.platformParams), {
546
- method: 'POST',
547
- headers: context.headers,
548
- body: createFormBody(fields),
549
- });
550
- if (options.requireResult === false) {
551
- return readOptionalResult(response, path);
552
- }
553
- return readRequiredResult(response, path);
554
- }
555
- async function readRequiredResult(response, pathWithQuery) {
556
- const result = await index.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: true });
557
- return result;
558
- }
559
- async function readOptionalResult(response, pathWithQuery) {
560
- return index.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: false });
561
- }
562
- function createPathWithQuery(path, query) {
563
- const params = new URLSearchParams();
564
- for (const [key, value] of Object.entries(query)) {
565
- if (value !== undefined && value !== null && value !== '') {
566
- params.set(key, String(value));
567
- }
568
- }
569
- const queryString = params.toString();
570
- return queryString ? `${path}?${queryString}` : path;
571
- }
572
- function createFormBody(fields) {
573
- const body = new URLSearchParams();
574
- for (const [key, value] of Object.entries(fields)) {
575
- if (value === undefined || value === null) {
576
- continue;
577
- }
578
- if (Array.isArray(value)) {
579
- body.set(key, value.join(','));
580
- continue;
581
- }
582
- if (typeof value === 'object') {
583
- body.set(key, JSON.stringify(value));
584
- continue;
585
- }
586
- body.set(key, String(value));
587
- }
588
- return body.toString();
589
- }
590
-
591
- async function resolveRemoteEnvironment(options = {}, runtime = {}) {
592
- const env = options.env ?? process.env;
593
- const apiBaseUrl = index.resolveHeyboxApiBaseUrl({ ...options, env });
594
- const loginBaseUrl = index.resolveHeyboxLoginBaseUrl({ ...options, env });
595
- const session = options.session ?? (await (runtime.requireAuthSession ?? index.requireHeyboxAuthSession)({ loginBaseUrl }));
596
- return {
597
- apiBaseUrl,
598
- loginBaseUrl,
599
- allowUnsafeApiBaseUrl: options.allowUnsafeApiBaseUrl === true || isTruthyEnvFlag(env.HB_SDK_ALLOW_UNSAFE_API_BASE_URL),
600
- env,
601
- fetchImpl: runtime.fetchImpl ?? options.fetchImpl ?? fetch,
602
- session,
603
- };
604
- }
605
- function createRemoteApiClientForEnvironment(environment) {
606
- return createRemoteApiClient({
607
- baseUrl: environment.apiBaseUrl,
608
- fetchImpl: environment.fetchImpl,
609
- session: environment.session,
610
- });
611
- }
612
- async function getBoundMiniProgram(options = {}, runtime = {}) {
613
- const cwd = options.cwd ?? process.cwd();
614
- const binding = await requireBoundMiniProgramId(cwd);
615
- const api = await resolveRemoteApiClient(options, runtime);
616
- const detail = await api.getUserMiniprogramDetail({ mini_program_id: binding.miniProgramId });
617
- return {
618
- ...binding,
619
- detail,
620
- };
621
- }
622
- async function createLocalDevLaunchToken(options, runtime = {}) {
623
- const miniProgramId = options.miniProgramId.trim();
624
- if (!miniProgramId) {
625
- throw new Error('mini-program-id 不能为空');
626
- }
627
- const api = await resolveRemoteApiClient(options, runtime);
628
- return api.createLocalDevLaunchToken({
629
- mini_program_id: miniProgramId,
630
- ...(options.developmentSnapshot ? { development_snapshot: options.developmentSnapshot } : {}),
631
- ...(options.companionManifestSha256
632
- ? { companion_manifest_sha256: options.companionManifestSha256 }
633
- : {}),
634
- });
635
- }
636
- async function resolveRemoteApiClient(options, runtime) {
637
- if (runtime.apiClient) {
638
- return runtime.apiClient;
639
- }
640
- return createRemoteApiClientForEnvironment(await resolveRemoteEnvironment(options, runtime));
641
- }
642
- function isTruthyEnvFlag(value) {
643
- return ['1', 'true', 'yes', 'on'].includes(String(value ?? '')
644
- .trim()
645
- .toLowerCase());
646
- }
647
-
648
648
  exports.MiniProgramProjectBindingError = MiniProgramProjectBindingError;
649
649
  exports.compareBasicInfo = compareBasicInfo;
650
650
  exports.createBrowserDevPermissionState = createBrowserDevPermissionState;
@@ -3,7 +3,7 @@
3
3
  var fs = require('node:fs/promises');
4
4
  var os = require('node:os');
5
5
  var path = require('node:path');
6
- var index = require('./index-Czupnh5A.cjs');
6
+ var index = require('./index-CxelQqdy.cjs');
7
7
  require('node:module');
8
8
  require('readline');
9
9
  require('os');
@@ -3,8 +3,8 @@
3
3
  var node_crypto = require('node:crypto');
4
4
  var fs = require('node:fs/promises');
5
5
  var path = require('node:path');
6
- var index = require('./index-Czupnh5A.cjs');
7
- var deployLock = require('./deploy-lock-DY7E8TFw.cjs');
6
+ var index = require('./index-CxelQqdy.cjs');
7
+ var deployLock = require('./deploy-lock-CtJXBtKK.cjs');
8
8
  require('node:module');
9
9
  require('readline');
10
10
  require('os');