intools-cli 1.0.0 → 1.0.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/PLUGIN_API.md +434 -0
- package/README.md +80 -126
- package/dist/commands/create/assets.js +53 -0
- package/dist/commands/create/basic.js +64 -0
- package/dist/commands/create/index.js +68 -0
- package/dist/commands/create/react.js +112 -0
- package/dist/commands/create/templates/basic.js +95 -0
- package/dist/commands/create/templates/react.js +1196 -0
- package/dist/commands/dev.js +24 -0
- package/package.json +4 -3
- package/dist/commands/create.js +0 -1038
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ InTools 插件开发的命令行工具,帮助你快速创建、调试、构建
|
|
|
10
10
|
- [插件开发指南](#插件开发指南)
|
|
11
11
|
- [项目结构](#项目结构)
|
|
12
12
|
- [manifest.json 配置](#manifestjson-配置)
|
|
13
|
+
- [动态功能入口](#动态功能入口)
|
|
13
14
|
- [开发模式](#开发模式)
|
|
14
15
|
- [使用第三方库](#使用第三方库)
|
|
15
16
|
- [插件 API](#插件-api)
|
|
@@ -140,6 +141,7 @@ my-plugin/
|
|
|
140
141
|
├── tsconfig.json # TypeScript 配置
|
|
141
142
|
├── vite.config.ts # Vite 配置
|
|
142
143
|
├── icon.png # 插件图标
|
|
144
|
+
├── PLUGIN_API.md # API 参考文档
|
|
143
145
|
├── src/
|
|
144
146
|
│ ├── main.ts # 后端逻辑(沙箱运行)
|
|
145
147
|
│ ├── types/
|
|
@@ -148,6 +150,8 @@ my-plugin/
|
|
|
148
150
|
│ ├── index.html
|
|
149
151
|
│ ├── main.tsx
|
|
150
152
|
│ ├── App.tsx
|
|
153
|
+
│ ├── hooks/
|
|
154
|
+
│ │ └── useIntools.ts
|
|
151
155
|
│ └── styles.css
|
|
152
156
|
├── dist/ # 后端构建输出
|
|
153
157
|
│ └── main.js
|
|
@@ -163,6 +167,7 @@ my-plugin/
|
|
|
163
167
|
├── package.json
|
|
164
168
|
├── manifest.json
|
|
165
169
|
├── icon.png
|
|
170
|
+
├── PLUGIN_API.md # API 参考文档
|
|
166
171
|
└── src/
|
|
167
172
|
└── main.ts
|
|
168
173
|
```
|
|
@@ -175,6 +180,7 @@ my-plugin/
|
|
|
175
180
|
|
|
176
181
|
```json
|
|
177
182
|
{
|
|
183
|
+
"id": "my-plugin",
|
|
178
184
|
"name": "my-plugin",
|
|
179
185
|
"version": "1.0.0",
|
|
180
186
|
"displayName": "我的插件",
|
|
@@ -202,6 +208,7 @@ my-plugin/
|
|
|
202
208
|
| `version` | string | ✅ | 语义化版本 (x.y.z) |
|
|
203
209
|
| `displayName` | string | ✅ | 用户看到的名称 |
|
|
204
210
|
| `description` | string | ✅ | 功能描述 |
|
|
211
|
+
| `id` | string | ✅ | 插件唯一 ID(推荐,优先于 name) |
|
|
205
212
|
| `main` | string | ✅ | 后端入口文件路径 |
|
|
206
213
|
| `ui` | string | ❌ | UI 文件路径(有界面时必填) |
|
|
207
214
|
| `icon` | string/object | ❌ | 插件图标 |
|
|
@@ -242,6 +249,8 @@ my-plugin/
|
|
|
242
249
|
| `code` | string | ✅ | 功能代码,传递给插件 |
|
|
243
250
|
| `explain` | string | ✅ | 功能说明,显示给用户 |
|
|
244
251
|
| `cmds` | array | ✅ | 触发命令列表 |
|
|
252
|
+
| `mode` | string | ❌ | `ui` / `silent` / `detached` |
|
|
253
|
+
| `route` | string | ❌ | UI 路由(用于子窗口或页内路由) |
|
|
245
254
|
|
|
246
255
|
#### 触发命令类型 (cmds)
|
|
247
256
|
|
|
@@ -272,6 +281,26 @@ my-plugin/
|
|
|
272
281
|
|
|
273
282
|
---
|
|
274
283
|
|
|
284
|
+
### 动态功能入口
|
|
285
|
+
|
|
286
|
+
后端可以通过 `context.api.features` 动态添加/移除功能入口:
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
export function onLoad(context?: any) {
|
|
290
|
+
const features = context?.api?.features
|
|
291
|
+
if (!features) return
|
|
292
|
+
|
|
293
|
+
features.setFeature({
|
|
294
|
+
code: 'dynamic:hello',
|
|
295
|
+
explain: '动态指令:hello',
|
|
296
|
+
mode: 'silent',
|
|
297
|
+
cmds: ['hello', { type: 'keyword', value: 'hi' }]
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
275
304
|
### 开发模式
|
|
276
305
|
|
|
277
306
|
#### 启动开发服务器
|
|
@@ -338,114 +367,34 @@ npm run build
|
|
|
338
367
|
|
|
339
368
|
插件在沙箱中运行,通过 `context.api` 访问各种 API。
|
|
340
369
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const { clipboard } = context.api
|
|
345
|
-
|
|
346
|
-
// 读取文本
|
|
347
|
-
const text = clipboard.readText()
|
|
348
|
-
|
|
349
|
-
// 写入文本
|
|
350
|
-
await clipboard.writeText('Hello World')
|
|
351
|
-
|
|
352
|
-
// 读取图片(返回 PNG Buffer)
|
|
353
|
-
const imageBuffer = clipboard.readImage()
|
|
354
|
-
|
|
355
|
-
// 写入图片
|
|
356
|
-
clipboard.writeImage(imageData)
|
|
370
|
+
> 📚 **完整 API 参考请查看 [`PLUGIN_API.md`](./PLUGIN_API.md)**
|
|
371
|
+
>
|
|
372
|
+
> 该文件会在创建插件时自动生成,包含全部 28 个 API 模块的详细说明。
|
|
357
373
|
|
|
358
|
-
|
|
359
|
-
const files = clipboard.readFiles()
|
|
360
|
-
// 返回: [{ path, name, size, isDirectory }]
|
|
361
|
-
|
|
362
|
-
// 获取剪贴板格式
|
|
363
|
-
const format = clipboard.getFormat()
|
|
364
|
-
// 返回: 'text' | 'image' | 'files' | 'empty'
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
#### 通知 API (notification)
|
|
374
|
+
#### 常用 API 快速示例
|
|
368
375
|
|
|
369
376
|
```typescript
|
|
370
|
-
|
|
377
|
+
// 剪贴板
|
|
378
|
+
const text = clipboard.readText()
|
|
379
|
+
await clipboard.writeText('Hello')
|
|
371
380
|
|
|
381
|
+
// 通知
|
|
372
382
|
notification.show('操作成功')
|
|
373
383
|
notification.show('发生错误', 'error')
|
|
374
|
-
// type: 'info' | 'success' | 'warning' | 'error'
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
#### 存储 API (storage)
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
const { storage } = context.api
|
|
381
384
|
|
|
382
|
-
//
|
|
383
|
-
await storage.set('key', {
|
|
384
|
-
|
|
385
|
-
// 读取数据
|
|
385
|
+
// 存储
|
|
386
|
+
await storage.set('key', { data: 'value' })
|
|
386
387
|
const data = await storage.get('key')
|
|
387
388
|
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
#### 网络 API (http)
|
|
393
|
-
|
|
394
|
-
```typescript
|
|
395
|
-
const { http } = context.api
|
|
389
|
+
// 文件系统
|
|
390
|
+
const content = filesystem.readFile('/path/file.txt', 'utf-8')
|
|
391
|
+
filesystem.writeFile('/path/output.txt', 'content', 'utf-8')
|
|
396
392
|
|
|
397
|
-
//
|
|
398
|
-
const response = await http.
|
|
399
|
-
url: 'https://api.example.com/data',
|
|
400
|
-
method: 'POST',
|
|
401
|
-
headers: { 'Authorization': 'Bearer token' },
|
|
402
|
-
body: { key: 'value' },
|
|
403
|
-
timeout: 5000
|
|
404
|
-
})
|
|
393
|
+
// HTTP 请求
|
|
394
|
+
const response = await http.post('https://api.example.com', { key: 'value' })
|
|
405
395
|
|
|
406
|
-
//
|
|
407
|
-
await
|
|
408
|
-
await http.post(url, body?, headers?)
|
|
409
|
-
await http.put(url, body?, headers?)
|
|
410
|
-
await http.delete(url, headers?)
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
#### 窗口 API (window)
|
|
414
|
-
|
|
415
|
-
```typescript
|
|
416
|
-
const { window } = context.api
|
|
417
|
-
|
|
418
|
-
// 设置窗口大小
|
|
419
|
-
await window.setSize(600, 400)
|
|
420
|
-
|
|
421
|
-
// 隐藏窗口
|
|
422
|
-
await window.hide()
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
#### 文件系统 API (filesystem)
|
|
426
|
-
|
|
427
|
-
```typescript
|
|
428
|
-
const { filesystem } = context.api
|
|
429
|
-
|
|
430
|
-
// 读写文件
|
|
431
|
-
const buffer = filesystem.readFile('/path/to/file.png')
|
|
432
|
-
const text = filesystem.readFile('/path/to/file.txt', 'utf-8')
|
|
433
|
-
filesystem.writeFile('/path/to/output.txt', 'content', 'utf-8')
|
|
434
|
-
|
|
435
|
-
// 文件操作
|
|
436
|
-
filesystem.exists('/path')
|
|
437
|
-
filesystem.unlink('/path')
|
|
438
|
-
filesystem.mkdir('/path')
|
|
439
|
-
filesystem.readdir('/path')
|
|
440
|
-
filesystem.stat('/path')
|
|
441
|
-
filesystem.copy(src, dest)
|
|
442
|
-
filesystem.move(src, dest)
|
|
443
|
-
|
|
444
|
-
// 路径工具
|
|
445
|
-
filesystem.extname('/file.txt') // '.txt'
|
|
446
|
-
filesystem.dirname('/path/file') // '/path'
|
|
447
|
-
filesystem.basename('/path/file.txt') // 'file.txt'
|
|
448
|
-
filesystem.join('/path', 'to', 'file')
|
|
396
|
+
// 对话框
|
|
397
|
+
const files = await dialog.showOpenDialog({ properties: ['openFile'] })
|
|
449
398
|
```
|
|
450
399
|
|
|
451
400
|
---
|
|
@@ -625,21 +574,34 @@ cd json-formatter
|
|
|
625
574
|
|
|
626
575
|
**src/main.ts:**
|
|
627
576
|
```typescript
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
try {
|
|
634
|
-
const obj = JSON.parse(text)
|
|
635
|
-
const formatted = JSON.stringify(obj, null, 2)
|
|
636
|
-
await clipboard.writeText(formatted)
|
|
637
|
-
notification.show('JSON 格式化成功')
|
|
638
|
-
} catch (e) {
|
|
639
|
-
notification.show('无效的 JSON', 'error')
|
|
577
|
+
interface PluginContext {
|
|
578
|
+
api: {
|
|
579
|
+
clipboard: {
|
|
580
|
+
readText: () => string
|
|
581
|
+
writeText: (text: string) => Promise<void>
|
|
640
582
|
}
|
|
583
|
+
notification: {
|
|
584
|
+
show: (message: string, type?: string) => void
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
input?: string
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
export async function run(context: PluginContext) {
|
|
591
|
+
const { clipboard, notification } = context.api
|
|
592
|
+
const text = context.input || clipboard.readText()
|
|
593
|
+
|
|
594
|
+
try {
|
|
595
|
+
const obj = JSON.parse(text)
|
|
596
|
+
const formatted = JSON.stringify(obj, null, 2)
|
|
597
|
+
await clipboard.writeText(formatted)
|
|
598
|
+
notification.show('JSON 格式化成功')
|
|
599
|
+
} catch (e) {
|
|
600
|
+
notification.show('无效的 JSON', 'error')
|
|
641
601
|
}
|
|
642
602
|
}
|
|
603
|
+
|
|
604
|
+
export default { run }
|
|
643
605
|
```
|
|
644
606
|
|
|
645
607
|
### 示例 2:翻译插件(带 UI)
|
|
@@ -674,16 +636,16 @@ npm install
|
|
|
674
636
|
|
|
675
637
|
**src/main.ts:**
|
|
676
638
|
```typescript
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
},
|
|
639
|
+
export function onLoad() {
|
|
640
|
+
console.log('翻译插件已加载')
|
|
641
|
+
}
|
|
681
642
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
}
|
|
643
|
+
export async function run() {
|
|
644
|
+
// UI 插件通常不需要在 run 中做太多事
|
|
645
|
+
// 主要逻辑在 UI 中处理
|
|
686
646
|
}
|
|
647
|
+
|
|
648
|
+
export default { onLoad, run }
|
|
687
649
|
```
|
|
688
650
|
|
|
689
651
|
**src/ui/App.tsx:**
|
|
@@ -768,13 +730,5 @@ A: 修改 `manifest.json` 中的 `version` 字段,重新打包后安装即可
|
|
|
768
730
|
|
|
769
731
|
### Q: 插件可以访问系统命令吗?
|
|
770
732
|
|
|
771
|
-
A:
|
|
772
|
-
|
|
773
|
-
---
|
|
774
|
-
|
|
775
|
-
## 相关文档
|
|
733
|
+
A: 前端通过 `window.intools.shell` 调用系统能力;后端运行在沙箱中,仅能使用 `context.api` 暴露的接口。具体能力以 `intools.d.ts` 为准。
|
|
776
734
|
|
|
777
|
-
- [InTools 插件开发规范](../../docs/plugin-spec.md)
|
|
778
|
-
- [InTools API 接口参考](../../docs/api-reference.md)
|
|
779
|
-
- [Manifest 规范 v2](../../docs/manifest-v2.md)
|
|
780
|
-
- [插件打包说明](../../docs/plugin-packaging.md)
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.copyDefaultIcon = copyDefaultIcon;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
function getAssetsDir() {
|
|
44
|
+
return path.resolve(__dirname, '../../../assets');
|
|
45
|
+
}
|
|
46
|
+
function copyDefaultIcon(targetDir) {
|
|
47
|
+
const defaultIconPath = path.join(getAssetsDir(), 'default-icon.png');
|
|
48
|
+
const targetIconPath = path.join(targetDir, 'icon.png');
|
|
49
|
+
if (fs.existsSync(defaultIconPath)) {
|
|
50
|
+
fs.copyFileSync(defaultIconPath, targetIconPath);
|
|
51
|
+
console.log(chalk_1.default.green(' ✓ icon.png'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createBasicProject = createBasicProject;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
const assets_1 = require("./assets");
|
|
44
|
+
const basic_1 = require("./templates/basic");
|
|
45
|
+
async function createBasicProject(targetDir, name) {
|
|
46
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
47
|
+
fs.mkdirSync(path.join(targetDir, 'src'));
|
|
48
|
+
(0, assets_1.copyDefaultIcon)(targetDir);
|
|
49
|
+
const manifest = (0, basic_1.buildBasicManifest)(name);
|
|
50
|
+
fs.writeJsonSync(path.join(targetDir, 'manifest.json'), manifest, { spaces: 2 });
|
|
51
|
+
console.log(chalk_1.default.green(' ✓ manifest.json'));
|
|
52
|
+
const pkg = (0, basic_1.buildBasicPackageJson)(name);
|
|
53
|
+
fs.writeJsonSync(path.join(targetDir, 'package.json'), pkg, { spaces: 2 });
|
|
54
|
+
console.log(chalk_1.default.green(' ✓ package.json'));
|
|
55
|
+
const mainTs = (0, basic_1.buildBasicMain)(name);
|
|
56
|
+
fs.writeFileSync(path.join(targetDir, 'src/main.ts'), mainTs);
|
|
57
|
+
console.log(chalk_1.default.green(' ✓ src/main.ts'));
|
|
58
|
+
// 复制 API 参考文档
|
|
59
|
+
const apiDocSrc = path.join(__dirname, '../../..', 'PLUGIN_API.md');
|
|
60
|
+
if (fs.existsSync(apiDocSrc)) {
|
|
61
|
+
fs.copyFileSync(apiDocSrc, path.join(targetDir, 'PLUGIN_API.md'));
|
|
62
|
+
console.log(chalk_1.default.green(' ✓ PLUGIN_API.md'));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.create = create;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
const basic_1 = require("./basic");
|
|
44
|
+
const react_1 = require("./react");
|
|
45
|
+
async function create(name, options) {
|
|
46
|
+
const targetDir = path.resolve(process.cwd(), name);
|
|
47
|
+
if (fs.existsSync(targetDir)) {
|
|
48
|
+
console.log(chalk_1.default.red(`错误: 目录 ${name} 已存在`));
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const template = options.template || 'react';
|
|
52
|
+
console.log(chalk_1.default.blue(`创建插件项目: ${name}`));
|
|
53
|
+
console.log(chalk_1.default.gray(`模板: ${template}`));
|
|
54
|
+
console.log();
|
|
55
|
+
if (template === 'react') {
|
|
56
|
+
await (0, react_1.createReactProject)(targetDir, name);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
await (0, basic_1.createBasicProject)(targetDir, name);
|
|
60
|
+
}
|
|
61
|
+
console.log();
|
|
62
|
+
console.log(chalk_1.default.green('插件创建成功!'));
|
|
63
|
+
console.log();
|
|
64
|
+
console.log('下一步:');
|
|
65
|
+
console.log(chalk_1.default.cyan(` cd ${name}`));
|
|
66
|
+
console.log(chalk_1.default.cyan(' npm install'));
|
|
67
|
+
console.log(chalk_1.default.cyan(' npm run dev'));
|
|
68
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createReactProject = createReactProject;
|
|
40
|
+
const fs = __importStar(require("fs-extra"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
43
|
+
const assets_1 = require("./assets");
|
|
44
|
+
const react_1 = require("./templates/react");
|
|
45
|
+
async function createReactProject(targetDir, name) {
|
|
46
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
47
|
+
fs.mkdirSync(path.join(targetDir, 'src'));
|
|
48
|
+
fs.mkdirSync(path.join(targetDir, 'src/ui'));
|
|
49
|
+
(0, assets_1.copyDefaultIcon)(targetDir);
|
|
50
|
+
createReactManifest(targetDir, name);
|
|
51
|
+
createReactPackageJson(targetDir, name);
|
|
52
|
+
createTsConfig(targetDir);
|
|
53
|
+
createViteConfig(targetDir);
|
|
54
|
+
createBackendMain(targetDir, name);
|
|
55
|
+
createReactUI(targetDir, name);
|
|
56
|
+
createIntoolsTypes(targetDir);
|
|
57
|
+
// 复制 API 参考文档
|
|
58
|
+
const apiDocSrc = path.join(__dirname, '../../..', 'PLUGIN_API.md');
|
|
59
|
+
if (fs.existsSync(apiDocSrc)) {
|
|
60
|
+
fs.copyFileSync(apiDocSrc, path.join(targetDir, 'PLUGIN_API.md'));
|
|
61
|
+
console.log(chalk_1.default.green(' ✓ PLUGIN_API.md'));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function createReactManifest(targetDir, name) {
|
|
65
|
+
const manifest = (0, react_1.buildReactManifest)(name);
|
|
66
|
+
fs.writeJsonSync(path.join(targetDir, 'manifest.json'), manifest, { spaces: 2 });
|
|
67
|
+
console.log(chalk_1.default.green(' ✓ manifest.json'));
|
|
68
|
+
}
|
|
69
|
+
function createReactPackageJson(targetDir, name) {
|
|
70
|
+
const pkg = (0, react_1.buildReactPackageJson)(name);
|
|
71
|
+
fs.writeJsonSync(path.join(targetDir, 'package.json'), pkg, { spaces: 2 });
|
|
72
|
+
console.log(chalk_1.default.green(' ✓ package.json'));
|
|
73
|
+
}
|
|
74
|
+
function createTsConfig(targetDir) {
|
|
75
|
+
const tsconfig = (0, react_1.buildTsConfig)();
|
|
76
|
+
fs.writeJsonSync(path.join(targetDir, 'tsconfig.json'), tsconfig, { spaces: 2 });
|
|
77
|
+
console.log(chalk_1.default.green(' ✓ tsconfig.json'));
|
|
78
|
+
}
|
|
79
|
+
function createViteConfig(targetDir) {
|
|
80
|
+
const viteConfig = (0, react_1.buildViteConfig)();
|
|
81
|
+
fs.writeFileSync(path.join(targetDir, 'vite.config.ts'), viteConfig);
|
|
82
|
+
console.log(chalk_1.default.green(' ✓ vite.config.ts'));
|
|
83
|
+
}
|
|
84
|
+
function createBackendMain(targetDir, name) {
|
|
85
|
+
const mainTs = (0, react_1.buildBackendMain)(name);
|
|
86
|
+
fs.writeFileSync(path.join(targetDir, 'src/main.ts'), mainTs);
|
|
87
|
+
console.log(chalk_1.default.green(' ✓ src/main.ts'));
|
|
88
|
+
}
|
|
89
|
+
function createReactUI(targetDir, name) {
|
|
90
|
+
fs.mkdirSync(path.join(targetDir, 'src/ui/hooks'), { recursive: true });
|
|
91
|
+
const indexHtml = (0, react_1.buildIndexHtml)(name);
|
|
92
|
+
fs.writeFileSync(path.join(targetDir, 'src/ui/index.html'), indexHtml);
|
|
93
|
+
console.log(chalk_1.default.green(' ✓ src/ui/index.html'));
|
|
94
|
+
const mainTsx = (0, react_1.buildMainTsx)();
|
|
95
|
+
fs.writeFileSync(path.join(targetDir, 'src/ui/main.tsx'), mainTsx);
|
|
96
|
+
console.log(chalk_1.default.green(' ✓ src/ui/main.tsx'));
|
|
97
|
+
const appTsx = (0, react_1.buildAppTsx)(name);
|
|
98
|
+
fs.writeFileSync(path.join(targetDir, 'src/ui/App.tsx'), appTsx);
|
|
99
|
+
console.log(chalk_1.default.green(' ✓ src/ui/App.tsx'));
|
|
100
|
+
const stylesCss = (0, react_1.buildStylesCss)();
|
|
101
|
+
fs.writeFileSync(path.join(targetDir, 'src/ui/styles.css'), stylesCss);
|
|
102
|
+
console.log(chalk_1.default.green(' ✓ src/ui/styles.css'));
|
|
103
|
+
const useIntools = (0, react_1.buildUseIntools)();
|
|
104
|
+
fs.writeFileSync(path.join(targetDir, 'src/ui/hooks/useIntools.ts'), useIntools);
|
|
105
|
+
console.log(chalk_1.default.green(' ✓ src/ui/hooks/useIntools.ts'));
|
|
106
|
+
}
|
|
107
|
+
function createIntoolsTypes(targetDir) {
|
|
108
|
+
fs.mkdirSync(path.join(targetDir, 'src/types'), { recursive: true });
|
|
109
|
+
const typesDts = (0, react_1.buildIntoolsTypes)();
|
|
110
|
+
fs.writeFileSync(path.join(targetDir, 'src/types/intools.d.ts'), typesDts);
|
|
111
|
+
console.log(chalk_1.default.green(' ✓ src/types/intools.d.ts'));
|
|
112
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildBasicManifest = buildBasicManifest;
|
|
4
|
+
exports.buildBasicPackageJson = buildBasicPackageJson;
|
|
5
|
+
exports.buildBasicMain = buildBasicMain;
|
|
6
|
+
function buildBasicManifest(name) {
|
|
7
|
+
return {
|
|
8
|
+
id: name,
|
|
9
|
+
name,
|
|
10
|
+
version: '1.0.0',
|
|
11
|
+
displayName: name,
|
|
12
|
+
description: '插件描述',
|
|
13
|
+
main: 'dist/main.js',
|
|
14
|
+
icon: 'icon.png',
|
|
15
|
+
// 独立窗口配置(可选)
|
|
16
|
+
// window: {
|
|
17
|
+
// width: 800, // 默认宽度
|
|
18
|
+
// height: 600, // 默认高度
|
|
19
|
+
// minWidth: 400, // 最小宽度
|
|
20
|
+
// minHeight: 300, // 最小高度
|
|
21
|
+
// maxWidth: 1200, // 最大宽度
|
|
22
|
+
// maxHeight: 900 // 最大高度
|
|
23
|
+
// },
|
|
24
|
+
features: [
|
|
25
|
+
{
|
|
26
|
+
code: 'main',
|
|
27
|
+
explain: '主功能',
|
|
28
|
+
cmds: [{ type: 'keyword', value: name }]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function buildBasicPackageJson(name) {
|
|
34
|
+
return {
|
|
35
|
+
name,
|
|
36
|
+
version: '1.0.0',
|
|
37
|
+
scripts: {
|
|
38
|
+
build: 'esbuild src/main.ts --bundle --platform=node --outfile=dist/main.js',
|
|
39
|
+
dev: 'intools dev',
|
|
40
|
+
pack: 'intools pack'
|
|
41
|
+
},
|
|
42
|
+
devDependencies: {
|
|
43
|
+
esbuild: '^0.20.0',
|
|
44
|
+
typescript: '^5.0.0'
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function buildBasicMain(name) {
|
|
49
|
+
return `interface PluginContext {
|
|
50
|
+
api: {
|
|
51
|
+
clipboard: {
|
|
52
|
+
readText: () => string
|
|
53
|
+
writeText: (text: string) => Promise<void>
|
|
54
|
+
readImage: () => ArrayBuffer | null
|
|
55
|
+
getFormat: () => string
|
|
56
|
+
}
|
|
57
|
+
notification: {
|
|
58
|
+
show: (message: string, type?: string) => void
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
input?: string
|
|
62
|
+
featureCode?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function onLoad() {
|
|
66
|
+
console.log('[${name}] 插件已加载')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function onUnload() {
|
|
70
|
+
console.log('[${name}] 插件已卸载')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function onEnable() {
|
|
74
|
+
console.log('[${name}] 插件已启用')
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function onDisable() {
|
|
78
|
+
console.log('[${name}] 插件已禁用')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function run(context: PluginContext) {
|
|
82
|
+
const { clipboard, notification } = context.api
|
|
83
|
+
const text = context.input || clipboard.readText()
|
|
84
|
+
|
|
85
|
+
// 在这里实现你的逻辑
|
|
86
|
+
const result = text.toUpperCase()
|
|
87
|
+
|
|
88
|
+
await clipboard.writeText(result)
|
|
89
|
+
notification.show('处理完成')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const plugin = { onLoad, onUnload, onEnable, onDisable, run }
|
|
93
|
+
export default plugin
|
|
94
|
+
`;
|
|
95
|
+
}
|