@heybox/hb-sdk 0.4.5 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -21
- package/dist/cli-chunks/{create-DpyZCNdo.cjs → create-BahMMgJH.cjs} +1 -1
- package/dist/cli-chunks/{dev-DWIpgJnn.cjs → dev-CTuXVPpU.cjs} +1 -1
- package/dist/cli-chunks/{doctor-DBotVUQI.cjs → doctor-9gg3ZIvt.cjs} +1 -1
- package/dist/cli-chunks/{index-DRsyeAcg.cjs → index-CLne_LW7.cjs} +2 -2
- package/dist/cli-chunks/{index-BYMTp2I6.cjs → index-DuwxUSkq.cjs} +24 -15
- package/dist/cli-chunks/{login-DIgcT1gv.cjs → login-OqaEx-Wd.cjs} +153 -2
- package/dist/cli-chunks/{remote-DjaOc1VS.cjs → remote-zX17hOT4.cjs} +220 -292
- package/dist/cli-chunks/{session-BAgaqpNL.cjs → session-D7lF9mpd.cjs} +347 -9
- package/dist/cli.cjs +1 -1
- package/dist/miniapp-publish.cjs.js +4 -0
- package/dist/miniapp-publish.esm.js +3 -1
- package/dist/templates/vue3-vite-ts/README.md.ejs +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +24 -22
- package/skill/references/api-root.md +1 -1
- package/skill/references/cli.md +37 -4
- package/skill/scripts/sync-references.mjs +38 -3
- package/skill/skill.json +4 -4
- package/types/miniapp-publish/index.d.ts +2 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var index = require('./index-DuwxUSkq.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
|
-
|
|
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
|
-
|
|
3024
|
-
|
|
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
|
@@ -2812,6 +2812,8 @@ function getMiniappManifestVersionError(version) {
|
|
|
2812
2812
|
const MINIAPP_UPLOAD_SCOPE = 'activity';
|
|
2813
2813
|
const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
|
|
2814
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';
|
|
2815
2817
|
const LIST_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/list';
|
|
2816
2818
|
const CREATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/create';
|
|
2817
2819
|
const UPDATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/update';
|
|
@@ -2887,6 +2889,8 @@ function shouldUploadDistFile(relativePath) {
|
|
|
2887
2889
|
exports.ACTIVITY_UPLOAD_KEY_MAX_LENGTH = ACTIVITY_UPLOAD_KEY_MAX_LENGTH;
|
|
2888
2890
|
exports.CREATE_USER_MINIPROGRAM_API_PATH = CREATE_USER_MINIPROGRAM_API_PATH;
|
|
2889
2891
|
exports.DETAIL_USER_MINIPROGRAM_API_PATH = DETAIL_USER_MINIPROGRAM_API_PATH;
|
|
2892
|
+
exports.DEVELOPER_ENTITY_LIST_API_PATH = DEVELOPER_ENTITY_LIST_API_PATH;
|
|
2893
|
+
exports.DEVELOPER_ENTITY_SWITCH_API_PATH = DEVELOPER_ENTITY_SWITCH_API_PATH;
|
|
2890
2894
|
exports.LIST_USER_MINIPROGRAM_API_PATH = LIST_USER_MINIPROGRAM_API_PATH;
|
|
2891
2895
|
exports.LIST_USER_MINIPROGRAM_VERSION_API_PATH = LIST_USER_MINIPROGRAM_VERSION_API_PATH;
|
|
2892
2896
|
exports.MINIAPP_UPLOAD_SCOPE = MINIAPP_UPLOAD_SCOPE;
|
|
@@ -2810,6 +2810,8 @@ function getMiniappManifestVersionError(version) {
|
|
|
2810
2810
|
const MINIAPP_UPLOAD_SCOPE = 'activity';
|
|
2811
2811
|
const ACTIVITY_UPLOAD_KEY_MAX_LENGTH = 64;
|
|
2812
2812
|
const USER_MINIPROGRAM_ACCESS_STATUS_API_PATH = '/mall/developer/user_miniprogram/access_status';
|
|
2813
|
+
const DEVELOPER_ENTITY_LIST_API_PATH = '/mall/developer/entity/list';
|
|
2814
|
+
const DEVELOPER_ENTITY_SWITCH_API_PATH = '/mall/developer/entity/switch';
|
|
2813
2815
|
const LIST_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/list';
|
|
2814
2816
|
const CREATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/create';
|
|
2815
2817
|
const UPDATE_USER_MINIPROGRAM_API_PATH = '/mall/developer/user_miniprogram/update';
|
|
@@ -2882,4 +2884,4 @@ function shouldUploadDistFile(relativePath) {
|
|
|
2882
2884
|
return true;
|
|
2883
2885
|
}
|
|
2884
2886
|
|
|
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 };
|
|
2887
|
+
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_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 };
|
|
@@ -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
|
|
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
|
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -49,28 +49,30 @@ Apply these instructions when writing, reviewing, or debugging code that consume
|
|
|
49
49
|
1. Use `hb-sdk create <project-name>` to scaffold a standalone external mini-program template.
|
|
50
50
|
2. Use `hb-sdk dev` for local browser debugging through the built-in mock runtime host.
|
|
51
51
|
3. Use `hb-sdk remote ...` for developer-owned remote mini-program management. Top-level `hb-sdk deploy` has been hard-cut and must not be recommended as a compatibility alias.
|
|
52
|
-
4. Use `hb-sdk remote
|
|
53
|
-
5. Use `hb-sdk remote
|
|
54
|
-
6. Use `hb-sdk remote
|
|
55
|
-
7. Use `hb-sdk remote deploy --
|
|
56
|
-
8.
|
|
57
|
-
9.
|
|
58
|
-
10.
|
|
59
|
-
11. For
|
|
60
|
-
12.
|
|
61
|
-
13.
|
|
62
|
-
14.
|
|
63
|
-
15.
|
|
64
|
-
16.
|
|
65
|
-
17. Use
|
|
66
|
-
18. Use
|
|
67
|
-
19. Use `hb-sdk
|
|
68
|
-
20.
|
|
69
|
-
21.
|
|
70
|
-
22. Do not
|
|
71
|
-
23.
|
|
72
|
-
24. Do not
|
|
73
|
-
25.
|
|
52
|
+
4. Use `hb-sdk remote entity list`, `hb-sdk remote entity current`, and `hb-sdk remote entity switch <entity-id>` to inspect or change the developer platform server-side current entity before remote management commands.
|
|
53
|
+
5. Use `hb-sdk remote create --name <name>` to create a remote mini-program under the server-side current entity and bind the returned id into `package.json.heybox.miniProgramId`; use `hb-sdk remote bind <mini-program-id>` to bind an existing remote mini-program after current-entity manageability is verified.
|
|
54
|
+
6. Use `hb-sdk remote info`, `hb-sdk remote update`, `hb-sdk remote list`, `hb-sdk remote access`, `hb-sdk remote versions`, `hb-sdk remote preview <version>`, and `hb-sdk remote allowlist ...` for read/basic/preview management workflows. Discovery commands show the server-side current entity scope; write commands target the current project binding rather than arbitrary ids.
|
|
55
|
+
7. Use `hb-sdk remote deploy --release-note <text>` to build, upload, and submit the current project for audit. It reads `package.json.heybox.miniProgramId`, validates that the bound mini-program belongs to the server-side current entity before precheck/build/upload, prechecks `package.json.version` before build, runs the project's `build` script via the package manager auto-detected by lockfile, uploads `dist/` to CDN (skipping `manifest.json`, `.DS_Store`, `.map`), then calls the submit-audit API.
|
|
56
|
+
8. Use `hb-sdk remote deploy --skip-build --release-note <text>` only when the `dist/` directory is already prepared by an upstream CI stage. In this mode the CLI reads `dist/manifest.json.version` before precheck. Missing `dist/manifest.json` or `dist/index.html` aborts the run.
|
|
57
|
+
9. Always provide a concise release note before deploy. Non-interactive environments must pass `--release-note`; interactive terminals may prompt for it. The default is manual release after approval with `hb-sdk remote release <version>`; use `--auto-publish` when the audited version should automatically release after approval.
|
|
58
|
+
10. Use `hb-sdk remote release <version>`, `hb-sdk remote withdraw <version>`, `hb-sdk remote take-down`, and `hb-sdk remote reopen` for dangerous remote changes. Interactive terminals should confirm after showing enough context; non-interactive environments must pass `--yes`.
|
|
59
|
+
11. For internal test/staging backend operations, use origin-only custom URLs: `HB_SDK_API_BASE_URL` or `hb-sdk remote ... --api-base-url <url>` for remote platform APIs, and `HB_SDK_LOGIN_BASE_URL` or `hb-sdk login --login-base-url <url>` for browser login. CLI flags override env vars. API base URLs must be Heybox trusted HTTPS origins by default; use `--allow-unsafe-api-base-url` or `HB_SDK_ALLOW_UNSAFE_API_BASE_URL=1` only for local backend debugging. Do not include path, query, or hash in these URLs.
|
|
60
|
+
12. For development routing or gray validation, configure `packages/hb-sdk/src/cli/config.ts` with `@heybox/hb-types` `RylaiServiceTagConfig` (`default_tag` / path-specific `special_tag`) to attach `x-rylai-service-tag` and the matching `special_tag` query parameter to Heybox backend API requests.
|
|
61
|
+
13. If a remote command targets a custom login environment, pass the same `--login-base-url` or `HB_SDK_LOGIN_BASE_URL` used for `hb-sdk login`; remote commands reject cached CLI login state from a different login origin.
|
|
62
|
+
14. Add `--verbose` / `-v` only when diagnosing failures; default CLI errors are intentionally concise, while verbose output includes backend envelope, HTTP status, trace fields, raw body, or original submit-audit failure details.
|
|
63
|
+
15. Use `--json` for script consumption of `hb-sdk remote` commands. With `--json`, stdout must contain exactly one JSON object; progress, warnings, update reminders, and verbose diagnostics must not pollute stdout.
|
|
64
|
+
16. Do not expect custom base URLs to affect `hb-sdk doctor`, npm latest checks, or mock-host `network.request()`.
|
|
65
|
+
17. Use the Mock runtime host's "在 Mac 版 APP 中启动" button for Mac App debugging, or the "Mobile App" QR code after selecting a LAN interface for phone App debugging; the phone must be on the same LAN and use a Heybox App version that supports the mini-program dev shell.
|
|
66
|
+
18. Use `--port`, `--mock-port`, and `--no-open` when the default Vite/mock ports or browser opening behavior need to be controlled.
|
|
67
|
+
19. Use `hb-sdk login`, `hb-sdk login status`, and `hb-sdk login clear` only for the CLI's own Heybox auth cache. Keep `hb-sdk login` top-level; it is not a remote mini-program command.
|
|
68
|
+
20. Treat `selectedEntity` in the CLI auth cache as a non-authoritative hint snapshot only. Every remote command must use the server-side current entity as the source of truth.
|
|
69
|
+
21. Use `hb-sdk doctor` to diagnose whether the local `hb-sdk` skill matches the installed SDK and remote latest skill metadata.
|
|
70
|
+
22. Do not use `hb-sdk doctor` to auto-install skills; when installation or refresh is needed, tell the user to run `npx skills add https://open.xiaoheihe.cn/agent-skills/hb-sdk`.
|
|
71
|
+
23. If doctor reports `SDK_MISMATCH`, upgrade `@heybox/hb-sdk@latest` before reinstalling the skill.
|
|
72
|
+
24. Do not treat CLI login cache as iframe SDK login state; it does not change `auth.login()`, `user.getInfo()`, `network.request()`, or mock-user behavior.
|
|
73
|
+
25. Keep the CLI and mock runtime under `@heybox/hb-sdk`; do not create or revive a separate mock runtime package.
|
|
74
|
+
26. Do not pass `mini_program_id` or `entity_id` as general CLI flags or environment variables; the mini-program id must come from `package.json.heybox.miniProgramId`, and the entity must come from the server-side current entity.
|
|
75
|
+
27. Do not import deploy / upload internals from outside the CLI; the only externally consumable subpath for publish-pipeline helpers is `@heybox/hb-sdk/miniapp-publish`.
|
|
74
76
|
|
|
75
77
|
## Step 6: Preserve capability boundaries
|
|
76
78
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
## Package metadata
|
|
20
20
|
|
|
21
21
|
- Package: `@heybox/hb-sdk`
|
|
22
|
-
- Version at generation time: `0.4.
|
|
22
|
+
- Version at generation time: `0.4.6`
|
|
23
23
|
- Public root export: `@heybox/hb-sdk`
|
|
24
24
|
- Protocol export: `@heybox/hb-sdk/protocol`
|
|
25
25
|
- Vite plugin export: `@heybox/hb-sdk/vite`
|