cloud-function-cli 1.0.1 → 1.1.0
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 +70 -9
- package/dist/cli/login.js +12 -2
- package/dist/index.js +2 -1
- package/dist/utils/config.js +23 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,37 @@ yarn global add cloud-function-cli
|
|
|
28
28
|
pnpm add -g cloud-function-cli
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## 🧰 在项目中使用(推荐)
|
|
32
|
+
|
|
33
|
+
如果你不想全局安装,推荐把它安装为项目依赖,并通过 `npx` / `pnpm exec` 来调用(会自动从 `node_modules/.bin` 解析到 `cf` 命令)。
|
|
34
|
+
|
|
35
|
+
### npm
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm i -D cloud-function-cli
|
|
39
|
+
|
|
40
|
+
npx cf login
|
|
41
|
+
npx cf create user/hello
|
|
42
|
+
npx cf list
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### pnpm
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pnpm add -D cloud-function-cli
|
|
49
|
+
|
|
50
|
+
pnpm exec cf login
|
|
51
|
+
pnpm exec cf create user/hello
|
|
52
|
+
pnpm exec cf list
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 临时执行(不安装到项目)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pnpm dlx cloud-function-cli cf login
|
|
59
|
+
pnpm dlx cloud-function-cli cf create user/hello
|
|
60
|
+
```
|
|
61
|
+
|
|
31
62
|
## 🚀 快速开始
|
|
32
63
|
|
|
33
64
|
### 1. 登录
|
|
@@ -209,30 +240,60 @@ cf list user --env prod
|
|
|
209
240
|
|
|
210
241
|
## ⚙️ 配置
|
|
211
242
|
|
|
212
|
-
|
|
243
|
+
配置优先级(从高到低):
|
|
244
|
+
1. 项目根目录 `cf.config.json`
|
|
245
|
+
2. 环境变量 `BASE_URL`
|
|
246
|
+
3. 用户目录 `~/.cloud-function/config.json`(登录后自动生成)
|
|
247
|
+
4. 默认值 `http://localhost:3000`
|
|
248
|
+
|
|
249
|
+
### 1) 项目配置文件(推荐)
|
|
250
|
+
|
|
251
|
+
在你的项目根目录创建 `cf.config.json`:
|
|
213
252
|
|
|
214
253
|
```json
|
|
215
254
|
{
|
|
216
|
-
"apiBaseUrl": "
|
|
217
|
-
"token": "your-jwt-token-here",
|
|
218
|
-
"username": "admin",
|
|
255
|
+
"apiBaseUrl": "https://your-server.com",
|
|
219
256
|
"environment": "dev"
|
|
220
257
|
}
|
|
221
258
|
```
|
|
222
259
|
|
|
223
|
-
|
|
260
|
+
之后在该项目内执行(本地安装时用 `pnpm exec` / `npx`):
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
pnpm exec cf login
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 2) 登录时直接指定
|
|
224
267
|
|
|
225
|
-
|
|
268
|
+
```bash
|
|
269
|
+
cf login --api https://your-server.com
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### 3) 用户目录配置文件(自动生成)
|
|
273
|
+
|
|
274
|
+
登录成功后,会在用户目录下创建 `.cloud-function/config.json`:
|
|
226
275
|
|
|
227
276
|
```json
|
|
228
277
|
{
|
|
229
|
-
"apiBaseUrl": "
|
|
278
|
+
"apiBaseUrl": "http://localhost:3000",
|
|
279
|
+
"token": "your-jwt-token-here",
|
|
280
|
+
"username": "admin",
|
|
281
|
+
"environment": "dev"
|
|
230
282
|
}
|
|
231
283
|
```
|
|
232
284
|
|
|
233
|
-
|
|
285
|
+
### 4) 环境变量
|
|
286
|
+
|
|
234
287
|
```bash
|
|
235
|
-
export
|
|
288
|
+
export BASE_URL="https://your-server.com"
|
|
289
|
+
cf login
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Windows PowerShell:
|
|
293
|
+
|
|
294
|
+
```powershell
|
|
295
|
+
$env:BASE_URL="https://your-server.com"
|
|
296
|
+
cf login
|
|
236
297
|
```
|
|
237
298
|
|
|
238
299
|
## 🏗️ API 模板结构
|
package/dist/cli/login.js
CHANGED
|
@@ -8,7 +8,11 @@ const inquirer_1 = __importDefault(require("inquirer"));
|
|
|
8
8
|
const apiClient_1 = require("../services/apiClient");
|
|
9
9
|
const config_1 = require("../utils/config");
|
|
10
10
|
const logger_1 = require("../utils/logger");
|
|
11
|
-
const login = async () => {
|
|
11
|
+
const login = async (options) => {
|
|
12
|
+
const apiBaseUrl = options?.api?.trim();
|
|
13
|
+
if (apiBaseUrl) {
|
|
14
|
+
config_1.config.set({ apiBaseUrl });
|
|
15
|
+
}
|
|
12
16
|
const answers = await inquirer_1.default.prompt([
|
|
13
17
|
{
|
|
14
18
|
type: 'input',
|
|
@@ -30,7 +34,13 @@ const login = async () => {
|
|
|
30
34
|
logger_1.logger.success('Login successful!');
|
|
31
35
|
}
|
|
32
36
|
catch (error) {
|
|
33
|
-
|
|
37
|
+
const cfg = config_1.config.get();
|
|
38
|
+
const status = error.response?.status;
|
|
39
|
+
const statusText = error.response?.statusText;
|
|
40
|
+
const details = error.response?.data?.error || error.response?.data?.message || error.message;
|
|
41
|
+
const statusPart = status ? ` (HTTP ${status}${statusText ? ` ${statusText}` : ''})` : '';
|
|
42
|
+
logger_1.logger.error(`Login failed${statusPart}: ${details}`);
|
|
43
|
+
logger_1.logger.error(`apiBaseUrl: ${cfg.apiBaseUrl}`);
|
|
34
44
|
}
|
|
35
45
|
};
|
|
36
46
|
exports.login = login;
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,8 @@ program
|
|
|
17
17
|
program
|
|
18
18
|
.command('login')
|
|
19
19
|
.description('Login to the system')
|
|
20
|
-
.
|
|
20
|
+
.option('--api <url>', 'API base URL (e.g., http://localhost:3000)')
|
|
21
|
+
.action((options) => (0, login_1.login)(options));
|
|
21
22
|
program
|
|
22
23
|
.command('create <name>')
|
|
23
24
|
.description('Create a new API (e.g., group/api)')
|
package/dist/utils/config.js
CHANGED
|
@@ -9,27 +9,29 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const os_1 = __importDefault(require("os"));
|
|
10
10
|
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.cloud-function');
|
|
11
11
|
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
12
|
+
const PROJECT_CONFIG_FILE = path_1.default.join(process.cwd(), 'cf.config.json');
|
|
12
13
|
const defaultConfig = {
|
|
13
14
|
apiBaseUrl: 'http://localhost:3000',
|
|
14
15
|
environment: 'dev'
|
|
15
16
|
};
|
|
16
17
|
exports.config = {
|
|
17
18
|
get: () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
const globalConfig = readJsonFile(CONFIG_FILE);
|
|
20
|
+
const projectConfig = readJsonFile(PROJECT_CONFIG_FILE);
|
|
21
|
+
const envApiBaseUrl = process.env.BASE_URL?.trim() || process.env.CLOUD_FUNCTION_API_BASE_URL?.trim();
|
|
22
|
+
const envConfig = envApiBaseUrl ? { apiBaseUrl: envApiBaseUrl } : {};
|
|
23
|
+
return {
|
|
24
|
+
...defaultConfig,
|
|
25
|
+
...globalConfig,
|
|
26
|
+
...envConfig,
|
|
27
|
+
...projectConfig
|
|
28
|
+
};
|
|
27
29
|
},
|
|
28
30
|
set: (newConfig) => {
|
|
29
31
|
if (!fs_1.default.existsSync(CONFIG_DIR)) {
|
|
30
32
|
fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
31
33
|
}
|
|
32
|
-
const current =
|
|
34
|
+
const current = { ...defaultConfig, ...readJsonFile(CONFIG_FILE) };
|
|
33
35
|
fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify({ ...current, ...newConfig }, null, 2));
|
|
34
36
|
},
|
|
35
37
|
clear: () => {
|
|
@@ -38,3 +40,14 @@ exports.config = {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
};
|
|
43
|
+
const readJsonFile = (filePath) => {
|
|
44
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(fs_1.default.readFileSync(filePath, 'utf-8'));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
};
|