@cloudbase/cli 3.0.0-alpha.3 → 3.0.0-alpha.4

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.
@@ -330606,7 +330606,7 @@ module.exports = function generate_pattern(it, $keyword, $ruleType) {
330606
330606
  /***/ ((module) => {
330607
330607
 
330608
330608
  "use strict";
330609
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"3.0.0-alpha.3","description":"cli tool for cloudbase","main":"lib/index.js","scripts":{"build":"rimraf lib types && tsc --resolveJsonModule && cpx \\"src/**/*.html\\" lib","watch":"rimraf lib types && tsc -w","dev":"rimraf lib types && cpx \\"src/**/*.html\\" lib && tsc -w","eslint":"eslint \\"./**/*.ts\\"","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --forceExit --detectOpenHandles --verbose --testTimeout=120000","test:e2e":"node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=\'test/e2e/\' --runInBand --forceExit --detectOpenHandles --verbose --testTimeout=120000","tsc":"tsc","pkg":"pkg ./bin/cloudbase.js --out-path ./pkg","postinstall":"node ./post-install.js || exit 0 && patch-package","prepublishOnly":"node ./scripts/check-publish-source.js","debug":"bin/tcb.js lowcode watch","build:bundle":"webpack --config build/webpack/cli.cjs && webpack --config build/webpack/ccr.cjs && node build/scripts/copy-figlet-fonts.js","package:darwin-arm64":"OS=darwin ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:darwin-x64":"OS=darwin ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-arm64":"OS=linux ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-x64":"OS=linux ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:all":"bash build/scripts/build-all.sh","node:fetch:one":"node -e \\"require(\'child_process\').execSync(\'bash build/scripts/fetch-node.sh\',{stdio:\'inherit\'})\\"","node:fetch:all":"NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh --all","node:fetch:win-x64":"OS=windows ARCH=x64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","node:fetch:win-arm64":"OS=windows ARCH=arm64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","package:windows-x64":"OS=windows ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-arm64":"OS=windows ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-all":"npm run -s node:fetch:win-x64 && npm run -s node:fetch:win-arm64 && npm run -s package:windows-x64 && npm run -s package:windows-arm64","package:npm":"npm run build && npm run build:bundle && bash build/scripts/prepare-publish.sh","out:prune":"bash build/scripts/prune-out.sh","i18n:scan":"i18next-scanner --config locales/i18next-scanner.config.js && node locales/scripts/generate.js","i18n:sync":"node locales/scripts/sync.js sync","publish":"node ./scripts/publish.js"},"repository":{"type":"git","url":"https://github.com/TencentCloudBase/cloud-base-cli.git"},"bin":{"cloudbase":"bin/cloudbase.js","cloudbase-mcp":"bin/cloudbase-mcp.cjs","tcb":"bin/tcb.js"},"husky":{"hooks":{"pre-commit":"npm run build"}},"author":"cwuyiqing@gmail.com","license":"ISC","dependencies":{"@cloudbase/cloud-api":"^0.5.5","@cloudbase/cloudbase-mcp":"^2.7.3","@cloudbase/framework-core":"^1.9.7","@cloudbase/functions-framework":"1.16.0","@cloudbase/iac-core":"0.0.3-alpha.14","@cloudbase/lowcode-cli":"^0.23.0","@cloudbase/manager-node":"4.11.0-alpha.7","@cloudbase/toolbox":"0.7.17","@dotenvx/dotenvx":"^1.48.3","@musistudio/claude-code-router":"1.0.36","address":"^1.1.2","camelcase-keys":"^7.0.2","chalk":"^2.4.2","cli-table3":"^0.5.1","commander":"7","del":"^5.1.0","didyoumean":"^1.2.2","enquirer":"^2.3.6","execa":"^4.0.3","figlet":"^1.7.0","fs-extra":"^8.1.0","gradient-string":"^2.0.2","https-proxy-agent":"^5.0.1","i":"^0.3.7","inquirer":"^6.5.0","json-schema-to-typescript":"^14.0.5","lodash":"^4.17.21","log-symbols":"^3.0.0","lowdb":"^1.0.0","make-dir":"^3.0.0","node-fetch":"^2.6.0","nodemon":"^3.1.4","npm":"^11.5.2","open":"^7.0.0","ora":"^4.0.2","os-locale":"5.0.0","patch-package":"^8.0.0","portfinder":"^1.0.28","progress":"^2.0.3","query-string":"^6.8.1","reflect-metadata":"^0.1.13","semver":"^7.3.7","simple-git":"^3.28.0","tar-fs":"^2.0.1","terminal-link":"^2.1.1","toml":"^3.0.0","unzipper":"^0.10.10","update-notifier":"^4.0.0","xdg-basedir":"^4.0.0","yargs":"^16.2.0","yargs-parser":"^21.0.1","zod":"^4.0.13"},"devDependencies":{"@babel/parser":"^7.28.4","@babel/traverse":"^7.28.4","@babel/types":"^7.28.4","@types/fs-extra":"^11.0.4","@types/jest":"^27","@types/koa__router":"^8.0.11","@types/lodash":"^4.14.182","@types/node":"^12.12.38","@types/node-fetch":"^2.5.4","@types/react":"^17.0.37","@types/semver":"^7.3.9","@types/unzipper":"^0.10.11","@types/webpack-dev-server":"^3.11.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","cpx":"^1.5.0","eslint":"^7.14.0","eslint-config-alloy":"^3.8.2","husky":"^3.0.9","i18next-scanner":"^4.6.0","jest":"^27","rimraf":"^3.0.2","ts-jest":"^27","typescript":"^4.7.2","webpack":"^5.92.0","webpack-cli":"^5.1.4"},"packageManager":"yarn@3.6.2+sha512.2c2f8b9615e6659773f65cdec7cf92ef773a98a99e611579601f61c7a91ec94c89c929aac86f1cee819421a9b0db7acfd53ec3ebb95af44f77f77634b08b9557","ai":{"skills":"./skills","skillsIndex":"./skills/index.json","compatible":["codebuddy","cursor","copilot","claude","windsurf"],"description":"CloudBase CLI - 腾讯云云开发命令行工具,支持云函数、云数据库、静态托管等全栈云开发能力"}}');
330609
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"3.0.0-alpha.4","description":"cli tool for cloudbase","main":"lib/index.js","scripts":{"build":"rimraf lib types && tsc --resolveJsonModule && cpx \\"src/**/*.html\\" lib","watch":"rimraf lib types && tsc -w","dev":"rimraf lib types && cpx \\"src/**/*.html\\" lib && tsc -w","eslint":"eslint \\"./**/*.ts\\"","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --forceExit --detectOpenHandles --verbose --testTimeout=120000","test:e2e":"node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=\'test/e2e/\' --runInBand --forceExit --detectOpenHandles --verbose --testTimeout=120000","tsc":"tsc","pkg":"pkg ./bin/cloudbase.js --out-path ./pkg","postinstall":"node ./post-install.js || exit 0 && patch-package","prepublishOnly":"node ./scripts/check-publish-source.js","debug":"bin/tcb.js lowcode watch","build:bundle":"webpack --config build/webpack/cli.cjs && webpack --config build/webpack/ccr.cjs && node build/scripts/copy-figlet-fonts.js","package:darwin-arm64":"OS=darwin ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:darwin-x64":"OS=darwin ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-arm64":"OS=linux ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-x64":"OS=linux ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:all":"bash build/scripts/build-all.sh","node:fetch:one":"node -e \\"require(\'child_process\').execSync(\'bash build/scripts/fetch-node.sh\',{stdio:\'inherit\'})\\"","node:fetch:all":"NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh --all","node:fetch:win-x64":"OS=windows ARCH=x64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","node:fetch:win-arm64":"OS=windows ARCH=arm64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","package:windows-x64":"OS=windows ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-arm64":"OS=windows ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-all":"npm run -s node:fetch:win-x64 && npm run -s node:fetch:win-arm64 && npm run -s package:windows-x64 && npm run -s package:windows-arm64","package:npm":"npm run build && npm run build:bundle && bash build/scripts/prepare-publish.sh","out:prune":"bash build/scripts/prune-out.sh","i18n:scan":"i18next-scanner --config locales/i18next-scanner.config.js && node locales/scripts/generate.js","i18n:sync":"node locales/scripts/sync.js sync","publish":"node ./scripts/publish.js"},"repository":{"type":"git","url":"https://github.com/TencentCloudBase/cloud-base-cli.git"},"bin":{"cloudbase":"bin/cloudbase.js","cloudbase-mcp":"bin/cloudbase-mcp.cjs","tcb":"bin/tcb.js"},"husky":{"hooks":{"pre-commit":"npm run build"}},"author":"cwuyiqing@gmail.com","license":"ISC","dependencies":{"@cloudbase/cloud-api":"^0.5.5","@cloudbase/cloudbase-mcp":"^2.7.3","@cloudbase/framework-core":"^1.9.7","@cloudbase/functions-framework":"1.16.0","@cloudbase/iac-core":"0.0.3-alpha.14","@cloudbase/lowcode-cli":"^0.23.0","@cloudbase/manager-node":"4.11.0-alpha.8","@cloudbase/toolbox":"0.7.17","@dotenvx/dotenvx":"^1.48.3","@musistudio/claude-code-router":"1.0.36","address":"^1.1.2","camelcase-keys":"^7.0.2","chalk":"^2.4.2","cli-table3":"^0.5.1","commander":"7","del":"^5.1.0","didyoumean":"^1.2.2","enquirer":"^2.3.6","execa":"^4.0.3","figlet":"^1.7.0","fs-extra":"^8.1.0","gradient-string":"^2.0.2","https-proxy-agent":"^5.0.1","i":"^0.3.7","inquirer":"^6.5.0","json-schema-to-typescript":"^14.0.5","lodash":"^4.17.21","log-symbols":"^3.0.0","lowdb":"^1.0.0","make-dir":"^3.0.0","node-fetch":"^2.6.0","nodemon":"^3.1.4","npm":"^11.5.2","open":"^7.0.0","ora":"^4.0.2","os-locale":"5.0.0","patch-package":"^8.0.0","portfinder":"^1.0.28","progress":"^2.0.3","query-string":"^6.8.1","reflect-metadata":"^0.1.13","semver":"^7.3.7","simple-git":"^3.28.0","tar-fs":"^2.0.1","terminal-link":"^2.1.1","toml":"^3.0.0","unzipper":"^0.10.10","update-notifier":"^4.0.0","xdg-basedir":"^4.0.0","yargs":"^16.2.0","yargs-parser":"^21.0.1","zod":"^4.0.13"},"devDependencies":{"@babel/parser":"^7.28.4","@babel/traverse":"^7.28.4","@babel/types":"^7.28.4","@types/fs-extra":"^11.0.4","@types/jest":"^27","@types/koa__router":"^8.0.11","@types/lodash":"^4.14.182","@types/node":"^12.12.38","@types/node-fetch":"^2.5.4","@types/react":"^17.0.37","@types/semver":"^7.3.9","@types/unzipper":"^0.10.11","@types/webpack-dev-server":"^3.11.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","cpx":"^1.5.0","eslint":"^7.14.0","eslint-config-alloy":"^3.8.2","husky":"^3.0.9","i18next-scanner":"^4.6.0","jest":"^27","rimraf":"^3.0.2","ts-jest":"^27","typescript":"^4.7.2","webpack":"^5.92.0","webpack-cli":"^5.1.4"},"packageManager":"yarn@3.6.2+sha512.2c2f8b9615e6659773f65cdec7cf92ef773a98a99e611579601f61c7a91ec94c89c929aac86f1cee819421a9b0db7acfd53ec3ebb95af44f77f77634b08b9557","ai":{"skills":"./skills","skillsIndex":"./skills/index.json","compatible":["codebuddy","cursor","copilot","claude","windsurf"],"description":"CloudBase CLI - 腾讯云云开发命令行工具,支持云函数、云数据库、静态托管等全栈云开发能力"}}');
330610
330610
 
330611
330611
  /***/ }),
330612
330612
 
@@ -394907,11 +394907,22 @@ async function createSymlink (srcpath, dstpath, type) {
394907
394907
  } catch { }
394908
394908
 
394909
394909
  if (stats && stats.isSymbolicLink()) {
394910
- const [srcStat, dstStat] = await Promise.all([
394911
- fs.stat(srcpath),
394912
- fs.stat(dstpath)
394913
- ])
394910
+ // When srcpath is relative, resolve it relative to dstpath's directory
394911
+ // (standard symlink behavior) or fall back to cwd if that doesn't exist
394912
+ let srcStat
394913
+ if (path.isAbsolute(srcpath)) {
394914
+ srcStat = await fs.stat(srcpath)
394915
+ } else {
394916
+ const dstdir = path.dirname(dstpath)
394917
+ const relativeToDst = path.join(dstdir, srcpath)
394918
+ try {
394919
+ srcStat = await fs.stat(relativeToDst)
394920
+ } catch {
394921
+ srcStat = await fs.stat(srcpath)
394922
+ }
394923
+ }
394914
394924
 
394925
+ const dstStat = await fs.stat(dstpath)
394915
394926
  if (areIdentical(srcStat, dstStat)) return
394916
394927
  }
394917
394928
 
@@ -394933,7 +394944,21 @@ function createSymlinkSync (srcpath, dstpath, type) {
394933
394944
  stats = fs.lstatSync(dstpath)
394934
394945
  } catch { }
394935
394946
  if (stats && stats.isSymbolicLink()) {
394936
- const srcStat = fs.statSync(srcpath)
394947
+ // When srcpath is relative, resolve it relative to dstpath's directory
394948
+ // (standard symlink behavior) or fall back to cwd if that doesn't exist
394949
+ let srcStat
394950
+ if (path.isAbsolute(srcpath)) {
394951
+ srcStat = fs.statSync(srcpath)
394952
+ } else {
394953
+ const dstdir = path.dirname(dstpath)
394954
+ const relativeToDst = path.join(dstdir, srcpath)
394955
+ try {
394956
+ srcStat = fs.statSync(relativeToDst)
394957
+ } catch {
394958
+ srcStat = fs.statSync(srcpath)
394959
+ }
394960
+ }
394961
+
394937
394962
  const dstStat = fs.statSync(dstpath)
394938
394963
  if (areIdentical(srcStat, dstStat)) return
394939
394964
  }
@@ -436732,6 +436757,327 @@ function listCacheGet(key) {
436732
436757
  module.exports = listCacheGet;
436733
436758
 
436734
436759
 
436760
+ /***/ }),
436761
+
436762
+ /***/ 24786:
436763
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
436764
+
436765
+ "use strict";
436766
+
436767
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
436768
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
436769
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
436770
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
436771
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
436772
+ };
436773
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
436774
+ exports.PermissionService = void 0;
436775
+ const utils_1 = __webpack_require__(62358);
436776
+ const PERMISSION_BY_RESOURCE = {
436777
+ function: ['CUSTOM'],
436778
+ storage: ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY', 'CUSTOM'],
436779
+ table: ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY'],
436780
+ collection: ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY', 'CUSTOM']
436781
+ };
436782
+ class PermissionService {
436783
+ constructor(environment) {
436784
+ this.environment = environment;
436785
+ this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
436786
+ }
436787
+ async modifyResourcePermission(options) {
436788
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
436789
+ const { resourceType, resource, permission, securityRule } = options;
436790
+ if (!resourceType || !PERMISSION_BY_RESOURCE[resourceType]) {
436791
+ throw new Error('Invalid resourceType');
436792
+ }
436793
+ if (typeof resource !== 'string' || resource.trim().length === 0) {
436794
+ throw new Error('Invalid resource');
436795
+ }
436796
+ const allowed = PERMISSION_BY_RESOURCE[resourceType];
436797
+ if (!allowed.includes(permission)) {
436798
+ throw new Error(`Permission ${permission} is not allowed for resourceType ${resourceType}`);
436799
+ }
436800
+ if (permission === 'CUSTOM') {
436801
+ if (typeof securityRule !== 'string' || securityRule.trim().length === 0) {
436802
+ throw new Error('securityRule is required when permission is CUSTOM');
436803
+ }
436804
+ // // 校验 JSON 字符串合法性
436805
+ // try {
436806
+ // JSON.parse(securityRule)
436807
+ // } catch {
436808
+ // throw new Error('securityRule must be a valid JSON string')
436809
+ // }
436810
+ }
436811
+ const reqData = {
436812
+ EnvId,
436813
+ ResourceType: resourceType,
436814
+ Resource: resource,
436815
+ Permission: permission
436816
+ };
436817
+ if (permission === 'CUSTOM') {
436818
+ reqData.SecurityRule = securityRule;
436819
+ }
436820
+ return this.tcbService.request('ModifyResourcePermission', reqData);
436821
+ }
436822
+ async describeResourcePermission(options) {
436823
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
436824
+ const { resourceType, resources } = options;
436825
+ if (!resourceType || !PERMISSION_BY_RESOURCE[resourceType]) {
436826
+ throw new Error('Invalid resourceType');
436827
+ }
436828
+ if (resources !== undefined) {
436829
+ if (!Array.isArray(resources)) {
436830
+ throw new Error('Invalid resources');
436831
+ }
436832
+ if (resources.length > 100) {
436833
+ throw new Error('resources length must be <= 100');
436834
+ }
436835
+ const invalid = resources.find(item => typeof item !== 'string' || item.trim().length === 0);
436836
+ if (invalid !== undefined) {
436837
+ throw new Error('resources contains invalid item');
436838
+ }
436839
+ }
436840
+ return this.tcbService.request('DescribeResourcePermission', Object.assign({ EnvId, ResourceType: resourceType }, (resources !== undefined ? { Resources: resources } : {})));
436841
+ }
436842
+ async createRole(options) {
436843
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
436844
+ const { roleName, roleIdentity, description, memberUids, policies } = options;
436845
+ // RoleName 校验:非空,2-32字符,中文/字母/数字/_-:@.,必须以字母或中文开头
436846
+ if (typeof roleName !== 'string' || roleName.trim().length === 0) {
436847
+ throw new Error('roleName is required');
436848
+ }
436849
+ if (roleName.length < 2 || roleName.length > 32) {
436850
+ throw new Error('roleName length must be between 2 and 32');
436851
+ }
436852
+ if (!/^[\u4e00-\u9fa5a-zA-Z]/.test(roleName)) {
436853
+ throw new Error('roleName must start with a letter or Chinese character');
436854
+ }
436855
+ if (!/^[\u4e00-\u9fa5a-zA-Z0-9\-_:@.]+$/.test(roleName)) {
436856
+ throw new Error('roleName can only contain Chinese, letters, digits, and -_:@.');
436857
+ }
436858
+ // RoleIdentity 校验:非空,字母/数字/_-:@.,不能与默认角色标识重复
436859
+ if (typeof roleIdentity !== 'string' || roleIdentity.trim().length === 0) {
436860
+ throw new Error('roleIdentity is required');
436861
+ }
436862
+ if (!/^[a-zA-Z0-9\-_:@.]+$/.test(roleIdentity)) {
436863
+ throw new Error('roleIdentity can only contain letters, digits, and -_:@.');
436864
+ }
436865
+ // Description 校验
436866
+ if (description !== undefined && description.length > 255) {
436867
+ throw new Error('description length must be <= 255');
436868
+ }
436869
+ // MemberUids 校验
436870
+ if (memberUids !== undefined) {
436871
+ if (!Array.isArray(memberUids)) {
436872
+ throw new Error('memberUids must be an array');
436873
+ }
436874
+ if (memberUids.length > 100) {
436875
+ throw new Error('memberUids length must be <= 100');
436876
+ }
436877
+ const invalidUid = memberUids.find(uid => typeof uid !== 'string' || uid.trim().length === 0);
436878
+ if (invalidUid !== undefined) {
436879
+ throw new Error('memberUids contains invalid item');
436880
+ }
436881
+ }
436882
+ // Policies 校验
436883
+ if (policies !== undefined) {
436884
+ if (!Array.isArray(policies)) {
436885
+ throw new Error('policies must be an array');
436886
+ }
436887
+ if (policies.length > 50) {
436888
+ throw new Error('policies length must be <= 50');
436889
+ }
436890
+ const invalidPolicy = policies.find(policy => !policy.ResourceType || !policy.Resource);
436891
+ if (invalidPolicy !== undefined) {
436892
+ throw new Error('each policy must have ResourceType and Resource');
436893
+ }
436894
+ }
436895
+ const reqData = {
436896
+ EnvId,
436897
+ RoleName: roleName,
436898
+ RoleIdentity: roleIdentity
436899
+ };
436900
+ if (description !== undefined) {
436901
+ reqData.Description = description;
436902
+ }
436903
+ if (memberUids !== undefined && memberUids.length > 0) {
436904
+ reqData.MemberUids = memberUids;
436905
+ }
436906
+ if (policies !== undefined && policies.length > 0) {
436907
+ reqData.Policies = policies;
436908
+ }
436909
+ return this.tcbService.request('CreateRole', reqData);
436910
+ }
436911
+ async describeRoleList(options = {}) {
436912
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
436913
+ const { pageNumber, pageSize, roleId, roleIdentity, roleName, loadDetails } = options;
436914
+ // PageNumber 校验:从1开始
436915
+ if (pageNumber !== undefined && (pageNumber < 1 || !Number.isInteger(pageNumber))) {
436916
+ throw new Error('pageNumber must be a positive integer');
436917
+ }
436918
+ // PageSize 校验:默认10,最大100
436919
+ if (pageSize !== undefined && (pageSize < 1 || pageSize > 100 || !Number.isInteger(pageSize))) {
436920
+ throw new Error('pageSize must be an integer between 1 and 100');
436921
+ }
436922
+ // RoleId 校验
436923
+ if (roleId !== undefined && (typeof roleId !== 'string' || roleId.trim().length === 0)) {
436924
+ throw new Error('Invalid roleId');
436925
+ }
436926
+ // RoleIdentity 校验
436927
+ if (roleIdentity !== undefined && (typeof roleIdentity !== 'string' || roleIdentity.trim().length === 0)) {
436928
+ throw new Error('Invalid roleIdentity');
436929
+ }
436930
+ // RoleName 校验
436931
+ if (roleName !== undefined && (typeof roleName !== 'string' || roleName.trim().length === 0)) {
436932
+ throw new Error('Invalid roleName');
436933
+ }
436934
+ const reqData = { EnvId };
436935
+ if (pageNumber !== undefined) {
436936
+ reqData.PageNumber = pageNumber;
436937
+ }
436938
+ if (pageSize !== undefined) {
436939
+ reqData.PageSize = pageSize;
436940
+ }
436941
+ if (roleId !== undefined) {
436942
+ reqData.RoleId = roleId;
436943
+ }
436944
+ if (roleIdentity !== undefined) {
436945
+ reqData.RoleIdentity = roleIdentity;
436946
+ }
436947
+ if (roleName !== undefined) {
436948
+ reqData.RoleName = roleName;
436949
+ }
436950
+ if (loadDetails !== undefined) {
436951
+ reqData.LoadDetails = loadDetails;
436952
+ }
436953
+ return this.tcbService.request('DescribeRoleList', reqData);
436954
+ }
436955
+ async modifyRole(options) {
436956
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
436957
+ const { roleId, roleName, description, addMemberUids, removeMemberUids, addPolicies, removePolicies } = options;
436958
+ // RoleId 校验:必填
436959
+ if (typeof roleId !== 'string' || roleId.trim().length === 0) {
436960
+ throw new Error('roleId is required');
436961
+ }
436962
+ // RoleName 校验:不传或传空 => 不修改;非空时校验规则
436963
+ if (roleName !== undefined && roleName !== '') {
436964
+ if (roleName.length < 2 || roleName.length > 32) {
436965
+ throw new Error('roleName length must be between 2 and 32');
436966
+ }
436967
+ if (!/^[\u4e00-\u9fa5a-zA-Z]/.test(roleName)) {
436968
+ throw new Error('roleName must start with a letter or Chinese character');
436969
+ }
436970
+ if (!/^[\u4e00-\u9fa5a-zA-Z0-9\-_:@.]+$/.test(roleName)) {
436971
+ throw new Error('roleName can only contain Chinese, letters, digits, and -_:@.');
436972
+ }
436973
+ }
436974
+ // Description 校验
436975
+ if (description !== undefined && description.length > 255) {
436976
+ throw new Error('description length must be <= 255');
436977
+ }
436978
+ // AddMemberUids 校验
436979
+ if (addMemberUids !== undefined) {
436980
+ if (!Array.isArray(addMemberUids)) {
436981
+ throw new Error('addMemberUids must be an array');
436982
+ }
436983
+ const invalidUid = addMemberUids.find(uid => typeof uid !== 'string' || uid.trim().length === 0);
436984
+ if (invalidUid !== undefined) {
436985
+ throw new Error('addMemberUids contains invalid item');
436986
+ }
436987
+ }
436988
+ // RemoveMemberUids 校验
436989
+ if (removeMemberUids !== undefined) {
436990
+ if (!Array.isArray(removeMemberUids)) {
436991
+ throw new Error('removeMemberUids must be an array');
436992
+ }
436993
+ const invalidUid = removeMemberUids.find(uid => typeof uid !== 'string' || uid.trim().length === 0);
436994
+ if (invalidUid !== undefined) {
436995
+ throw new Error('removeMemberUids contains invalid item');
436996
+ }
436997
+ }
436998
+ // AddPolicies 校验
436999
+ if (addPolicies !== undefined) {
437000
+ if (!Array.isArray(addPolicies)) {
437001
+ throw new Error('addPolicies must be an array');
437002
+ }
437003
+ const invalidPolicy = addPolicies.find(policy => !policy.ResourceType || !policy.Resource);
437004
+ if (invalidPolicy !== undefined) {
437005
+ throw new Error('each addPolicy must have ResourceType and Resource');
437006
+ }
437007
+ }
437008
+ // RemovePolicies 校验
437009
+ if (removePolicies !== undefined) {
437010
+ if (!Array.isArray(removePolicies)) {
437011
+ throw new Error('removePolicies must be an array');
437012
+ }
437013
+ const invalidPolicy = removePolicies.find(policy => !policy.ResourceType || !policy.Resource);
437014
+ if (invalidPolicy !== undefined) {
437015
+ throw new Error('each removePolicy must have ResourceType and Resource');
437016
+ }
437017
+ }
437018
+ const reqData = { EnvId, RoleId: roleId };
437019
+ // RoleName:不传或传空 => 不修改(不下发)
437020
+ if (roleName !== undefined && roleName !== '') {
437021
+ reqData.RoleName = roleName;
437022
+ }
437023
+ if (description !== undefined) {
437024
+ reqData.Description = description;
437025
+ }
437026
+ if (addMemberUids !== undefined) {
437027
+ reqData.AddMemberUids = addMemberUids;
437028
+ }
437029
+ if (removeMemberUids !== undefined) {
437030
+ reqData.RemoveMemberUids = removeMemberUids;
437031
+ }
437032
+ if (addPolicies !== undefined) {
437033
+ reqData.AddPolicies = addPolicies;
437034
+ }
437035
+ if (removePolicies !== undefined) {
437036
+ reqData.RemovePolicies = removePolicies;
437037
+ }
437038
+ return this.tcbService.request('ModifyRole', reqData);
437039
+ }
437040
+ async deleteRoles(options) {
437041
+ const { EnvId } = this.environment.lazyEnvironmentConfig;
437042
+ const { roleIds } = options;
437043
+ // RoleIds 校验:必填数组,最多100个
437044
+ if (!Array.isArray(roleIds) || roleIds.length === 0) {
437045
+ throw new Error('roleIds is required and must be a non-empty array');
437046
+ }
437047
+ if (roleIds.length > 100) {
437048
+ throw new Error('roleIds length must be <= 100');
437049
+ }
437050
+ const invalidId = roleIds.find(id => typeof id !== 'string' || id.trim().length === 0);
437051
+ if (invalidId !== undefined) {
437052
+ throw new Error('roleIds contains invalid item');
437053
+ }
437054
+ return this.tcbService.request('DeleteRoles', {
437055
+ EnvId,
437056
+ RoleIds: roleIds
437057
+ });
437058
+ }
437059
+ }
437060
+ exports.PermissionService = PermissionService;
437061
+ __decorate([
437062
+ (0, utils_1.preLazy)()
437063
+ ], PermissionService.prototype, "modifyResourcePermission", null);
437064
+ __decorate([
437065
+ (0, utils_1.preLazy)()
437066
+ ], PermissionService.prototype, "describeResourcePermission", null);
437067
+ __decorate([
437068
+ (0, utils_1.preLazy)()
437069
+ ], PermissionService.prototype, "createRole", null);
437070
+ __decorate([
437071
+ (0, utils_1.preLazy)()
437072
+ ], PermissionService.prototype, "describeRoleList", null);
437073
+ __decorate([
437074
+ (0, utils_1.preLazy)()
437075
+ ], PermissionService.prototype, "modifyRole", null);
437076
+ __decorate([
437077
+ (0, utils_1.preLazy)()
437078
+ ], PermissionService.prototype, "deleteRoles", null);
437079
+
437080
+
436735
437081
  /***/ }),
