cloud-function-cli 1.0.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 ADDED
@@ -0,0 +1,299 @@
1
+ # Cloud Function CLI
2
+
3
+ 一个强大的命令行工具,用于管理云函数系统 API 的创建、部署和版本控制。
4
+
5
+ [![npm version](https://badge.fury.io/js/cloud-function-cli.svg)](https://www.npmjs.com/package/cloud-function-cli)
6
+ [![License](https://img.shields.io/npm/l/cloud-function-cli.svg)](LICENSE)
7
+
8
+ ## ✨ 特性
9
+
10
+ - 🚀 快速创建 API 接口模板
11
+ - 📤 一键部署到服务器
12
+ - 📥 从服务器拉取 API 代码
13
+ - 📜 版本历史查看
14
+ - 🔄 版本回滚
15
+ - 🔐 安全的 JWT 认证
16
+ - 🎯 支持多环境(dev/prod)
17
+
18
+ ## 📦 安装
19
+
20
+ ```bash
21
+ # 全局安装
22
+ npm install -g cloud-function-cli
23
+
24
+ # 或使用 yarn
25
+ yarn global add cloud-function-cli
26
+
27
+ # 或使用 pnpm
28
+ pnpm add -g cloud-function-cli
29
+ ```
30
+
31
+ ## 🚀 快速开始
32
+
33
+ ### 1. 登录
34
+
35
+ ```bash
36
+ cf login
37
+ ```
38
+
39
+ 输入你的用户名和密码。
40
+
41
+ ### 2. 创建 API
42
+
43
+ ```bash
44
+ # 创建单个 API
45
+ cf create user/hello
46
+
47
+ # 创建 group 目录下的 API
48
+ cf create user/profile
49
+ ```
50
+
51
+ 这将在当前目录生成 `api/group/name.js` 文件,包含完整的 API 模板。
52
+
53
+ ### 3. 编辑 API
54
+
55
+ ```bash
56
+ # 编辑生成的文件
57
+ nano api/user/hello.js
58
+ # 或使用你喜欢的编辑器
59
+ code api/user/hello.js
60
+ ```
61
+
62
+ ### 4. 保存到服务器
63
+
64
+ ```bash
65
+ # 保存单个 API 到开发环境
66
+ cf save user/hello --env dev
67
+
68
+ # 保存整个 group 的所有 API
69
+ cf save user --env dev
70
+
71
+ # 保存到生产环境
72
+ cf save user/hello --env prod
73
+ ```
74
+
75
+ ### 5. 调用 API
76
+
77
+ ```bash
78
+ # 假设后端运行在 localhost:3000
79
+ curl http://localhost:3000/api/user/hello
80
+ ```
81
+
82
+ ## 📚 命令详解
83
+
84
+ ### `cf login`
85
+
86
+ 登录系统,保存认证信息到本地配置文件。
87
+
88
+ ```bash
89
+ cf login
90
+ ```
91
+
92
+ 登录成功后,配置文件保存在:
93
+ - Windows: `C:\Users\<你>\.cloud-function\config.json`
94
+ - macOS/Linux: `~/.cloud-function/config.json`
95
+
96
+ ### `cf create <name>`
97
+
98
+ 创建新的 API 接口文件。
99
+
100
+ ```bash
101
+ # 语法
102
+ cf create <group>/<name>
103
+
104
+ # 示例
105
+ cf create user/login
106
+ cf create product/list
107
+ cf create order/create
108
+ ```
109
+
110
+ 生成的文件位于 `api/<group>/<name>.js`
111
+
112
+ ### `cf save <name>`
113
+
114
+ 保存 API 到服务器。
115
+
116
+ ```bash
117
+ # 保存单个 API
118
+ cf save <group>/<name> --env <env>
119
+
120
+ # 保存整个 group
121
+ cf save <group> --env <env>
122
+
123
+ # 示例
124
+ cf save user/login --env dev
125
+ cf save user --env prod
126
+ ```
127
+
128
+ 参数:
129
+ - `-e, --env <env>`: 环境选择(dev/prod,默认 dev)
130
+
131
+ ### `cf get <name>`
132
+
133
+ 从服务器拉取 API 代码。
134
+
135
+ ```bash
136
+ # 拉取单个 API
137
+ cf get <group>/<name> --env <env>
138
+
139
+ # 拉取整个 group
140
+ cf get <group> --env <env>
141
+
142
+ # 示例
143
+ cf get user/login --env dev
144
+ ```
145
+
146
+ 参数:
147
+ - `-e, --env <env>`: 环境选择(dev/prod,默认 dev)
148
+
149
+ ### `cf history <name>`
150
+
151
+ 查看 API 的版本历史。
152
+
153
+ ```bash
154
+ cf history <group>/<name> --env <env>
155
+
156
+ # 示例
157
+ cf history user/login --env dev
158
+ ```
159
+
160
+ 参数:
161
+ - `-e, --env <env>`: 环境选择(dev/prod,默认 dev)
162
+
163
+ 输出示例:
164
+ ```
165
+ ┌──────┬─────────────────────┬────────────────────┬─────────┐
166
+ │ 版本 │ 创建时间 │ 作者 │ 备注 │
167
+ ├──────┼─────────────────────┼────────────────────┼─────────┤
168
+ │ 1 │ 2025-01-23 14:30:00 │ admin │ 初始版本 │
169
+ │ 2 │ 2025-01-23 15:20:00 │ admin │ 修复bug │
170
+ │ 3 │ 2025-01-23 16:10:00 │ admin │ 新增功能 │
171
+ └──────┴─────────────────────┴────────────────────┴─────────┘
172
+ ```
173
+
174
+ ### `cf rollback <name> <version>`
175
+
176
+ 回滚 API 到指定版本。
177
+
178
+ ```bash
179
+ cf rollback <group>/<name> <version> --env <env>
180
+
181
+ # 示例
182
+ cf rollback user/login 2 --env dev
183
+ ```
184
+
185
+ 参数:
186
+ - `<version>`: 目标版本号
187
+ - `-e, --env <env>`: 环境选择(dev/prod,默认 dev)
188
+
189
+ ## ⚙️ 配置
190
+
191
+ 登录后,配置文件会自动创建在用户目录下的 `.cloud-function/config.json`:
192
+
193
+ ```json
194
+ {
195
+ "apiBaseUrl": "http://localhost:3000",
196
+ "token": "your-jwt-token-here",
197
+ "username": "admin",
198
+ "environment": "dev"
199
+ }
200
+ ```
201
+
202
+ ### 自定义后端地址
203
+
204
+ 如果你的后端不在 `localhost:3000`,可以手动修改配置文件:
205
+
206
+ ```json
207
+ {
208
+ "apiBaseUrl": "https://your-server.com"
209
+ }
210
+ ```
211
+
212
+ 或使用环境变量:
213
+ ```bash
214
+ export CLOUD_FUNCTION_API_BASE_URL="https://your-server.com"
215
+ ```
216
+
217
+ ## 🏗️ API 模板结构
218
+
219
+ 生成的 API 文件包含以下结构:
220
+
221
+ ```javascript
222
+ async function handler(context) {
223
+ // context 包含:
224
+ // - request: Express Request 对象
225
+ // - query: 查询参数
226
+ // - body: 请求体
227
+ // - headers: 请求头
228
+ // - params: 路径参数
229
+ // - env: 环境变量
230
+
231
+ const { request, query, body } = context;
232
+
233
+ // 你的业务逻辑
234
+ const result = {
235
+ success: true,
236
+ message: 'Hello from Cloud Function!',
237
+ data: query
238
+ };
239
+
240
+ return result;
241
+ }
242
+
243
+ module.exports = { handler };
244
+ ```
245
+
246
+ ## 🔐 安全性
247
+
248
+ - 使用 JWT Token 认证
249
+ - Token 自动附加到请求头
250
+ - Token 过期自动提示重新登录
251
+ - 支持 HTTPS 连接
252
+
253
+ ## 🐛 故障排查
254
+
255
+ ### cf: command not found
256
+
257
+ 如果提示命令找不到,请执行:
258
+
259
+ ```bash
260
+ # 重新安装
261
+ npm uninstall -g cloud-function-cli
262
+ npm install -g cloud-function-cli
263
+
264
+ # 或重新打开终端(刷新环境变量)
265
+ hash -r # Unix/Linux/Mac
266
+ refreshenv # Windows PowerShell
267
+ ```
268
+
269
+ ### Token 过期
270
+
271
+ 如果提示 Token 过期,重新登录:
272
+
273
+ ```bash
274
+ cf login
275
+ ```
276
+
277
+ ### 连接超时
278
+
279
+ 如果遇到连接超时,检查配置文件中的 `apiBaseUrl` 是否正确。
280
+
281
+ ```bash
282
+ # 查看配置文件路径
283
+ # Windows: C:\Users\<你>\.cloud-function\config.json
284
+ # Mac/Linux: ~/.cloud-function/config.json
285
+ ```
286
+
287
+ ## 📝 许可证
288
+
289
+ MIT License
290
+
291
+ ## 🤝 贡献
292
+
293
+ 欢迎提交 Issue 和 Pull Request!
294
+
295
+ ## 🔗 相关链接
296
+
297
+ - [云函数系统 GitHub 仓库](https://github.com/your-username/cloud-function)
298
+ - [后端服务](https://github.com/your-username/cloud-function-backend)
299
+ - [Web 管理界面](https://github.com/your-username/cloud-function-web)
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.create = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../utils/logger");
10
+ const api_template_1 = require("../template/api-template");
11
+ const create = async (name) => {
12
+ const parts = name.split('/');
13
+ let group, api;
14
+ if (parts.length === 1) {
15
+ group = parts[0];
16
+ api = 'index';
17
+ }
18
+ else {
19
+ group = parts[0];
20
+ api = parts[1];
21
+ }
22
+ const apiRootDir = path_1.default.join(process.cwd(), 'api');
23
+ const groupDir = path_1.default.join(apiRootDir, group);
24
+ if (!fs_1.default.existsSync(groupDir)) {
25
+ fs_1.default.mkdirSync(groupDir, { recursive: true });
26
+ logger_1.logger.success(`Created group: ${group}`);
27
+ }
28
+ const apiPath = path_1.default.join(groupDir, `${api}.js`);
29
+ if (fs_1.default.existsSync(apiPath)) {
30
+ logger_1.logger.warn(`API ${group}/${api}.js already exists`);
31
+ return;
32
+ }
33
+ fs_1.default.writeFileSync(apiPath, api_template_1.apiTemplate);
34
+ logger_1.logger.success(`Created API: api/${group}/${api}.js`);
35
+ };
36
+ exports.create = create;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.get = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const apiClient_1 = require("../services/apiClient");
10
+ const config_1 = require("../utils/config");
11
+ const logger_1 = require("../utils/logger");
12
+ const get = async (name, options) => {
13
+ const cfg = config_1.config.get();
14
+ const environment = options.env || cfg.environment || 'dev';
15
+ const parts = name.split('/');
16
+ const group = parts[0];
17
+ const apiRootDir = path_1.default.join(process.cwd(), 'api');
18
+ if (parts.length === 1) {
19
+ try {
20
+ const res = await apiClient_1.apiClient.get(`/api/management/list/${group}`, { environment });
21
+ const apis = res.data;
22
+ if (apis.length === 0) {
23
+ logger_1.logger.warn(`No APIs found in group ${group}`);
24
+ return;
25
+ }
26
+ for (const apiDoc of apis) {
27
+ await getFile(apiRootDir, group, apiDoc.api, environment);
28
+ }
29
+ logger_1.logger.success('All APIs retrieved successfully!');
30
+ }
31
+ catch (error) {
32
+ logger_1.logger.error(`Failed to list APIs: ${error.response?.data?.error || error.message}`);
33
+ }
34
+ }
35
+ else {
36
+ const api = parts[1];
37
+ await getFile(apiRootDir, group, api, environment);
38
+ }
39
+ };
40
+ exports.get = get;
41
+ const getFile = async (apiRootDir, group, api, environment) => {
42
+ try {
43
+ const res = await apiClient_1.apiClient.get(`/api/management/get/${group}/${api}`, { environment });
44
+ const groupDir = path_1.default.join(apiRootDir, group);
45
+ if (!fs_1.default.existsSync(groupDir)) {
46
+ fs_1.default.mkdirSync(groupDir, { recursive: true });
47
+ }
48
+ const filePath = path_1.default.join(groupDir, `${api}.js`);
49
+ fs_1.default.writeFileSync(filePath, res.data.handler);
50
+ logger_1.logger.success(`${group}/${api}.js ← Retrieved (Version: ${res.data.version})`);
51
+ }
52
+ catch (error) {
53
+ logger_1.logger.error(`Failed to get ${group}/${api}: ${error.response?.data?.error || error.message}`);
54
+ }
55
+ };
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.history = void 0;
4
+ const apiClient_1 = require("../services/apiClient");
5
+ const config_1 = require("../utils/config");
6
+ const logger_1 = require("../utils/logger");
7
+ const history = async (name, options) => {
8
+ const cfg = config_1.config.get();
9
+ const environment = options.env || cfg.environment || 'dev';
10
+ const parts = name.split('/');
11
+ if (parts.length < 2) {
12
+ logger_1.logger.error('Please specify API: group/api');
13
+ return;
14
+ }
15
+ const group = parts[0];
16
+ const api = parts[1];
17
+ try {
18
+ const res = await apiClient_1.apiClient.get(`/api/management/history/${group}/${api}`, { environment });
19
+ logger_1.logger.info(`History for ${group}/${api} (${environment}):`);
20
+ res.data.forEach((item) => {
21
+ const active = item.isActive ? ' (Active)' : '';
22
+ logger_1.logger.info(` v${item.version}${active} - ${new Date(item.createdAt).toLocaleString()} - by ${item.author}`);
23
+ });
24
+ }
25
+ catch (error) {
26
+ logger_1.logger.error(`Failed to get history: ${error.response?.data?.error || error.message}`);
27
+ }
28
+ };
29
+ exports.history = history;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.login = void 0;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ const apiClient_1 = require("../services/apiClient");
9
+ const config_1 = require("../utils/config");
10
+ const logger_1 = require("../utils/logger");
11
+ const login = async () => {
12
+ const answers = await inquirer_1.default.prompt([
13
+ {
14
+ type: 'input',
15
+ name: 'username',
16
+ message: 'Username:'
17
+ },
18
+ {
19
+ type: 'password',
20
+ name: 'password',
21
+ message: 'Password:'
22
+ }
23
+ ]);
24
+ try {
25
+ const res = await apiClient_1.apiClient.post('/api/auth/login', answers);
26
+ config_1.config.set({
27
+ token: res.data.accessToken,
28
+ username: res.data.user.username
29
+ });
30
+ logger_1.logger.success('Login successful!');
31
+ }
32
+ catch (error) {
33
+ logger_1.logger.error(`Login failed: ${error.response?.data?.error || error.message}`);
34
+ }
35
+ };
36
+ exports.login = login;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rollback = void 0;
4
+ const apiClient_1 = require("../services/apiClient");
5
+ const config_1 = require("../utils/config");
6
+ const logger_1 = require("../utils/logger");
7
+ const rollback = async (name, version, options) => {
8
+ const cfg = config_1.config.get();
9
+ const environment = options.env || cfg.environment || 'dev';
10
+ const parts = name.split('/');
11
+ if (parts.length < 2) {
12
+ logger_1.logger.error('Please specify API: group/api');
13
+ return;
14
+ }
15
+ const group = parts[0];
16
+ const api = parts[1];
17
+ try {
18
+ const res = await apiClient_1.apiClient.post('/api/management/rollback', {
19
+ group,
20
+ api,
21
+ version: parseInt(version),
22
+ environment
23
+ });
24
+ logger_1.logger.success(`Rollback successful! New version: ${res.data.version}`);
25
+ }
26
+ catch (error) {
27
+ logger_1.logger.error(`Failed to rollback: ${error.response?.data?.error || error.message}`);
28
+ }
29
+ };
30
+ exports.rollback = rollback;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.save = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const apiClient_1 = require("../services/apiClient");
10
+ const config_1 = require("../utils/config");
11
+ const logger_1 = require("../utils/logger");
12
+ const save = async (name, options) => {
13
+ const cfg = config_1.config.get();
14
+ const environment = options.env || cfg.environment || 'dev';
15
+ const parts = name.split('/');
16
+ const group = parts[0];
17
+ const apiRootDir = path_1.default.join(process.cwd(), 'api');
18
+ // If only group provided, save all in group
19
+ if (parts.length === 1) {
20
+ const groupDir = path_1.default.join(apiRootDir, group);
21
+ if (!fs_1.default.existsSync(groupDir)) {
22
+ logger_1.logger.error(`Group directory api/${group} not found`);
23
+ return;
24
+ }
25
+ const files = fs_1.default.readdirSync(groupDir).filter(f => f.endsWith('.js'));
26
+ for (const file of files) {
27
+ await saveFile(apiRootDir, group, file.replace('.js', ''), environment);
28
+ }
29
+ logger_1.logger.success('All APIs saved successfully!');
30
+ }
31
+ else {
32
+ // Save specific API
33
+ const api = parts[1];
34
+ await saveFile(apiRootDir, group, api, environment);
35
+ }
36
+ };
37
+ exports.save = save;
38
+ const saveFile = async (apiRootDir, group, api, environment) => {
39
+ const filePath = path_1.default.join(apiRootDir, group, `${api}.js`);
40
+ if (!fs_1.default.existsSync(filePath)) {
41
+ logger_1.logger.error(`File ${filePath} not found`);
42
+ return;
43
+ }
44
+ const handler = fs_1.default.readFileSync(filePath, 'utf-8');
45
+ try {
46
+ const res = await apiClient_1.apiClient.post('/api/management/save', {
47
+ group,
48
+ api,
49
+ handler,
50
+ environment
51
+ });
52
+ logger_1.logger.success(`${group}/${api}.js -> Saved (Version: ${res.data.version})`);
53
+ }
54
+ catch (error) {
55
+ logger_1.logger.error(`Failed to save ${group}/${api}: ${error.response?.data?.error || error.message}`);
56
+ }
57
+ };
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const login_1 = require("./cli/login");
6
+ const create_1 = require("./cli/create");
7
+ const save_1 = require("./cli/save");
8
+ const get_1 = require("./cli/get");
9
+ const history_1 = require("./cli/history");
10
+ const rollback_1 = require("./cli/rollback");
11
+ const program = new commander_1.Command();
12
+ program
13
+ .name('cf')
14
+ .description('Cloud Function CLI')
15
+ .version('1.0.0');
16
+ program
17
+ .command('login')
18
+ .description('Login to the system')
19
+ .action(login_1.login);
20
+ program
21
+ .command('create <name>')
22
+ .description('Create a new API (e.g., group/api)')
23
+ .action(create_1.create);
24
+ program
25
+ .command('save <name>')
26
+ .description('Save API to server')
27
+ .option('-e, --env <env>', 'Environment (dev/prod)')
28
+ .action(save_1.save);
29
+ program
30
+ .command('get <name>')
31
+ .description('Get API from server')
32
+ .option('-e, --env <env>', 'Environment (dev/prod)')
33
+ .action(get_1.get);
34
+ program
35
+ .command('history <name>')
36
+ .description('Show version history')
37
+ .option('-e, --env <env>', 'Environment (dev/prod)')
38
+ .action(history_1.history);
39
+ program
40
+ .command('rollback <name> <version>')
41
+ .description('Rollback to a specific version')
42
+ .option('-e, --env <env>', 'Environment (dev/prod)')
43
+ .action(rollback_1.rollback);
44
+ program.parse(process.argv);
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.apiClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const config_1 = require("../utils/config");
9
+ const logger_1 = require("../utils/logger");
10
+ const getClient = () => {
11
+ const cfg = config_1.config.get();
12
+ const client = axios_1.default.create({
13
+ baseURL: cfg.apiBaseUrl,
14
+ timeout: 10000
15
+ });
16
+ client.interceptors.request.use((req) => {
17
+ const cfg = config_1.config.get();
18
+ if (cfg.token) {
19
+ req.headers.Authorization = `Bearer ${cfg.token}`;
20
+ }
21
+ return req;
22
+ });
23
+ client.interceptors.response.use((res) => res, (error) => {
24
+ if (error.response?.status === 401) {
25
+ logger_1.logger.error('Token expired or invalid. Please login again.');
26
+ }
27
+ return Promise.reject(error);
28
+ });
29
+ return client;
30
+ };
31
+ exports.apiClient = {
32
+ get: (url, params) => getClient().get(url, { params }),
33
+ post: (url, data) => getClient().post(url, data),
34
+ put: (url, data) => getClient().put(url, data),
35
+ delete: (url) => getClient().delete(url)
36
+ };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apiTemplate = void 0;
4
+ exports.apiTemplate = `async function handler(context) {
5
+ const { log, cacher, options, utils, mongo, http, https, request, response } = context
6
+
7
+ let query = request.query
8
+ let data = request.body
9
+
10
+ return { code: 1, data: data || query }
11
+ }
12
+ `;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.config = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.cloud-function');
11
+ const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
12
+ const defaultConfig = {
13
+ apiBaseUrl: 'http://localhost:3000',
14
+ environment: 'dev'
15
+ };
16
+ exports.config = {
17
+ get: () => {
18
+ if (!fs_1.default.existsSync(CONFIG_FILE)) {
19
+ return defaultConfig;
20
+ }
21
+ try {
22
+ return { ...defaultConfig, ...JSON.parse(fs_1.default.readFileSync(CONFIG_FILE, 'utf-8')) };
23
+ }
24
+ catch {
25
+ return defaultConfig;
26
+ }
27
+ },
28
+ set: (newConfig) => {
29
+ if (!fs_1.default.existsSync(CONFIG_DIR)) {
30
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
31
+ }
32
+ const current = exports.config.get();
33
+ fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify({ ...current, ...newConfig }, null, 2));
34
+ },
35
+ clear: () => {
36
+ if (fs_1.default.existsSync(CONFIG_FILE)) {
37
+ fs_1.default.unlinkSync(CONFIG_FILE);
38
+ }
39
+ }
40
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logger = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ exports.logger = {
9
+ info: (msg) => console.log(chalk_1.default.blue(msg)),
10
+ success: (msg) => console.log(chalk_1.default.green('✓ ' + msg)),
11
+ warn: (msg) => console.log(chalk_1.default.yellow('⚠️ ' + msg)),
12
+ error: (msg) => console.log(chalk_1.default.red('✗ ' + msg)),
13
+ debug: (msg) => {
14
+ if (process.env.DEBUG)
15
+ console.log(chalk_1.default.gray(msg));
16
+ }
17
+ };
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "cloud-function-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI for Cloud Function System - Create, deploy, and manage serverless functions",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "cf": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node dist/index.js",
11
+ "cf": "node dist/index.js",
12
+ "dev": "ts-node src/index.ts",
13
+ "cli": "ts-node src/index.ts",
14
+ "build": "tsc",
15
+ "prepublishOnly": "npm run build",
16
+ "test": "echo \"No tests yet\" && exit 0"
17
+ },
18
+ "keywords": [
19
+ "cli",
20
+ "cloud-function",
21
+ "serverless",
22
+ "api",
23
+ "function",
24
+ "deploy",
25
+ "deploy-tool",
26
+ "cloud",
27
+ "aws-lambda",
28
+ "azure-functions"
29
+ ],
30
+ "author": "Your Name <your.email@example.com>",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/your-username/cloud-function.git"
35
+ },
36
+ "homepage": "https://github.com/your-username/cloud-function#readme",
37
+ "bugs": {
38
+ "url": "https://github.com/your-username/cloud-function/issues"
39
+ },
40
+ "engines": {
41
+ "node": ">=16.0.0"
42
+ },
43
+ "files": [
44
+ "dist/",
45
+ "README.md",
46
+ "LICENSE"
47
+ ],
48
+ "dependencies": {
49
+ "axios": "^1.6.7",
50
+ "chalk": "^4.1.2",
51
+ "commander": "^11.1.0",
52
+ "dotenv": "^16.4.1",
53
+ "inquirer": "^8.2.6"
54
+ },
55
+ "devDependencies": {
56
+ "@types/inquirer": "^9.0.7",
57
+ "@types/node": "^20.11.16",
58
+ "ts-node": "^10.9.2",
59
+ "typescript": "^5.3.3"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public"
63
+ }
64
+ }