@geek-fun/serverlessinsight 0.3.4 → 0.4.1

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 (43) hide show
  1. package/README.md +209 -21
  2. package/README.zh-CN.md +232 -0
  3. package/dist/package.json +33 -33
  4. package/dist/src/commands/index.js +50 -12
  5. package/dist/src/commands/local.js +6 -3
  6. package/dist/src/commands/template.js +3 -1
  7. package/dist/src/common/constants.js +3 -1
  8. package/dist/src/common/context.js +56 -30
  9. package/dist/src/common/credentials.js +15 -0
  10. package/dist/src/common/iacHelper.js +39 -4
  11. package/dist/src/common/index.d.ts +2 -1
  12. package/dist/src/common/index.js +2 -1
  13. package/dist/src/common/logger.js +6 -0
  14. package/dist/src/common/requestHelper.js +16 -0
  15. package/dist/src/common/rosClient.js +3 -0
  16. package/dist/src/parser/eventParser.js +1 -1
  17. package/dist/src/parser/index.d.ts +2 -1
  18. package/dist/src/parser/index.js +32 -1
  19. package/dist/src/stack/localStack/aliyunFc.js +145 -0
  20. package/dist/src/stack/localStack/bucket.js +226 -0
  21. package/dist/src/stack/localStack/event.js +133 -26
  22. package/dist/src/stack/localStack/function.js +120 -0
  23. package/dist/src/stack/localStack/functionRunner.js +270 -0
  24. package/dist/src/stack/localStack/index.d.ts +4 -1
  25. package/dist/src/stack/localStack/index.js +14 -4
  26. package/dist/src/stack/localStack/localServer.js +111 -0
  27. package/dist/src/stack/localStack/utils.js +36 -0
  28. package/dist/src/stack/rosStack/bootstrap.js +1 -1
  29. package/dist/src/types/localStack/index.d.ts +81 -0
  30. package/dist/src/types/localStack/index.js +10 -0
  31. package/dist/src/validator/iacSchema.js +17 -2
  32. package/dist/src/validator/rootSchema.js +46 -0
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/layers/si-bootstrap-sdk/README.md +63 -0
  35. package/layers/si-bootstrap-sdk/package-lock.json +39 -33
  36. package/layers/si-bootstrap-sdk/package.json +5 -5
  37. package/layers/si-bootstrap-sdk/support/operation-collection/README.md +47 -0
  38. package/layers/si-bootstrap-sdk/support/operation-collection/package-lock.json +298 -0
  39. package/layers/si-bootstrap-sdk/support/operation-collection/package.json +18 -0
  40. package/layers/si-bootstrap-sdk/support/operation-collection/publish.js +257 -0
  41. package/package.json +33 -33
  42. package/samples/aliyun-poc-es.yml +16 -12
  43. package/dist/src/common/domainHelper.js +0 -10
@@ -8,26 +8,62 @@ const deploy_1 = require("./deploy");
8
8
  const template_1 = require("./template");
9
9
  const destroy_1 = require("./destroy");
10
10
  const local_1 = require("./local");
11
+ // Global error handler
12
+ const handleCommandError = (error, commandName) => {
13
+ // Log error message as string to preserve newlines
14
+ common_1.logger.error(`Command '${commandName}' failed with error:\n${error?.message || 'Unknown error occurred'}`);
15
+ if (error?.stack && process.env.DEBUG) {
16
+ common_1.logger.debug(`Stack trace:\n${error.stack}`);
17
+ }
18
+ let exitCode = 1;
19
+ if (error?.code) {
20
+ if (typeof error.code === 'number') {
21
+ exitCode = error.code;
22
+ }
23
+ else if (typeof error.code === 'string') {
24
+ const errorCodeMap = {
25
+ ENOENT: 2,
26
+ EACCES: 3,
27
+ VALIDATION: 4,
28
+ NETWORK: 5,
29
+ };
30
+ exitCode = errorCodeMap[error.code] || 1;
31
+ }
32
+ }
33
+ process.exit(exitCode);
34
+ };
35
+ const actionWrapper = (commandName, handler) => {
36
+ // Reset context before each command execution
37
+ (0, common_1.clearContext)();
38
+ return async (...args) => {
39
+ try {
40
+ await handler(...args);
41
+ }
42
+ catch (error) {
43
+ handleCommandError(error, commandName);
44
+ }
45
+ };
46
+ };
11
47
  const program = new commander_1.Command();