436736
437082
 
436737
437083
  /***/ 24808:
@@ -464861,6 +465207,7 @@ const { mkdirs } = __webpack_require__(23585)
464861
465207
  const { pathExists } = __webpack_require__(65057)
464862
465208
  const { utimesMillis } = __webpack_require__(53430)
464863
465209
  const stat = __webpack_require__(62039)
465210
+ const { asyncIteratorConcurrentProcess } = __webpack_require__(64129)
464864
465211
 
464865
465212
  async function copy (src, dest, opts = {}) {
464866
465213
  if (typeof opts === 'function') {
@@ -464968,28 +465315,20 @@ async function onDir (srcStat, destStat, src, dest, opts) {
464968
465315
  await fs.mkdir(dest)
464969
465316
  }
464970
465317
 
464971
- const promises = []
464972
-
464973
- // loop through the files in the current directory to copy everything
464974
- for await (const item of await fs.opendir(src)) {
465318
+ // iterate through the files in the current directory to copy everything
465319
+ await asyncIteratorConcurrentProcess(await fs.opendir(src), async (item) => {
464975
465320
  const srcItem = path.join(src, item.name)
464976
465321
  const destItem = path.join(dest, item.name)
464977
465322
 
464978
- promises.push(
464979
- runFilter(srcItem, destItem, opts).then(include => {
464980
- if (include) {
464981
- // only copy the item if it matches the filter function
464982
- return stat.checkPaths(srcItem, destItem, 'copy', opts).then(({ destStat }) => {
464983
- // If the item is a copyable file, `getStatsAndPerformCopy` will copy it
464984
- // If the item is a directory, `getStatsAndPerformCopy` will call `onDir` recursively
464985
- return getStatsAndPerformCopy(destStat, srcItem, destItem, opts)
464986
- })
464987
- }
464988
- })
464989
- )
464990
- }
464991
-
464992
- await Promise.all(promises)
465323
+ const include = await runFilter(srcItem, destItem, opts)
465324
+ // only copy the item if it matches the filter function
465325
+ if (include) {
465326
+ const { destStat } = await stat.checkPaths(srcItem, destItem, 'copy', opts)
465327
+ // If the item is a copyable file, `getStatsAndPerformCopy` will copy it
465328
+ // If the item is a directory, `getStatsAndPerformCopy` will call `onDir` recursively
465329
+ await getStatsAndPerformCopy(destStat, srcItem, destItem, opts)
465330
+ }
465331
+ })
464993
465332
 
464994
465333
  if (!destStat) {
464995
465334
  await fs.chmod(dest, srcStat.mode)
@@ -465018,15 +465357,20 @@ async function onLink (destStat, src, dest, opts) {
465018
465357
  if (opts.dereference) {
465019
465358
  resolvedDest = path.resolve(process.cwd(), resolvedDest)
465020
465359
  }
465021
- if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) {
465022
- throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)
465023
- }
465360
+ // If both symlinks resolve to the same target, they are still distinct symlinks
465361
+ // that can be copied/overwritten. Only check subdirectory constraints when
465362
+ // the resolved paths are different.
465363
+ if (resolvedSrc !== resolvedDest) {
465364
+ if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) {
465365
+ throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)
465366
+ }
465024
465367
 
465025
- // do not copy if src is a subdir of dest since unlinking
465026
- // dest in this case would result in removing src contents
465027
- // and therefore a broken symlink would be created.
465028
- if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) {
465029
- throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
465368
+ // do not copy if src is a subdir of dest since unlinking
465369
+ // dest in this case would result in removing src contents
465370
+ // and therefore a broken symlink would be created.
465371
+ if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) {
465372
+ throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
465373
+ }
465030
465374
  }
