@heybox/hb-sdk 0.6.6-alpha.1 → 0.6.6-alpha.3
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 +41 -6
- package/dist/cli-chunks/build-De-QADpA.cjs +137 -0
- package/dist/cli-chunks/context-CvZs9ZBf.cjs +311 -0
- package/dist/cli-chunks/{create-DlU4nWz_.cjs → create-B5gGBaSV.cjs} +1 -1
- package/dist/cli-chunks/{dev-Bb4U965a.cjs → dev-BcCWCeac.cjs} +11 -42
- package/dist/cli-chunks/{doctor-DwDqOLdV.cjs → doctor-BhBM4cWH.cjs} +1 -1
- package/dist/cli-chunks/{context-D-cb_pNY.cjs → index-BQm5XmMC.cjs} +19 -308
- package/dist/cli-chunks/{index-B6gnwx39.cjs → index-DyUo67lf.cjs} +3 -3
- package/dist/cli-chunks/{index-gP0K2xx1.cjs → index-QAkYgxPI.cjs} +32 -16
- package/dist/cli-chunks/{login-BFIcNgmi.cjs → login-BNLH13Zd.cjs} +2 -2
- package/dist/cli-chunks/project-vite-VcJMyz1l.cjs +45 -0
- package/dist/cli-chunks/remote-BE53wntR.cjs +1504 -0
- package/dist/cli-chunks/{remote-YESvKni6.cjs → runtime-gate-B2MQf1vc.cjs} +7 -1501
- package/dist/cli-chunks/{session-BRwveiW8.cjs → session-YJ8xNESM.cjs} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/devtools/mock-host/main.js +149 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/templates/vue3-vite-ts/README.md.ejs +2 -2
- package/dist/templates/vue3-vite-ts/package.json.ejs +1 -1
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.esm.js +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +19 -14
- package/skill/references/api-protocol.md +3 -2
- package/skill/references/api-root.md +20 -7
- package/skill/references/cli.md +33 -1
- package/skill/references/recipes.md +53 -0
- package/skill/references/safety-boundaries.md +1 -1
- package/skill/scripts/sync-references.mjs +23 -1
- package/skill/skill.json +4 -4
- package/types/index.d.ts +1 -1
- package/types/modules/share/types.d.ts +11 -0
- package/types/protocol.d.ts +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,10 @@ await share.showShareMenu({
|
|
|
132
132
|
title: '我的小程序页面',
|
|
133
133
|
desc: '来自黑盒小程序的分享',
|
|
134
134
|
imageUrl: 'https://imgheybox.max-c.com/demo.png',
|
|
135
|
+
post: {
|
|
136
|
+
topicIds: [235709],
|
|
137
|
+
topics: ['无畏契约战绩'],
|
|
138
|
+
},
|
|
135
139
|
});
|
|
136
140
|
```
|
|
137
141
|
|
|
@@ -139,15 +143,23 @@ await share.showShareMenu({
|
|
|
139
143
|
`/tools/common_share?user_miniprogram_id=...` 分享落地页。只有确实要分享外部
|
|
140
144
|
HTTP(S) 页面时才显式传 `url`。
|
|
141
145
|
|
|
146
|
+
`post` 用于给“转发到社区”预置可编辑的分区与话题。`topicIds` 接受正整数或非空字符串并按首次出现顺序去重;`topics` 只传话题内容,不要包含首尾 `#`。`showShareMenu()` 只支持一个默认分区,并且不能与 `channel` 同时使用;本地 Mock、App Dev Shell 和开发 Runtime 会直接拒绝这类错误,生产 Runtime 会过滤非法项、只取第一个分区并继续普通分享。`post: null` 等同于不配置。
|
|
147
|
+
|
|
142
148
|
截图分享:
|
|
143
149
|
|
|
144
150
|
```ts
|
|
145
151
|
await share.screenshot({
|
|
146
152
|
delay: 100,
|
|
147
153
|
saveToAlbum: true,
|
|
154
|
+
post: {
|
|
155
|
+
topicIds: [235709, 66739],
|
|
156
|
+
topics: ['无畏契约战绩'],
|
|
157
|
+
},
|
|
148
158
|
});
|
|
149
159
|
```
|
|
150
160
|
|
|
161
|
+
截图分享支持多个预置分区;分区与话题仍由用户在客户端发帖页中确认和修改,SDK 不会直接发布内容。
|
|
162
|
+
|
|
151
163
|
### 基础 UI
|
|
152
164
|
|
|
153
165
|
```ts
|
|
@@ -385,6 +397,7 @@ try {
|
|
|
385
397
|
| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
386
398
|
| `hb-sdk create <project-name>` | 创建外部小程序模板。 |
|
|
387
399
|
| `hb-sdk dev [--runtime-url <url>]` | 启动 Vite 和浏览器 mock 宿主;远端权限可用时使用真实快照,否则以缺失快照启动并默认拒绝受管能力。 |
|
|
400
|
+
| `hb-sdk build [--env <name>]` | 直接使用项目 Vite 构建固定的 `dist/` 生产产物;不执行类型检查,也不要求登录或绑定小程序。 |
|
|
388
401
|
| `hb-sdk login [--login-base-url <url>] [--no-select-entity]` | 登录 Heybox,并把 CLI 自己需要的登录态和登录入口环境保存在本地缓存中;默认会引导多主体用户选择服务端 current entity。 |
|
|
389
402
|
| `hb-sdk login status` | 查看脱敏后的 CLI 登录态。 |
|
|
390
403
|
| `hb-sdk login clear` | 清理 CLI 登录态。 |
|
|
@@ -414,6 +427,28 @@ try {
|
|
|
414
427
|
|
|
415
428
|
所有命令都支持 `--verbose` / `-v`。默认输出只展示关键阶段状态、可访问 URL、下一步命令和可直接处理的错误提示;需要排查后端 envelope、HTTP 状态、trace id、原始响应体、cache 路径、API origin、逐文件上传进度或提交审核原始失败原因时,再追加 `--verbose` 查看详细调试信息。交互式终端会用颜色、符号和 loading 动画区分成功、警告、错误与耗时步骤;CI、非 TTY 和管道输出会退化为 `[hb-sdk] LEVEL ...` 这种稳定文本行。
|
|
416
429
|
|
|
430
|
+
## hb-sdk build
|
|
431
|
+
|
|
432
|
+
生产构建推荐使用:
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
hb-sdk build [--env <name>] [--verbose]
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
`hb-sdk build` 直接调用当前项目安装的 Vite,固定清理并重新生成 `dist/`,然后校验 `index.html`、`manifest.json` 和可上传产物。命令只负责生产构建,不执行 `scripts.build` 或 TypeScript 类型检查,也不需要 CLI 登录、项目绑定或远端网络。`--env <name>` 用于选择同名构建环境;除 `--env` 和 `--verbose` 外不提供其他构建参数。
|
|
439
|
+
|
|
440
|
+
项目必须在 `vite.config.ts` 中显式注册 `miniappManifest()`。推荐让项目脚本保留类型检查:
|
|
441
|
+
|
|
442
|
+
```json
|
|
443
|
+
{
|
|
444
|
+
"scripts": {
|
|
445
|
+
"build": "vue-tsc --noEmit && hb-sdk build"
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
现有项目继续使用 `vite build` 仍然兼容,不会被自动迁移;新模板和新文档以 `hb-sdk build` 作为生产构建入口。`hb-sdk remote deploy` 仍执行项目自己的 `scripts.build`,因此会保留项目定义的类型检查和其他发布前步骤。
|
|
451
|
+
|
|
417
452
|
## hb-sdk remote deploy
|
|
418
453
|
|
|
419
454
|
`hb-sdk remote deploy` 把版本预检、build、CDN 上传、提交审核 API 串成单条命令。顶层 `hb-sdk deploy` 已删除;旧脚本必须改成 `hb-sdk remote deploy`。命令前置要求:
|
|
@@ -538,7 +573,7 @@ CLI 登录态只供 CLI 命令访问黑盒接口时复用,不会注入 iframe
|
|
|
538
573
|
|
|
539
574
|
## Manifest
|
|
540
575
|
|
|
541
|
-
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()
|
|
576
|
+
`@heybox/hb-sdk/vite` 提供构建时插件 `miniappManifest()`。项目通过 `hb-sdk build` 完成生产构建后,会在固定的 `dist/` 中写入 `manifest.json`:
|
|
542
577
|
|
|
543
578
|
```json
|
|
544
579
|
{
|
|
@@ -547,7 +582,7 @@ CLI 登录态只供 CLI 命令访问黑盒接口时复用,不会注入 iframe
|
|
|
547
582
|
}
|
|
548
583
|
```
|
|
549
584
|
|
|
550
|
-
`version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk create`
|
|
585
|
+
`version` 来自小程序项目自身的 `package.json.version`,`sdkVersion` 来自当前安装 SDK 的构建版本且不能由业务覆盖。`hb-sdk build` 要求项目显式注册这个插件;`hb-sdk create` 生成的模板默认已注册,现有 Vite 项目可以在 `vite.config.ts` 中手动接入:
|
|
551
586
|
|
|
552
587
|
```ts
|
|
553
588
|
import { miniappManifest } from '@heybox/hb-sdk/vite';
|
|
@@ -565,13 +600,13 @@ export default defineConfig({
|
|
|
565
600
|
|
|
566
601
|
插件只接受单页应用:输出目录只能存在入口 `index.html`。build 会用结构化 HTML parser 校验入口,并把平台 CSP 插入 `<head>` 首位;已有 CSP 会原样保留,两份策略按浏览器交集生效。正式策略禁止 `fetch`、XHR、WebSocket、EventSource、Beacon、Worker、iframe、表单和对象加载等浏览器原生出口;业务网络请求应使用 `network.request()`。dev 使用相同策略,只额外放行当前 Vite 的精确 HMR WebSocket 地址。
|
|
567
602
|
|
|
568
|
-
meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、外部资源 URL 和额外 HTML 会使 build 失败。内联 script/style 允许,但 `unsafe-eval` 不允许。`dev` 和手动 Vite build
|
|
603
|
+
meta refresh、外部 anchor、`dns-prefetch`、`preconnect`、`prerender`、外部资源 URL 和额外 HTML 会使 build 失败。内联 script/style 允许,但 `unsafe-eval` 不允许。`dev`、`hb-sdk build` 和手动 Vite build 都不请求远端最低 SDK 版本;构建仍会把当前 `sdkVersion` 写入 Manifest,`hb-sdk remote deploy` 仍校验 Manifest 结构并经过服务端 precheck / submit-audit 策略。
|
|
569
604
|
|
|
570
605
|
失败与警告语义:
|
|
571
606
|
|
|
572
|
-
- 读取 `package.json` 失败或 JSON
|
|
573
|
-
- `package.json.version`
|
|
574
|
-
- `package.json.version` 仍是模板默认值 `0.0.0
|
|
607
|
+
- 读取 `package.json` 失败或 JSON 解析失败:build 直接失败,并输出具体原因。
|
|
608
|
+
- `package.json.version` 不是非空字符串:build 直接失败。
|
|
609
|
+
- `package.json.version` 仍是模板默认值 `0.0.0`:build 直接失败,必须改成实际 SemVer。
|
|
575
610
|
- 版本号不是严格 SemVer、包含 build metadata 或缺少 `sdkVersion`:build/deploy 直接失败。
|
|
576
611
|
|
|
577
612
|
`manifest.json` 不部署到 CDN,只交给发布流水线读取后上送后台;Host 通过后台 API 间接读取版本信息。第一阶段只支持 Vite 项目,非 Vite 打包器未来通过其他子入口扩展。
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs$1 = require('node:fs');
|
|
4
|
+
var fs = require('node:fs/promises');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var index$1 = require('./index-BQm5XmMC.cjs');
|
|
7
|
+
var runtimeGate = require('./runtime-gate-B2MQf1vc.cjs');
|
|
8
|
+
var index = require('./index-QAkYgxPI.cjs');
|
|
9
|
+
var projectVite = require('./project-vite-VcJMyz1l.cjs');
|
|
10
|
+
require('node:module');
|
|
11
|
+
require('path');
|
|
12
|
+
require('os');
|
|
13
|
+
require('readline');
|
|
14
|
+
require('tty');
|
|
15
|
+
require('assert');
|
|
16
|
+
require('events');
|
|
17
|
+
require('stream');
|
|
18
|
+
require('buffer');
|
|
19
|
+
require('util');
|
|
20
|
+
require('node:url');
|
|
21
|
+
|
|
22
|
+
async function runBuildCommand(_options = {}, runtime = {}) {
|
|
23
|
+
const logger = runtime.logger ?? index.createCliLogger();
|
|
24
|
+
const projectRoot = projectVite.findProjectRoot(runtime.cwd ?? process.cwd());
|
|
25
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
26
|
+
const mode = (runtime.env ?? process.env).HB_SDK_ENV?.trim() || undefined;
|
|
27
|
+
await fs.rm(distDir, { force: true, recursive: true });
|
|
28
|
+
try {
|
|
29
|
+
const vite = await logger.task('正在加载项目 Vite', () => projectVite.loadProjectVite(projectRoot), {
|
|
30
|
+
successText: '已加载项目 Vite',
|
|
31
|
+
});
|
|
32
|
+
await logger.task('正在构建小程序', () => vite.build({
|
|
33
|
+
root: projectRoot,
|
|
34
|
+
...(mode ? { mode } : {}),
|
|
35
|
+
plugins: [createFixedBuildOutputPlugin(projectRoot)],
|
|
36
|
+
build: {
|
|
37
|
+
outDir: 'dist',
|
|
38
|
+
emptyOutDir: true,
|
|
39
|
+
watch: null,
|
|
40
|
+
write: true,
|
|
41
|
+
},
|
|
42
|
+
}), { successText: 'Vite 构建完成' });
|
|
43
|
+
const result = await validateBuildOutput(projectRoot, logger);
|
|
44
|
+
logger.success(`构建完成: dist/ | manifest version ${result.version} | sdkVersion ${result.sdkVersion} | 待上传文件 ${result.fileCount} 个 | ${formatSize(result.totalBytes)}`);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
await fs.rm(distDir, { force: true, recursive: true });
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function createFixedBuildOutputPlugin(projectRoot) {
|
|
53
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
54
|
+
return {
|
|
55
|
+
name: 'heybox:fixed-miniapp-build-output',
|
|
56
|
+
configResolved(config) {
|
|
57
|
+
if (path.resolve(config.root, config.build.outDir) !== distDir || config.build.watch || config.build.write === false) {
|
|
58
|
+
throw new Error('hb-sdk build 必须执行一次性落盘构建,并输出到项目 dist 目录');
|
|
59
|
+
}
|
|
60
|
+
const outputs = Array.isArray(config.build.rollupOptions.output) ? config.build.rollupOptions.output : [config.build.rollupOptions.output];
|
|
61
|
+
for (const output of outputs) {
|
|
62
|
+
if (!output)
|
|
63
|
+
continue;
|
|
64
|
+
if (output.file || output.dir) {
|
|
65
|
+
throw new Error('hb-sdk build 不允许通过 Rollup output.dir/file 覆盖固定的 dist 输出目录');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function validateBuildOutput(projectRoot, logger) {
|
|
72
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
73
|
+
const entryHtmlPath = path.join(distDir, 'index.html');
|
|
74
|
+
const manifestPath = path.join(distDir, 'manifest.json');
|
|
75
|
+
if (!fs$1.existsSync(entryHtmlPath)) {
|
|
76
|
+
throw new Error('未找到 dist/index.html,Vite 构建产物不完整');
|
|
77
|
+
}
|
|
78
|
+
if (!fs$1.existsSync(manifestPath)) {
|
|
79
|
+
throw new Error('未找到 dist/manifest.json,请在 Vite 配置中显式启用 miniappManifest()');
|
|
80
|
+
}
|
|
81
|
+
const entryHtml = await fs.readFile(entryHtmlPath, 'utf8');
|
|
82
|
+
if (!runtimeGate.hasMiniappRuntimeGate(entryHtml)) {
|
|
83
|
+
throw new Error('dist/index.html 缺少平台 Runtime 启动门禁,请在 Vite 配置中显式启用 miniappManifest()');
|
|
84
|
+
}
|
|
85
|
+
const { manifest, hadBom } = runtimeGate.parseMiniappManifestJson(await fs.readFile(manifestPath, 'utf8'), 'dist/manifest.json');
|
|
86
|
+
if (hadBom) {
|
|
87
|
+
logger.warn('dist/manifest.json 包含 BOM,已自动剥离');
|
|
88
|
+
}
|
|
89
|
+
const { sdkVersion, version } = runtimeGate.validateMiniappManifestForDeploy(manifest);
|
|
90
|
+
const allFiles = await walkDistFiles(distDir);
|
|
91
|
+
const uploadFiles = allFiles.filter((file) => index$1.shouldUploadDistFile(file.relativePath));
|
|
92
|
+
const sizeError = index$1.validateUploadTotalSize(uploadFiles);
|
|
93
|
+
if (sizeError) {
|
|
94
|
+
throw new Error(sizeError.replace('重新 deploy', '重新 build'));
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
distDir,
|
|
98
|
+
fileCount: uploadFiles.length,
|
|
99
|
+
sdkVersion,
|
|
100
|
+
totalBytes: uploadFiles.reduce((total, file) => total + file.size, 0),
|
|
101
|
+
version,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
async function walkDistFiles(distDir) {
|
|
105
|
+
const results = [];
|
|
106
|
+
await walk(distDir, '');
|
|
107
|
+
return results;
|
|
108
|
+
async function walk(absDir, relDir) {
|
|
109
|
+
const entries = await fs.readdir(absDir, { withFileTypes: true });
|
|
110
|
+
for (const entry of entries) {
|
|
111
|
+
const absPath = path.join(absDir, entry.name);
|
|
112
|
+
const relPath = index$1.normalizeRelativePath(relDir ? `${relDir}/${entry.name}` : entry.name);
|
|
113
|
+
const link = await fs.lstat(absPath);
|
|
114
|
+
if (link.isSymbolicLink()) {
|
|
115
|
+
throw new Error(`dist 目录包含 symlink,拒绝处理:${relPath}`);
|
|
116
|
+
}
|
|
117
|
+
if (index$1.relativePathContainsNodeModulesSegment(relPath)) {
|
|
118
|
+
throw new Error(`dist 目录含 node_modules:${relPath}`);
|
|
119
|
+
}
|
|
120
|
+
if (entry.isDirectory()) {
|
|
121
|
+
await walk(absPath, relPath);
|
|
122
|
+
}
|
|
123
|
+
else if (entry.isFile()) {
|
|
124
|
+
results.push({ relativePath: relPath, size: (await fs.stat(absPath)).size });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function formatSize(bytes) {
|
|
130
|
+
if (bytes < 1024)
|
|
131
|
+
return `${bytes} B`;
|
|
132
|
+
if (bytes < 1024 * 1024)
|
|
133
|
+
return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
134
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
exports.runBuildCommand = runBuildCommand;
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var session = require('./session-YJ8xNESM.cjs');
|
|
4
|
+
var index = require('./index-BQm5XmMC.cjs');
|
|
5
|
+
var fs$1 = require('node:fs');
|
|
6
|
+
var fs = require('node:fs/promises');
|
|
7
|
+
var path = require('node:path');
|
|
8
|
+
|
|
9
|
+
function createRemoteApiClient(options) {
|
|
10
|
+
return {
|
|
11
|
+
listDeveloperEntities: () => listDeveloperEntities(options),
|
|
12
|
+
switchDeveloperEntity: (requestOptions) => switchDeveloperEntity(requestOptions, options),
|
|
13
|
+
getDeveloperAccessStatus: () => getDeveloperAccessStatus(options),
|
|
14
|
+
listUserMiniprograms: (requestOptions = {}) => listUserMiniprograms(requestOptions, options),
|
|
15
|
+
createUserMiniprogram: () => createUserMiniprogram(options),
|
|
16
|
+
getUserMiniprogramDetail: (requestOptions) => getUserMiniprogramDetail(requestOptions, options),
|
|
17
|
+
getPreviewAllowlist: (requestOptions) => getPreviewAllowlist(requestOptions, options),
|
|
18
|
+
updatePreviewAllowlist: (requestOptions) => updatePreviewAllowlist(requestOptions, options),
|
|
19
|
+
createUserMiniprogramLeaderboard: (requestOptions) => createUserMiniprogramLeaderboard(requestOptions, options),
|
|
20
|
+
getUserMiniprogramLeaderboard: (requestOptions) => getUserMiniprogramLeaderboard(requestOptions, options),
|
|
21
|
+
listUserMiniprogramLeaderboards: (requestOptions) => listUserMiniprogramLeaderboards(requestOptions, options),
|
|
22
|
+
deleteUserMiniprogramLeaderboard: (requestOptions) => deleteUserMiniprogramLeaderboard(requestOptions, options),
|
|
23
|
+
precheckUserMiniprogramVersion: (requestOptions) => precheckUserMiniprogramVersion(requestOptions, options),
|
|
24
|
+
submitUserMiniprogramAudit: (requestOptions) => submitUserMiniprogramAudit(requestOptions, options),
|
|
25
|
+
getVersionPreviewInfo: (requestOptions) => getVersionPreviewInfo(requestOptions, options),
|
|
26
|
+
withdrawUserMiniprogramVersion: (requestOptions) => withdrawUserMiniprogramVersion(requestOptions, options),
|
|
27
|
+
releaseUserMiniprogramVersion: (requestOptions) => releaseUserMiniprogramVersion(requestOptions, options),
|
|
28
|
+
takeDownUserMiniprogram: (requestOptions) => takeDownUserMiniprogram(requestOptions, options),
|
|
29
|
+
reopenUserMiniprogram: (requestOptions) => reopenUserMiniprogram(requestOptions, options),
|
|
30
|
+
updateSquareDisplay: (requestOptions) => updateSquareDisplay(requestOptions, options),
|
|
31
|
+
listUserMiniprogramVersions: (requestOptions) => listUserMiniprogramVersions(requestOptions, options),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async function listDeveloperEntities(runtime) {
|
|
35
|
+
return remoteGet(index.DEVELOPER_ENTITY_LIST_API_PATH, {}, runtime);
|
|
36
|
+
}
|
|
37
|
+
async function switchDeveloperEntity(options, runtime) {
|
|
38
|
+
return (await remotePostForm(index.DEVELOPER_ENTITY_SWITCH_API_PATH, options, runtime, { requireResult: false })) ?? {};
|
|
39
|
+
}
|
|
40
|
+
async function getDeveloperAccessStatus(runtime) {
|
|
41
|
+
return remoteGet(index.USER_MINIPROGRAM_ACCESS_STATUS_API_PATH, {}, runtime);
|
|
42
|
+
}
|
|
43
|
+
async function listUserMiniprograms(options, runtime) {
|
|
44
|
+
return remoteGet(index.LIST_USER_MINIPROGRAM_API_PATH, options, runtime);
|
|
45
|
+
}
|
|
46
|
+
async function createUserMiniprogram(runtime) {
|
|
47
|
+
return remotePostForm(index.CREATE_USER_MINIPROGRAM_API_PATH, {}, runtime);
|
|
48
|
+
}
|
|
49
|
+
async function getUserMiniprogramDetail(options, runtime) {
|
|
50
|
+
return remoteGet(index.DETAIL_USER_MINIPROGRAM_API_PATH, options, runtime);
|
|
51
|
+
}
|
|
52
|
+
async function getPreviewAllowlist(options, runtime) {
|
|
53
|
+
return remoteGet(index.USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
|
|
54
|
+
}
|
|
55
|
+
async function updatePreviewAllowlist(options, runtime) {
|
|
56
|
+
return remotePostForm(index.UPDATE_USER_MINIPROGRAM_PREVIEW_ALLOWLIST_API_PATH, options, runtime);
|
|
57
|
+
}
|
|
58
|
+
async function createUserMiniprogramLeaderboard(options, runtime) {
|
|
59
|
+
return remotePostForm(index.CREATE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
|
|
60
|
+
}
|
|
61
|
+
async function getUserMiniprogramLeaderboard(options, runtime) {
|
|
62
|
+
return remoteGet(index.DETAIL_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
|
|
63
|
+
}
|
|
64
|
+
async function listUserMiniprogramLeaderboards(options, runtime) {
|
|
65
|
+
return remoteGet(index.LIST_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime);
|
|
66
|
+
}
|
|
67
|
+
async function deleteUserMiniprogramLeaderboard(options, runtime) {
|
|
68
|
+
return (await remotePostForm(index.DELETE_USER_MINIPROGRAM_LEADERBOARD_API_PATH, options, runtime, { requireResult: false })) ?? {};
|
|
69
|
+
}
|
|
70
|
+
async function precheckUserMiniprogramVersion(options, runtime) {
|
|
71
|
+
return remotePostForm(index.PRECHECK_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
|
|
72
|
+
}
|
|
73
|
+
async function submitUserMiniprogramAudit(options, runtime) {
|
|
74
|
+
const form = { ...options };
|
|
75
|
+
if (form.manifest && typeof form.manifest !== 'string') {
|
|
76
|
+
form.manifest = JSON.stringify(form.manifest);
|
|
77
|
+
}
|
|
78
|
+
return remotePostForm(index.SUBMIT_USER_MINIPROGRAM_AUDIT_API_PATH, form, runtime);
|
|
79
|
+
}
|
|
80
|
+
async function getVersionPreviewInfo(options, runtime) {
|
|
81
|
+
return remoteGet(index.USER_MINIPROGRAM_VERSION_PREVIEW_INFO_API_PATH, {
|
|
82
|
+
mini_program_id: options.mini_program_id,
|
|
83
|
+
preview_version: options.version,
|
|
84
|
+
}, runtime);
|
|
85
|
+
}
|
|
86
|
+
async function withdrawUserMiniprogramVersion(options, runtime) {
|
|
87
|
+
return remotePostForm(index.WITHDRAW_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
|
|
88
|
+
}
|
|
89
|
+
async function releaseUserMiniprogramVersion(options, runtime) {
|
|
90
|
+
return remotePostForm(index.RELEASE_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
|
|
91
|
+
}
|
|
92
|
+
async function takeDownUserMiniprogram(options, runtime) {
|
|
93
|
+
return remotePostForm(index.TAKE_DOWN_USER_MINIPROGRAM_API_PATH, options, runtime);
|
|
94
|
+
}
|
|
95
|
+
async function reopenUserMiniprogram(options, runtime) {
|
|
96
|
+
return remotePostForm(index.REOPEN_USER_MINIPROGRAM_API_PATH, options, runtime);
|
|
97
|
+
}
|
|
98
|
+
async function updateSquareDisplay(options, runtime) {
|
|
99
|
+
return remotePostForm(index.UPDATE_SQUARE_DISPLAY_API_PATH, options, runtime);
|
|
100
|
+
}
|
|
101
|
+
async function listUserMiniprogramVersions(options, runtime) {
|
|
102
|
+
return remoteGet(index.LIST_USER_MINIPROGRAM_VERSION_API_PATH, options, runtime);
|
|
103
|
+
}
|
|
104
|
+
async function remoteGet(path, query, runtime) {
|
|
105
|
+
const pathWithQuery = createPathWithQuery(path, query);
|
|
106
|
+
const context = session.createHeyboxOpenPlatformRequestContext(runtime.session, pathWithQuery);
|
|
107
|
+
const fetchImpl = runtime.fetchImpl ?? fetch;
|
|
108
|
+
const response = await fetchImpl(session.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, pathWithQuery, context.platformParams), {
|
|
109
|
+
method: 'GET',
|
|
110
|
+
headers: context.headers,
|
|
111
|
+
});
|
|
112
|
+
return readRequiredResult(response, pathWithQuery);
|
|
113
|
+
}
|
|
114
|
+
async function remotePostForm(path, fields, runtime, options = {}) {
|
|
115
|
+
const context = session.createHeyboxOpenPlatformRequestContext(runtime.session, path, {
|
|
116
|
+
contentType: 'application/x-www-form-urlencoded',
|
|
117
|
+
});
|
|
118
|
+
const fetchImpl = runtime.fetchImpl ?? fetch;
|
|
119
|
+
const response = await fetchImpl(session.createHeyboxApiUrl(runtime.baseUrl ?? context.baseUrl, path, context.platformParams), {
|
|
120
|
+
method: 'POST',
|
|
121
|
+
headers: context.headers,
|
|
122
|
+
body: createFormBody(fields),
|
|
123
|
+
});
|
|
124
|
+
if (options.requireResult === false) {
|
|
125
|
+
return readOptionalResult(response, path);
|
|
126
|
+
}
|
|
127
|
+
return readRequiredResult(response, path);
|
|
128
|
+
}
|
|
129
|
+
async function readRequiredResult(response, pathWithQuery) {
|
|
130
|
+
const result = await session.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: true });
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
async function readOptionalResult(response, pathWithQuery) {
|
|
134
|
+
return session.readHeyboxApiEnvelope(response, { pathWithQuery, requireResult: false });
|
|
135
|
+
}
|
|
136
|
+
function createPathWithQuery(path, query) {
|
|
137
|
+
const params = new URLSearchParams();
|
|
138
|
+
for (const [key, value] of Object.entries(query)) {
|
|
139
|
+
if (value !== undefined && value !== null && value !== '') {
|
|
140
|
+
params.set(key, String(value));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const queryString = params.toString();
|
|
144
|
+
return queryString ? `${path}?${queryString}` : path;
|
|
145
|
+
}
|
|
146
|
+
function createFormBody(fields) {
|
|
147
|
+
const body = new URLSearchParams();
|
|
148
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
149
|
+
if (value === undefined || value === null) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (Array.isArray(value)) {
|
|
153
|
+
body.set(key, value.join(','));
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (typeof value === 'object') {
|
|
157
|
+
body.set(key, JSON.stringify(value));
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
body.set(key, String(value));
|
|
161
|
+
}
|
|
162
|
+
return body.toString();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
class MiniProgramProjectBindingError extends Error {
|
|
166
|
+
code;
|
|
167
|
+
constructor(message, code) {
|
|
168
|
+
super(message);
|
|
169
|
+
this.code = code;
|
|
170
|
+
this.name = 'MiniProgramProjectBindingError';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function findMiniProgramProjectRoot(startDir) {
|
|
174
|
+
let current = path.resolve(startDir);
|
|
175
|
+
while (true) {
|
|
176
|
+
if (fs$1.existsSync(path.join(current, 'package.json'))) {
|
|
177
|
+
return current;
|
|
178
|
+
}
|
|
179
|
+
const parent = path.dirname(current);
|
|
180
|
+
if (parent === current) {
|
|
181
|
+
throw new MiniProgramProjectBindingError('当前目录或父目录未找到 package.json', 'PACKAGE_JSON_NOT_FOUND');
|
|
182
|
+
}
|
|
183
|
+
current = parent;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function readMiniProgramProjectPackage(startDir) {
|
|
187
|
+
const projectRoot = findMiniProgramProjectRoot(startDir);
|
|
188
|
+
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
189
|
+
const raw = await fs.readFile(packageJsonPath, 'utf8');
|
|
190
|
+
let packageJson;
|
|
191
|
+
try {
|
|
192
|
+
packageJson = JSON.parse(raw);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
196
|
+
throw new MiniProgramProjectBindingError(`package.json 不是合法 JSON:${packageJsonPath}\n${message}`, 'PACKAGE_JSON_INVALID');
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
projectRoot,
|
|
200
|
+
packageJsonPath,
|
|
201
|
+
packageJson,
|
|
202
|
+
raw,
|
|
203
|
+
indent: detectJsonIndent(raw),
|
|
204
|
+
trailingNewline: raw.endsWith('\r\n') ? '\r\n' : raw.endsWith('\n') ? '\n' : '',
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function readBoundMiniProgramIdFromPackageJson(packageJson) {
|
|
208
|
+
const value = packageJson.heybox?.miniProgramId;
|
|
209
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
210
|
+
}
|
|
211
|
+
async function readBoundMiniProgramId(startDir) {
|
|
212
|
+
return readBoundMiniProgramIdFromPackageJson((await readMiniProgramProjectPackage(startDir)).packageJson);
|
|
213
|
+
}
|
|
214
|
+
async function requireBoundMiniProgramId(startDir) {
|
|
215
|
+
const context = await readMiniProgramProjectPackage(startDir);
|
|
216
|
+
const miniProgramId = readBoundMiniProgramIdFromPackageJson(context.packageJson);
|
|
217
|
+
if (!miniProgramId) {
|
|
218
|
+
throw new MiniProgramProjectBindingError(`当前项目未绑定小程序。请先运行 hb-sdk remote create 或 hb-sdk remote bind <mini-program-id>。\n配置位置:${context.packageJsonPath}#heybox.miniProgramId`, 'MINI_PROGRAM_UNBOUND');
|
|
219
|
+
}
|
|
220
|
+
return { ...context, miniProgramId };
|
|
221
|
+
}
|
|
222
|
+
async function writeBoundMiniProgramId(startDir, miniProgramId, options = {}) {
|
|
223
|
+
const context = await readMiniProgramProjectPackage(startDir);
|
|
224
|
+
const normalizedMiniProgramId = String(miniProgramId).trim();
|
|
225
|
+
if (!normalizedMiniProgramId) {
|
|
226
|
+
throw new MiniProgramProjectBindingError('miniProgramId 不能为空', 'PACKAGE_JSON_INVALID');
|
|
227
|
+
}
|
|
228
|
+
const currentMiniProgramId = readBoundMiniProgramIdFromPackageJson(context.packageJson);
|
|
229
|
+
if (currentMiniProgramId && currentMiniProgramId !== normalizedMiniProgramId && !options.force) {
|
|
230
|
+
throw new MiniProgramProjectBindingError(`当前项目已绑定小程序 ${currentMiniProgramId}。如需覆盖本地绑定,请使用 --force。`, 'MINI_PROGRAM_BINDING_EXISTS');
|
|
231
|
+
}
|
|
232
|
+
if (currentMiniProgramId === normalizedMiniProgramId) {
|
|
233
|
+
return {
|
|
234
|
+
...context,
|
|
235
|
+
changed: false,
|
|
236
|
+
miniProgramId: normalizedMiniProgramId,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (context.packageJson.heybox !== undefined && !isPlainObject(context.packageJson.heybox)) {
|
|
240
|
+
throw new MiniProgramProjectBindingError('package.json heybox 字段必须是对象,不能写入 miniProgramId', 'PACKAGE_JSON_HEYBOX_INVALID');
|
|
241
|
+
}
|
|
242
|
+
context.packageJson.heybox = {
|
|
243
|
+
...(context.packageJson.heybox ?? {}),
|
|
244
|
+
miniProgramId: normalizedMiniProgramId,
|
|
245
|
+
};
|
|
246
|
+
await fs.writeFile(context.packageJsonPath, `${JSON.stringify(context.packageJson, null, context.indent)}${context.trailingNewline || '\n'}`, 'utf8');
|
|
247
|
+
return {
|
|
248
|
+
...context,
|
|
249
|
+
changed: true,
|
|
250
|
+
miniProgramId: normalizedMiniProgramId,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function detectJsonIndent(raw) {
|
|
254
|
+
const match = raw.match(/\n(\s+)"[^"]+":/);
|
|
255
|
+
return match?.[1] ?? 2;
|
|
256
|
+
}
|
|
257
|
+
function isPlainObject(value) {
|
|
258
|
+
return Object.prototype.toString.call(value) === '[object Object]';
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async function resolveRemoteEnvironment(options = {}, runtime = {}) {
|
|
262
|
+
const env = options.env ?? process.env;
|
|
263
|
+
const apiBaseUrl = session.resolveHeyboxApiBaseUrl({ ...options, env });
|
|
264
|
+
const loginBaseUrl = session.resolveHeyboxLoginBaseUrl({ ...options, env });
|
|
265
|
+
const session$1 = options.session ?? (await (runtime.requireAuthSession ?? session.requireHeyboxAuthSession)({ loginBaseUrl }));
|
|
266
|
+
return {
|
|
267
|
+
apiBaseUrl,
|
|
268
|
+
loginBaseUrl,
|
|
269
|
+
allowUnsafeApiBaseUrl: options.allowUnsafeApiBaseUrl === true || isTruthyEnvFlag(env.HB_SDK_ALLOW_UNSAFE_API_BASE_URL),
|
|
270
|
+
env,
|
|
271
|
+
fetchImpl: runtime.fetchImpl ?? options.fetchImpl ?? fetch,
|
|
272
|
+
session: session$1,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function createRemoteApiClientForEnvironment(environment) {
|
|
276
|
+
return createRemoteApiClient({
|
|
277
|
+
baseUrl: environment.apiBaseUrl,
|
|
278
|
+
fetchImpl: environment.fetchImpl,
|
|
279
|
+
session: environment.session,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
async function getBoundMiniProgram(options = {}, runtime = {}) {
|
|
283
|
+
const cwd = options.cwd ?? process.cwd();
|
|
284
|
+
const binding = await requireBoundMiniProgramId(cwd);
|
|
285
|
+
const api = await resolveRemoteApiClient(options, runtime);
|
|
286
|
+
const detail = await api.getUserMiniprogramDetail({ mini_program_id: binding.miniProgramId });
|
|
287
|
+
return {
|
|
288
|
+
...binding,
|
|
289
|
+
detail,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async function resolveRemoteApiClient(options, runtime) {
|
|
293
|
+
if (runtime.apiClient) {
|
|
294
|
+
return runtime.apiClient;
|
|
295
|
+
}
|
|
296
|
+
return createRemoteApiClientForEnvironment(await resolveRemoteEnvironment(options, runtime));
|
|
297
|
+
}
|
|
298
|
+
function isTruthyEnvFlag(value) {
|
|
299
|
+
return ['1', 'true', 'yes', 'on'].includes(String(value ?? '')
|
|
300
|
+
.trim()
|
|
301
|
+
.toLowerCase());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
exports.MiniProgramProjectBindingError = MiniProgramProjectBindingError;
|
|
305
|
+
exports.createRemoteApiClientForEnvironment = createRemoteApiClientForEnvironment;
|
|
306
|
+
exports.getBoundMiniProgram = getBoundMiniProgram;
|
|
307
|
+
exports.readBoundMiniProgramId = readBoundMiniProgramId;
|
|
308
|
+
exports.readBoundMiniProgramIdFromPackageJson = readBoundMiniProgramIdFromPackageJson;
|
|
309
|
+
exports.readMiniProgramProjectPackage = readMiniProgramProjectPackage;
|
|
310
|
+
exports.resolveRemoteEnvironment = resolveRemoteEnvironment;
|
|
311
|
+
exports.writeBoundMiniProgramId = writeBoundMiniProgramId;
|
|
@@ -5,7 +5,7 @@ var fs = require('node:fs/promises');
|
|
|
5
5
|
var path = require('node:path');
|
|
6
6
|
var require$$0 = require('fs');
|
|
7
7
|
var require$$1 = require('path');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-QAkYgxPI.cjs');
|
|
9
9
|
require('node:module');
|
|
10
10
|
require('os');
|
|
11
11
|
require('readline');
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var node_module = require('node:module');
|
|
4
3
|
var fs = require('node:fs');
|
|
5
|
-
var fs$1 = require('node:fs/promises');
|
|
6
4
|
var os = require('node:os');
|
|
7
5
|
var path = require('node:path');
|
|
8
|
-
var node_url = require('node:url');
|
|
9
6
|
var net = require('node:net');
|
|
10
7
|
var promises = require('node:dns/promises');
|
|
11
8
|
var node_http = require('node:http');
|
|
12
9
|
var node_crypto = require('node:crypto');
|
|
13
10
|
var undici = require('undici');
|
|
14
11
|
var browser = require('./browser-RAy8e8cV.cjs');
|
|
15
|
-
var index = require('./index-
|
|
16
|
-
var
|
|
12
|
+
var index = require('./index-QAkYgxPI.cjs');
|
|
13
|
+
var projectVite = require('./project-vite-VcJMyz1l.cjs');
|
|
14
|
+
var context = require('./context-CvZs9ZBf.cjs');
|
|
15
|
+
var fs$1 = require('node:fs/promises');
|
|
17
16
|
require('node:process');
|
|
18
17
|
require('node:buffer');
|
|
18
|
+
require('node:url');
|
|
19
19
|
require('node:util');
|
|
20
20
|
require('node:child_process');
|
|
21
|
+
require('node:module');
|
|
21
22
|
require('path');
|
|
22
23
|
require('os');
|
|
23
24
|
require('readline');
|
|
@@ -27,9 +28,10 @@ require('events');
|
|
|
27
28
|
require('stream');
|
|
28
29
|
require('buffer');
|
|
29
30
|
require('util');
|
|
30
|
-
require('./session-
|
|
31
|
+
require('./session-YJ8xNESM.cjs');
|
|
31
32
|
require('fs');
|
|
32
33
|
require('constants');
|
|
34
|
+
require('./index-BQm5XmMC.cjs');
|
|
33
35
|
|
|
34
36
|
class Locked extends Error {
|
|
35
37
|
constructor(port) {
|
|
@@ -1257,7 +1259,7 @@ function cloneDefaultPermissionState() {
|
|
|
1257
1259
|
/** 构建时替换为当前发布包的实际版本。 */
|
|
1258
1260
|
const HB_SDK_VERSION = typeof undefined === 'string'
|
|
1259
1261
|
? undefined
|
|
1260
|
-
: '0.6.6-alpha.
|
|
1262
|
+
: '0.6.6-alpha.3';
|
|
1261
1263
|
|
|
1262
1264
|
class DevPermissionOverrideStoreError extends Error {
|
|
1263
1265
|
code;
|
|
@@ -1405,7 +1407,7 @@ async function runDevCommand(options, runtime = {}) {
|
|
|
1405
1407
|
hmrHost: createLanInterfaceCandidates(networkInterfaceSnapshot)[0]?.address,
|
|
1406
1408
|
port: appPort,
|
|
1407
1409
|
};
|
|
1408
|
-
const projectRoot = findProjectRoot(runtime.cwd ?? process.cwd());
|
|
1410
|
+
const projectRoot = projectVite.findProjectRoot(runtime.cwd ?? process.cwd());
|
|
1409
1411
|
const devLaunchContext = await loadDevLaunchContext({
|
|
1410
1412
|
env: runtime.env,
|
|
1411
1413
|
fetchImpl,
|
|
@@ -1427,7 +1429,7 @@ async function runDevCommand(options, runtime = {}) {
|
|
|
1427
1429
|
}),
|
|
1428
1430
|
projectRoot,
|
|
1429
1431
|
});
|
|
1430
|
-
const vite = await logger.task('正在加载项目 Vite', () => loadProjectVite(projectRoot), { successText: '已加载项目 Vite' });
|
|
1432
|
+
const vite = await logger.task('正在加载项目 Vite', () => projectVite.loadProjectVite(projectRoot), { successText: '已加载项目 Vite' });
|
|
1431
1433
|
const appServer = await logger.task('正在创建 Vite dev server', () => withManagedDevOutputEnv(() => vite.createServer(createViteServerOptions(projectRoot, resolvedOptions)), runtime.env), { successText: '已创建 Vite dev server' });
|
|
1432
1434
|
await logger.task('正在启动 Vite dev server', () => appServer.listen(appPort), {
|
|
1433
1435
|
successText: 'Vite dev server 已启动',
|
|
@@ -1623,39 +1625,6 @@ async function loadRemoteDevContextWithTimeout(options) {
|
|
|
1623
1625
|
}
|
|
1624
1626
|
}
|
|
1625
1627
|
}
|
|
1626
|
-
function findProjectRoot(startDir) {
|
|
1627
|
-
let current = path.resolve(startDir);
|
|
1628
|
-
while (true) {
|
|
1629
|
-
if (fs.existsSync(path.join(current, 'package.json'))) {
|
|
1630
|
-
return current;
|
|
1631
|
-
}
|
|
1632
|
-
const parent = path.dirname(current);
|
|
1633
|
-
if (parent === current) {
|
|
1634
|
-
throw new Error('当前目录或父目录未找到 package.json');
|
|
1635
|
-
}
|
|
1636
|
-
current = parent;
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
async function loadProjectVite(projectRoot) {
|
|
1640
|
-
const projectRequire = node_module.createRequire(path.join(projectRoot, 'package.json'));
|
|
1641
|
-
try {
|
|
1642
|
-
const packageJson = JSON.parse(await fs$1.readFile(path.join(projectRoot, 'package.json'), 'utf8'));
|
|
1643
|
-
if (!hasPackageDependency(packageJson, 'vite')) {
|
|
1644
|
-
throw new Error('package.json 未声明 vite');
|
|
1645
|
-
}
|
|
1646
|
-
const viteEntry = projectRequire.resolve('vite');
|
|
1647
|
-
return (await import(node_url.pathToFileURL(viteEntry).href));
|
|
1648
|
-
}
|
|
1649
|
-
catch (error) {
|
|
1650
|
-
throw new Error(`当前项目未安装 vite。请先安装项目依赖,或将 vite 放到项目 devDependencies。原始错误: ${index.readErrorMessage(error)}`);
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
function hasPackageDependency(packageJson, name) {
|
|
1654
|
-
return Boolean(packageJson.dependencies?.[name] ||
|
|
1655
|
-
packageJson.devDependencies?.[name] ||
|
|
1656
|
-
packageJson.optionalDependencies?.[name] ||
|
|
1657
|
-
packageJson.peerDependencies?.[name]);
|
|
1658
|
-
}
|
|
1659
1628
|
function createViteServerOptions(projectRoot, options) {
|
|
1660
1629
|
const configFile = resolveProjectViteConfig(projectRoot);
|
|
1661
1630
|
const server = {
|