mini-upload 0.0.1

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 ADDED
@@ -0,0 +1,116 @@
1
+ # mini-upload
2
+
3
+ 微信小程序 CI 上传工具,支持通过命令行上传小程序代码到体验版。
4
+ 暂不支持需要 npm 构建项目
5
+
6
+ ## 安装
7
+
8
+ ```bash
9
+ npm install mini-upload -g
10
+ ```
11
+
12
+ ## 快速开始
13
+
14
+ ### 1. 创建配置文件
15
+
16
+ 在小程序项目根目录创建 `mini.config.ts`:
17
+
18
+ ```typescript
19
+ import { defineConfig } from "mini-upload";
20
+
21
+ export default defineConfig({
22
+ keyDirectory: "./keys",
23
+ version: "1.0.0",
24
+ desc: "版本描述",
25
+ setting: {},
26
+ });
27
+ ```
28
+
29
+ ### 2. 放置密钥文件
30
+
31
+ 在 `keys` 目录下放置小程序上传密钥,命名格式:`private.{appid}.key`
32
+
33
+ ```
34
+ 项目根目录/
35
+ ├── mini.config.ts
36
+ ├── keys/
37
+ │ └── private.wx1234567890.key
38
+ ├── pages/
39
+ └── app.json
40
+ ```
41
+
42
+ > 密钥获取:微信公众平台 → 开发 → 开发管理 → 开发设置 → 小程序代码上传
43
+
44
+ ### 3. 上传代码
45
+
46
+ ```bash
47
+ npx mini-upload upload
48
+ ```
49
+
50
+ ## 配置选项
51
+
52
+ | 选项 | 类型 | 必填 | 说明 |
53
+ | ---------------- | -------- | ---- | -------------------------------------------------------------------------------- |
54
+ | `appid` | `string` | 否 | 小程序 AppID,不配置则从密钥文件名自动获取 |
55
+ | `keyDirectory` | `string` | 是 | 密钥文件夹路径 |
56
+ | `privateKeyName` | `string` | 否 | 密钥文件名,默认 `private.{appid}.key` |
57
+ | `version` | `string` | 否 | 版本号,默认 `1.0.0` |
58
+ | `desc` | `string` | 否 | 版本描述 |
59
+ | `robot` | `number` | 否 | CI 机器人编号 (1-30),默认 `1` |
60
+ | `type` | `string` | 否 | 项目类型:`miniProgram` \| `miniProgramPlugin` \| `miniGame` \| `miniGamePlugin` |
61
+ | `setting` | `object` | 否 | 编译设置 |
62
+
63
+ ### setting 编译设置
64
+
65
+ ```typescript
66
+ export default defineConfig({
67
+ keyDirectory: "./keys",
68
+ version: "1.0.0",
69
+ setting: {
70
+ es6: true, // ES6 转 ES5
71
+ es7: true, // 增强编译
72
+ minify: true, // 压缩代码
73
+ minifyJS: true, // 压缩 JS
74
+ minifyWXML: true, // 压缩 WXML
75
+ minifyWXSS: true, // 压缩 WXSS
76
+ autoPrefixWXSS: true, // 样式自动补全
77
+ codeProtect: false, // 代码保护
78
+ },
79
+ });
80
+ ```
81
+
82
+ ## CLI 命令
83
+
84
+ ```bash
85
+ # 上传代码
86
+ mini-upload upload
87
+
88
+ # 查看帮助
89
+ mini-upload --help
90
+ ```
91
+
92
+ ## 多小程序上传
93
+
94
+ 如果 `keys` 目录下有多个密钥文件,会自动循环上传所有小程序:
95
+
96
+ ```
97
+ keys/
98
+ ├── private.wx1111111111.key
99
+ ├── private.wx2222222222.key
100
+ └── private.wx3333333333.key
101
+ ```
102
+
103
+ ```bash
104
+ mini-upload upload
105
+ # 将依次上传 wx1111111111、wx2222222222、wx3333333333
106
+ ```
107
+
108
+ ## 注意事项
109
+
110
+ - 小程序项目路径为 `mini.config.ts` 所在目录
111
+ - 密钥文件请勿提交到版本控制,建议添加到 `.gitignore`
112
+ - 上传前请确保项目可以在微信开发者工具中正常编译
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,3 @@
1
+ import { MiniConfig, defineConfig } from './types.js';
2
+ export { defineConfig };
3
+ export type { MiniConfig };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import*as o from"fs";import*as e from"path";import{createJiti as n}from"jiti";import r from"miniprogram-ci";function t(o){return o}async function i(o){const n=new r.Project({appid:o.appid,type:o.type||"miniProgram",projectPath:e.resolve(o.projectPath),privateKeyPath:o.privateKeyPath,ignores:["node_modules/**/*"]});console.log("正在上传代码...");const t=await r.upload({project:n,version:o.version||"1.0.0",desc:o.desc||"upload via miniprogram-ci",robot:o.robot||1,setting:o.setting||{es6:!0,minify:!0}});console.log("✅ 上传成功!"),console.log(t)}async function c(o){console.log("正在创建项目实例..."),console.log(` AppID: ${o.appid}`),console.log(` 项目路径: ${e.resolve(o.projectPath)}`),console.log(` 密钥路径: ${o.privateKeyPath}`);const n=new r.Project({appid:o.appid,type:o.type||"miniProgram",projectPath:e.resolve(o.projectPath),privateKeyPath:o.privateKeyPath,ignores:["node_modules/**/*"]}),t=o.qrcodeOutputPath||`./preview-qrcode-${o.appid}.jpg`;console.log("正在生成预览..."),console.log(` 版本: ${o.version||"1.0.0"}`),console.log(` 描述: ${o.desc||"preview via miniprogram-ci"}`),console.log(` 机器人: ${o.robot||1}`),console.log(` 二维码输出: ${t}`);const i=await r.preview({project:n,version:o.version||"1.0.0",desc:o.desc||"preview via miniprogram-ci",robot:o.robot||1,qrcodeFormat:"image",qrcodeOutputDest:t,setting:{es6:!0}});console.log("✅ 预览成功! 二维码已保存至:",t),console.log(i)}const s=/^private\.(.+)\.key$/;function p(o){const e=o.match(s);return e?e[1]:null}function a(n,r){const t=[];if(n.appid){const i=e.resolve(n.keyDirectory,n.privateKeyName||`private.${n.appid}.key`);if(!o.existsSync(i))return console.error(`❌ 密钥文件不存在: ${i}`),[];t.push({...n,appid:n.appid,privateKeyPath:i,projectPath:r})}else{const i=function(n){const r=e.resolve(n);if(!o.existsSync(r))return console.error(`❌ 密钥目录不存在: ${r}`),[];const t=o.readdirSync(r),i=[];for(const o of t){const n=p(o);n&&i.push({appid:n,keyPath:e.join(r,o)})}return i}(n.keyDirectory);if(0===i.length)return console.error(`❌ 在 ${n.keyDirectory} 目录下未找到有效的密钥文件`),console.error("密钥文件命名格式: private.{appid}.key"),[];console.log(`📁 找到 ${i.length} 个密钥文件:`);for(const o of i)console.log(` - ${o.appid}`),t.push({...n,appid:o.appid,privateKeyPath:o.keyPath,projectPath:r})}return t}const l="1.0.0";!async function(){const r=function(){const o=process.argv.slice(2),e={action:"upload"};if(0===o.length)return e.action="help",e;const n=o[0];if("upload"===n||"preview"===n)e.action=n;else{if("help"===n||"-h"===n||"--help"===n)return e.action="help",e;if("version"===n||"-v"===n||"--version"===n){if("--version"!==n||!o[1])return e.action="version",e;e.version=o[1]}}for(let r=1;r<o.length;r++){const n=o[r],t=o[r+1];switch(n){case"--version":e.version=t,r++;break;case"--desc":case"-d":e.desc=t,r++;break;case"-h":case"--help":return e.action="help",e}}return e}();if("help"===r.action)return void console.log(`\n微信小程序 CI 上传工具 v${l}\n\n用法:\n mini-upload <command> [options]\n\n命令:\n upload 上传代码到体验版\n preview 生成预览二维码\n help 显示帮助信息\n version 显示版本号\n\n选项:\n --version <v> 指定版本号\n --desc <desc> 指定版本描述\n -h, --help 显示帮助信息\n -v 显示版本号\n\n示例:\n mini-upload upload # 上传\n mini-upload preview # 生成预览\n mini-upload upload --version 1.2.0 # 指定版本号上传\n mini-upload upload --desc "新功能" # 指定描述上传\n\n配置文件:\n 在项目根目录创建 mini.config.ts 文件配置 appid、密钥目录等\n\n密钥文件:\n 放置在 keyDirectory 指定的目录下\n 命名格式: private.{appid}.key\n 如果不配置 appid,将自动从密钥文件名获取\n 支持多个密钥文件,会循环执行上传\n`);if("version"===r.action)return void console.log(`mini-upload v${l}`);console.log("🚀 微信小程序 CI 工具"),console.log("=".repeat(40)),console.log(`操作: ${r.action}`);const{config:t,projectPath:s}=await async function(){const r=process.cwd(),t=["mini.config.ts","mini.config.js"],i=n(import.meta.url);for(const n of t){const t=e.resolve(r,n);if(o.existsSync(t))try{const o=await i.import(t);return{config:o.default||o,projectPath:r}}catch(c){console.error(`❌ 加载配置文件 ${n} 失败:`,c),process.exit(1)}}console.error("❌ 未找到配置文件"),console.error(`请在 ${r} 下创建 mini.config.ts 或 mini.config.js`),process.exit(1)}();!function(n){n.keyDirectory||(console.error("❌ 配置错误: 未配置 keyDirectory"),console.error("请在 mini.config.ts 中配置 keyDirectory 字段,指定密钥文件夹路径"),process.exit(1));const r=e.resolve(process.cwd(),n.keyDirectory);o.existsSync(r)||(console.error("❌ 配置错误: keyDirectory 目录不存在"),console.error(` 配置路径: ${n.keyDirectory}`),console.error(` 解析路径: ${r}`),console.error("请确保密钥目录存在,或修改 mini.config.ts 中的 keyDirectory 配置"),process.exit(1))}(t);const p=a(function(o,e){const n={...o};return e.version&&(n.version=e.version),e.desc&&(n.desc=e.desc),n}(t,r),s);console.log(`项目路径: ${s}`),0===p.length&&(console.error("❌ 没有找到有效的配置"),process.exit(1)),console.log("=".repeat(40));try{await async function(o,e){const n=e.length;let r=0,t=0;for(let p=0;p<e.length;p++){const a=e[p];console.log(`\n[${p+1}/${n}] 正在处理: ${a.appid}`),console.log("-".repeat(40));try{"upload"===o?await i(a):await c(a),r++}catch(s){console.error(`❌ ${a.appid} 操作失败:`,s),t++}}console.log("\n"+"=".repeat(40)),console.log(`📊 执行结果: 成功 ${r}, 失败 ${t}, 总计 ${n}`)}(r.action,p)}catch(d){console.error("❌ 操作失败:",d),process.exit(1)}}();export{t as defineConfig};
@@ -0,0 +1,2 @@
1
+ import { ResolvedConfig } from './types.js';
2
+ export declare function preview(config: ResolvedConfig): Promise<void>;
@@ -0,0 +1,29 @@
1
+ interface WXUploadSetting {
2
+ es6?: boolean;
3
+ es7?: boolean;
4
+ minify?: boolean;
5
+ minifyJS?: boolean;
6
+ minifyWXML?: boolean;
7
+ minifyWXSS?: boolean;
8
+ autoPrefixWXSS?: boolean;
9
+ codeProtect?: boolean;
10
+ }
11
+ export interface MiniConfig {
12
+ appid?: string;
13
+ type?: 'miniProgram' | 'miniProgramPlugin' | 'miniGame' | 'miniGamePlugin';
14
+ keyDirectory: string;
15
+ privateKeyName?: string;
16
+ version?: string;
17
+ desc?: string;
18
+ robot?: number;
19
+ qrcodeOutputPath?: string;
20
+ setting?: WXUploadSetting;
21
+ }
22
+ export interface ResolvedConfig extends MiniConfig {
23
+ appid: string;
24
+ privateKeyPath: string;
25
+ projectPath: string;
26
+ }
27
+ export type UserConfig = MiniConfig;
28
+ export declare function defineConfig(config: UserConfig): UserConfig;
29
+ export {};
@@ -0,0 +1,2 @@
1
+ import { ResolvedConfig } from './types.js';
2
+ export declare function upload(config: ResolvedConfig): Promise<void>;
@@ -0,0 +1,20 @@
1
+ import { MiniConfig, ResolvedConfig } from './types.js';
2
+ /**
3
+ * 从密钥文件名中提取 appid
4
+ */
5
+ export declare function extractAppidFromKeyFile(filename: string): string | null;
6
+ /**
7
+ * 扫描密钥目录,获取所有密钥文件信息
8
+ */
9
+ export declare function scanKeyFiles(keyDirectory: string): Array<{
10
+ appid: string;
11
+ keyPath: string;
12
+ }>;
13
+ /**
14
+ * 解析配置,返回需要执行的配置列表
15
+ * - 如果配置了 appid,返回单个配置
16
+ * - 如果没有配置 appid,从密钥目录扫描所有密钥文件
17
+ * @param config 用户配置
18
+ * @param projectPath 项目路径(配置文件所在目录)
19
+ */
20
+ export declare function resolveConfigs(config: MiniConfig, projectPath: string): ResolvedConfig[];
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "mini-upload",
3
+ "version": "0.0.1",
4
+ "description": "微信小程序 CI 上传工具",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "author": {
8
+ "name": "awumiao"
9
+ },
10
+ "bin": {
11
+ "mini-upload": "dist/index.js"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "vite build",
19
+ "upload": "npm run build && node dist/index.js upload"
20
+ },
21
+ "dependencies": {
22
+ "jiti": "^2.6.1",
23
+ "miniprogram-ci": "^1.9.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.0.0",
27
+ "typescript": "^5.0.0",
28
+ "vite": "^7.3.1",
29
+ "vite-plugin-dts": "^4.5.4"
30
+ }
31
+ }