465031
465375
 
465032
465376
  // copy the link
@@ -586104,14 +586448,62 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
586104
586448
  };
586105
586449
  Object.defineProperty(exports, "__esModule", ({ value: true }));
586106
586450
  exports.LogService = void 0;
586451
+ exports.isLogServiceEnabled = isLogServiceEnabled;
586107
586452
  const utils_1 = __webpack_require__(62358);
586108
586453
  __exportStar(__webpack_require__(83700), exports);
586454
+ /**
586455
+ * 纯函数:根据 DescribeEnvs 返回的 LogServices 列表判断日志服务是否已开通。
586456
+ * 已开通条件:至少一个条目有有效的 TopicId。
586457
+ */
586458
+ function isLogServiceEnabled(logServices) {
586459
+ if (!logServices || logServices.length === 0)
586460
+ return false;
586461
+ return logServices.some(svc => !!svc.TopicId);
586462
+ }
586109
586463
  class LogService {
586110
586464
  constructor(environment) {
586111
586465
  this.envId = environment.getEnvId();
586112
586466
  this.cloudService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
586113
586467
  this.tcbrService = new utils_1.CloudService(environment.cloudBaseContext, 'tcbr', '2022-02-17');
586114
586468
  }
586469
+ /**
586470
+ * 检查当前环境的日志服务是否已开通
586471
+ *
586472
+ * 通过 DescribeEnvs 接口获取环境信息,判断 LogServices 字段中是否包含有效的
586473
+ * 日志主题(TopicId 不为空)。
586474
+ *
586475
+ * @returns true 表示已开通,false 表示未开通或开通中
586476
+ */
586477
+ async checkLogServiceEnabled() {
586478
+ var _a;
586479
+ const res = await this.cloudService.request('DescribeEnvs', {
586480
+ EnvId: this.envId
586481
+ });
586482
+ const envInfo = (_a = res === null || res === void 0 ? void 0 : res.EnvList) === null || _a === void 0 ? void 0 : _a[0];
586483
+ if (!envInfo) {
586484
+ return false;
586485
+ }
586486
+ const logServices = envInfo.LogServices;
586487
+ if (!logServices || logServices.length === 0) {
586488
+ return false;
586489
+ }
586490
+ // 已开通:LogServiceInfo 中存在有效的日志主题 ID
586491
+ return isLogServiceEnabled(logServices);
586492
+ }
586493
+ /**
586494
+ * 开通环境日志服务(异步操作)
586495
+ *
586496
+ * 调用 CreateEnvResource 接口开通日志资源。
586497
+ * 注意:接口调用成功不代表日志资源立即可用,需通过 checkLogServiceEnabled() 轮询确认。
586498
+ *
586499
+ * @returns 请求 ID
586500
+ */
586501
+ async createLogService() {
586502
+ return this.cloudService.request('CreateEnvResource', {
586503
+ EnvId: this.envId,
586504
+ Resources: ['log']
586505
+ });
586506
+ }
586115
586507
  /**
586116
586508
  * 搜索 CLS 日志
586117
586509
  *
@@ -648299,6 +648691,13 @@ let LogSearchCommand = class LogSearchCommand extends common_1.Command {
648299
648691
  }
648300
648692
  try {
648301
648693
  const logService = yield (0, utils_3.getLogService)(selectedEnvId);
648694
+ if (!jsonOutput) {
648695
+ loading.stop();
648696
+ }
648697
+ yield (0, utils_3.ensureLogServiceEnabled)(logService, log, { jsonOutput });
648698
+ if (!jsonOutput) {
648699
+ loading.start((0, i18n_1.t)('正在检索日志...'));
648700
+ }
648302
648701
  const result = yield logService.searchClsLog({
648303
648702
  queryString,
648304
648703
  StartTime: startTime,
@@ -648357,6 +648756,9 @@ let LogSearchCommand = class LogSearchCommand extends common_1.Command {
648357
648756
  if (!jsonOutput) {
648358
648757
  loading.fail((0, i18n_1.t)('日志检索失败'));
648359
648758
  }
648759
+ if (e instanceof error_1.CloudBaseError) {
648760
+ throw e;
648761
+ }
648360
648762
  throw new error_1.CloudBaseError({
648361
648763
  message: (0, i18n_1.t)('日志检索失败:{{msg}}', {
648362
648764
  msg: e instanceof Error ? e.message : String(e)
@@ -664886,6 +665288,7 @@ const access_1 = __webpack_require__(70427);
664886
665288
  const user_1 = __webpack_require__(71858);
664887
665289
  const cloudBaseRun_1 = __webpack_require__(24344);
664888
665290
  const mysql_1 = __webpack_require__(61697);
665291
+ const permission_1 = __webpack_require__(24786);
664889
665292
  class Environment {
664890
665293
  constructor(context, envId) {
664891
665294
  this.inited = false;
@@ -664907,6 +665310,7 @@ class Environment {
664907
665310
  this.userService = new user_1.UserService(this);
664908
665311
  this.cloudBaseRunService = new cloudBaseRun_1.CloudBaseRunService(this);
664909
665312
  this.mysqlService = new mysql_1.MysqlService(this);
665313
+ this.permissionService = new permission_1.PermissionService(this);
664910
665314
  }
664911
665315
  async lazyInit() {
664912
665316
  if (!this.inited) {
@@ -664969,6 +665373,9 @@ class Environment {
664969
665373
  getMysqlService() {
664970
665374
  return this.mysqlService;
664971
665375
  }
665376
+ getPermissionService() {
665377
+ return this.permissionService;
665378
+ }
664972
665379
  getCommonService(serviceType = 'tcb', serviceVersion) {
664973
665380
  return new common_1.CommonService(this, serviceType, serviceVersion);
664974
665381
  }
@@ -684684,7 +685091,8 @@ function checkParentPathsSync (src, srcStat, dest, funcName) {
684684
685091
  }
684685
685092
 
684686
685093
  function areIdentical (srcStat, destStat) {
684687
- return destStat.ino && destStat.dev && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev
685094
+ // stat.dev can be 0n on windows when node version >= 22.x.x
685095
+ return destStat.ino !== undefined && destStat.dev !== undefined && destStat.ino === srcStat.ino && destStat.dev === srcStat.dev
684688
685096
  }
684689
685097
 
684690
685098
  // return true if dest is a subdir of src, otherwise false.
@@ -700723,6 +701131,43 @@ class CloudBaseError extends Error {
700723
701131
  exports.CloudBaseError = CloudBaseError;
700724
701132
 
700725
701133
 
701134
+ /***/ }),
701135
+
701136
+ /***/ 64129:
701137
+ /***/ ((module) => {
701138
+
701139
+ "use strict";
701140
+
701141
+
701142
+ // https://github.com/jprichardson/node-fs-extra/issues/1056
701143
+ // Performing parallel operations on each item of an async iterator is
701144
+ // surprisingly hard; you need to have handlers in place to avoid getting an
701145
+ // UnhandledPromiseRejectionWarning.
701146
+ // NOTE: This function does not presently handle return values, only errors
701147
+ async function asyncIteratorConcurrentProcess (iterator, fn) {
701148
+ const promises = []
701149
+ for await (const item of iterator) {
701150
+ promises.push(
701151
+ fn(item).then(
701152
+ () => null,
701153
+ (err) => err ?? new Error('unknown error')
701154
+ )
701155
+ )
701156
+ }
701157
+ await Promise.all(
701158
+ promises.map((promise) =>
701159
+ promise.then((possibleErr) => {
701160
+ if (possibleErr !== null) throw possibleErr
701161
+ })
701162
+ )
701163
+ )
701164
+ }
701165
+
701166
+ module.exports = {
701167
+ asyncIteratorConcurrentProcess
701168
+ }
701169
+
701170
+
700726
701171
  /***/ }),
