@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.
Files changed (47) hide show
  1. package/dist/package.json +40 -37
  2. package/dist/src/commands/deploy.js +2 -2
  3. package/dist/src/commands/destroy.js +2 -1
  4. package/dist/src/commands/index.js +32 -16
  5. package/dist/src/commands/local.js +35 -0
  6. package/dist/src/commands/template.js +3 -3
  7. package/dist/src/commands/validate.js +3 -2
  8. package/dist/src/common/constants.js +5 -2
  9. package/dist/src/common/{actionContext.js → context.js} +30 -9
  10. package/dist/src/common/iacHelper.js +54 -27
  11. package/dist/src/common/index.d.ts +1 -1
  12. package/dist/src/common/index.js +1 -1
  13. package/dist/src/common/rosAssets.js +34 -8
  14. package/dist/src/common/rosClient.js +6 -4
  15. package/dist/src/parser/index.js +2 -0
  16. package/dist/src/parser/tableParser.js +41 -0
  17. package/dist/src/stack/deploy.js +30 -13
  18. package/dist/src/stack/localStack/event.js +38 -0
  19. package/dist/src/stack/localStack/index.d.ts +2 -0
  20. package/dist/src/stack/localStack/index.js +23 -0
  21. package/dist/src/stack/rfsStack/index.d.ts +2 -2
  22. package/dist/src/stack/rfsStack/index.js +2 -1
  23. package/dist/src/stack/rosStack/bootstrap.js +157 -8
  24. package/dist/src/stack/rosStack/bucket.js +13 -12
  25. package/dist/src/stack/rosStack/database.js +11 -12
  26. package/dist/src/stack/rosStack/event.js +21 -21
  27. package/dist/src/stack/rosStack/function.js +66 -46
  28. package/dist/src/stack/rosStack/index.d.ts +2 -2
  29. package/dist/src/stack/rosStack/index.js +6 -3
  30. package/dist/src/stack/rosStack/stage.js +1 -1
  31. package/dist/src/stack/rosStack/table.js +95 -0
  32. package/dist/src/stack/rosStack/tag.js +1 -1
  33. package/dist/src/stack/rosStack/vars.js +3 -3
  34. package/dist/src/types/domains/table.js +16 -0
  35. package/dist/src/types/index.d.ts +5 -0
  36. package/dist/src/validator/functionSchema.js +1 -1
  37. package/dist/src/validator/iacSchema.js +2 -0
  38. package/dist/src/validator/rootSchema.js +3 -0
  39. package/dist/src/validator/tableschema.js +72 -0
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +12 -0
  42. package/layers/si-bootstrap-sdk/README.md +1 -0
  43. package/layers/si-bootstrap-sdk/package-lock.json +875 -0
  44. package/layers/si-bootstrap-sdk/package.json +33 -0
  45. package/package.json +40 -37
  46. package/samples/aliyun-poc-fc-gpu.yml +23 -22
  47. package/samples/aliyun-poc-table.yml +48 -0
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTable = parseTable;
4
+ const lodash_1 = require("lodash");
5
+ function parseTable(tablesRaw) {
6
+ if ((0, lodash_1.isEmpty)(tablesRaw)) {
7
+ return undefined;
8
+ }
9
+ return Object.entries(tablesRaw)?.map(([key, table]) => {
10
+ const throughput = (0, lodash_1.omitBy)({
11
+ reserved: (0, lodash_1.omitBy)({
12
+ read: table.throughput?.reserved?.read,
13
+ write: table.throughput?.reserved?.write,
14
+ }, lodash_1.isNil),
15
+ onDemand: (0, lodash_1.omitBy)({
16
+ read: table.throughput?.on_demand?.read,
17
+ write: table.throughput?.on_demand?.write,
18
+ }, lodash_1.isNil),
19
+ }, lodash_1.isEmpty);
20
+ return {
21
+ key,
22
+ collection: table.collection,
23
+ name: table.name,
24
+ type: table.type,
25
+ desc: table.desc,
26
+ network: {
27
+ type: table.network?.type ?? 'PRIVATE',
28
+ ingressRules: table.network?.ingress_rules ?? [],
29
+ },
30
+ throughput: !(0, lodash_1.isEmpty)(throughput) ? throughput : undefined,
31
+ keySchema: table.key_schema?.map((keySchema) => ({
32
+ name: keySchema.name,
33
+ type: keySchema.type,
34
+ })) ?? [],
35
+ attributes: table.attributes?.map((attribute) => ({
36
+ name: attribute.name,
37
+ type: attribute.type,
38
+ })) ?? [],
39
+ };
40
+ });
41
+ }
@@ -43,7 +43,8 @@ const common_1 = require("../common");
43
43
  const rosStack_1 = require("./rosStack");
