ms-vite-plugin 1.3.3 → 1.3.5

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/dist/build.js CHANGED
@@ -42,6 +42,7 @@ const child_process_1 = require("child_process");
42
42
  const fsExtra = __importStar(require("fs-extra"));
43
43
  const os = __importStar(require("os"));
44
44
  const path = __importStar(require("path"));
45
+ const stopGuardPlugin_1 = require("./stopGuardPlugin");
45
46
  const vite_plugin_bundle_obfuscator_1 = __importDefault(require("vite-plugin-bundle-obfuscator"));
46
47
  /**
47
48
  * 压缩目录
@@ -202,15 +203,18 @@ const buildAll = async (isDev = true, workspacePath) => {
202
203
  sourcemap: isDev,
203
204
  minify: !isDev, // 开发环境不压缩变量名
204
205
  },
205
- plugins: isDev
206
- ? []
207
- : [
208
- (0, vite_plugin_bundle_obfuscator_1.default)({
209
- autoExcludeNodeModules: true,
210
- threadPool: true,
211
- options: obfuscatorConfig,
212
- }),
213
- ],
206
+ plugins: [
207
+ (0, stopGuardPlugin_1.createStopGuardPlugin)(),
208
+ ...(isDev
209
+ ? []
210
+ : [
211
+ (0, vite_plugin_bundle_obfuscator_1.default)({
212
+ autoExcludeNodeModules: true,
213
+ threadPool: true,
214
+ options: obfuscatorConfig,
215
+ }),
216
+ ]),
217
+ ],
214
218
  });
215
219
  }
216
220
  }
@@ -0,0 +1,8 @@
1
+ import type { Plugin } from "vite";
2
+ /**
3
+ * 为最终 JS chunk 的 catch 块补充停止异常转抛逻辑。
4
+ *
5
+ * 这个插件运行在 renderChunk 阶段:Vite 已经把 TS/模块语法编译成最终 JS,但尚未写入文件。
6
+ * 使用 MagicString 返回 sourcemap,让新增保护代码不映射到用户源码,原有代码继续保持映射。
7
+ */
8
+ export declare function createStopGuardPlugin(): Plugin;
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createStopGuardPlugin = createStopGuardPlugin;
37
+ const acorn = __importStar(require("acorn"));
38
+ const MagicString = require("magic-string");
39
+ const STOP_GUARD_ERROR = "__kuaijs_stop_guard_error";
40
+ const STOP_EXCEPTION_NAME = "KuaiJSManualExitException";
41
+ /**
42
+ * 为最终 JS chunk 的 catch 块补充停止异常转抛逻辑。
43
+ *
44
+ * 这个插件运行在 renderChunk 阶段:Vite 已经把 TS/模块语法编译成最终 JS,但尚未写入文件。
45
+ * 使用 MagicString 返回 sourcemap,让新增保护代码不映射到用户源码,原有代码继续保持映射。
46
+ */
47
+ function createStopGuardPlugin() {
48
+ return {
49
+ name: "kuaijs-stop-guard",
50
+ enforce: "post",
51
+ renderChunk(code) {
52
+ const edits = createStopGuardEdits(code);
53
+ if (edits.length === 0) {
54
+ return null;
55
+ }
56
+ const magic = new MagicString(code);
57
+ for (const edit of edits) {
58
+ if (edit.start === edit.end) {
59
+ magic.appendLeft(edit.start, edit.text);
60
+ }
61
+ else {
62
+ magic.overwrite(edit.start, edit.end, edit.text);
63
+ }
64
+ }
65
+ return {
66
+ code: magic.toString(),
67
+ map: magic.generateMap({ hires: true }),
68
+ };
69
+ },
70
+ };
71
+ }
72
+ function createStopGuardEdits(code) {
73
+ const ast = parseJavaScript(code);
74
+ const edits = [];
75
+ walkAst(ast, (node) => {
76
+ if (node.type === "CatchClause" && node.body?.type === "BlockStatement") {
77
+ addCatchStopExceptionGuard(edits, node, code);
78
+ }
79
+ });
80
+ return edits;
81
+ }
82
+ function parseJavaScript(code) {
83
+ try {
84
+ return acorn.parse(code, {
85
+ allowHashBang: true,
86
+ ecmaVersion: "latest",
87
+ sourceType: "script",
88
+ });
89
+ }
90
+ catch {
91
+ return acorn.parse(code, {
92
+ allowHashBang: true,
93
+ ecmaVersion: "latest",
94
+ sourceType: "module",
95
+ });
96
+ }
97
+ }
98
+ function addCatchStopExceptionGuard(edits, catchClause, code) {
99
+ if (typeof catchClause.body.start !== "number") {
100
+ return;
101
+ }
102
+ let errorExpression = STOP_GUARD_ERROR;
103
+ let restoreCatchPattern = "";
104
+ if (catchClause.param) {
105
+ if (catchClause.param.type === "Identifier") {
106
+ errorExpression = catchClause.param.name;
107
+ }
108
+ else if (typeof catchClause.param.start === "number" &&
109
+ typeof catchClause.param.end === "number") {
110
+ const originalPattern = code.slice(catchClause.param.start, catchClause.param.end);
111
+ edits.push({
112
+ start: catchClause.param.start,
113
+ end: catchClause.param.end,
114
+ text: STOP_GUARD_ERROR,
115
+ });
116
+ restoreCatchPattern = `let ${originalPattern}=${STOP_GUARD_ERROR};`;
117
+ }
118
+ }
119
+ else {
120
+ edits.push({
121
+ start: catchClause.body.start,
122
+ end: catchClause.body.start,
123
+ text: `(${STOP_GUARD_ERROR})`,
124
+ });
125
+ }
126
+ const stopGuard = `if(String(${errorExpression}).includes("${STOP_EXCEPTION_NAME}")){` +
127
+ `throw ${errorExpression};` +
128
+ `}`;
129
+ edits.push({
130
+ start: catchClause.body.start + 1,
131
+ end: catchClause.body.start + 1,
132
+ text: stopGuard + restoreCatchPattern,
133
+ });
134
+ }
135
+ function walkAst(node, visit) {
136
+ if (!node || typeof node !== "object") {
137
+ return;
138
+ }
139
+ if (typeof node.type === "string") {
140
+ visit(node);
141
+ }
142
+ for (const key of Object.keys(node)) {
143
+ if (key === "parent" ||
144
+ key === "start" ||
145
+ key === "end" ||
146
+ key === "loc" ||
147
+ key === "range" ||
148
+ key === "raw") {
149
+ continue;
150
+ }
151
+ const value = node[key];
152
+ if (Array.isArray(value)) {
153
+ for (const child of value) {
154
+ walkAst(child, visit);
155
+ }
156
+ }
157
+ else if (value && typeof value === "object") {
158
+ walkAst(value, visit);
159
+ }
160
+ }
161
+ }
package/docs/api/hid.md CHANGED
@@ -775,7 +775,6 @@ function pressButton(
775
775
  | "brightnessup"
776
776
  | "brightnessdown"
777
777
  | "power"
778
- | "menu"
779
778
  | "snapshot",
780
779
  ): boolean;
