@cloudbase/manager-node 4.2.10 → 4.3.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.
@@ -1,36 +1,54 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
8
12
  }));
9
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
15
  };
12
16
  var __importDefault = (this && this.__importDefault) || function (mod) {
13
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
14
18
  };
15
19
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.upperCaseObjKey = exports.upperCaseStringFisrt = exports.sleep = exports.rsaEncrypt = exports.getEnvVar = exports.getRuntime = exports.compressToZip = void 0;
17
- const fs_1 = __importDefault(require("fs"));
20
+ exports.guid6 = void 0;
21
+ exports.compressToZip = compressToZip;
22
+ exports.downloadAndExtractRemoteZip = downloadAndExtractRemoteZip;
23
+ exports.getRuntime = getRuntime;
24
+ exports.getEnvVar = getEnvVar;
25
+ exports.rsaEncrypt = rsaEncrypt;
26
+ exports.sleep = sleep;
27
+ exports.upperCaseStringFisrt = upperCaseStringFisrt;
28
+ exports.upperCaseObjKey = upperCaseObjKey;
29
+ exports.fetchTemplates = fetchTemplates;
18
30
  const archiver_1 = __importDefault(require("archiver"));
19
31
  const crypto_1 = __importDefault(require("crypto"));
32
+ const fs_extra_1 = __importDefault(require("fs-extra"));
33
+ const lodash_1 = __importDefault(require("lodash"));
34
+ const path_1 = __importDefault(require("path"));
35
+ const stream_1 = require("stream");
36
+ const unzipper_1 = __importDefault(require("unzipper"));
20
37
  const constant_1 = require("../constant");
21
- var uuid_1 = require("./uuid");
22
- Object.defineProperty(exports, "guid6", { enumerable: true, get: function () { return uuid_1.guid6; } });
23
- __exportStar(require("./cloud-api-request"), exports);
38
+ const http_request_1 = require("./http-request");
24
39
  __exportStar(require("./auth"), exports);
40
+ __exportStar(require("./cloud-api-request"), exports);
25
41
  __exportStar(require("./cloudbase-request"), exports);
26
- __exportStar(require("./http-request"), exports);
27
42
  __exportStar(require("./envLazy"), exports);
28
43
  __exportStar(require("./fs"), exports);