44
44
  const rfsStack_1 = require("./rfsStack");
45
45
  const lodash_1 = require("lodash");
46
- const generateRosStackTemplate = (stackName, iac, context) => {
46
+ const generateRosStackTemplate = (stackName, iac) => {
47
+ const context = (0, common_1.getContext)();
47
48
  const app = new ros.App();
48
49
  new rosStack_1.RosStack(app, iac, context);
49
50
  const assembly = app.synth();
@@ -57,29 +58,45 @@ const generateRosStackTemplate = (stackName, iac, context) => {
57
58
  return { template, assets };
58
59
  };
59
60
  exports.generateRosStackTemplate = generateRosStackTemplate;
60
- const generateRfsStackTemplate = (stackName, iac, context) => {
61
- const stack = new rfsStack_1.RfsStack(iac, context);
61
+ const generateRfsStackTemplate = (stackName, iac) => {
62
+ const stack = new rfsStack_1.RfsStack(iac);
62
63
  const hcl = stack.toHclTerraform();
63
64
  console.log('HCL:', hcl);
64
65
  return { template: hcl };
65
66
  };
66
67
  exports.generateRfsStackTemplate = generateRfsStackTemplate;
67
- const deployStack = async (stackName, iac, context) => {
68
- const { template, assets } = (0, exports.generateRosStackTemplate)(stackName, iac, context);
69
- await (0, rosStack_1.prepareBootstrapStack)(context);
68
+ const deployStack = async (stackName, iac) => {
69
+ const { template, assets } = (0, exports.generateRosStackTemplate)(stackName, iac);
70
+ await (0, rosStack_1.prepareBootstrapStack)();
70
71
  common_1.logger.info(`Deploying stack, publishing assets...`);
71
- await (0, common_1.publishAssets)(assets, context);
72
- common_1.logger.info(`Assets published! 🎉`);
73
- await (0, common_1.rosStackDeploy)(stackName, template, context);
74
- common_1.logger.info(`Stack deployed! 🎉`);
72
+ const constructedAssets = await (0, common_1.constructAssets)(assets);
73
+ try {
74
+ await (0, common_1.publishAssets)(constructedAssets);
75
+ common_1.logger.info(`Assets published! 🎉`);
76
+ await (0, common_1.rosStackDeploy)(stackName, template);
77
+ }
78
+ catch (e) {
79
+ common_1.logger.error(`Failed to deploy stack: ${e}`);
80
+ throw e;
81
+ }
82
+ finally {
83
+ try {
84
+ common_1.logger.info(`Cleaning up temporary Assets...`);
85
+ await (0, common_1.cleanupAssets)(constructedAssets);
86
+ common_1.logger.info(`Assets cleaned up!♻️`);
87
+ }
88
+ catch (e) {
89
+ common_1.logger.error(`Failed to cleanup assets, it wont affect the deployment result, but to avoid potential cost, you can delete the temporary bucket : ${constructedAssets?.[0].bucketName}, error details:${e}`);
90
+ }
91
+ }
75
92
  };
76
93
  exports.deployStack = deployStack;
77
- const generateStackTemplate = (stackName, iac, context) => {
94
+ const generateStackTemplate = (stackName, iac) => {
78
95
  if (iac.provider.name === common_1.ProviderEnum.ALIYUN) {
79
- return (0, exports.generateRosStackTemplate)(stackName, iac, context);
96
+ return (0, exports.generateRosStackTemplate)(stackName, iac);
80
97
  }
81
98
  else if (iac.provider.name === common_1.ProviderEnum.HUAWEI) {
82
- return (0, exports.generateRfsStackTemplate)(stackName, iac, context);
99
+ return (0, exports.generateRfsStackTemplate)(stackName, iac);
83
100
  }
84
101
  return { template: '' };
85
102
  };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startEvents = void 0;
7
+ const node_http_1 = __importDefault(require("node:http"));
8
+ const common_1 = require("../../common");
9
+ const types_1 = require("../../types");
10
+ const lodash_1 = require("lodash");
11
+ const startApiGatewayServer = (event) => {
12
+ const server = node_http_1.default.createServer((req, res) => {
13
+ const matchedTrigger = event.triggers.find((trigger) => trigger.method === req.method && trigger.path === req.url);
14
+ if (!matchedTrigger) {
15
+ res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
16
+ res.end('Not Found\n');
17
+ common_1.logger.warn(`API Gateway Event - ${req.method} ${req.url} -> Not Found`);
18
+ return;
19
+ }
20
+ res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
21
+ res.end(`Invoked backend: ${matchedTrigger.backend}\n`);
22
+ common_1.logger.info(`API Gateway Event - ${req.method} ${req.url} -> ${matchedTrigger.backend}`);
23
+ });
24
+ const port = 3000 + Math.floor(Math.random() * 1000);
25
+ server.listen(port, () => {
26
+ common_1.logger.info(`API Gateway "${event.name}" listening on http://localhost:${port}`);
27
+ });
28
+ };
29
+ const startEvents = (events) => {
30
+ const apiGateways = events?.filter((event) => event.type === types_1.EventTypes.API_GATEWAY);
31
+ if ((0, lodash_1.isEmpty)(apiGateways)) {
32
+ return;
33
+ }
34
+ apiGateways.forEach((gateway) => {
35
+ startApiGatewayServer(gateway);
36
+ });
37
+ };
38
+ exports.startEvents = startEvents;
@@ -0,0 +1,2 @@
1
+ export * from './event';
2
+ export declare const startLocalStack: () => Promise<void>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = 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);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.startLocalStack = void 0;
18
+ __exportStar(require("./event"), exports);
19
+ const startLocalStack = async () => {
20
+ // Placeholder for starting local stack logic
21
+ console.log('Local stack started');
22
+ };
23
+ exports.startLocalStack = startLocalStack;
@@ -1,9 +1,9 @@
1
- import { ActionContext, ServerlessIac } from '../../types';
1
+ import { Context, ServerlessIac } from '../../types';
2
2
  export declare class RfsStack {
3
3
  private readonly iac;
4
4
  private readonly context;
5
5
  private hcl;
6
- constructor(iac: ServerlessIac, context: ActionContext);
6
+ constructor(iac: ServerlessIac, context?: Context);
7
7
  toHclTerraform(): string;
8
8
  appendHcl(hcl: string): void;
9
9
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RfsStack = void 0;
4
4
  const function_1 = require("./function");
5
+ const common_1 = require("../../common");
5
6
  const provider = (stack, context) => {
6
7
  const hcl = `
7
8
  terraform {
@@ -22,7 +23,7 @@ provider "huaweicloud" {
22
23
  stack.appendHcl(hcl);
23
24
  };
24
25
  class RfsStack {
25
- constructor(iac, context) {
26
+ constructor(iac, context = (0, common_1.getContext)()) {
26
27
  this.iac = iac;
27
28
  this.context = context;
28
29
  this.hcl = '';
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.prepareBootstrapStack = void 0;
4
4
  const common_1 = require("../../common");
5
5
  const getBootstrapTemplate = async (context) => {
6
- const iamInfo = await (0, common_1.getIamInfo)(context);
7
- const stackName = `serverlessInsight-bootstrap-${iamInfo?.accountId}-${context.region}`;
6
+ const stackName = `si-bootstrap-${context.accountId}-${context.region}`;
8
7
  const template = {
9
8
  Description: 'ServerlessInsight Bootstrap Stack',
10
9
  Metadata: {
@@ -14,12 +13,10 @@ const getBootstrapTemplate = async (context) => {
14
13
  },
15
14
  ROSTemplateFormatVersion: '2015-09-01',
16
15
  Resources: {
17
- ServerlessInsight_artifacts_bucket: {
16
+ si_auto_artifacts_bucket: {
18
17
  Type: 'ALIYUN::OSS::Bucket',
19
18
  Properties: {
20
- BucketName: {
21
- 'Fn::Sub': 'si-bootstrap-artifacts-${ALIYUN::AccountId}-${ALIYUN::Region}',
22
- },
19
+ BucketName: `${common_1.SI_BOOTSTRAP_BUCKET_PREFIX}-${context.accountId}-${context.region}`,
23
20
  AccessControl: 'private',
24
21
  DeletionForce: false,
25
22
  EnableOssHdfsService: false,
@@ -29,12 +26,164 @@ const getBootstrapTemplate = async (context) => {
29
26
  },
30
27
  },
31
28
  },
29
+ si_auto_bootstrap_api_lambda: {
30
+ Type: 'ALIYUN::FC3::Function',
31
+ Properties: {
32
+ FunctionName: `${common_1.SI_BOOTSTRAP_FC_PREFIX}-${context.accountId}-${context.region}`,
33
+ Description: 'ServerlessInsight Bootstrap API',
34
+ Handler: 'index.handler',
35
+ Runtime: 'nodejs20',
36
+ Layers: [
37
+ `acs:fc:${context.region}:${context.accountId}:layers/si-bootstrap-sdk/versions/18`,
38
+ ],
39
+ Code: {
40
+ SourceCode: `
41
+ const { bootstrapHandler } = require('@geek-fun/si-bootstrap-sdk');
42
+
43
+ module.exports.handler = async (rawEvent, context) => {
44
+ // 处理 Buffer 类型的事件
45
+ const event = parseEvent(rawEvent);
46
+
47
+ const commonResponse = {
48
+ RequestId: event.requestId,
49
+ LogicalResourceId: event.logicalResourceId,
50
+ StackId: event.stackId
51
+ };
52
+
53
+ try {
54
+ // 处理业务逻辑
55
+ const result = await bootstrapHandler(event);
56
+
57
+ // 构建符合 ROS 要求的响应结构
58
+ const rosResponse = {
59
+ ...commonResponse,
60
+ Status: result.status,
61
+ Reason: result.reason,
62
+ PhysicalResourceId: result.physicalResourceId,
63
+ Data: result.data || {} // 业务数据
64
+ };
65
+
66
+ // 如果是删除操作,不需要返回数据
67
+ if (event.requestType === 'Delete') {
68
+ delete rosResponse.Data;
69
+ }
70
+
71
+ // 发送响应到 ROS 服务(如果提供了 ResponseURL)
72
+ if (event.responseURL) {
73
+ await sendResponse(event.responseURL, rosResponse);
74
+ }
75
+
76
+ // 返回成功响应
77
+ return {
78
+ statusCode: 200,
79
+ body: JSON.stringify({
80
+ message: 'Request processed successfully',
81
+ rosResponse
82
+ })
83
+ };
84
+ } catch (error) {
85
+ console.error('Error:', error);
86
+
87
+ // 构建错误响应
88
+ const errorResponse = {
89
+ ...commonResponse,
90
+ Status: 'FAILED',
91
+ Reason: error.message || 'Internal Server Error',
92
+ PhysicalResourceId: 'error-' + Date.now()
93
+ };
94
+
95
+ // 发送错误响应到 ROS 服务
96
+ if (event.responseURL) {
97
+ try {
98
+ await sendResponse(event.responseURL, errorResponse);
99
+ } catch (err) {
100
+ console.error('Failed to send error response:', err);
101
+ }
102
+ }
103
+
104
+ // 返回错误响应
105
+ return {
106
+ statusCode: 500,
107
+ body: JSON.stringify({
108
+ error: 'Internal Server Error',
109
+ details: error.message,
110
+ rosErrorResponse: errorResponse
111
+ })
112
+ };
113
+ }
114
+ };
115
+
116
+ // 使用原生 fetch API 发送响应
117
+ async function sendResponse(responseUrl, responseBody) {
118
+
119
+ try {
120
+ const body = JSON.stringify(responseBody);
121
+
122
+ const response = await fetch(responseUrl, {
123
+ method: 'POST',
124
+ headers: {
125
+ 'Content-Type': 'application/json',
126
+ 'Content-Length': Buffer.byteLength(body).toString(),
127
+ 'Date': new Date().toUTCString()
128
+ },
129
+ body: body
130
+ });
131
+
132
+ if (!response.ok) {
133
+ const errorText = await response.text();
134
+ throw new Error(\`Failed to send response. Status: \${response.status}, Body: \${errorText}\`);
135
+ }
136
+
137
+ console.log('Response sent successfully');
138
+ } catch (error) {
139
+ console.error('Error sending response:', error);
140
+ throw error;
141
+ }
142
+ }
143
+
144
+
145
+ const parseEvent = (rawEvent) => {
146
+ // 处理 Buffer 类型的事件
147
+ let event;
148
+ if (Buffer.isBuffer(rawEvent)) {
149
+ event = JSON.parse(rawEvent.toString('utf8'));
150
+ } else if (typeof rawEvent === 'string') {
151
+ event = JSON.parse(rawEvent);
152
+ } else {
153
+ event = rawEvent;
154
+ }
155
+
156
+ const { credentials, ...resourceProperties } = event.ResourceProperties
157
+ return {
158
+ stackId: event.StackId,
159
+ responseURL: event.ResponseURL,
160
+ resourceOwnerId: event.ResourceOwnerId,
161
+ callerId: event.CallerId,
162
+ resourceProperties,
163
+ eventType: event.ResourceType,
164
+ requestType: event.RequestType?.toUpperCase(),
165
+ resourceType: resourceProperties.resource,
166
+ regionId: event.RegionId,
167
+ stackName: event.StackName,
168
+ requestId: event.RequestId,
169
+ intranetResponseURL: event.IntranetResponseURL,
170
+ logicalResourceId: event.LogicalResourceId,
171
+ physicalResourceId: event.PhysicalResourceId,
172
+ credentials
173
+ };
174
+ };`,
175
+ },
176
+ MemorySize: 512,
177
+ Timeout: 900, // 15 minutes
178
+ },
179
+ },
32
180
  },
33
181
  };
34
182
  return { stackName, template };
35
183
  };
36
- const prepareBootstrapStack = async (context) => {
184
+ const prepareBootstrapStack = async () => {
185
+ const context = (0, common_1.getContext)();
37
186
  const { stackName, template } = await getBootstrapTemplate(context);
38
- await (0, common_1.rosStackDeploy)(stackName, template, context);
187
+ await (0, common_1.rosStackDeploy)(stackName, template);
39
188
  };
40
189
  exports.prepareBootstrapStack = prepareBootstrapStack;
@@ -78,41 +78,42 @@ const resolveBuckets = (scope, buckets, context) => {
78
78
  }, true);
79
79
  }
80
80
  buckets.forEach((bucket) => {
81
- const ossBucket = new oss.Bucket(scope, (0, common_1.replaceReference)(bucket.key, context), {
82
- bucketName: (0, common_1.replaceReference)(bucket.name, context),
83
- accessControl: aclMap.get((0, common_1.replaceReference)(bucket.security?.acl, context) ?? ''),
81
+ const ossBucket = new oss.Bucket(scope, bucket.key, {
82
+ bucketName: (0, common_1.calcRefs)(bucket.name, context),
83
+ accessControl: aclMap.get((0, common_1.calcRefs)(bucket.security?.acl, context) ?? ''),
84
+ blockPublicAccess: (0, common_1.calcRefs)(bucket.security?.acl, context) === types_1.BucketAccessEnum.PRIVATE,
84
85
  websiteConfigurationV2: bucket.website
85
86
  ? {
86
87
  indexDocument: {
87
88
  type: '0',
88
- suffix: (0, common_1.replaceReference)(bucket.website.index, context),
89
+ suffix: (0, common_1.calcRefs)(bucket.website.index, context),
89
90
  supportSubDir: 'true',
90
91
  },
91
92
  errorDocument: {
92
- httpStatus: `${(0, common_1.replaceReference)(bucket.website.error_code, context)}`,
93
- key: (0, common_1.replaceReference)(bucket.website.error_page, context),
93
+ httpStatus: `${(0, common_1.calcRefs)(bucket.website.error_code, context)}`,
94
+ key: (0, common_1.calcRefs)(bucket.website.error_page, context),
94
95
  },
95
96
  }
96
97
  : undefined,
97
98
  });
98
99
  if (bucket.website?.code) {
99
- const filePath = node_path_1.default.resolve(process.cwd(), (0, common_1.replaceReference)(bucket.website.code, context));
100
- new ossDeployment.BucketDeployment(scope, `si_auto_${bucket.key}_bucket_code_deployment`, {
100
+ const filePath = node_path_1.default.resolve(process.cwd(), (0, common_1.calcValue)(bucket.website.code, context));
101
+ new ossDeployment.BucketDeployment(scope, (0, common_1.formatRosId)(`si_auto_${bucket.key}_bucket_code_deployment`), {
101
102
  sources: (0, common_1.getAssets)(filePath),
102
103
  destinationBucket: ossBucket.attrName,
103
104
  roleArn: siAutoOssDeploymentBucketRole.attrArn,
104
- timeout: 3000,
105
+ timeout: common_1.OSS_DEPLOYMENT_TIMEOUT,
105
106
  logMonitoring: false,
106
107
  retainOnCreate: false,
107
108
  }, true);
108
109
  }
109
110
  if (bucket.website?.domain) {
110
111
  const { rr, domainName } = (0, common_1.splitDomain)(bucket.website.domain);
111
- new oss.Domain(scope, `${bucket.key}_custom_domain_${(0, common_1.encodeBase64ForRosId)(bucket.website.domain)}`, {
112
+ new oss.Domain(scope, (0, common_1.formatRosId)(`${bucket.key}_custom_domain`), {
112
113
  bucketName: ossBucket.attrName,
113
- domainName: (0, common_1.replaceReference)(bucket.website.domain, context),
114
+ domainName: (0, common_1.calcRefs)(bucket.website.domain, context),
114
115
  });
115
- new dns.DomainRecord(scope, `${bucket.key}_custom_domain_record_${(0, common_1.encodeBase64ForRosId)(bucket.website.domain)}`, {
116
+ new dns.DomainRecord(scope, (0, common_1.formatRosId)(`${bucket.key}_custom_domain_record`), {
116
117
  domainName: domainName,
117
118
  rr,
118
119
  type: 'CNAME',
@@ -212,19 +212,18 @@ const resolveDatabases = (scope, databases, context) => {
212
212
  databases.forEach((db) => {
213
213
  const { engine, version, category, dbInstanceClass, quota, storage } = rdsEngineMap.get(`${db.type}-${db.version}`) ?? {};
214
214
  if (["ELASTICSEARCH_SERVERLESS" /* DatabaseEnum.ELASTICSEARCH_SERVERLESS */].includes(db.type)) {
215
- new esServerless.App(scope, (0, common_1.replaceReference)(db.key, context), {
216
- appName: (0, common_1.replaceReference)(db.name, context),
215
+ new esServerless.App(scope, db.key, {
216
+ appName: (0, common_1.calcRefs)(db.name, context),
217
217
  appVersion: version,
218
218
  authentication: {
219
219
  basicAuth: [
220
220
  {
221
- password: (0, common_1.replaceReference)(db.security.basicAuth.password, context),
221
+ password: (0, common_1.calcRefs)(db.security.basicAuth.password, context),
222
222
  },
223
223
  ],
224
224
  },
225
225
  quotaInfo: {
226
- cu: db.cu.min,
227
- storage: db.storage.min,
226
+ minCu: db.cu.min,
228
227
  appType: category,
229
228
  },
230
229
  // network: [
@@ -246,7 +245,7 @@ const resolveDatabases = (scope, databases, context) => {
246
245
  "RDS_PGSQL_SERVERLESS" /* DatabaseEnum.RDS_PGSQL_SERVERLESS */,
247
246
  "RDS_MSSQL_SERVERLESS" /* DatabaseEnum.RDS_MSSQL_SERVERLESS */,
248
247
  ].includes(db.type)) {
249
- new rds.DBInstance(scope, (0, common_1.replaceReference)(db.key, context), {
248
+ new rds.DBInstance(scope, db.key, {
250
249
  engine: engine,
251
250
  /**
252
251
  * Serverless 实例
@@ -255,7 +254,7 @@ const resolveDatabases = (scope, databases, context) => {
255
254
  * PostgreSQL:14.0、15.0、16.0 - PGSQL_HA_14, PGSQL_14 PGSQL_HA_15, PGSQL_15, PGSQL_HA_16,PGSQL_16
256
255
  */
257
256
  engineVersion: version,
258
- dbInstanceStorage: (0, common_1.replaceReference)(db.storage.min, context),
257
+ dbInstanceStorage: (0, common_1.calcRefs)(db.storage.min, context),
259
258
  /** Serverless 实例
260
259
  * serverless_basic:Serverless 基础系列。(仅适用 MySQL 和 PostgreSQL)
261
260
  * serverless_standard:Serverless 高可用系列。(仅适用 MySQL 和 PostgreSQL)
@@ -293,18 +292,18 @@ const resolveDatabases = (scope, databases, context) => {
293
292
  */
294
293
  serverlessConfig: {
295
294
  // @TODO db.cu.min should get parameter value when it refer to a parameter
296
- minCapacity: (0, common_1.replaceReference)(db.cu.min === 0 ? quota.minCapacity : db.cu.min + quota.minCapacity, context),
297
- maxCapacity: (0, common_1.replaceReference)(db.cu.max + quota.minCapacity <= quota.maxCapacity
295
+ minCapacity: (0, common_1.calcRefs)(db.cu.min === 0 ? quota.minCapacity : db.cu.min + quota.minCapacity, context),
296
+ maxCapacity: (0, common_1.calcRefs)(db.cu.max + quota.minCapacity <= quota.maxCapacity
298
297
  ? db.cu.max + quota.minCapacity
299
298
  : quota.maxCapacity, context),
300
299
  autoPause: db.cu.min === 0,
301
300
  switchForce: false,
302
301
  },
303
- masterUsername: (0, common_1.replaceReference)(db.security.basicAuth.username, context),
304
- masterUserPassword: (0, common_1.replaceReference)(db.security.basicAuth.password, context),
302
+ masterUsername: (0, common_1.calcRefs)(db.security.basicAuth.username, context),
303
+ masterUserPassword: (0, common_1.calcRefs)(db.security.basicAuth.password, context),
305
304
  masterUserType: 'Super',
306
305
  multiAz: quota.ha,
307
- securityIpList: (0, common_1.replaceReference)(db.network.ingressRules.join(','), context),
306
+ securityIpList: (0, common_1.calcRefs)(db.network.ingressRules.join(','), context),
308
307
  connectionStringType: db.network.type === 'PRIVATE' ? 'Inner' : 'Public',
309
308
  dbInstanceNetType: db.network.type === 'PRIVATE' ? 'Intranet' : 'Internet',
310
309
  }, true);
@@ -48,9 +48,9 @@ const resolveEvents = (scope, events, tags, context, service) => {
48
48
  if (!apiGateway?.length)
49
49
  return;
50
50
  apiGateway.forEach((event) => {
51
- const gatewayAccessRole = new ram.RosRole(scope, (0, common_1.replaceReference)(`${event.key}_role`, context), {
52
- roleName: (0, common_1.replaceReference)(`${service}-${event.name}-agw-access-role`, context),
53
- description: (0, common_1.replaceReference)(`${service} role`, context),
51
+ const gatewayAccessRole = new ram.RosRole(scope, (0, common_1.formatRosId)(`${event.key}_agw_role`), {
52
+ roleName: (0, common_1.calcRefs)(`${event.name}-agw-access-role`, context),
53
+ description: (0, common_1.calcRefs)(`${service} role`, context),
54
54
  assumeRolePolicyDocument: {
55
55
  version: '1',
56
56
  statement: [
@@ -65,7 +65,7 @@ const resolveEvents = (scope, events, tags, context, service) => {
65
65
  },
66
66
  policies: [
67
67
  {
68
- policyName: (0, common_1.replaceReference)(`${service}-${event.name}-policy`, context),
68
+ policyName: (0, common_1.calcRefs)(`${service}-${event.name}-policy`, context),
69
69
  policyDocument: {
70
70
  version: '1',
71
71
  statement: [
@@ -80,62 +80,62 @@ const resolveEvents = (scope, events, tags, context, service) => {
80
80
  },
81
81
  ],
82
82
  }, true);
83
- const apiGatewayGroup = new agw.RosGroup(scope, (0, common_1.replaceReference)(`${service}_apigroup`, context), {
84
- groupName: (0, common_1.replaceReference)(`${service}_apigroup`, context),
85
- tags: (0, common_1.replaceReference)(tags, context),
83
+ const apiGatewayGroup = new agw.RosGroup(scope, (0, common_1.formatRosId)(`${event.key}_agw_group`), {
84
+ groupName: (0, common_1.calcRefs)(`${service}-agw-group`, context),
85
+ tags: (0, common_1.calcRefs)(tags, context),
86
86
  passthroughHeaders: 'host',
87
87
  }, true);
88
88
  if (event.domain) {
89
- const dnsRecordRosId = `${event.key}_custom_domain_record_${(0, common_1.encodeBase64ForRosId)(event.domain.domain_name)}`;
89
+ const dnsRecordId = (0, common_1.formatRosId)(`${event.key}_agw_custom_domain_record`);
90
90
  const { domainName, rr } = (0, common_1.splitDomain)(event.domain?.domain_name);
91
- new dns.DomainRecord(scope, dnsRecordRosId, {
91
+ new dns.DomainRecord(scope, dnsRecordId, {
92
92
  domainName,
93
93
  rr,
94
94
  type: 'CNAME',
95
95
  value: apiGatewayGroup.attrSubDomain,
96
96
  });
97
- const agwCustomDomain = new agw.RosCustomDomain(scope, `${event.key}_custom_domain_${(0, common_1.encodeBase64ForRosId)(event.domain.domain_name)}`, {
97
+ const agwCustomDomain = new agw.RosCustomDomain(scope, (0, common_1.formatRosId)(`${event.key}_agw_custom_domain`), {
98
98
  groupId: apiGatewayGroup.attrGroupId,
99
99
  domainName: event.domain.domain_name,
100
100
  certificateName: event.domain.certificate_name,
101
101
  certificateBody: event.domain.certificate_body,
102
102
  certificatePrivateKey: event.domain.certificate_private_key,
103
103
  }, true);
104
- agwCustomDomain.addRosDependency(dnsRecordRosId);
104
+ agwCustomDomain.addRosDependency(dnsRecordId);
105
105
  }
106
106
  event.triggers.forEach((trigger) => {
107
- const key = (0, common_1.encodeBase64ForRosId)((0, common_1.replaceReference)(`${trigger.method}_${trigger.path}`, context));
108
- const api = new agw.RosApi(scope, `${event.key}_api_${key}`, {
109
- apiName: (0, common_1.replaceReference)(`${event.name}_api_${key}`, context),
107
+ const key = (0, common_1.formatRosId)((0, common_1.calcValue)(`${trigger.method}_${trigger.path}`, context));
108
+ const api = new agw.RosApi(scope, (0, common_1.formatRosId)(`${event.key}_agw_api_${key}`), {
109
+ apiName: (0, common_1.calcRefs)(`${event.name}-agw-api-${key.replace(/_/g, '-')}`, context),
110
110
  groupId: apiGatewayGroup.attrGroupId,
111
111
  visibility: 'PRIVATE',
112
112
  authType: 'ANONYMOUS',
113
113
  requestConfig: {
114
114
  requestProtocol: 'HTTP',
115
- requestHttpMethod: (0, common_1.replaceReference)(trigger.method, context),
116
- requestPath: (0, common_1.replaceReference)(trigger.path, context),
115
+ requestHttpMethod: (0, common_1.calcRefs)(trigger.method, context),
116
+ requestPath: (0, common_1.calcRefs)(trigger.path, context),
117
117
  requestMode: 'PASSTHROUGH',
118
118
  },
119
119
  serviceConfig: {
120
120
  serviceProtocol: 'FunctionCompute',
121
121
  functionComputeConfig: {
122
122
  fcRegionId: context.region,
123
- functionName: (0, common_1.replaceReference)(trigger.backend, context),
123
+ functionName: (0, common_1.calcRefs)(trigger.backend, context),
124
124
  roleArn: gatewayAccessRole.attrArn,
125
125
  fcVersion: '3.0',
126
- method: (0, common_1.replaceReference)(trigger.method, context),
126
+ method: (0, common_1.calcRefs)(trigger.method, context),
127
127
  },
128
128
  },
129
129
  resultSample: 'ServerlessInsight resultSample',
130
130
  resultType: 'PASSTHROUGH',
131
- tags: (0, common_1.replaceReference)(tags, context),
131
+ tags: (0, common_1.calcRefs)(tags, context),
132
132
  }, true);
133
133
  api.addDependsOn(apiGatewayGroup);
134
- new agw.Deployment(scope, `${service}_deployment`, {
134
+ new agw.Deployment(scope, (0, common_1.formatRosId)(`${event.key}_agw_api_deployment_${key}`), {
135
135
  apiId: api.attrApiId,
136
136
  groupId: apiGatewayGroup.attrGroupId,
137
137
  stageName: 'RELEASE',
138
- description: `${service} Api Gateway deployment`,
138
+ description: (0, common_1.calcRefs)(`${service} Api Gateway deployment for api: ${trigger.method} ${trigger.path}`, context),
139
139
  });
140
140
  });
141
141
  });