781
780
  ```
@@ -784,7 +783,7 @@ function pressButton(
784
783
 
785
784
  | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
786
785
  | -------- | ------ | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
787
- | `button` | string | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"menu"` Home/Menu 键 <br>- `"snapshot"` 系统截图键 |
786
+ | `button` | string | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"snapshot"` 系统截图键 |
788
787
 
789
788
  **返回值:**
790
789
 
@@ -908,7 +907,7 @@ hid.back();
908
907
 
909
908
  ### recent - 最近应用
910
909
 
911
- 显示 APP 切换器
910
+ 双击 Home 显示 APP 切换器。
912
911
 
913
912
  ```typescript
914
913
  function recent(): boolean;
package/docs/apicn/hid.md CHANGED
@@ -775,7 +775,6 @@ function 按键(
775
775
  | "brightnessup"
776
776
  | "brightnessdown"
777
777
  | "power"
778
- | "menu"
779
778
  | "snapshot",
780
779
  ): 布尔值;
781
780
  ```
@@ -784,7 +783,7 @@ function 按键(
784
783
 
785
784
  | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
786
785
  | ------ | ------ | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
787
- | `按键` | 字符串 | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"menu"` Home/Menu 键 <br>- `"snapshot"` 系统截图键 |
786
+ | `按键` | 字符串 | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"snapshot"` 系统截图键 |
788
787
 
789
788
  **返回值:**
790
789
 
@@ -911,7 +910,7 @@ $HID.返回();
911
910
 
912
911
  ### 最近应用
913
912
 
914
- 显示 APP 切换器
913
+ 双击 Home 显示 APP 切换器。
915
914
 
916
915
  ```typescript