44
+ __exportStar(require("./http-request"), exports);
45
+ var uuid_1 = require("./uuid");
46
+ Object.defineProperty(exports, "guid6", { enumerable: true, get: function () { return uuid_1.guid6; } });
29
47
  async function compressToZip(option) {
30
48
  const { dirPath, outputPath, ignore, pattern = '**/*' } = option;
31
49
  return new Promise((resolve, reject) => {
32
- const output = fs_1.default.createWriteStream(outputPath);
33
- const archive = archiver_1.default('zip');
50
+ const output = fs_extra_1.default.createWriteStream(outputPath);
51
+ const archive = (0, archiver_1.default)('zip');
34
52
  output.on('close', function () {
35
53
  resolve({
36
54
  zipPath: outputPath,
@@ -51,15 +69,42 @@ async function compressToZip(option) {
51
69
  archive.finalize();
52
70
  });
53
71
  }
54
- exports.compressToZip = compressToZip;
72
+ /**
73
+ * 下载并解压云托管模板到指定目录
74
+ * @param {string} downloadUrl 模板下载地址
75
+ * @param {string} targetPath 目标路径
76
+ * @returns {Promise<void>}
77
+ * @throws 当下载失败或解压失败时抛出错误
78
+ */
79
+ async function downloadAndExtractRemoteZip(downloadUrl, targetPath) {
80
+ const downloadResponse = await (0, http_request_1.fetchStream)(downloadUrl);
81
+ if (!downloadResponse.ok) {
82
+ throw new Error(`下载失败,状态码: ${downloadResponse.status}`);
83
+ }
84
+ if (!downloadResponse.body) {
85
+ throw new Error('下载响应中没有数据流');
86
+ }
87
+ // 将响应数据转为Buffer
88
+ const zipBuffer = Buffer.from(await downloadResponse.arrayBuffer());
89
+ // 创建目标目录
90
+ const dirPath = path_1.default.resolve(targetPath);
91
+ await fs_extra_1.default.ensureDir(dirPath);
92
+ // 使用unzipper解压
93
+ await new Promise((resolve, reject) => {
94
+ const bufferStream = new stream_1.PassThrough();
95
+ bufferStream.end(zipBuffer);
96
+ bufferStream
97
+ .pipe(unzipper_1.default.Extract({ path: dirPath }))
98
+ .on('close', resolve)
99
+ .on('error', reject);
100
+ });
101
+ }
55
102
  function getRuntime() {
56
103
  return process.env[constant_1.ENV_NAME.ENV_RUNENV];
57
104
  }
58
- exports.getRuntime = getRuntime;
59
105
  function getEnvVar(envName) {
60
106
  return process.env[envName];
61
107
  }
62
- exports.getEnvVar = getEnvVar;
63
108
  function rsaEncrypt(data) {
64
109
  const buffer = Buffer.from(data);
65
110
  const encrypted = crypto_1.default.publicEncrypt({
@@ -68,7 +113,6 @@ function rsaEncrypt(data) {
68
113
  }, buffer);
69
114
  return encrypted.toString('base64');
70
115
  }
71
- exports.rsaEncrypt = rsaEncrypt;
72
116
  function sleep(time) {
73
117
  return new Promise(resolve => {
74
118
  setTimeout(() => {
@@ -76,11 +120,9 @@ function sleep(time) {
76
120
  }, time);
77
121
  });
78
122
  }
79
- exports.sleep = sleep;
80
123
  function upperCaseStringFisrt(str) {
81
124
  return str.slice(0, 1).toUpperCase().concat(str.slice(1));
82
125
  }
83
- exports.upperCaseStringFisrt = upperCaseStringFisrt;
84
126
  function upperCaseObjKey(object) {
85
127
  const type = Object.prototype.toString.call(object).slice(8, -1);
86
128
  if (type === 'Object') {
@@ -100,4 +142,15 @@ function upperCaseObjKey(object) {
100
142
  }
101
143
  return object;
102
144
  }
103
- exports.upperCaseObjKey = upperCaseObjKey;
145
+ /**
146
+ * 获取函数模板列表
147
+ * @param type 函数模板类型,支持 'scfFunc' 和 'tcbrFunc'
148
+ * @returns
149
+ */
150
+ async function fetchTemplates(types) {
151
+ const apiUrl = 'https://qcloud-tcb-console-1258344699.ap-shanghai.service.tcloudbase.com/func_tpl/v1.0/function_list/find?skip=0&limit=500';
152
+ const responseData = await (0, http_request_1.fetch)(apiUrl, {
153
+ method: 'POST'
154
+ });
155
+ return responseData.data.filter((item) => lodash_1.default.intersection(types, item.funcTypes).length > 0);
156
+ }
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkIsInScf = void 0;
3
+ exports.checkIsInScf = checkIsInScf;
4
4
  function checkIsInScf() {
5
5
  // TENCENTCLOUD_RUNENV
6
6
  return process.env.TENCENTCLOUD_RUNENV === 'SCF';
7
7
  }
8
- exports.checkIsInScf = checkIsInScf;
package/lib/utils/uuid.js CHANGED
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uuidv4 = exports.guid6 = void 0;
3
+ exports.guid6 = guid6;
4
+ exports.uuidv4 = uuidv4;
4
5
  // 环境 uuid
5
6
  function guid6() {
6
7
  return Math.floor((1 + Math.random()) * 0x1000000)
7
8
  .toString(16)
8
9
  .substring(1);
9
10
  }
10
- exports.guid6 = guid6;
11
11
  function uuidv4() {
12
12
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
13
13
  const r = (Math.random() * 16) | 0;
@@ -15,4 +15,3 @@ function uuidv4() {
15
15
  return v.toString(16);
16
16
  });
17
17
  }
18
- exports.uuidv4 = uuidv4;
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@cloudbase/manager-node",
3
- "version": "4.2.10",
3
+ "version": "4.3.0",
4
4
  "description": "The node manage service api for cloudbase.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
7
7
  "build": "rimraf lib types && npx tsc",
8
- "test": "jest --runInBand --detectOpenHandles --coverage --testTimeout=50000",
8
+ "test:coverage": "jest --runInBand --detectOpenHandles --coverage --testTimeout=50000",
9
+ "test": "jest --runInBand --detectOpenHandles --testTimeout=50000",
9
10
  "lint": "eslint \"./**/*.ts\"",
10
11
  "lint:fix": "eslint --fix \"./**/*.ts\"",
11
12
  "prepublishOnly": "npm run build",
12
- "watch": "rimraf lib types && tsc -w"
13
+ "watch": "rimraf lib types && tsc -w",
14
+ "link": "node scripts/link.js",
15
+ "unlink": "node scripts/link.js -d"
13
16
  },
14
17
  "repository": {
15
18
  "type": "git",
@@ -19,9 +22,12 @@
19
22
  "license": "ISC",
20
23
  "typings": "types/index.d.ts",
21
24
  "devDependencies": {
25
+ "@lerna/create-symlink": "^6.4.1",
26
+ "@types/fs-extra": "^11.0.4",
22
27
  "@types/jest": "^24.0.18",
23
28
  "@types/node": "^12.7.4",
24
29
  "@types/node-fetch": "^2.5.0",
30
+ "@types/unzipper": "^0.10.11",
25
31
  "@typescript-eslint/eslint-plugin": "^3.7.1",
26
32
  "@typescript-eslint/parser": "^3.7.1",
27
33
  "eslint": "^7.6.0",
@@ -31,18 +37,21 @@
31
37
  "lint-staged": "^9.2.5",
32
38
  "rimraf": "^3.0.0",
33
39
  "ts-jest": "^24.1.0",
34
- "typescript": "^3.8.3"
40
+ "typescript": "^5.8.3"
35
41
  },
36
42
  "dependencies": {
37
43
  "@cloudbase/database": "^0.6.2",
38
44
  "archiver": "^3.1.1",
39
- "cos-nodejs-sdk-v5": "2.14.0",
45
+ "cos-nodejs-sdk-v5": "^2.14.0",
40
46
  "del": "^5.1.0",
47
+ "fs-extra": "^11.3.0",
41
48
  "https-proxy-agent": "^5.0.1",
49
+ "lodash": "^4.17.21",
42
50
  "make-dir": "^3.0.0",
43
51
  "micromatch": "^4.0.2",
44
52
  "node-fetch": "^2.6.0",
45
53
  "query-string": "^6.8.3",
54
+ "unzipper": "^0.12.3",
46
55
  "walkdir": "^0.4.1"
47
56
  },
48
57
  "husky": {
@@ -55,5 +64,6 @@
55
64
  "eslint --fix",
56
65
  "git add"
57
66
  ]
58
- }
67
+ },
68
+ "packageManager": "yarn@1.22.22"
59
69
  }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Tencent is pleased to support the open source community by making CloudBaseFramework - 云原生一体化部署工具 available.
3
+ *
4
+ * Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Please refer to license text included with this package for license details.
7
+ */
8
+
9
+ const os = require('os')
10
+ const fs = require('fs')
11
+ const fse = require('fs-extra')
12
+ const del = require('del')
13
+ const path = require('path')
14
+ const mkdirp = require('mkdirp')
15
+ const { execSync } = require('child_process')
16
+ const { createSymlink } = require('@lerna/create-symlink')
17
+
18
+ const globalNpmPath = execSync('npm root -g', {
19
+ encoding: 'utf-8'
20
+ }).trim()
21
+ // 如果不支持workspace 可以用下面写死
22
+ // const globalNpmPath = '/usr/local/lib/node_modules';
23
+
24
+ async function main() {
25
+ const unlink = process.argv?.[2] === '-d'
26
+ await linkCore(unlink)
27
+ }
28
+
29
+ async function linkCore(unlink = false) {
30
+ const jsonString = await fs.readFileSync(path.join(__dirname, '../package.json'))
31
+ const { name } = JSON.parse(jsonString)
32
+ await link(path.join(process.cwd()), path.join(globalNpmPath, '@cloudbase/cli'), name, unlink)
33
+ }
34
+
35
+ function isSymlink(path) {
36
+ const stats = fs.lstatSync(path)
37
+ return stats.isSymbolicLink()
38
+ }
39
+
40
+ // 将 global tcb cli 工具中的 framework-core link 到 packages/framework-core
41
+ async function link(src, dest, packageName, unlink = false) {
42
+ const prevCwd = process.cwd()
43
+ const destPlugin = path.join(dest, 'node_modules', '@cloudbase')
44
+ // 确保目录存在
45
+ mkdirp.sync(destPlugin)
46
+ // 切换 cwd
47
+ process.chdir(destPlugin)
48
+
49
+ const pathName = packageName.replace('@cloudbase/', '')
50
+ const backupPathName = `${pathName}_backup`
51
+
52
+ if (unlink) {
53
+ if (fs.existsSync(pathName) && !isSymlink(pathName)) {
54
+ console.log(`【失败】${pathName} 不是软链接`, process.cwd())
55
+ return
56
+ }
57
+
58
+ if (fs.existsSync(pathName) && fs.existsSync(backupPathName)) {
59
+ // 删除软链接
60
+ del.sync([pathName])
61
+
62
+ // 恢复备份
63
+ fse.moveSync(backupPathName, pathName)
64
+
65
+ // 删除软链接
66
+ console.log('【成功】删除软链接:', process.cwd())
67
+ } else {
68
+ console.info(
69
+ `不存在 ${pathName} 或 ${backupPathName},请重装安装 npm i @cloudbase/cli -g`,
70
+ process.cwd()
71
+ )
72
+ }
73
+ } else {
74
+ // 创建软链接
75
+
76
+ if (fs.existsSync(pathName)) {
77
+ if (!fs.existsSync(backupPathName)) {
78
+ // 不存在备份则进行备份
79
+
80
+ if (!isSymlink(pathName)) {
81
+ // 不是软链接才备份
82
+ fse.moveSync(pathName, backupPathName)
83
+ }
84
+ } else {
85
+ // 存在备份则直接删除
86
+ del.sync([pathName])
87
+ }
88
+ }
89
+
90
+ await createSymlink(src, pathName, 'junction')
91
+ console.log('【成功】创建软链接:', process.cwd())
92
+ }
93
+
94
+ // 切回源目录
95
+ process.chdir(prevCwd)
96
+ }
97
+
98
+ main()
package/tsconfig.json CHANGED
@@ -11,7 +11,8 @@
11
11
  "declaration": true,
12
12
  "declarationDir": "./types",
13
13
  "experimentalDecorators": true,
14
- "newLine": "LF"
14
+ "newLine": "LF",
15
+ "skipLibCheck": true
15
16
  },
16
17
  "include": ["src/**/*"],
17
18
  "exclude": ["node_modules", "test"]
@@ -0,0 +1,81 @@
1
+ import { Environment } from '../environment';
2
+ import { IResponseInfo } from '../interfaces';
3
+ import { CloudrunServerType, ICloudrunDetailResponse, ICloudrunListResponse, ITemplate } from './type';
4
+ /**
5
+ * 云托管服务管理类
6
+ * 提供云托管服务的初始化、下载、列表查询和删除等功能
7
+ */
8
+ export declare class CloudRunService {
9
+ private environment;
10
+ private tcbrService;
11
+ private tcbService;
12
+ constructor(environment: Environment);
13
+ /**
14
+ * 初始化云托管代码项目
15
+ * @param {Object} params 初始化参数
16
+ * @param {string} params.serverName 服务名称,将作为项目目录名
17
+ * @param {string} [params.template='helloworld'] 模板标识符,默认为'helloworld'
18
+ * @param {string} [params.targetPath='.'] 目标路径,默认为当前目录
19
+ * @returns {Promise<void>}
20
+ * @throws 当模板不存在、下载失败或解压失败时抛出错误
21
+ */
22
+ init(params: {
23
+ serverName: string;
24
+ template?: string;
25
+ targetPath?: string;
26
+ }): Promise<{
27
+ projectDir: string;
28
+ }>;
29
+ /**
30
+ * 下载云托管服务代码到本地目录
31
+ * @param {Object} params 下载参数
32
+ * @param {string} params.serverName 要下载的服务名称
33
+ * @param {string} params.targetPath 下载的目标路径(绝对路径或相对路径)
34
+ * @returns {Promise<void>}
35
+ * @throws 当以下情况发生时抛出错误:
36
+ * - 未找到服务版本
37
+ * - 获取下载地址失败
38
+ * - 下载或解压过程中出错
39
+ */
40
+ download(params: {
41
+ serverName: string;
42
+ targetPath: string;
43
+ }): Promise<void>;
44
+ /**
45
+ * 获取云托管服务列表
46
+ * @param {Object} [params] 查询参数
47
+ * @param {number} [params.pageSize] 每页数量
48
+ * @param {number} [params.pageNum] 页码
49
+ * @param {string} [params.serverName] 服务名称筛选
50
+ * @param {string} [params.serverType] 服务类型筛选
51
+ * @returns {Promise<ICloudrunListResponse>} 包含服务列表和总数等信息的响应对象
52
+ */
53
+ list(params?: {
54
+ pageSize?: number;
55
+ pageNum?: number;
56
+ serverName?: string;
57
+ serverType?: CloudrunServerType;
58
+ }): Promise<ICloudrunListResponse>;
59
+ /**
60
+ *查询云托管服务详情
61
+ * @param {Object} params 查询参数
62
+ * @param {string} params.serverName 要查询的服务名称
63
+ * @returns {Promise<ICloudrunDetailResponse>} 返回服务详情响应对象
64
+ */
65
+ detail(params: {
66
+ serverName: string;
67
+ }): Promise<ICloudrunDetailResponse>;
68
+ /**
69
+ * 删除指定的云托管服务
70
+ * @param {string} serverName - 要删除的服务名称,必须是在当前环境中已存在的服务
71
+ * @returns {Promise<IResponseInfo>} 返回删除操作的响应信息
72
+ */
73
+ delete(params: {
74
+ serverName: string;
75
+ }): Promise<IResponseInfo>;
76
+ /**
77
+ * 获取云托管服务模板列表
78
+ * @returns {Promise<ITemplate[]>} 返回模板数组
79
+ */
80
+ getTemplates(): Promise<ITemplate[]>;
81
+ }