12
48
  program.name('si').description('CLI for ServerlessInsight').version((0, common_1.getVersion)());
13
49
  program
14
50
  .command('show')
15
51
  .description('show string')
16
- .action(async (options) => {
52
+ .action(actionWrapper('show', async (options) => {
17
53
  await (0, common_1.setContext)({ ...options });
18
54
  const context = (0, common_1.getContext)();
19
55
  const result = await (0, common_1.getIamInfo)(context);
20
56
  console.log('result:', JSON.stringify(result));
21
- });
57
+ }));
22
58
  program
23
59
  .command('validate [stackName]')
24
60
  .description('validate serverless Iac yaml')
25
61
  .option('-f, --file <path>', 'specify the yaml file')
26
62
  .option('-s, --stage <stage>', 'specify the stage')
27
- .action(async (stackName, { file, stage }) => {
63
+ .action(actionWrapper('validate', async (stackName, { file, stage }) => {
28
64
  common_1.logger.debug('log command info');
29
65
  await (0, validate_1.validate)(stackName, { stage, location: file });
30
- });
66
+ }));
31
67
  program
32
68
  .command('deploy <stackName>')
33
69
  .description('deploy serverless Iac yaml')
@@ -43,7 +79,7 @@ program
43
79
  previous[key] = val;
44
80
  return previous;
45
81
  }, {})