917
916
  function 最近应用(): 布尔值;
@@ -800,7 +800,6 @@ def pressButton(
800
800
  "brightnessup",
801
801
  "brightnessdown",
802
802
  "power",
803
- "menu",
804
803
  "snapshot",
805
804
  ],
806
805
  ) -> bool
@@ -810,7 +809,7 @@ def pressButton(
810
809
 
811
810
  | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
812
811
  | -------- | ------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
813
- | `button` | Literal | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"menu"` Home/Menu 键 <br>- `"snapshot"` 系统截图键 |
812
+ | `button` | Literal | 是 | - | 按钮类型: <br>-`"home"` Home 键 <br>- `"volumeup"` 音量上键 <br>- `"volumedown"` 音量下键 <br>- `"mute"` 静音键 <br>- `"playpause"` 播放/暂停键 <br>- `"next"` 下一首/下一章节 <br>- `"prev"` 上一首/上一章节 <br>- `"eject"` 显示/隐藏键盘 <br>- `"globe"` Globe 键 <br>- `"search"` 搜索键 <br>- `"brightnessup"` 调高屏幕亮度 <br>- `"brightnessdown"` 调低屏幕亮度 <br>- `"power"` 电源/锁屏键 <br>- `"snapshot"` 系统截图键 |
814
813
 
815
814
  **返回值:**
816
815
 
@@ -932,7 +931,7 @@ hid.back()
932
931
 
933
932
  ### recent - 最近应用
934
933
 
935
- 显示 APP 切换器
934
+ 双击 Home 显示 APP 切换器。
936
935
 
937
936
  ```python
938
937
  def recent() -> bool
@@ -2504,6 +2504,154 @@ GET /api/hid/mouseUp
2504
2504
  |---|---|---|---|---|---|
2505
2505
  |» success|boolean|true|none|是否成功|none|
2506
2506
 
2507
+ ## POST 保存图像到相册
2508
+
2509
+ POST /api/media/saveImageToAlbum
2510
+
2511
+ ### 请求体
2512
+
2513
+ 请求体为图片文件原始二进制数据。接口会流式写入临时文件,不会把完整文件缓存到内存。可通过 query 参数 `filename` 传入文件名用于保留扩展名。
2514
+
2515
+ > 返回示例
2516
+
2517
+ > 200 Response
2518
+
2519
+ ```json
2520
+ {
2521
+ "success": true
2522
+ }
2523
+ ```
2524
+
2525
+ ### 返回结果
2526
+
2527
+ |状态码|状态码含义|说明|数据模型|
2528
+ |---|---|---|---|
2529
+ |200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline|
2530
+
2531
+ ### 返回数据结构
2532
+
2533
+ 状态码 **200**
2534
+
2535
+ |名称|类型|必选|约束|中文名|说明|
2536
+ |---|---|---|---|---|---|
2537
+ |» success|boolean|true|none|是否成功|none|
2538
+
2539
+ ## POST 保存视频到相册
2540
+
2541
+ POST /api/media/saveVideoToAlbumPath
2542
+
2543
+ ### 请求体
2544
+
2545
+ 请求体为视频文件原始二进制数据。接口会流式写入临时文件,不会把完整文件缓存到内存。可通过 query 参数 `filename` 传入文件名用于保留扩展名。
2546
+
2547
+ > 返回示例
2548
+
2549
+ > 200 Response
2550
+
2551
+ ```json
2552
+ {
2553
+ "success": true
2554
+ }
2555
+ ```
2556
+
2557
+ ### 返回结果
2558
+
2559
+ |状态码|状态码含义|说明|数据模型|
2560
+ |---|---|---|---|
2561
+ |200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline|
2562
+
2563
+ ### 返回数据结构
2564
+
2565
+ 状态码 **200**
2566
+
2567
+ |名称|类型|必选|约束|中文名|说明|
2568
+ |---|---|---|---|---|---|
2569
+ |» success|boolean|true|none|是否成功|none|
2570
+
2571
+ ## GET 清空相册图片
2572
+
2573
+ GET /api/media/deleteAllPhotos
2574
+
2575
+ > 返回示例
2576
+
2577
+ > 200 Response
2578
+
2579
+ ```json
2580
+ {
2581
+ "success": true
2582
+ }
2583
+ ```
2584
+
2585
+ ### 返回结果
2586
+
2587
+ |状态码|状态码含义|说明|数据模型|
2588
+ |---|---|---|---|
2589
+ |200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline|
2590
+
2591
+ ### 返回数据结构
2592
+
2593
+ 状态码 **200**
2594
+
2595
+ |名称|类型|必选|约束|中文名|说明|
2596
+ |---|---|---|---|---|---|
2597
+ |» success|boolean|true|none|是否成功|none|
2598
+
2599
+ ## GET 清空相册视频
2600
+
2601
+ GET /api/media/deleteAllVideos
2602
+
2603
+ > 返回示例
2604
+
2605
+ > 200 Response
2606
+
2607
+ ```json
2608
+ {
2609
+ "success": true
2610
+ }
2611
+ ```
2612
+
2613
+ ### 返回结果
2614
+
2615
+ |状态码|状态码含义|说明|数据模型|
2616
+ |---|---|---|---|
2617
+ |200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline|
2618
+
2619
+ ### 返回数据结构
2620
+
2621
+ 状态码 **200**
2622
+
2623
+ |名称|类型|必选|约束|中文名|说明|
2624
+ |---|---|---|---|---|---|
2625
+ |» success|boolean|true|none|是否成功|none|
2626
+
2627
+ ## GET 清空相册截图
2628
+
2629
+ GET /api/media/deleteAllScreenshots
2630
+
2631
+ > 返回示例
2632
+
2633
+ > 200 Response
2634
+
2635
+ ```json
2636
+ {
2637
+ "success": true
2638
+ }
2639
+ ```
2640
+
2641
+ ### 返回结果
2642
+
2643
+ |状态码|状态码含义|说明|数据模型|
2644
+ |---|---|---|---|
2645
+ |200|[OK](https://tools.ietf.org/html/rfc7231#section-6.3.1)|none|Inline|
2646
+
2647
+ ### 返回数据结构
2648
+
2649
+ 状态码 **200**
2650
+
2651
+ |名称|类型|必选|约束|中文名|说明|
2652
+ |---|---|---|---|---|---|
2653
+ |» success|boolean|true|none|是否成功|none|
2654
+
2507
2655
  # 数据模型
2508
2656
 
2509
2657
  <h2 id="tocS_软件状态">软件状态</h2>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ms-vite-plugin",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "type": "commonjs",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -22,10 +22,12 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@modelcontextprotocol/sdk": "^1.29.0",
25
+ "acorn": "8.15.0",
25
26
  "archiver": "^7.0.1",
26
27
  "commander": "^14.0.3",
27
28
  "crc": "^4.3.2",
28
29
  "fs-extra": "^11.3.5",
30
+ "magic-string": "^0.30.21",
29
31
  "sharp": "^0.34.5",
30
32
  "uuid": "^14.0.0",
31
33
  "vite": "^8.0.13",
@@ -42,4 +44,4 @@
42
44
  "@types/ws": "^8.18.1",
43
45
  "typescript": "~6.0.3"
44
46
  }
45
- }
47
+ }
package/dist/device.d.ts DELETED
@@ -1,32 +0,0 @@
1
- /**
2
- * 设备命令选项
3
- */
4
- export interface DeviceCliOptions {
5
- ip: string;
6
- port?: string;
7
- path?: string;
8
- }
9
- /**
10
- * 在设备上运行项目(先同步后运行)
11
- * @param options 命令选项
12
- * @returns 执行完成后返回 Promise<void>
13
- * @example
14
- * await runOnDevice({ ip: "192.168.1.10", port: "9800", path: "./demo" })
15
- */
16
- export declare function runOnDevice(options: DeviceCliOptions): Promise<void>;
17
- /**
18
- * 在设备上预览 UI(先同步后调用 runUI)
19
- * @param options 命令选项
20
- * @returns 执行完成后返回 Promise<void>
21
- * @example
22
- * await runUIOnDevice({ ip: "192.168.1.10", port: "9800", path: "./demo" })
23
- */
24
- export declare function runUIOnDevice(options: DeviceCliOptions): Promise<void>;
25
- /**
26
- * 停止设备上的项目
27
- * @param options 命令选项
28
- * @returns 执行完成后返回 Promise<void>
29
- * @example
30
- * await stopOnDevice({ ip: "192.168.1.10", port: "9800" })
31
- */
32
- export declare function stopOnDevice(options: DeviceCliOptions): Promise<void>;