700727
701172
 
700728
701173
  /***/ 64179:
@@ -833283,15 +833728,20 @@ function onLink (destStat, src, dest, opts) {
833283
833728
  if (opts.dereference) {
833284
833729
  resolvedDest = path.resolve(process.cwd(), resolvedDest)
833285
833730
  }
833286
- if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) {
833287
- throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)
833288
- }
833731
+ // If both symlinks resolve to the same target, they are still distinct symlinks
833732
+ // that can be copied/overwritten. Only check subdirectory constraints when
833733
+ // the resolved paths are different.
833734
+ if (resolvedSrc !== resolvedDest) {
833735
+ if (stat.isSrcSubdir(resolvedSrc, resolvedDest)) {
833736
+ throw new Error(`Cannot copy '${resolvedSrc}' to a subdirectory of itself, '${resolvedDest}'.`)
833737
+ }
833289
833738
 
833290
- // prevent copy if src is a subdir of dest since unlinking
833291
- // dest in this case would result in removing src contents
833292
- // and therefore a broken symlink would be created.
833293
- if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) {
833294
- throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
833739
+ // prevent copy if src is a subdir of dest since unlinking
833740
+ // dest in this case would result in removing src contents
833741
+ // and therefore a broken symlink would be created.
833742
+ if (stat.isSrcSubdir(resolvedDest, resolvedSrc)) {
833743
+ throw new Error(`Cannot overwrite '${resolvedDest}' with '${resolvedSrc}'.`)
833744
+ }
833295
833745
  }
