@geek-fun/serverlessinsight 0.3.0 → 0.3.2
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/dist/package.json +40 -37
- package/dist/src/commands/deploy.js +2 -2
- package/dist/src/commands/destroy.js +2 -1
- package/dist/src/commands/index.js +32 -16
- package/dist/src/commands/local.js +35 -0
- package/dist/src/commands/template.js +3 -3
- package/dist/src/commands/validate.js +3 -2
- package/dist/src/common/constants.js +5 -2
- package/dist/src/common/{actionContext.js → context.js} +30 -9
- package/dist/src/common/iacHelper.js +54 -27
- package/dist/src/common/index.d.ts +1 -1
- package/dist/src/common/index.js +1 -1
- package/dist/src/common/rosAssets.js +34 -8
- package/dist/src/common/rosClient.js +6 -4
- package/dist/src/parser/index.js +2 -0
- package/dist/src/parser/tableParser.js +41 -0
- package/dist/src/stack/deploy.js +30 -13
- package/dist/src/stack/localStack/event.js +38 -0
- package/dist/src/stack/localStack/index.d.ts +2 -0
- package/dist/src/stack/localStack/index.js +23 -0
- package/dist/src/stack/rfsStack/index.d.ts +2 -2
- package/dist/src/stack/rfsStack/index.js +2 -1
- package/dist/src/stack/rosStack/bootstrap.js +157 -8
- package/dist/src/stack/rosStack/bucket.js +13 -12
- package/dist/src/stack/rosStack/database.js +11 -12
- package/dist/src/stack/rosStack/event.js +21 -21
- package/dist/src/stack/rosStack/function.js +66 -46
- package/dist/src/stack/rosStack/index.d.ts +2 -2
- package/dist/src/stack/rosStack/index.js +6 -3
- package/dist/src/stack/rosStack/stage.js +1 -1
- package/dist/src/stack/rosStack/table.js +95 -0
- package/dist/src/stack/rosStack/tag.js +1 -1
- package/dist/src/stack/rosStack/vars.js +3 -3
- package/dist/src/types/domains/table.js +16 -0
- package/dist/src/types/index.d.ts +5 -0
- package/dist/src/validator/functionSchema.js +1 -1
- package/dist/src/validator/iacSchema.js +2 -0
- package/dist/src/validator/rootSchema.js +3 -0
- package/dist/src/validator/tableschema.js +72 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +12 -0
- package/layers/si-bootstrap-sdk/README.md +1 -0
- package/layers/si-bootstrap-sdk/package-lock.json +875 -0
- package/layers/si-bootstrap-sdk/package.json +33 -0
- package/package.json +40 -37
- package/samples/aliyun-poc-fc-gpu.yml +23 -22
- package/samples/aliyun-poc-table.yml +48 -0
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geek-fun/serverlessinsight",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Full life cycle cross providers serverless application management for your fast-growing business.",
|
|
5
5
|
"homepage": "https://serverlessinsight.geekfun.club",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -49,51 +49,54 @@
|
|
|
49
49
|
"function"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@alicloud/ims20190815": "^2.
|
|
53
|
-
"@alicloud/openapi-client": "^0.4.
|
|
54
|
-
"@alicloud/ros-cdk-apigateway": "^1.
|
|
55
|
-
"@alicloud/ros-cdk-core": "^1.
|
|
56
|
-
"@alicloud/ros-cdk-dns": "^1.
|
|
57
|
-
"@alicloud/ros-cdk-ecs": "^1.
|
|
58
|
-
"@alicloud/ros-cdk-elasticsearchserverless": "^1.
|
|
59
|
-
"@alicloud/ros-cdk-fc3": "^1.
|
|
60
|
-
"@alicloud/ros-cdk-nas": "^1.
|
|
61
|
-
"@alicloud/ros-cdk-oss": "^1.
|
|
62
|
-
"@alicloud/ros-cdk-ossdeployment": "^1.
|
|
63
|
-
"@alicloud/ros-cdk-
|
|
64
|
-
"@alicloud/ros-cdk-
|
|
65
|
-
"@alicloud/ros-cdk-
|
|
66
|
-
"@alicloud/
|
|
52
|
+
"@alicloud/ims20190815": "^2.3.2",
|
|
53
|
+
"@alicloud/openapi-client": "^0.4.15",
|
|
54
|
+
"@alicloud/ros-cdk-apigateway": "^1.10.0",
|
|
55
|
+
"@alicloud/ros-cdk-core": "^1.10.0",
|
|
56
|
+
"@alicloud/ros-cdk-dns": "^1.10.0",
|
|
57
|
+
"@alicloud/ros-cdk-ecs": "^1.10.0",
|
|
58
|
+
"@alicloud/ros-cdk-elasticsearchserverless": "^1.10.0",
|
|
59
|
+
"@alicloud/ros-cdk-fc3": "^1.10.0",
|
|
60
|
+
"@alicloud/ros-cdk-nas": "^1.10.0",
|
|
61
|
+
"@alicloud/ros-cdk-oss": "^1.10.0",
|
|
62
|
+
"@alicloud/ros-cdk-ossdeployment": "^1.10.0",
|
|
63
|
+
"@alicloud/ros-cdk-ots": "^1.10.0",
|
|
64
|
+
"@alicloud/ros-cdk-ram": "^1.10.0",
|
|
65
|
+
"@alicloud/ros-cdk-rds": "^1.10.0",
|
|
66
|
+
"@alicloud/ros-cdk-ros": "^1.10.0",
|
|
67
|
+
"@alicloud/ros-cdk-sls": "^1.10.0",
|
|
68
|
+
"@alicloud/ros-cdk-vpc": "^1.10.0",
|
|
69
|
+
"@alicloud/ros20190910": "^3.6.0",
|
|
67
70
|
"ajv": "^8.17.1",
|
|
68
|
-
"ali-oss": "^6.
|
|
69
|
-
"chalk": "^5.
|
|
70
|
-
"commander": "^
|
|
71
|
+
"ali-oss": "^6.23.0",
|
|
72
|
+
"chalk": "^5.6.2",
|
|
73
|
+
"commander": "^14.0.1",
|
|
71
74
|
"i": "^0.3.7",
|
|
72
|
-
"i18n": "^0.15.
|
|
75
|
+
"i18n": "^0.15.2",
|
|
73
76
|
"jszip": "^3.10.1",
|
|
74
77
|
"lodash": "^4.17.21",
|
|
75
|
-
"npm": "^11.
|
|
76
|
-
"pino": "^9.
|
|
77
|
-
"pino-pretty": "^13.
|
|
78
|
-
"yaml": "^2.
|
|
78
|
+
"npm": "^11.5.2",
|
|
79
|
+
"pino": "^9.9.4",
|
|
80
|
+
"pino-pretty": "^13.1.1",
|
|
81
|
+
"yaml": "^2.8.1"
|
|
79
82
|
},
|
|
80
83
|
"devDependencies": {
|
|
81
84
|
"@types/ali-oss": "^6.16.11",
|
|
82
85
|
"@types/i18n": "^0.13.12",
|
|
83
|
-
"@types/jest": "^
|
|
84
|
-
"@types/lodash": "^4.17.
|
|
85
|
-
"@types/node": "^
|
|
86
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
87
|
-
"@typescript-eslint/parser": "^8.
|
|
88
|
-
"eslint": "^9.
|
|
89
|
-
"eslint-config-prettier": "^
|
|
90
|
-
"eslint-plugin-prettier": "^5.
|
|
91
|
-
"globals": "^
|
|
86
|
+
"@types/jest": "^30.0.0",
|
|
87
|
+
"@types/lodash": "^4.17.20",
|
|
88
|
+
"@types/node": "^24.3.0",
|
|
89
|
+
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
|
90
|
+
"@typescript-eslint/parser": "^8.39.1",
|
|
91
|
+
"eslint": "^9.33.0",
|
|
92
|
+
"eslint-config-prettier": "^10.1.8",
|
|
93
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
94
|
+
"globals": "^16.3.0",
|
|
92
95
|
"husky": "^9.1.7",
|
|
93
|
-
"jest": "^
|
|
94
|
-
"prettier": "^3.
|
|
95
|
-
"ts-jest": "^29.
|
|
96
|
+
"jest": "^30.0.5",
|
|
97
|
+
"prettier": "^3.6.2",
|
|
98
|
+
"ts-jest": "^29.4.1",
|
|
96
99
|
"ts-node": "^10.9.2",
|
|
97
|
-
"typescript": "^5.
|
|
100
|
+
"typescript": "^5.9.2"
|
|
98
101
|
}
|
|
99
102
|
}
|
|
@@ -8,9 +8,9 @@ const deploy = async (stackName, options) => {
|
|
|
8
8
|
common_1.logger.info('Validating yaml...');
|
|
9
9
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
10
10
|
common_1.logger.info('Yaml is valid! 🎉');
|
|
11
|
-
|
|
11
|
+
await (0, common_1.setContext)({ ...options, stackName, iacProvider: iac.provider }, true);
|
|
12
12
|
common_1.logger.info('Deploying stack...');
|
|
13
|
-
await (0, stack_1.deployStack)(stackName, iac
|
|
13
|
+
await (0, stack_1.deployStack)(stackName, iac);
|
|
14
14
|
common_1.logger.info('Stack deployed! 🎉');
|
|
15
15
|
};
|
|
16
16
|
exports.deploy = deploy;
|
|
@@ -5,7 +5,8 @@ const common_1 = require("../common");
|
|
|
5
5
|
const parser_1 = require("../parser");
|
|
6
6
|
const destroyStack = async (stackName, options) => {
|
|
7
7
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
8
|
-
|
|
8
|
+
await (0, common_1.setContext)({ stackName, ...options, iacProvider: iac.provider }, true);
|
|
9
|
+
const context = (0, common_1.getContext)();
|
|
9
10
|
common_1.logger.info(`Destroying stack: ${stackName}, provider: ${context.provider}, region: ${context.region}...`);
|
|
10
11
|
await (0, common_1.rosStackDelete)(context);
|
|
11
12
|
};
|
|
@@ -7,15 +7,16 @@ const validate_1 = require("./validate");
|
|
|
7
7
|
const deploy_1 = require("./deploy");
|
|
8
8
|
const template_1 = require("./template");
|
|
9
9
|
const destroy_1 = require("./destroy");
|
|
10
|
-
const
|
|
10
|
+
const local_1 = require("./local");
|
|
11
11
|
const program = new commander_1.Command();
|
|
12
12
|
program.name('si').description('CLI for ServerlessInsight').version((0, common_1.getVersion)());
|
|
13
13
|
program
|
|
14
14
|
.command('show')
|
|
15
15
|
.description('show string')
|
|
16
16
|
.action(async (options) => {
|
|
17
|
-
|
|
18
|
-
const
|
|
17
|
+
await (0, common_1.setContext)({ ...options });
|
|
18
|
+
const context = (0, common_1.getContext)();
|
|
19
|
+
const result = await (0, common_1.getIamInfo)(context);
|
|
19
20
|
console.log('result:', JSON.stringify(result));
|
|
20
21
|
});
|
|
21
22
|
program
|
|
@@ -23,9 +24,9 @@ program
|
|
|
23
24
|
.description('validate serverless Iac yaml')
|
|
24
25
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
25
26
|
.option('-s, --stage <stage>', 'specify the stage')
|
|
26
|
-
.action((stackName, { file, stage }) => {
|
|
27
|
+
.action(async (stackName, { file, stage }) => {
|
|
27
28
|
common_1.logger.debug('log command info');
|
|
28
|
-
(0, validate_1.validate)(stackName, { stage, location: file });
|
|
29
|
+
await (0, validate_1.validate)(stackName, { stage, location: file });
|
|
29
30
|
});
|
|
30
31
|
program
|
|
31
32
|
.command('deploy <stackName>')
|
|
@@ -33,10 +34,10 @@ program
|
|
|
33
34
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
34
35
|
.option('-s, --stage <stage>', 'specify the stage')
|
|
35
36
|
.option('-r, --region <region>', 'specify the region')
|
|
36
|
-
.option('-
|
|
37
|
-
.option('-
|
|
38
|
-
.option('-
|
|
39
|
-
.option('-
|
|
37
|
+
.option('-v, --provider <provider>', 'specify the provider')
|
|
38
|
+
.option('-k, --accessKeyId <accessKeyId>', 'specify the AccessKeyId')
|
|
39
|
+
.option('-x, --accessKeySecret <accessKeySecret>', 'specify the AccessKeySecret')
|
|
40
|
+
.option('-n, --securityToken <securityToken>', 'specify the SecurityToken')
|
|
40
41
|
.option('-p, --parameter <key=value>', 'override parameters', (value, previous) => {
|
|
41
42
|
const [key, val] = value.split('=');
|
|
42
43
|
previous[key] = val;
|
|
@@ -56,21 +57,21 @@ program
|
|
|
56
57
|
});
|
|
57
58
|
program
|
|
58
59
|
.command('template <stackName>')
|
|
59
|
-
.description('print
|
|
60
|
+
.description('print platform specific infrastructure as code template')
|
|
60
61
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
61
62
|
.option('-s, --stage <stage>', 'specify the stage')
|
|
62
63
|
.option('-t, --format <type>', 'output content type (JSON or YAML)', 'JSON')
|
|
63
|
-
.action((stackName, { format, file, stage }) => {
|
|
64
|
-
(0, template_1.template)(stackName, { format, location: file, stage });
|
|
64
|
+
.action(async (stackName, { format, file, stage }) => {
|
|
65
|
+
await (0, template_1.template)(stackName, { format, location: file, stage });
|
|
65
66
|
});
|
|
66
67
|
program
|
|
67
68
|
.command('destroy <stackName>')
|
|
68
69
|
.option('-f, --file <path>', 'specify the yaml file')
|
|
69
70
|
.option('-r, --region <region>', 'specify the region')
|
|
70
|
-
.option('-
|
|
71
|
-
.option('-
|
|
72
|
-
.option('-
|
|
73
|
-
.option('-
|
|
71
|
+
.option('-v, --provider <provider>', 'specify the provider')
|
|
72
|
+
.option('-k, --accessKeyId <accessKeyId>', 'specify the AccessKeyId')
|
|
73
|
+
.option('-x, --accessKeySecret <accessKeySecret>', 'specify the AccessKeySecret')
|
|
74
|
+
.option('-n, --securityToken <securityToken>', 'specify the SecurityToken')
|
|
74
75
|
.description('destroy serverless stack')
|
|
75
76
|
.action(async (stackName, { file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
|
|
76
77
|
await (0, destroy_1.destroyStack)(stackName, {
|
|
@@ -82,4 +83,19 @@ program
|
|
|
82
83
|
securityToken,
|
|
83
84
|
});
|
|
84
85
|
});
|
|
86
|
+
program
|
|
87
|
+
.command('local <stackName>')
|
|
88
|
+
.description('run Serverless application locally for debugging')
|
|
89
|
+
.option('-s, --stage <stage>', 'specify the stage', 'default')
|
|
90
|
+
.option('-p, --port <port>', 'specify the port', '3000')
|
|
91
|
+
.option('-d, --debug', 'enable debug mode')
|
|
92
|
+
.option('-w, --watch', 'enable file watch', true)
|
|
93
|
+
.action(async (stackName, { stage, port, debug, watch }) => {
|
|
94
|
+
await (0, local_1.runLocal)(stackName, {
|
|
95
|
+
stage,
|
|
96
|
+
port: Number(port) || 3000,
|
|
97
|
+
debug: !!debug,
|
|
98
|
+
watch: typeof watch === 'boolean' ? watch : true,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
85
101
|
program.parse();
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runLocal = void 0;
|
|
4
|
+
const common_1 = require("../common");
|
|
5
|
+
const localStack_1 = require("../stack/localStack");
|
|
6
|
+
const runLocal = async (stackName, opts) => {
|
|
7
|
+
const { stage, port, debug, watch } = opts;
|
|
8
|
+
await (0, common_1.setContext)({ stage });
|
|
9
|
+
common_1.logger.info(`run-local starting: stack=${stackName} stage=${stage} port=${port} debug=${debug} watch=${watch}`);
|
|
10
|
+
await (0, localStack_1.startLocalStack)();
|
|
11
|
+
// if (watch) {
|
|
12
|
+
// const cwd = process.cwd();
|
|
13
|
+
// try {
|
|
14
|
+
// fs.watch(cwd, { recursive: true }, (eventType, filename) => {
|
|
15
|
+
// if (!filename) return;
|
|
16
|
+
// const filePath = path.join(cwd, filename);
|
|
17
|
+
// logger.info(`file change detected: ${eventType} ${filePath}`);
|
|
18
|
+
// });
|
|
19
|
+
// logger.info(`watching files under ${process.cwd()}`);
|
|
20
|
+
// } catch (err) {
|
|
21
|
+
// logger.warn(`file watch not available: ${String(err)}`);
|
|
22
|
+
// }
|
|
23
|
+
// }
|
|
24
|
+
//
|
|
25
|
+
// const shutdown = () => {
|
|
26
|
+
// logger.info('shutting down run-local server');
|
|
27
|
+
// server.close(() => process.exit(0));
|
|
28
|
+
// };
|
|
29
|
+
// process.on('SIGINT', shutdown);
|
|
30
|
+
// process.on('SIGTERM', shutdown);
|
|
31
|
+
//
|
|
32
|
+
// // return server for tests if needed
|
|
33
|
+
// return { server, port, stage, debug, watch };
|
|
34
|
+
};
|
|
35
|
+
exports.runLocal = runLocal;
|
|
@@ -9,10 +9,10 @@ const yaml_1 = __importDefault(require("yaml"));
|
|
|
9
9
|
const deploy_1 = require("../stack/deploy");
|
|
10
10
|
const common_1 = require("../common");
|
|
11
11
|
const parser_1 = require("../parser");
|
|
12
|
-
const template = (stackName, options) => {
|
|
12
|
+
const template = async (stackName, options) => {
|
|
13
13
|
const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
|
|
14
|
-
|
|
15
|
-
const { template } = (0, deploy_1.generateStackTemplate)(stackName, iac
|
|
14
|
+
await (0, common_1.setContext)({ ...options, stackName, provider: iac.provider.name }, true);
|
|
15
|
+
const { template } = (0, deploy_1.generateStackTemplate)(stackName, iac);
|
|
16
16
|
if (typeof template === 'string') {
|
|
17
17
|
common_1.logger.info(`\n${template}`);
|
|
18
18
|
}
|
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.validate = void 0;
|
|
4
4
|
const common_1 = require("../common");
|
|
5
5
|
const parser_1 = require("../parser");
|
|
6
|
-
const validate = (stackName, options) => {
|
|
7
|
-
|
|
6
|
+
const validate = async (stackName, options) => {
|
|
7
|
+
await (0, common_1.setContext)({ stackName, ...options });
|
|
8
|
+
const context = (0, common_1.getContext)();
|
|
8
9
|
(0, parser_1.parseYaml)(context.iacLocation);
|
|
9
10
|
common_1.logger.info('Yaml is valid! 🎉');
|
|
10
11
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CODE_ZIP_SIZE_LIMIT = void 0;
|
|
4
|
-
exports.CODE_ZIP_SIZE_LIMIT =
|
|
3
|
+
exports.SI_BOOTSTRAP_BUCKET_PREFIX = exports.SI_BOOTSTRAP_FC_PREFIX = exports.OSS_DEPLOYMENT_TIMEOUT = exports.CODE_ZIP_SIZE_LIMIT = void 0;
|
|
4
|
+
exports.CODE_ZIP_SIZE_LIMIT = 300 * 1000; // 300 KB ROS TemplateBody size limit 512 KB
|
|
5
|
+
exports.OSS_DEPLOYMENT_TIMEOUT = 3000; // in seconds
|
|
6
|
+
exports.SI_BOOTSTRAP_FC_PREFIX = 'si-bootstrap-api';
|
|
7
|
+
exports.SI_BOOTSTRAP_BUCKET_PREFIX = 'si-bootstrap-artifacts';
|
|
@@ -3,9 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getContext = exports.setContext = exports.getIacLocation = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
8
|
const providerEnum_1 = require("./providerEnum");
|
|
9
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
10
|
+
const imsClient_1 = require("./imsClient");
|
|
11
|
+
const asyncLocalStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
9
12
|
const getIacLocation = (location) => {
|
|
10
13
|
const projectRoot = node_path_1.default.resolve(process.cwd());
|
|
11
14
|
return location
|
|
@@ -16,21 +19,39 @@ const getIacLocation = (location) => {
|
|
|
16
19
|
node_path_1.default.resolve(projectRoot, 'serverless-insight.yml');
|
|
17
20
|
};
|
|
18
21
|
exports.getIacLocation = getIacLocation;
|
|
19
|
-
const
|
|
20
|
-
|
|
22
|
+
const setContext = async (config, reaValToken = false) => {
|
|
23
|
+
const region = config.region ??
|
|
24
|
+
config.iacProvider?.region ??
|
|
25
|
+
process.env.ROS_REGION_ID ??
|
|
26
|
+
process.env.ALIYUN_REGION ??
|
|
27
|
+
'cn-hangzhou';
|
|
28
|
+
const context = {
|
|
21
29
|
stage: config.stage ?? 'default',
|
|
22
30
|
stackName: config.stackName ?? '',
|
|
23
31
|
provider: (config.provider ?? config.iacProvider?.name ?? providerEnum_1.ProviderEnum.ALIYUN),
|
|
24
|
-
region
|
|
25
|
-
config.iacProvider?.region ??
|
|
26
|
-
process.env.ROS_REGION_ID ??
|
|
27
|
-
process.env.ALIYUN_REGION ??
|
|
28
|
-
'cn-hangzhou',
|
|
32
|
+
region,
|
|
29
33
|
accessKeyId: config.accessKeyId ?? process.env.ALIYUN_ACCESS_KEY_ID,
|
|
30
34
|
accessKeySecret: config.accessKeySecret ?? process.env.ALIYUN_ACCESS_KEY_SECRET,
|
|
31
35
|
securityToken: config.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN,
|
|
32
36
|
iacLocation: (0, exports.getIacLocation)(config.location),
|
|
33
37
|
parameters: Object.entries(config.parameters ?? {}).map(([key, value]) => ({ key, value })),
|
|
38
|
+
stages: Object.entries(config.stages ?? {}).reduce((acc, [stage, parameters]) => ({
|
|
39
|
+
...acc,
|
|
40
|
+
[stage]: Object.entries(parameters).map(([key, value]) => ({ key, value })),
|
|
41
|
+
}), {}),
|
|
34
42
|
};
|
|
43
|
+
if (reaValToken) {
|
|
44
|
+
const iamInfo = await (0, imsClient_1.getIamInfo)(context);
|
|
45
|
+
context.accountId = iamInfo?.accountId;
|
|
46
|
+
}
|
|
47
|
+
asyncLocalStorage.enterWith(context);
|
|
35
48
|
};
|
|
36
|
-
exports.
|
|
49
|
+
exports.setContext = setContext;
|
|
50
|
+
const getContext = () => {
|
|
51
|
+
const context = asyncLocalStorage.getStore();
|
|
52
|
+
if (!context) {
|
|
53
|
+
throw new Error('No context found');
|
|
54
|
+
}
|
|
55
|
+
return context;
|
|
56
|
+
};
|
|
57
|
+
exports.getContext = getContext;
|
|
@@ -36,12 +36,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
39
|
+
exports.formatRosId = exports.calcValue = exports.calcRefs = exports.getFileSource = exports.readCodeSize = exports.resolveCode = void 0;
|
|
40
40
|
const node_path_1 = __importDefault(require("node:path"));
|
|
41
41
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
42
42
|
const ros = __importStar(require("@alicloud/ros-cdk-core"));
|
|
43
43
|
const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment"));
|
|
44
44
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
45
|
+
const lodash_1 = require("lodash");
|
|
45
46
|
const resolveCode = (location) => {
|
|
46
47
|
const filePath = node_path_1.default.resolve(process.cwd(), location);
|
|
47
48
|
const fileContent = node_fs_1.default.readFileSync(filePath);
|
|
@@ -65,19 +66,17 @@ const getFileSource = (fcName, location) => {
|
|
|
65
66
|
return { source, objectKey };
|
|
66
67
|
};
|
|
67
68
|
exports.getFileSource = getFileSource;
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
};
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (value.match(/\$\{ctx.\w+}/)) {
|
|
80
|
-
return evalCtx(value, ctx);
|
|
69
|
+
const calcRefs = (rawValue, ctx) => {
|
|
70
|
+
if (typeof rawValue === 'string') {
|
|
71
|
+
const containsStage = rawValue.match(/\$\{ctx.\w+}/);
|
|
72
|
+
const matchVar = rawValue.match(/^\$\{vars\.(\w+)}$/);
|
|
73
|
+
const containsVar = rawValue.match(/\$\{vars\.(\w+)}/);
|
|
74
|
+
const matchMap = rawValue.match(/^\$\{stages\.(\w+)}$/);
|
|
75
|
+
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
76
|
+
const matchFn = rawValue.match(/^\$\{functions\.(\w+(\.\w+)?)}$/);
|
|
77
|
+
let value = rawValue;
|
|
78
|
+
if (containsStage) {
|
|
79
|
+
value = value.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
81
80
|
}
|
|
82
81
|
if (matchVar?.length) {
|
|
83
82
|
return ros.Fn.ref(matchVar[1]);
|
|
@@ -88,23 +87,51 @@ const replaceReference = (value, ctx) => {
|
|
|
88
87
|
if (matchFn?.length) {
|
|
89
88
|
return ros.Fn.getAtt(matchFn[1], 'FunctionName');
|
|
90
89
|
}
|
|
91
|
-
if (containsMap?.length
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
if (containsVar?.length) {
|
|
95
|
-
return ros.Fn.sub(value.replace(/\$\{vars\.(\w+)}/g, '${$1}'));
|
|
96
|
-
}
|
|
97
|
-
if (containsMap?.length) {
|
|
98
|
-
return ros.Fn.sub(value.replace(/\$\{stages\.(\w+)}/g, '${$1}'));
|
|
90
|
+
if (containsMap?.length || containsVar?.length) {
|
|
91
|
+
value = ros.Fn.sub(rawValue.replace(/\$\{stages\.(\w+)}/g, '${$1}').replace(/\$\{vars\.(\w+)}/g, '${$1}'));
|
|
99
92
|
}
|
|
100
93
|
return value;
|
|
101
94
|
}
|
|
102
|
-
if (Array.isArray(
|
|
103
|
-
return
|
|
95
|
+
if (Array.isArray(rawValue)) {
|
|
96
|
+
return rawValue.map((item) => (0, exports.calcRefs)(item, ctx));
|
|
104
97
|
}
|
|
105
|
-
if (typeof
|
|
106
|
-
return Object.fromEntries(Object.entries(
|
|
98
|
+
if (typeof rawValue === 'object' && rawValue !== null) {
|
|
99
|
+
return Object.fromEntries(Object.entries(rawValue).map(([key, val]) => [key, (0, exports.calcRefs)(val, ctx)]));
|
|
100
|
+
}
|
|
101
|
+
return rawValue;
|
|
102
|
+
};
|
|
103
|
+
exports.calcRefs = calcRefs;
|
|
104
|
+
const getParam = (key, records) => {
|
|
105
|
+
return records?.find((param) => param.key === key)?.value;
|
|
106
|
+
};
|
|
107
|
+
const calcValue = (rawValue, ctx) => {
|
|
108
|
+
const containsStage = rawValue.match(/\$\{ctx.stage}/);
|
|
109
|
+
const containsVar = rawValue.match(/\$\{vars.\w+}/);
|
|
110
|
+
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
111
|
+
let value = rawValue;
|
|
112
|
+
if (containsStage?.length) {
|
|
113
|
+
value = rawValue.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
114
|
+
}
|
|
115
|
+
if (containsVar?.length) {
|
|
116
|
+
value = value.replace(/\$\{vars\.(\w+)}/g, (_, key) => getParam(key, ctx.parameters));
|
|
117
|
+
}
|
|
118
|
+
if (containsMap?.length) {
|
|
119
|
+
value = value.replace(/\$\{stages\.(\w+)}/g, (_, key) => getParam(key, (0, lodash_1.get)(ctx.stages, `${ctx.stage}`)));
|
|
107
120
|
}
|
|
108
121
|
return value;
|
|
109
122
|
};
|
|
110
|
-
exports.
|
|
123
|
+
exports.calcValue = calcValue;
|
|
124
|
+
const formatRosId = (id) => {
|
|
125
|
+
// Insert underscore before uppercase letters, but only when they follow a lowercase letter
|
|
126
|
+
let result = id.replace(/([a-z])([A-Z])/g, '$1_$2');
|
|
127
|
+
// Convert to lowercase
|
|
128
|
+
result = result.toLowerCase();
|
|
129
|
+
// Replace special characters with underscores
|
|
130
|
+
result = result.replace(/[/*,/#,-]/g, '_');
|
|
131
|
+
// Remove any number of underscores to single one
|
|
132
|
+
result = result.replace(/_+/g, '_');
|
|
133
|
+
// Remove leading underscores
|
|
134
|
+
result = result.replace(/^_/, '');
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
exports.formatRosId = formatRosId;
|
|
@@ -2,7 +2,7 @@ export * from './providerEnum';
|
|
|
2
2
|
export * from './logger';
|
|
3
3
|
export * from './getVersion';
|
|
4
4
|
export * from './rosClient';
|
|
5
|
-
export * from './
|
|
5
|
+
export * from './context';
|
|
6
6
|
export * from './iacHelper';
|
|
7
7
|
export * from './constants';
|
|
8
8
|
export * from './imsClient';
|
package/dist/src/common/index.js
CHANGED
|
@@ -18,7 +18,7 @@ __exportStar(require("./providerEnum"), exports);
|
|
|
18
18
|
__exportStar(require("./logger"), exports);
|
|
19
19
|
__exportStar(require("./getVersion"), exports);
|
|
20
20
|
__exportStar(require("./rosClient"), exports);
|
|
21
|
-
__exportStar(require("./
|
|
21
|
+
__exportStar(require("./context"), exports);
|
|
22
22
|
__exportStar(require("./iacHelper"), exports);
|
|
23
23
|
__exportStar(require("./constants"), exports);
|
|
24
24
|
__exportStar(require("./imsClient"), exports);
|
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.publishAssets = exports.getAssets = void 0;
|
|
39
|
+
exports.cleanupAssets = exports.publishAssets = exports.constructAssets = exports.getAssets = void 0;
|
|
40
40
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment"));
|
|
42
42
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -44,6 +44,7 @@ const jszip_1 = __importDefault(require("jszip"));
|
|
|
44
44
|
const logger_1 = require("./logger");
|
|
45
45
|
const lodash_1 = require("lodash");
|
|
46
46
|
const ali_oss_1 = __importDefault(require("ali-oss"));
|
|
47
|
+
const context_1 = require("./context");
|
|
47
48
|
const buildAssets = (rootPath, relativePath) => {
|
|
48
49
|
const location = node_path_1.default.resolve(rootPath, relativePath);
|
|
49
50
|
if (!node_fs_1.default.existsSync(location)) {
|
|
@@ -95,7 +96,8 @@ const zipAssets = async (assetsPath) => {
|
|
|
95
96
|
});
|
|
96
97
|
return zipPath;
|
|
97
98
|
};
|
|
98
|
-
const constructAssets = async ({ files, rootPath }
|
|
99
|
+
const constructAssets = async ({ files, rootPath, }) => {
|
|
100
|
+
const { region } = (0, context_1.getContext)();
|
|
99
101
|
const assets = await Promise.all(Object.entries(files)
|
|
100
102
|
.filter(([, fileItem]) => !fileItem.source.path.endsWith('.template.json'))
|
|
101
103
|
.map(async ([, fileItem]) => {
|
|
@@ -111,6 +113,7 @@ const constructAssets = async ({ files, rootPath }, region) => {
|
|
|
111
113
|
}));
|
|
112
114
|
return !(0, lodash_1.isEmpty)(assets) ? assets : undefined;
|
|
113
115
|
};
|
|
116
|
+
exports.constructAssets = constructAssets;
|
|
114
117
|
const ensureBucketExits = async (bucketName, ossClient) => await ossClient.getBucketInfo(bucketName).catch((err) => {
|
|
115
118
|
if (err.code === 'NoSuchBucket') {
|
|
116
119
|
logger_1.logger.info(`Bucket: ${bucketName} not exists, creating...`);
|
|
@@ -124,18 +127,19 @@ const ensureBucketExits = async (bucketName, ossClient) => await ossClient.getBu
|
|
|
124
127
|
throw err;
|
|
125
128
|
}
|
|
126
129
|
});
|
|
127
|
-
const publishAssets = async (assets
|
|
128
|
-
|
|
129
|
-
if (!constructedAssets?.length) {
|
|
130
|
+
const publishAssets = async (assets) => {
|
|
131
|
+
if (!assets?.length) {
|
|
130
132
|
logger_1.logger.info('No assets to publish, skipped!');
|
|
131
133
|
return;
|
|
132
134
|
}
|
|
133
|
-
const
|
|
135
|
+
const context = (0, context_1.getContext)();
|
|
136
|
+
const bucketName = assets[0].bucketName;
|
|
134
137
|
const client = new ali_oss_1.default({
|
|
135
138
|
region: `oss-${context.region}`,
|
|
136
139
|
accessKeyId: context.accessKeyId,
|
|
137
140
|
accessKeySecret: context.accessKeySecret,
|
|
138
141
|
bucket: bucketName,
|
|
142
|
+
timeout: 600000, // 10 minutes
|
|
139
143
|
});
|
|
140
144
|
await ensureBucketExits(bucketName, client);
|
|
141
145
|
const headers = {
|
|
@@ -143,10 +147,32 @@ const publishAssets = async (assets, context) => {
|
|
|
143
147
|
'x-oss-object-acl': 'default',
|
|
144
148
|
'x-oss-forbid-overwrite': 'false',
|
|
145
149
|
};
|
|
146
|
-
await Promise.all(
|
|
150
|
+
await Promise.all(assets.map(async ({ source, objectKey }) => {
|
|
147
151
|
await client.put(objectKey, node_path_1.default.normalize(source), { headers });
|
|
148
|
-
logger_1.logger.
|
|
152
|
+
logger_1.logger.debug(`Upload file: ${source} to bucket: ${bucketName} successfully!`);
|
|
149
153
|
}));
|
|
150
154
|
return bucketName;
|
|
151
155
|
};
|
|
152
156
|
exports.publishAssets = publishAssets;
|
|
157
|
+
const cleanupAssets = async (assets) => {
|
|
158
|
+
if (!assets?.length) {
|
|
159
|
+
logger_1.logger.info('No assets to cleanup, skipped!');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const context = (0, context_1.getContext)();
|
|
163
|
+
const bucketName = assets[0].bucketName;
|
|
164
|
+
const client = new ali_oss_1.default({
|
|
165
|
+
region: `oss-${context.region}`,
|
|
166
|
+
accessKeyId: context.accessKeyId,
|
|
167
|
+
accessKeySecret: context.accessKeySecret,
|
|
168
|
+
bucket: bucketName,
|
|
169
|
+
});
|
|
170
|
+
await Promise.all(assets.map(async ({ objectKey }) => {
|
|
171
|
+
await client.delete(objectKey);
|
|
172
|
+
logger_1.logger.debug(`Cleanup file: ${objectKey} from bucket: ${bucketName} successfully!`);
|
|
173
|
+
}));
|
|
174
|
+
// delete the bucket
|
|
175
|
+
await client.deleteBucket(bucketName);
|
|
176
|
+
logger_1.logger.debug(`Cleanup bucket: ${bucketName} successfully!`);
|
|
177
|
+
};
|
|
178
|
+
exports.cleanupAssets = cleanupAssets;
|
|
@@ -37,11 +37,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.rosStackDelete = exports.rosStackDeploy = void 0;
|
|
40
|
-
const tea_util_1 = __importDefault(require("@alicloud/tea-util"));
|
|
41
40
|
const ros20190910_1 = __importStar(require("@alicloud/ros20190910"));
|
|
42
41
|
const openapi_client_1 = require("@alicloud/openapi-client");
|
|
42
|
+
const tea_util_1 = __importDefault(require("@alicloud/tea-util"));
|
|
43
43
|
const logger_1 = require("./logger");
|
|
44
44
|
const lang_1 = require("../lang");
|
|
45
|
+
const context_1 = require("./context");
|
|
45
46
|
const client = new ros20190910_1.default(new openapi_client_1.Config({
|
|
46
47
|
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
|
|
47
48
|
accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET,
|
|
@@ -85,7 +86,7 @@ const updateStack = async (stackId, templateBody, context) => {
|
|
|
85
86
|
return await getStackActionResult(response.body?.stackId || '', context.region);
|
|
86
87
|
}
|
|
87
88
|
catch (err) {
|
|
88
|
-
const {
|
|
89
|
+
const { message, statusCode } = err || {};
|
|
89
90
|
if (statusCode === 400 && message.includes('Update the completely same stack')) {
|
|
90
91
|
logger_1.logger.warn(`${lang_1.lang.__('UPDATE_COMPLETELY_SAME_STACK')}`);
|
|
91
92
|
return null;
|
|
@@ -154,7 +155,8 @@ const getStackActionResult = async (stackId, region) => {
|
|
|
154
155
|
}, 5000); // 5 seconds interval
|
|
155
156
|
});
|
|
156
157
|
};
|
|
157
|
-
const rosStackDeploy = async (stackName, templateBody
|
|
158
|
+
const rosStackDeploy = async (stackName, templateBody) => {
|
|
159
|
+
const context = (0, context_1.getContext)();
|
|
158
160
|
const stackInfo = await getStackByName(stackName, context.region);
|
|
159
161
|
if (stackInfo) {
|
|
160
162
|
const { Status: stackStatus } = stackInfo;
|
|
@@ -186,7 +188,7 @@ const rosStackDelete = async ({ stackName, region, }) => {
|
|
|
186
188
|
});
|
|
187
189
|
await client.deleteStack(deleteStackRequest);
|
|
188
190
|
await getStackActionResult(stackInfo.stackId, region);
|
|
189
|
-
logger_1.logger.info(`Stack: ${stackName} deleted
|
|
191
|
+
logger_1.logger.info(`Stack: ${stackName} deleted!🗑 `);
|
|
190
192
|
}
|
|
191
193
|
catch (err) {
|
|
192
194
|
logger_1.logger.error(`Stack: ${stackName} delete failed! ❌, error: ${JSON.stringify(err)}`);
|
package/dist/src/parser/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const tagParser_1 = require("./tagParser");
|
|
|
9
9
|
const yaml_1 = require("yaml");
|
|
10
10
|
const validator_1 = require("../validator");
|
|
11
11
|
const bucketParser_1 = require("./bucketParser");
|
|
12
|
+
const tableParser_1 = require("./tableParser");
|
|
12
13
|
const validateExistence = (path) => {
|
|
13
14
|
if (!(0, node_fs_1.existsSync)(path)) {
|
|
14
15
|
throw new Error(`File does not exist at path: ${path}`);
|
|
@@ -24,6 +25,7 @@ const transformYaml = (iacJson) => {
|
|
|
24
25
|
functions: (0, functionParser_1.parseFunction)(iacJson.functions),
|
|
25
26
|
events: (0, eventParser_1.parseEvent)(iacJson.events),
|
|
26
27
|
databases: (0, databaseParser_1.parseDatabase)(iacJson.databases),
|
|
28
|
+
tables: (0, tableParser_1.parseTable)(iacJson.tables),
|
|
27
29
|
tags: (0, tagParser_1.parseTag)(iacJson.tags),
|
|
28
30
|
buckets: (0, bucketParser_1.parseBucket)(iacJson.buckets),
|
|
29
31
|
};
|