agent-publish-server 1.0.15 → 1.0.16

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 CHANGED
@@ -1,80 +1,292 @@
1
- ## agent-publish-server
1
+ # agent-publish-server
2
2
 
3
- > 这是一个基于 nodejs+express+http-proxy-middleware 的一款可支持代理的前端服务启动插件
3
+ [English](#english) | [中文](#chinese)
4
+
5
+ ---
6
+
7
+ ## <a id="english"></a>English
8
+
9
+ > A frontend service startup plugin based on nodejs+express+http-proxy-middleware with proxy support
10
+
11
+ ### Features
12
+
13
+ - 🚀 **Quick Start**: One-command startup for development server
14
+ - 🔄 **Proxy Support**: Built-in proxy middleware for API forwarding
15
+ - 📁 **Static File Serving**: Serve static files from any directory
16
+ - ⚙️ **Interactive Configuration**: Easy setup with interactive CLI
17
+ - 📝 **Access Logging**: Optional request logging with timestamps
18
+ - 🛡️ **Path Validation**: Automatic project path validation
19
+ - 🎯 **SPA Support**: Single Page Application routing support
4
20
 
5
- ## 安装
21
+ ### Installation
6
22
 
7
23
  ```bash
8
24
  npm install agent-publish-server -g
9
25
  ```
10
26
 
11
- ## 使用步骤
27
+ ### Quick Start
12
28
 
13
- ### 步骤 1:初始化配置文件
14
-
15
- 首先,初始化配置文件:
29
+ #### Method 1: Interactive Configuration (Recommended)
16
30
 
17
31
  ```bash
18
- agent-publish-server init
32
+ agent-publish-server -wp
19
33
  ```
20
34
 
21
- 这将在当前目录生成默认配置文件 `agent_config.json`。
35
+ This will guide you through an interactive setup:
36
+
37
+ 1. Enter port number
38
+ 2. Enter project directory (after build)
39
+ 3. Enter proxy configuration (format: `/api:http://localhost:3000`)
40
+ 4. Choose to continue adding proxies (1: continue, 0: finish)
41
+ 5. Generate `agent_config.json` and get startup command
42
+
43
+ #### Method 2: Manual Configuration
44
+
45
+ 1. **Initialize configuration file:**
22
46
 
23
- ### 步骤 2:自定义配置(可选)
47
+ ```bash
48
+ agent-publish-server init
49
+ ```
24
50
 
25
- 根据需要修改生成的 `agent_config.json` 配置文件。配置格式如下:
51
+ 2. **Edit the generated `agent_config.json`:**
26
52
 
27
53
  ```json
28
54
  {
29
- "port": 8080, // 端口号
30
- "dir": "./", // 静态文件目录
55
+ "port": 8080,
56
+ "dir": "./",
57
+ "log": true,
31
58
  "proxy": {
32
59
  "/api": {
33
- // 代理路径
34
- "target": "URL_ADDRESS", // 代理地址
35
- "changeOrigin": true, // 是否改变域名
60
+ "target": "http://localhost:3000",
61
+ "changeOrigin": true,
36
62
  "pathRewrite": {
37
- // 路径重写
38
- "^/api": "" // 重写后路径
63
+ "^/api": ""
39
64
  }
40
65
  }
41
66
  }
42
67
  }
43
68
  ```
44
69
 
45
- ### 步骤 3:启动服务
70
+ 3. **Start the server:**
71
+
72
+ ```bash
73
+ agent-publish-server -c ./agent_config.json
74
+ ```
75
+
76
+ ### Command Line Options
77
+
78
+ | Option | Description | Example |
79
+ | --------------------- | ------------------------------- | --------------------------------------- |
80
+ | `-wp, --write-proxy` | Interactive proxy configuration | `agent-publish-server -wp` |
81
+ | `-c, --config <path>` | Specify configuration file path | `agent-publish-server -c ./config.json` |
82
+ | `-p, --port <number>` | Override port number | `agent-publish-server -p 3000` |
83
+ | `-d, --dir <path>` | Override static directory | `agent-publish-server -d ./dist` |
84
+ | `--log <boolean>` | Enable/disable access logging | `agent-publish-server --log false` |
85
+ | `-v, --version` | Show version | `agent-publish-server -v` |
86
+ | `init` | Initialize configuration file | `agent-publish-server init` |
87
+
88
+ ### Configuration Schema
89
+
90
+ ```typescript
91
+ interface AgentConfig {
92
+ port?: number; // Server port (default: 8080)
93
+ dir?: string; // Static files directory (default: "./")
94
+ log?: boolean; // Enable access logging (default: true)
95
+ proxy?: {
96
+ // Proxy configurations
97
+ [path: string]: {
98
+ target: string; // Target URL
99
+ changeOrigin?: boolean; // Change origin header
100
+ pathRewrite?: {
101
+ // Path rewrite rules
102
+ [pattern: string]: string;
103
+ };
104
+ };
105
+ };
106
+ }
107
+ ```
108
+
109
+ ### Access Logging
110
+
111
+ Access logging is enabled by default and shows:
112
+
113
+ - Timestamp (ISO format)
114
+ - Client IP address
115
+ - HTTP method and URL
116
+ - User agent string
117
+
118
+ Example log output:
119
+
120
+ ```
121
+ [2025-08-27T11:02:48.854Z] ::1 "GET /" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
122
+ ```
123
+
124
+ To disable logging:
125
+
126
+ ```bash
127
+ agent-publish-server --log false
128
+ ```
129
+
130
+ ### Error Handling
131
+
132
+ - **Invalid project path**: Shows "项目路径错误" (Project path error) and exits
133
+ - **Invalid port**: Validates port numbers (1-65535)
134
+ - **Missing configuration**: Falls back to defaults
135
+
136
+ ### Use Cases
137
+
138
+ - **React/Vue Development**: Serve built applications with API proxying
139
+ - **Frontend Testing**: Quick static file serving with CORS handling
140
+ - **Local Development**: Proxy API calls to backend services
141
+ - **SPA Deployment**: Proper routing support for single-page applications
142
+
143
+ ---
144
+
145
+ ## <a id="chinese"></a>中文
146
+
147
+ > 这是一个基于 nodejs+express+http-proxy-middleware 的一款可支持代理的前端服务启动插件
148
+
149
+ ### 功能特性
150
+
151
+ - 🚀 **快速启动**: 一键启动开发服务器
152
+ - 🔄 **代理支持**: 内置代理中间件,支持 API 转发
153
+ - 📁 **静态文件服务**: 支持任意目录的静态文件托管
154
+ - ⚙️ **交互式配置**: 通过问答方式轻松配置
155
+ - 📝 **访问日志**: 可选的请求日志记录功能
156
+ - 🛡️ **路径验证**: 自动验证项目路径有效性
157
+ - 🎯 **SPA 支持**: 单页应用路由支持
158
+
159
+ ### 安装
160
+
161
+ ```bash
162
+ npm install agent-publish-server -g
163
+ ```
164
+
165
+ ### 快速开始
166
+
167
+ #### 方式一:交互式配置(推荐)
46
168
 
47
169
  ```bash
48
- agent-publish-server
170
+ agent-publish-server -wp
49
171
  ```
50
172
 
51
- ## 配置选项
173
+ 这将引导您完成交互式设置:
174
+
175
+ 1. 输入端口号
176
+ 2. 输入项目地址(打包后)
177
+ 3. 输入代理接口配置(格式:`/api:http://localhost:3000`)
178
+ 4. 选择是否继续添加代理(1:继续,0:结束)
179
+ 5. 生成 `agent_config.json` 并获得启动命令提示
180
+
181
+ #### 方式二:手动配置
182
+
183
+ 1. **初始化配置文件:**
52
184
 
53
- ### 指定配置文件
185
+ ```bash
186
+ agent-publish-server init
187
+ ```
54
188
 
55
- 你可以通过以下方式指定自定义配置文件路径:
189
+ 2. **编辑生成的 `agent_config.json`:**
190
+
191
+ ```json
192
+ {
193
+ "port": 8080,
194
+ "dir": "./",
195
+ "log": true,
196
+ "proxy": {
197
+ "/api": {
198
+ "target": "http://localhost:3000",
199
+ "changeOrigin": true,
200
+ "pathRewrite": {
201
+ "^/api": ""
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
56
207
 
57
- 1. 使用相对路径(相对于当前工作目录):
208
+ 3. **启动服务:**
58
209
 
59
210
  ```bash
60
211
  agent-publish-server -c ./agent_config.json
61
212
  ```
62
213
 
63
- 2. 使用绝对路径:
214
+ ### 命令行选项
215
+
216
+ | 选项 | 说明 | 示例 |
217
+ | --------------------- | ----------------- | --------------------------------------- |
218
+ | `-wp, --write-proxy` | 交互式代理配置 | `agent-publish-server -wp` |
219
+ | `-c, --config <路径>` | 指定配置文件路径 | `agent-publish-server -c ./config.json` |
220
+ | `-p, --port <端口>` | 覆盖端口号 | `agent-publish-server -p 3000` |
221
+ | `-d, --dir <目录>` | 覆盖静态文件目录 | `agent-publish-server -d ./dist` |
222
+ | `--log <布尔值>` | 启用/禁用访问日志 | `agent-publish-server --log false` |
223
+ | `-v, --version` | 显示版本 | `agent-publish-server -v` |
224
+ | `init` | 初始化配置文件 | `agent-publish-server init` |
225
+
226
+ ### 配置文件格式
227
+
228
+ ```typescript
229
+ interface AgentConfig {
230
+ port?: number; // 服务器端口(默认:8080)
231
+ dir?: string; // 静态文件目录(默认:"./")
232
+ log?: boolean; // 启用访问日志(默认:true)
233
+ proxy?: {
234
+ // 代理配置
235
+ [path: string]: {
236
+ target: string; // 目标URL
237
+ changeOrigin?: boolean; // 更改源头
238
+ pathRewrite?: {
239
+ // 路径重写规则
240
+ [pattern: string]: string;
241
+ };
242
+ };
243
+ };
244
+ }
245
+ ```
246
+
247
+ ### 访问日志
248
+
249
+ 访问日志默认启用,显示内容包括:
250
+
251
+ - 时间戳(ISO 格式)
252
+ - 客户端 IP 地址
253
+ - HTTP 方法和 URL
254
+ - 用户代理字符串
255
+
256
+ 日志输出示例:
257
+
258
+ ```
259
+ [2025-08-27T11:02:48.854Z] ::1 "GET /" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
260
+ ```
261
+
262
+ 禁用日志:
64
263
 
65
264
  ```bash
66
- agent-publish-server -c /path/to/agent_config.json
265
+ agent-publish-server --log false
67
266
  ```
68
267
 
69
- 支持的配置文件参数:
268
+ ### 错误处理
269
+
270
+ - **项目路径无效**:显示"项目路径错误"并退出
271
+ - **端口号无效**:验证端口号范围(1-65535)
272
+ - **配置缺失**:使用默认配置
273
+
274
+ ### 使用场景
275
+
276
+ - **React/Vue 开发**:为构建后的应用提供服务并代理 API
277
+ - **前端测试**:快速静态文件服务,处理跨域问题
278
+ - **本地开发**:代理 API 调用到后端服务
279
+ - **SPA 部署**:为单页应用提供正确的路由支持
280
+
281
+ ### 版本历史
282
+
283
+ - **v1.0.16**: 新增交互式配置、访问日志、路径验证功能
284
+ - **v1.0.15**: 基础代理和静态文件服务功能
285
+
286
+ ### 许可证
70
287
 
71
- - `-c`
72
- - `--config`
73
- - `--cf`
74
- - `--config-file`
288
+ MIT License
75
289
 
76
- ## 其他说明
290
+ ### 贡献
77
291
 
78
- - 适配 React、Vue 等前端框架
79
- - 使用 `-v` 或 `--version` 查看当前版本
80
- - 默认配置文件名为 `agent_config.json`
292
+ 欢迎提交 Issue Pull Request!
package/dist/cli.js CHANGED
@@ -1,11 +1,116 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
4
37
  const commander_1 = require("commander");
5
38
  const config_1 = require("./config");
6
39
  const server_1 = require("./server");
7
40
  const fs_1 = require("fs");
8
41
  const path_1 = require("path");
42
+ const readline = __importStar(require("readline"));
43
+ // 交互式配置函数
44
+ async function interactiveWriteProxyConfig() {
45
+ const rl = readline.createInterface({
46
+ input: process.stdin,
47
+ output: process.stdout
48
+ });
49
+ const question = (prompt) => {
50
+ return new Promise((resolve) => {
51
+ rl.question(prompt, resolve);
52
+ });
53
+ };
54
+ try {
55
+ // 询问端口号
56
+ const portInput = await question('请输入端口号: ');
57
+ const port = parseInt(portInput.trim(), 10);
58
+ if (isNaN(port) || port <= 0 || port > 65535) {
59
+ throw new Error('无效的端口号,请输入1-65535之间的数字');
60
+ }
61
+ // 询问项目地址
62
+ const dirInput = await question('请输入项目地址(打包后): ');
63
+ const dir = dirInput.trim() || './';
64
+ const config = {
65
+ port,
66
+ dir,
67
+ proxy: {},
68
+ log: true // 默认启用日志
69
+ };
70
+ // 循环添加代理配置
71
+ while (true) {
72
+ const proxyInput = await question('请输入代理接口(格式例如:/api:http://localhost:3000): ');
73
+ const proxyStr = proxyInput.trim();
74
+ if (proxyStr) {
75
+ const parts = proxyStr.split(':');
76
+ if (parts.length < 2) {
77
+ console.log('格式错误,请按照 /api:http://localhost:3000 的格式输入');
78
+ continue;
79
+ }
80
+ const path = parts[0].trim();
81
+ const target = parts.slice(1).join(':'); // 处理URL中的冒号
82
+ if (!path.startsWith('/')) {
83
+ console.log('代理路径必须以 / 开头');
84
+ continue;
85
+ }
86
+ if (!target.startsWith('http://') && !target.startsWith('https://')) {
87
+ console.log('代理目标地址必须是完整的URL(以http://或https://开头)');
88
+ continue;
89
+ }
90
+ config.proxy[path] = {
91
+ target: target,
92
+ changeOrigin: true,
93
+ pathRewrite: {
94
+ [`^${path}`]: ''
95
+ }
96
+ };
97
+ console.log(`✓ 已添加代理:${path} -> ${target}`);
98
+ }
99
+ const continueInput = await question('是否继续添加代理接口:1:继续,0:结束: ');
100
+ if (continueInput.trim() === '0') {
101
+ break;
102
+ }
103
+ else if (continueInput.trim() !== '1') {
104
+ console.log('请输入 1 继续或 0 结束');
105
+ continue;
106
+ }
107
+ }
108
+ return config;
109
+ }
110
+ finally {
111
+ rl.close();
112
+ }
113
+ }
9
114
  const program = new commander_1.Command();
10
115
  const packageJson = require('../package.json');
11
116
  program
@@ -14,11 +119,30 @@ program
14
119
  .option('--cf <path>', '配置文件路径')
15
120
  .option('--config-file <path>', '配置文件路径')
16
121
  .option('-p, --port <number>', '服务器端口号')
17
- .option('-d, --dir <path>', '静态文件目录路径');
122
+ .option('-d, --dir <path>', '静态文件目录路径')
123
+ .option('-wp, --write-proxy', '交互式配置代理服务')
124
+ .option('--log <boolean>', '是否显示访问日志 (true/false),默认为true');
18
125
  // 添加一个默认命令,用于处理没有指定任何子命令的情况
19
126
  program
20
- .action(() => {
127
+ .action(async () => {
21
128
  const options = program.opts();
129
+ // 检查是否使用 -wp 选项
130
+ if (options.writeProxy) {
131
+ try {
132
+ console.log('✨ 欢迎使用交互式代理配置\n');
133
+ // 交互式配置
134
+ const config = await interactiveWriteProxyConfig();
135
+ const configPath = (0, path_1.join)(process.cwd(), 'agent_config.json');
136
+ (0, fs_1.writeFileSync)(configPath, JSON.stringify(config, null, 2));
137
+ console.log('\n✓ 已配置完成,请运行:agent-publish-server -c ./agent_config.json');
138
+ process.exit(0);
139
+ }
140
+ catch (error) {
141
+ const errorMessage = error instanceof Error ? error.message : String(error);
142
+ console.error('\n✗ 配置失败:', errorMessage);
143
+ process.exit(1);
144
+ }
145
+ }
22
146
  // 加载配置
23
147
  const config = (0, config_1.loadConfig)(options);
24
148
  // 命令行参数优先级高于配置文件
@@ -33,6 +157,20 @@ program
33
157
  if (options.dir) {
34
158
  config.dir = options.dir;
35
159
  }
160
+ // 处理日志参数
161
+ if (options.log !== undefined) {
162
+ const logValue = options.log.toLowerCase();
163
+ if (logValue === 'true') {
164
+ config.log = true;
165
+ }
166
+ else if (logValue === 'false') {
167
+ config.log = false;
168
+ }
169
+ else {
170
+ console.error('日志参数必须是 true 或 false');
171
+ process.exit(1);
172
+ }
173
+ }
36
174
  // 启动服务器
37
175
  (0, server_1.startServer)(config).catch((error) => {
38
176
  console.error('Server failed to start:', error);
package/dist/server.js CHANGED
@@ -12,6 +12,24 @@ const fs_1 = __importDefault(require("fs"));
12
12
  function createServer(config) {
13
13
  const app = (0, express_1.default)();
14
14
  const staticDir = config.dir || './';
15
+ const enableLog = config.log !== false; // 默认为true
16
+ // 检查项目路径是否存在
17
+ const absoluteStaticDir = path_1.default.resolve(process.cwd(), staticDir);
18
+ if (!fs_1.default.existsSync(absoluteStaticDir)) {
19
+ throw new Error('项目路径错误');
20
+ }
21
+ // 添加日志中间件
22
+ if (enableLog) {
23
+ app.use((req, res, next) => {
24
+ const timestamp = new Date().toISOString();
25
+ const method = req.method;
26
+ const url = req.url;
27
+ const userAgent = req.get('User-Agent') || '-';
28
+ const ip = req.ip || req.connection.remoteAddress || '-';
29
+ console.log(`[${timestamp}] ${ip} "${method} ${url}" "${userAgent}"`);
30
+ next();
31
+ });
32
+ }
15
33
  // 配置代理
16
34
  if (config.proxy) {
17
35
  Object.entries(config.proxy).forEach(([path, proxyConfig]) => {
@@ -46,18 +64,25 @@ function createServer(config) {
46
64
  return app;
47
65
  }
48
66
  function startServer(config) {
49
- const app = createServer(config);
50
- const port = config.port || 8080;
51
- return new Promise((resolve, reject) => {
52
- try {
53
- app.listen(port, () => {
54
- console.log(`Server is running at http://localhost:${port}`);
55
- resolve();
56
- });
57
- }
58
- catch (error) {
59
- console.error('Failed to start server:', error);
60
- reject(error);
61
- }
62
- });
67
+ try {
68
+ const app = createServer(config);
69
+ const port = config.port || 8080;
70
+ return new Promise((resolve, reject) => {
71
+ try {
72
+ app.listen(port, () => {
73
+ console.log(`Server is running at http://localhost:${port}`);
74
+ resolve();
75
+ });
76
+ }
77
+ catch (error) {
78
+ console.error('Failed to start server:', error);
79
+ reject(error);
80
+ }
81
+ });
82
+ }
83
+ catch (error) {
84
+ const errorMessage = error instanceof Error ? error.message : String(error);
85
+ console.error(errorMessage);
86
+ process.exit(1);
87
+ }
63
88
  }
package/dist/types.d.ts CHANGED
@@ -7,6 +7,7 @@ export interface AgentConfig {
7
7
  port?: number;
8
8
  dir?: string;
9
9
  proxy?: Record<string, ProxyConfig>;
10
+ log?: boolean;
10
11
  }
11
12
  export interface CommandOptions {
12
13
  config?: string;
@@ -15,4 +16,6 @@ export interface CommandOptions {
15
16
  configFile?: string;
16
17
  port?: string;
17
18
  dir?: string;
19
+ writeProxy?: boolean;
20
+ log?: string;
18
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-publish-server",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "基于 nodejs+express+http-proxy-middleware 的前端服务启动插件",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",