833296
833746
  return copyLink(resolvedSrc, dest)
833297
833747
  }
@@ -944381,6 +944831,9 @@ class CloudBase {
944381
944831
  get user() {
944382
944832
  return this.currentEnvironment().getUserService();
944383
944833
  }
944834
+ get permission() {
944835
+ return this.currentEnvironment().getPermissionService();
944836
+ }
944384
944837
  get docs() {
944385
944838
  if (!this.docsService) {
944386
944839
  this.docsService = new docs_1.DocsService();
@@ -955227,12 +955680,96 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
955227
955680
  return (mod && mod.__esModule) ? mod : { "default": mod };
955228
955681
  };
955229
955682
  Object.defineProperty(exports, "__esModule", ({ value: true }));
955230
- exports.safeParseJSON = exports.resolveTimeRange = exports.getLogService = void 0;
955683
+ exports.safeParseJSON = exports.resolveTimeRange = exports.getLogService = exports.ensureLogServiceEnabled = void 0;
955231
955684
  const manager_node_1 = __importDefault(__webpack_require__(95492));
955232
955685
  const toolbox_1 = __webpack_require__(25901);
955233
955686
  const utils_1 = __webpack_require__(82079);
955234
955687
  const error_1 = __webpack_require__(66759);
955235
955688
  const i18n_1 = __webpack_require__(69258);
955689
+ function ensureLogServiceEnabled(logService, log, opts = {}) {
955690
+ return __awaiter(this, void 0, void 0, function* () {
955691
+ const { jsonOutput = false } = opts;
955692
+ let enabled;
955693
+ try {
955694
+ enabled = yield logService.checkLogServiceEnabled();
955695
+ }
955696
+ catch (e) {
955697
+ throw new error_1.CloudBaseError({
955698
+ message: (0, i18n_1.t)('检查日志服务状态失败:{{message}}', { message: e.message || String(e) }),
955699
+ original: e
955700
+ });
955701
+ }
955702
+ if (enabled) {
955703
+ return;
955704
+ }
955705
+ const notEnabledError = new error_1.CloudBaseError({
955706
+ message: (0, i18n_1.t)('日志服务未开通,无法执行日志查询。请开通日志服务后重试。'),
955707
+ code: 'LOG_SERVICE_NOT_ENABLED',
955708
+ solution: [
955709
+ (0, i18n_1.t)('运行 tcb logs search --yes 可自动开通日志服务'),
955710
+ (0, i18n_1.t)('或前往云开发控制台手动开通')
955711
+ ]
955712
+ });
955713
+ if (jsonOutput) {
955714
+ throw notEnabledError;
955715
+ }
955716
+ log.warn((0, i18n_1.t)('您的环境尚未开通日志服务,开通后不额外计费,日志将按照您购买的套餐提供不同时长保存,' +
955717
+ '详情可参考文档:https://cloud.tencent.com/document/product/876/75213'));
955718
+ const confirm = yield (0, utils_1.autoConfirm)((0, i18n_1.t)('是否现在开通日志服务?'), true);
955719
+ if (!confirm) {
955720
+ throw notEnabledError;
955721
+ }
955722
+ if (!jsonOutput) {
955723
+ log.info((0, i18n_1.t)('正在开通日志服务(异步操作,最长等待 5 分钟)...'));
955724
+ }
955725
+ try {
955726
+ yield logService.createLogService();
955727
+ }
955728
+ catch (e) {
955729
+ const code = (e === null || e === void 0 ? void 0 : e.code) || (e === null || e === void 0 ? void 0 : e.Code) || '';
955730
+ if (code !== 'ResourceInUse.LogExist') {
955731
+ throw new error_1.CloudBaseError({
955732
+ message: (0, i18n_1.t)('开通日志服务失败:{{message}}', { message: e.message || String(e) }),
955733
+ original: e
955734
+ });
955735
+ }
955736
+ }
955737
+ const MAX_POLL = 60;
955738
+ const POLL_INTERVAL_MS = 2000;
955739
+ let pollCount = 0;
955740
+ yield new Promise((resolve, reject) => {
955741
+ const timer = setInterval(() => __awaiter(this, void 0, void 0, function* () {
955742
+ pollCount++;
955743
+ try {
955744
+ const ready = yield logService.checkLogServiceEnabled();
955745
+ if (ready) {
955746
+ clearInterval(timer);
955747
+ if (!jsonOutput) {
955748
+ log.info((0, i18n_1.t)('日志服务开通成功!'));
955749
+ }
955750
+ resolve();
955751
+ return;
955752
+ }
955753
+ }
955754
+ catch (e) {
955755
+ clearInterval(timer);
955756
+ reject(new error_1.CloudBaseError({
955757
+ message: (0, i18n_1.t)('轮询日志服务状态失败:{{message}}', {
955758
+ message: e.message || String(e)
955759
+ }),
955760
+ original: e
955761
+ }));
955762
+ return;
955763
+ }
955764
+ if (pollCount >= MAX_POLL) {
955765
+ clearInterval(timer);
955766
+ reject(new error_1.CloudBaseError((0, i18n_1.t)('日志服务开通超时(已等待 5 分钟),请稍后重试或前往控制台确认开通状态。')));
955767
+ }
955768
+ }), POLL_INTERVAL_MS);
955769
+ });
955770
+ });
955771
+ }
955772
+ exports.ensureLogServiceEnabled = ensureLogServiceEnabled;
955236
955773
  function getLogService(envId) {
955237
955774
  return __awaiter(this, void 0, void 0, function* () {
955238
955775
  const region = yield (0, toolbox_1.getRegion)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/cli",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.4",
4
4
  "description": "CLI for Tencent CloudBase (standalone bundle)",
5
5
  "bin": {
6
6
  "tcb": "bin/tcb",