46
- .action(async (stackName, { stage, parameter, file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
82
+ .action(actionWrapper('deploy', async (stackName, { stage, parameter, file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
47
83
  await (0, deploy_1.deploy)(stackName, {
48
84
  stage,
49
85
  parameters: parameter,
@@ -54,16 +90,16 @@ program
54
90
  accessKeySecret,
55
91
  securityToken,
56
92
  });
57
- });
93
+ }));
58
94
  program
59
95
  .command('template <stackName>')
60
96
  .description('print platform specific infrastructure as code template')
61
97
  .option('-f, --file <path>', 'specify the yaml file')
62
98
  .option('-s, --stage <stage>', 'specify the stage')
63
99
  .option('-t, --format <type>', 'output content type (JSON or YAML)', 'JSON')
64
- .action(async (stackName, { format, file, stage }) => {
100
+ .action(actionWrapper('template', async (stackName, { format, file, stage }) => {
65
101
  await (0, template_1.template)(stackName, { format, location: file, stage });
66
- });
102
+ }));
67
103
  program
68
104
  .command('destroy <stackName>')
69
105
  .option('-f, --file <path>', 'specify the yaml file')
@@ -73,7 +109,7 @@ program
73
109
  .option('-x, --accessKeySecret <accessKeySecret>', 'specify the AccessKeySecret')
74
110
  .option('-n, --securityToken <securityToken>', 'specify the SecurityToken')
75
111
  .description('destroy serverless stack')
76
- .action(async (stackName, { file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
112
+ .action(actionWrapper('destroy', async (stackName, { file, region, provider, accessKeyId, accessKeySecret, securityToken }) => {
77
113
  await (0, destroy_1.destroyStack)(stackName, {
78
114
  location: file,
79
115
  region,
@@ -82,20 +118,22 @@ program
82
118
  accessKeySecret,
83
119
  securityToken,
84
120
  });
85
- });
121
+ }));
86
122
  program
87
123
  .command('local <stackName>')
88
124
  .description('run Serverless application locally for debugging')
125
+ .option('-f, --file <path>', 'specify the yaml file')
89
126
  .option('-s, --stage <stage>', 'specify the stage', 'default')
90
127
  .option('-p, --port <port>', 'specify the port', '3000')
91
128
  .option('-d, --debug', 'enable debug mode')
92
129
  .option('-w, --watch', 'enable file watch', true)
93
- .action(async (stackName, { stage, port, debug, watch }) => {
130
+ .action(actionWrapper('local', async (stackName, { stage, port, debug, watch, file }) => {
94
131
  await (0, local_1.runLocal)(stackName, {
95
132
  stage,
96
133
  port: Number(port) || 3000,
97
134
  debug: !!debug,
98
135
  watch: typeof watch === 'boolean' ? watch : true,
136
+ location: file,
99
137
  });
100
- });
138
+ }));
101
139
  program.parse();
@@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runLocal = void 0;
4
4
  const common_1 = require("../common");
5
5
  const localStack_1 = require("../stack/localStack");
6
+ const parser_1 = require("../parser");
6
7
  const runLocal = async (stackName, opts) => {
7
- const { stage, port, debug, watch } = opts;
8
- await (0, common_1.setContext)({ stage });
8
+ const { stage, port, debug, watch, location } = opts;
9
+ await (0, common_1.setContext)({ stage, location });
10
+ const ctx = (0, common_1.getContext)();
11
+ const iac = (0, parser_1.revalYaml)((0, common_1.getIacLocation)(location), ctx);
9
12
  common_1.logger.info(`run-local starting: stack=${stackName} stage=${stage} port=${port} debug=${debug} watch=${watch}`);
10
- await (0, localStack_1.startLocalStack)();
13
+ await (0, localStack_1.startLocalStack)(iac);
11
14
  // if (watch) {
12
15
  // const cwd = process.cwd();
13
16
  // try {
@@ -11,7 +11,9 @@ const common_1 = require("../common");
11
11
  const parser_1 = require("../parser");
12
12
  const template = async (stackName, options) => {
13
13
  const iac = (0, parser_1.parseYaml)((0, common_1.getIacLocation)(options.location));
14
- await (0, common_1.setContext)({ ...options, stackName, provider: iac.provider.name }, true);
14
+ const credentials = (0, common_1.getCredentials)();
15
+ const shouldFetchIamInfo = (0, common_1.hasCredentials)(credentials);
16
+ await (0, common_1.setContext)({ ...options, stackName, provider: iac.provider.name }, shouldFetchIamInfo);
15
17
  const { template } = (0, deploy_1.generateStackTemplate)(stackName, iac);
16
18
  if (typeof template === 'string') {
17
19
  common_1.logger.info(`\n${template}`);
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SI_BOOTSTRAP_BUCKET_PREFIX = exports.SI_BOOTSTRAP_FC_PREFIX = exports.OSS_DEPLOYMENT_TIMEOUT = exports.CODE_ZIP_SIZE_LIMIT = void 0;
3
+ exports.SI_LOCALSTACK_SERVER_PORT = exports.SI_BOOTSTRAP_BUCKET_PREFIX = exports.SI_BOOTSTRAP_FC_PREFIX = exports.ROS_STACK_OPERATION_TIMEOUT = exports.OSS_DEPLOYMENT_TIMEOUT = exports.CODE_ZIP_SIZE_LIMIT = void 0;
4
4
  exports.CODE_ZIP_SIZE_LIMIT = 300 * 1000; // 300 KB ROS TemplateBody size limit 512 KB
5
5
  exports.OSS_DEPLOYMENT_TIMEOUT = 3000; // in seconds
6
+ exports.ROS_STACK_OPERATION_TIMEOUT = 3600; // in seconds
6
7
  exports.SI_BOOTSTRAP_FC_PREFIX = 'si-bootstrap-api';
7
8
  exports.SI_BOOTSTRAP_BUCKET_PREFIX = 'si-bootstrap-artifacts';
9
+ exports.SI_LOCALSTACK_SERVER_PORT = 4567;
@@ -3,35 +3,53 @@ 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.getContext = exports.setContext = exports.getIacLocation = void 0;
7
- const node_path_1 = __importDefault(require("node:path"));
6
+ exports.clearContext = exports.getContext = exports.setContext = exports.getIacLocation = void 0;
8
7
  const node_fs_1 = __importDefault(require("node:fs"));
9
- const providerEnum_1 = require("./providerEnum");
10
- const node_async_hooks_1 = require("node:async_hooks");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const credentials_1 = require("./credentials");
11
10
  const imsClient_1 = require("./imsClient");
12
- const asyncLocalStorage = new node_async_hooks_1.AsyncLocalStorage();
11
+ const providerEnum_1 = require("./providerEnum");
12
+ let context;
13
+ const DEFAULT_IAC_FILES = [
14
+ 'serverlessinsight.yml',
15
+ 'serverlessInsight.yml',
16
+ 'ServerlessInsight.yml',
17
+ 'serverless-insight.yml',
18
+ ];
13
19
  const getIacLocation = (location) => {
14
20
  const projectRoot = node_path_1.default.resolve(process.cwd());
15
- if (location) {
16
- const candidate = node_path_1.default.isAbsolute(location) ? location : node_path_1.default.resolve(projectRoot, location);
17
- if (node_fs_1.default.existsSync(candidate)) {
18
- return candidate;
21
+ const searchTargets = location ? [location] : DEFAULT_IAC_FILES;
22
+ const attempted = new Set();
23
+ const toAbsolutePath = (target) => node_path_1.default.isAbsolute(target) ? target : node_path_1.default.resolve(projectRoot, target);
24
+ const tryResolveCandidate = (target) => {
25
+ const resolved = toAbsolutePath(target);
26
+ attempted.add(resolved);
27
+ if (!node_fs_1.default.existsSync(resolved)) {
28
+ return undefined;
19
29
  }
20
- throw new Error(`IaC file not found at '${candidate}'`);
21
- }
22
- const candidates = [
23
- 'serverlessinsight.yml',
24
- 'serverlessInsight.yml',
25
- 'ServerlessInsight.yml',
26
- 'serverless-insight.yml',
27
- ];
28
- for (const name of candidates) {
29
- const candidate = node_path_1.default.resolve(projectRoot, name);
30
- if (node_fs_1.default.existsSync(candidate)) {
31
- return candidate;
30
+ const stats = node_fs_1.default.statSync(resolved);
31
+ if (stats.isDirectory()) {
32
+ for (const fileName of DEFAULT_IAC_FILES) {
33
+ const nested = node_path_1.default.join(resolved, fileName);
34
+ attempted.add(nested);
35
+ if (node_fs_1.default.existsSync(nested) && node_fs_1.default.statSync(nested).isFile()) {
36
+ return nested;
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ return resolved;
42
+ };
43
+ for (const candidate of searchTargets) {
44
+ const match = tryResolveCandidate(candidate);
45
+ if (match) {
46
+ return match;
32
47
  }
33
48
  }
34
- throw new Error(`No IaC file found. Tried: ${candidates.map((n) => `'${node_path_1.default.resolve(projectRoot, n)}'`).join(', ')}`);
49
+ const attemptedList = Array.from(attempted)
50
+ .map((n) => `'${n}'`)
51
+ .join(', ');
52
+ throw new Error(`No IaC file found. Tried: ${attemptedList}`);
35
53
  };
36
54
  exports.getIacLocation = getIacLocation;
37
55
  const setContext = async (config, reaValToken = false) => {
@@ -40,14 +58,19 @@ const setContext = async (config, reaValToken = false) => {
40
58
  process.env.ROS_REGION_ID ??
41
59
  process.env.ALIYUN_REGION ??
42
60
  'cn-hangzhou';
43
- const context = {
61
+ const credentials = (0, credentials_1.getCredentials)({
62
+ accessKeyId: config.accessKeyId,
63
+ accessKeySecret: config.accessKeySecret,
64
+ securityToken: config.securityToken,
65
+ });
66
+ const newContext = {
44
67
  stage: config.stage ?? 'default',
45
68
  stackName: config.stackName ?? '',
46
69
  provider: (config.provider ?? config.iacProvider?.name ?? providerEnum_1.ProviderEnum.ALIYUN),
47
70
  region,
48
- accessKeyId: config.accessKeyId ?? process.env.ALIYUN_ACCESS_KEY_ID,
49
- accessKeySecret: config.accessKeySecret ?? process.env.ALIYUN_ACCESS_KEY_SECRET,
50
- securityToken: config.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN,
71
+ accessKeyId: credentials.accessKeyId,
72
+ accessKeySecret: credentials.accessKeySecret,
73
+ securityToken: credentials.securityToken,
51
74
  iacLocation: (0, exports.getIacLocation)(config.location),
52
75
  parameters: Object.entries(config.parameters ?? {}).map(([key, value]) => ({ key, value })),
53
76
  stages: Object.entries(config.stages ?? {}).reduce((acc, [stage, parameters]) => ({
@@ -56,17 +79,20 @@ const setContext = async (config, reaValToken = false) => {
56
79
  }), {}),
57
80
  };
58
81
  if (reaValToken) {
59
- const iamInfo = await (0, imsClient_1.getIamInfo)(context);
60
- context.accountId = iamInfo?.accountId;
82
+ const iamInfo = await (0, imsClient_1.getIamInfo)(newContext);
83
+ newContext.accountId = iamInfo?.accountId;
61
84
  }
62
- asyncLocalStorage.enterWith(context);
85
+ context = newContext;
63
86
  };
64
87
  exports.setContext = setContext;
65
88
  const getContext = () => {
66
- const context = asyncLocalStorage.getStore();
67
89
  if (!context) {
68
90
  throw new Error('No context found');
69
91
  }
70
92
  return context;
71
93
  };
72
94
  exports.getContext = getContext;
95
+ const clearContext = () => {
96
+ context = undefined;
97
+ };
98
+ exports.clearContext = clearContext;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasCredentials = exports.getCredentials = void 0;
4
+ const getCredentials = (config) => {
5
+ return {
6
+ accessKeyId: config?.accessKeyId ?? process.env.ALIYUN_ACCESS_KEY_ID,
7
+ accessKeySecret: config?.accessKeySecret ?? process.env.ALIYUN_ACCESS_KEY_SECRET,
8
+ securityToken: config?.securityToken ?? process.env.ALIYUN_SECURITY_TOKEN,
9
+ };
10
+ };
11
+ exports.getCredentials = getCredentials;
12
+ const hasCredentials = (credentials) => {
13
+ return !!credentials.accessKeyId && !!credentials.accessKeySecret;
14
+ };
15
+ exports.hasCredentials = hasCredentials;
@@ -36,13 +36,15 @@ 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.formatRosId = exports.calcValue = exports.calcRefs = exports.getFileSource = exports.readCodeSize = exports.resolveCode = void 0;
39
+ exports.splitDomain = exports.formatRosId = exports.getIacDefinition = 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
45
  const lodash_1 = require("lodash");
46
+ const parser_1 = require("../parser");
47
+ const logger_1 = require("./logger");
46
48
  const resolveCode = (location) => {
47
49
  const filePath = node_path_1.default.resolve(process.cwd(), location);
48
50
  const fileContent = node_fs_1.default.readFileSync(filePath);
@@ -104,7 +106,7 @@ exports.calcRefs = calcRefs;
104
106
  const getParam = (key, records) => {
105
107
  return records?.find((param) => param.key === key)?.value;
106
108
  };
107
- const calcValue = (rawValue, ctx) => {
109
+ const calcValue = (rawValue, ctx, iacVars) => {
108
110
  const containsStage = rawValue.match(/\$\{ctx.stage}/);
109
111
  const containsVar = rawValue.match(/\$\{vars.\w+}/);
110
112
  const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
@@ -113,14 +115,40 @@ const calcValue = (rawValue, ctx) => {
113
115
  value = rawValue.replace(/\$\{ctx.stage}/g, ctx.stage);
114
116
  }
115
117
  if (containsVar?.length) {
116
- value = value.replace(/\$\{vars\.(\w+)}/g, (_, key) => getParam(key, ctx.parameters));
118
+ // Use provided iacVars or parse from file
119
+ const vars = iacVars ?? (0, parser_1.parseYaml)(ctx.iacLocation).vars;
120
+ const mergedParams = Array.from(new Map([
121
+ ...Object.entries(vars ?? {}).map(([key, value]) => [key, String(value)]),
122
+ ...(ctx.parameters ?? []).map(({ key, value }) => [key, value]),
123
+ ].filter(([, v]) => v !== undefined)).entries()).map(([key, value]) => ({ key, value }));
124
+ value = value.replace(/\$\{vars\.(\w+)}/g, (_, key) => {
125
+ const paramValue = getParam(key, mergedParams);
126
+ if (!paramValue) {
127
+ logger_1.logger.warn(`Variable '${key}' not found in vars or parameters, using empty string`);
128
+ }
129
+ return paramValue || '';
130
+ });
117
131
  }
118
132
  if (containsMap?.length) {
119
- value = value.replace(/\$\{stages\.(\w+)}/g, (_, key) => getParam(key, (0, lodash_1.get)(ctx.stages, `${ctx.stage}`)));
133
+ value = value.replace(/\$\{stages\.(\w+)}/g, (_, key) => {
134
+ const stageValue = getParam(key, (0, lodash_1.get)(ctx.stages, `${ctx.stage}`));
135
+ if (!stageValue) {
136
+ logger_1.logger.warn(`Stage variable '${key}' not found in stage '${ctx.stage}', using empty string`);
137
+ }
138
+ return stageValue || '';
139
+ });
120
140
  }
121
141
  return value;
122
142
  };
123
143
  exports.calcValue = calcValue;
144
+ const getIacDefinition = (iac, rawValue) => {
145
+ const matchFn = rawValue.match(/^\$\{functions\.(\w+(\.\w+)?)}$/);
146
+ if (matchFn?.length) {
147
+ return iac.functions?.find((fc) => fc.key === matchFn[1]);
148
+ }
149
+ return iac.functions?.find((fc) => fc.key === rawValue);
150
+ };
151
+ exports.getIacDefinition = getIacDefinition;
124
152
  const formatRosId = (id) => {
125
153
  // Insert underscore before uppercase letters, but only when they follow a lowercase letter
126
154
  let result = id.replace(/([a-z])([A-Z])/g, '$1_$2');
@@ -135,3 +163,10 @@ const formatRosId = (id) => {
135
163
  return result;
136
164
  };
137
165
  exports.formatRosId = formatRosId;
166
+ const splitDomain = (domain) => {
167
+ const parts = domain.split('.');
168
+ const rr = parts.length > 2 ? parts[0] : '@';
169
+ const domainName = parts.length > 2 ? parts.slice(1).join('.') : domain;
170
+ return { rr, domainName };
171
+ };
172
+ exports.splitDomain = splitDomain;
@@ -8,4 +8,5 @@ export * from './constants';
8
8
  export * from './imsClient';
9
9
  export * from './base64';
10
10
  export * from './rosAssets';
11
- export * from './domainHelper';
11
+ export * from './requestHelper';
12
+ export * from './credentials';
@@ -24,4 +24,5 @@ __exportStar(require("./constants"), exports);
24
24
  __exportStar(require("./imsClient"), exports);
25
25
  __exportStar(require("./base64"), exports);
26
26
  __exportStar(require("./rosAssets"), exports);
27
- __exportStar(require("./domainHelper"), exports);
27
+ __exportStar(require("./requestHelper"), exports);
28
+ __exportStar(require("./credentials"), exports);
@@ -10,6 +10,12 @@ const logger = (0, pino_1.default)({
10
10
  level: ['ServerlessInsight', '*'].includes(process.env.DEBUG || '') ? 'debug' : 'info',
11
11
  transport: {
12
12
  target: 'pino-pretty',
13
+ options: {
14
+ colorize: true,
15
+ translateTime: 'HH:MM:ss',
16
+ ignore: 'pid,hostname',
17
+ messageFormat: '{msg}',
18
+ },
13
19
  },
14
20
  });
15
21
  exports.logger = logger;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readRequestBody = void 0;
4
+ const readRequestBody = (req) => {
5
+ return new Promise((resolve, reject) => {
6
+ let body = '';
7
+ req.on('data', (chunk) => {
8
+ body += chunk.toString();
9
+ });
10
+ req.on('end', () => {
11
+ resolve(body);
12
+ });
13
+ req.on('error', reject);
14
+ });
15
+ };
16
+ exports.readRequestBody = readRequestBody;
@@ -43,11 +43,14 @@ const tea_util_1 = __importDefault(require("@alicloud/tea-util"));
43
43
  const logger_1 = require("./logger");
44
44
  const lang_1 = require("../lang");
45
45
  const context_1 = require("./context");
46
+ const constants_1 = require("./constants");
46
47
  const client = new ros20190910_1.default(new openapi_client_1.Config({
47
48
  accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID,
48
49
  accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET,
49
50
  regionId: process.env.ALIYUN_REGION,
50
51
  disableRollback: false,
52
+ readTimeout: constants_1.ROS_STACK_OPERATION_TIMEOUT,
53
+ connectTimeout: constants_1.ROS_STACK_OPERATION_TIMEOUT,
51
54
  }));
52
55
  const createStack = async (stackName, templateBody, context) => {
53
56
  const parameters = context.parameters?.map((parameter) => new ros20190910_1.CreateStackRequestParameters({
@@ -9,7 +9,7 @@ const parseEvent = (events) => {
9
9
  key,
10
10
  name: event.name,
11
11
  type: event.type,
12
- triggers: event.triggers,
12
+ triggers: event.triggers?.map((trigger) => ({ ...trigger, method: trigger.method ?? 'GET' })),
13
13
  domain: event.domain,
14
14
  }));
15
15
  };
@@ -1,2 +1,3 @@
1
- import { ServerlessIac } from '../types';
1
+ import { ServerlessIac, Context } from '../types';
2
2
  export declare const parseYaml: (iacLocation: string) => ServerlessIac;
3
+ export declare const revalYaml: (iacLocation: string, ctx: Context) => ServerlessIac;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseYaml = void 0;
3
+ exports.revalYaml = exports.parseYaml = void 0;
4
4
  const node_fs_1 = require("node:fs");
5
5
  const functionParser_1 = require("./functionParser");
6
6
  const eventParser_1 = require("./eventParser");
@@ -10,6 +10,7 @@ const yaml_1 = require("yaml");
10
10
  const validator_1 = require("../validator");
11
11
  const bucketParser_1 = require("./bucketParser");
12
12
  const tableParser_1 = require("./tableParser");
13
+ const common_1 = require("../common");
13
14
  const validateExistence = (path) => {
14
15
  if (!(0, node_fs_1.existsSync)(path)) {
15
16
  throw new Error(`File does not exist at path: ${path}`);
@@ -38,3 +39,33 @@ const parseYaml = (iacLocation) => {
38
39
  return transformYaml(iacJson);
39
40
  };
40
41
  exports.parseYaml = parseYaml;
42
+ const evaluateObject = (obj, ctx, iacVars) => {
43
+ if (typeof obj === 'string') {
44
+ return (0, common_1.calcValue)(obj, ctx, iacVars);
45
+ }
46
+ if (Array.isArray(obj)) {
47
+ return obj.map((item) => evaluateObject(item, ctx, iacVars));
48
+ }
49
+ if (typeof obj === 'object' && obj !== null) {
50
+ return Object.fromEntries(Object.entries(obj).map(([key, val]) => [key, evaluateObject(val, ctx, iacVars)]));
51
+ }
52
+ return obj;
53
+ };
54
+ const revalYaml = (iacLocation, ctx) => {
55
+ validateExistence(iacLocation);
56
+ const yamlContent = (0, node_fs_1.readFileSync)(iacLocation, 'utf8');
57
+ const iacJson = (0, yaml_1.parse)(yamlContent);
58
+ (0, validator_1.validateYaml)(iacJson);
59
+ const evaluatedIacJson = evaluateObject(iacJson, ctx, iacJson.vars);
60
+ const iac = transformYaml(evaluatedIacJson);
61
+ // Set default values for optional fields in functions
62
+ if (iac.functions) {
63
+ iac.functions = iac.functions.map((fn) => ({
64
+ ...fn,
65
+ memory: fn.memory || 128,
66
+ timeout: fn.timeout || 3,
67
+ }));
68
+ }
69
+ return iac;
70
+ };
71
+ exports.revalYaml = revalYaml;