@geek-fun/serverlessinsight 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/.gitattributes +1 -0
  2. package/README.md +108 -8
  3. package/README.zh-CN.md +52 -8
  4. package/dist/package.json +37 -35
  5. package/dist/src/commands/deploy.js +17 -7
  6. package/dist/src/commands/destroy.js +27 -4
  7. package/dist/src/commands/forceUnlock.js +61 -0
  8. package/dist/src/commands/index.js +86 -14
  9. package/dist/src/commands/local.js +10 -1
  10. package/dist/src/commands/plan.js +33 -0
  11. package/dist/src/commands/template.js +3 -1
  12. package/dist/src/commands/validate.js +2 -1
  13. package/dist/src/common/aliyunClient/apigwOperations.js +652 -0
  14. package/dist/src/common/aliyunClient/dnsOperations.js +90 -0
  15. package/dist/src/common/aliyunClient/ecsOperations.js +141 -0
  16. package/dist/src/common/aliyunClient/esOperations.js +219 -0
  17. package/dist/src/common/aliyunClient/fc3Operations.js +270 -0
  18. package/dist/src/common/aliyunClient/index.js +141 -0
  19. package/dist/src/common/aliyunClient/nasOperations.js +233 -0
  20. package/dist/src/common/aliyunClient/ossOperations.js +237 -0
  21. package/dist/src/common/aliyunClient/ramOperations.js +205 -0
  22. package/dist/src/common/aliyunClient/rdsOperations.js +206 -0
  23. package/dist/src/common/aliyunClient/slsOperations.js +218 -0
  24. package/dist/src/common/aliyunClient/tablestoreOperations.js +199 -0
  25. package/dist/src/common/aliyunClient/types.js +2 -0
  26. package/dist/src/common/constants.js +7 -1
  27. package/dist/src/common/context.js +32 -14
  28. package/dist/src/common/credentials.js +39 -0
  29. package/dist/src/common/dependencyGraph/graph.js +280 -0
  30. package/dist/src/common/dependencyGraph/index.js +18 -0
  31. package/dist/src/common/dependencyGraph/types.js +2 -0
  32. package/dist/src/common/fileUtils.js +16 -0
  33. package/dist/src/common/hashUtils.js +121 -0
  34. package/dist/src/common/iacHelper.js +25 -97
  35. package/dist/src/common/imsClient.js +4 -0
  36. package/dist/src/common/index.js +7 -2
  37. package/dist/src/common/lockManager.js +212 -0
  38. package/dist/src/common/logger.js +89 -6
  39. package/dist/src/common/providerEnum.js +2 -3
  40. package/dist/src/common/runtimeMapper.js +160 -0
  41. package/dist/src/common/scfClient.js +84 -0
  42. package/dist/src/common/stateManager.js +107 -0
  43. package/dist/src/common/tencentClient/cosOperations.js +287 -0
  44. package/dist/src/common/tencentClient/esOperations.js +156 -0
  45. package/dist/src/common/tencentClient/index.js +116 -0
  46. package/dist/src/common/tencentClient/scfOperations.js +141 -0
  47. package/dist/src/common/tencentClient/tdsqlcOperations.js +211 -0
  48. package/dist/src/common/tencentClient/types.js +17 -0
  49. package/dist/src/lang/en.js +254 -0
  50. package/dist/src/lang/index.js +28 -8
  51. package/dist/src/lang/zh-CN.js +229 -0
  52. package/dist/src/parser/bucketParser.js +25 -12
  53. package/dist/src/parser/databaseParser.js +14 -10
  54. package/dist/src/parser/functionParser.js +19 -6
  55. package/dist/src/parser/parseUtils.js +74 -0
  56. package/dist/src/parser/tableParser.js +19 -17
  57. package/dist/src/stack/aliyunStack/apigwExecutor.js +84 -0
  58. package/dist/src/stack/aliyunStack/apigwPlanner.js +118 -0
  59. package/dist/src/stack/aliyunStack/apigwResource.js +339 -0
  60. package/dist/src/stack/aliyunStack/apigwTypes.js +125 -0
  61. package/dist/src/stack/aliyunStack/databaseExecutor.js +112 -0
  62. package/dist/src/stack/aliyunStack/databasePlanner.js +128 -0
  63. package/dist/src/stack/aliyunStack/databaseResource.js +228 -0
  64. package/dist/src/stack/aliyunStack/deployer.js +133 -0
  65. package/dist/src/stack/aliyunStack/destroyer.js +114 -0
  66. package/dist/src/stack/aliyunStack/esServerlessTypes.js +141 -0
  67. package/dist/src/stack/aliyunStack/fc3Executor.js +91 -0
  68. package/dist/src/stack/aliyunStack/fc3Planner.js +77 -0
  69. package/dist/src/stack/aliyunStack/fc3Resource.js +511 -0
  70. package/dist/src/stack/aliyunStack/fc3Types.js +76 -0
  71. package/dist/src/stack/aliyunStack/index.js +40 -0
  72. package/dist/src/stack/aliyunStack/ossExecutor.js +91 -0
  73. package/dist/src/stack/aliyunStack/ossPlanner.js +76 -0
  74. package/dist/src/stack/aliyunStack/ossResource.js +196 -0
  75. package/dist/src/stack/aliyunStack/ossTypes.js +50 -0
  76. package/dist/src/stack/aliyunStack/planner.js +37 -0
  77. package/dist/src/stack/aliyunStack/rdsTypes.js +217 -0
  78. package/dist/src/stack/aliyunStack/tablestoreExecutor.js +92 -0
  79. package/dist/src/stack/aliyunStack/tablestorePlanner.js +94 -0
  80. package/dist/src/stack/aliyunStack/tablestoreResource.js +120 -0
  81. package/dist/src/stack/aliyunStack/tablestoreTypes.js +77 -0
  82. package/dist/src/stack/bucketTypes.js +17 -0
  83. package/dist/src/stack/deploy.js +24 -77
  84. package/dist/src/stack/localStack/bucket.js +11 -6
  85. package/dist/src/stack/localStack/event.js +10 -5
  86. package/dist/src/stack/localStack/function.js +13 -7
  87. package/dist/src/stack/localStack/functionRunner.js +1 -1
  88. package/dist/src/stack/localStack/localServer.js +7 -6
  89. package/dist/src/stack/scfStack/cosExecutor.js +91 -0
  90. package/dist/src/stack/scfStack/cosPlanner.js +76 -0
  91. package/dist/src/stack/scfStack/cosResource.js +126 -0
  92. package/dist/src/stack/scfStack/cosTypes.js +46 -0
  93. package/dist/src/stack/scfStack/deployer.js +91 -0
  94. package/dist/src/stack/scfStack/destroyer.js +88 -0
  95. package/dist/src/stack/scfStack/esServerlessExecutor.js +105 -0
  96. package/dist/src/stack/scfStack/esServerlessPlanner.js +86 -0
  97. package/dist/src/stack/scfStack/esServerlessResource.js +94 -0
  98. package/dist/src/stack/scfStack/esServerlessTypes.js +48 -0
  99. package/dist/src/stack/scfStack/index.js +35 -0
  100. package/dist/src/stack/scfStack/planner.js +91 -0
  101. package/dist/src/stack/scfStack/scfExecutor.js +91 -0
  102. package/dist/src/stack/scfStack/scfPlanner.js +78 -0
  103. package/dist/src/stack/scfStack/scfResource.js +216 -0
  104. package/dist/src/stack/scfStack/scfTypes.js +41 -0
  105. package/dist/src/stack/scfStack/tdsqlcExecutor.js +105 -0
  106. package/dist/src/stack/scfStack/tdsqlcPlanner.js +90 -0
  107. package/dist/src/stack/scfStack/tdsqlcResource.js +146 -0
  108. package/dist/src/stack/scfStack/tdsqlcTypes.js +59 -0
  109. package/dist/src/types/domains/lock.js +2 -0
  110. package/dist/src/types/domains/resolvable.js +2 -0
  111. package/dist/src/types/domains/state.js +19 -0
  112. package/dist/src/types/index.js +4 -0
  113. package/dist/src/validator/bucketSchema.js +4 -10
  114. package/dist/src/validator/databaseSchema.js +36 -36
  115. package/dist/src/validator/eventSchema.js +3 -2
  116. package/dist/src/validator/functionSchema.js +51 -46
  117. package/dist/src/validator/iacSchema.js +52 -3
  118. package/dist/src/validator/rootSchema.js +47 -1
  119. package/dist/src/validator/tableschema.js +9 -8
  120. package/dist/src/validator/templateRefSchema.js +23 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -1
  122. package/package.json +37 -35
  123. package/samples/README_TENCENT_COS.md +486 -0
  124. package/samples/README_TENCENT_SCF.md +272 -0
  125. package/samples/aliyun-poc-api.yml +1 -1
  126. package/samples/aliyun-poc-bucket.yml +0 -1
  127. package/samples/aliyun-poc-domain.yml +0 -1
  128. package/samples/aliyun-poc-es.yml +14 -13
  129. package/samples/aliyun-poc-rds.yml +0 -2
  130. package/samples/aliyun-poc-table.yml +1 -3
  131. package/samples/tencent-poc-cos.yml +20 -0
  132. package/samples/tencent-poc-scf.yml +36 -0
  133. package/dist/src/commands/index.d.ts +0 -2
  134. package/dist/src/common/index.d.ts +0 -11
  135. package/dist/src/common/rosAssets.js +0 -178
  136. package/dist/src/common/rosClient.js +0 -198
  137. package/dist/src/index.d.ts +0 -1
  138. package/dist/src/lang/index.d.ts +0 -3
  139. package/dist/src/parser/index.d.ts +0 -3
  140. package/dist/src/stack/index.d.ts +0 -1
  141. package/dist/src/stack/localStack/index.d.ts +0 -5
  142. package/dist/src/stack/rfsStack/index.d.ts +0 -9
  143. package/dist/src/stack/rosStack/bootstrap.js +0 -187
  144. package/dist/src/stack/rosStack/bucket.js +0 -127
  145. package/dist/src/stack/rosStack/database.js +0 -313
  146. package/dist/src/stack/rosStack/event.js +0 -143
  147. package/dist/src/stack/rosStack/function.js +0 -259
  148. package/dist/src/stack/rosStack/index.d.ts +0 -7
  149. package/dist/src/stack/rosStack/index.js +0 -75
  150. package/dist/src/stack/rosStack/stage.js +0 -46
  151. package/dist/src/stack/rosStack/table.js +0 -95
  152. package/dist/src/stack/rosStack/tag.js +0 -11
  153. package/dist/src/stack/rosStack/vars.js +0 -49
  154. package/dist/src/types/index.d.ts +0 -55
  155. package/dist/src/types/localStack/index.d.ts +0 -81
  156. package/dist/src/validator/index.d.ts +0 -1
  157. package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +0 -12
  158. package/layers/si-bootstrap-sdk/README.md +0 -1
  159. package/layers/si-bootstrap-sdk/package-lock.json +0 -875
  160. package/layers/si-bootstrap-sdk/package.json +0 -33
@@ -0,0 +1,212 @@
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.readLockFileForCommand = exports.withLock = exports.forceUnlock = exports.formatLockInfo = exports.generateLockId = exports.getLockPath = exports.LockError = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_crypto_1 = __importDefault(require("node:crypto"));
11
+ const node_child_process_1 = require("node:child_process");
12
+ const constants_1 = require("./constants");
13
+ const lang_1 = require("../lang");
14
+ class LockError extends Error {
15
+ constructor(message, lockInfo) {
16
+ super(message);
17
+ this.lockInfo = lockInfo;
18
+ this.name = 'LockError';
19
+ }
20
+ }
21
+ exports.LockError = LockError;
22
+ const getLockPath = (statePath) => {
23
+ return `${statePath}${constants_1.LOCK_FILE_SUFFIX}`;
24
+ };
25
+ exports.getLockPath = getLockPath;
26
+ const generateLockId = () => {
27
+ return node_crypto_1.default.randomBytes(16).toString('hex');
28
+ };
29
+ exports.generateLockId = generateLockId;
30
+ const getUserEmail = () => {
31
+ // Try to get git user email first
32
+ try {
33
+ const email = (0, node_child_process_1.execSync)('git config user.email', {
34
+ encoding: 'utf-8',
35
+ stdio: ['pipe', 'pipe', 'ignore'],
36
+ }).trim();
37
+ if (email)
38
+ return email;
39
+ }
40
+ catch {
41
+ // Ignore errors
42
+ }
43
+ // Fallback to username@hostname
44
+ const username = node_os_1.default.userInfo().username || 'unknown';
45
+ const hostname = node_os_1.default.hostname() || 'unknown';
46
+ return `${username}@${hostname}`;
47
+ };
48
+ const createLockMetadata = (statePath, operation) => {
49
+ return {
50
+ id: (0, exports.generateLockId)(),
51
+ user: getUserEmail(),
52
+ processId: process.pid,
53
+ hostname: node_os_1.default.hostname(),
54
+ operation,
55
+ acquiredAt: new Date().toISOString(),
56
+ path: statePath,
57
+ };
58
+ };
59
+ const readLockFile = (lockPath) => {
60
+ try {
61
+ if (node_fs_1.default.existsSync(lockPath)) {
62
+ const content = node_fs_1.default.readFileSync(lockPath, 'utf-8');
63
+ return JSON.parse(content);
64
+ }
65
+ }
66
+ catch {
67
+ // If we can't read the lock file, treat it as if it doesn't exist
68
+ }
69
+ return null;
70
+ };
71
+ const writeLockFile = (lockPath, metadata) => {
72
+ const lockDir = node_path_1.default.dirname(lockPath);
73
+ if (!node_fs_1.default.existsSync(lockDir)) {
74
+ node_fs_1.default.mkdirSync(lockDir, { recursive: true });
75
+ }
76
+ node_fs_1.default.writeFileSync(lockPath, JSON.stringify(metadata, null, 2), 'utf-8');
77
+ };
78
+ const removeLockFile = (lockPath) => {
79
+ if (node_fs_1.default.existsSync(lockPath)) {
80
+ node_fs_1.default.unlinkSync(lockPath);
81
+ }
82
+ };
83
+ const isLockStale = (lock) => {
84
+ const acquiredAt = new Date(lock.acquiredAt).getTime();
85
+ const now = Date.now();
86
+ return now - acquiredAt > constants_1.STALE_LOCK_THRESHOLD;
87
+ };
88
+ const getTimeAgo = (acquiredAt) => {
89
+ const now = new Date();
90
+ const minutesAgo = Math.floor((now.getTime() - acquiredAt.getTime()) / 60000);
91
+ if (minutesAgo < 1) {
92
+ return lang_1.lang.__('LOCK_TIME_AGO_LESS_THAN_MINUTE');
93
+ }
94
+ else if (minutesAgo === 1) {
95
+ return lang_1.lang.__('LOCK_TIME_AGO_ONE_MINUTE');
96
+ }
97
+ else if (minutesAgo < 60) {
98
+ return lang_1.lang.__('LOCK_TIME_AGO_MINUTES', { minutes: String(minutesAgo) });
99
+ }
100
+ else {
101
+ const hoursAgo = Math.floor(minutesAgo / 60);
102
+ if (hoursAgo === 1) {
103
+ return lang_1.lang.__('LOCK_TIME_AGO_ONE_HOUR');
104
+ }
105
+ else {
106
+ return lang_1.lang.__('LOCK_TIME_AGO_HOURS', { hours: String(hoursAgo) });
107
+ }
108
+ }
109
+ };
110
+ const formatLockInfo = (lock) => {
111
+ const acquiredAt = new Date(lock.acquiredAt);
112
+ const timeAgo = getTimeAgo(acquiredAt);
113
+ return `
114
+ ${lang_1.lang.__('LOCK_INFO_HEADER')}
115
+ ${lang_1.lang.__('LOCK_INFO_ID', { id: lock.id })}
116
+ ${lang_1.lang.__('LOCK_INFO_HELD_BY', { user: lock.user })}
117
+ ${lang_1.lang.__('LOCK_INFO_PROCESS', { operation: lock.operation, processId: String(lock.processId) })}
118
+ ${lang_1.lang.__('LOCK_INFO_HOST', { hostname: lock.hostname })}
119
+ ${lang_1.lang.__('LOCK_INFO_ACQUIRED', { acquiredAt: acquiredAt.toISOString(), timeAgo })}
120
+ ${lang_1.lang.__('LOCK_INFO_OPERATION', { operation: lock.operation })}
121
+ `;
122
+ };
123
+ exports.formatLockInfo = formatLockInfo;
124
+ const sleep = (ms) => {
125
+ return new Promise((resolve) => setTimeout(resolve, ms));
126
+ };
127
+ const acquireLockInternal = async (statePath, operation, options = {}) => {
128
+ const timeout = options.timeout ?? constants_1.DEFAULT_LOCK_TIMEOUT;
129
+ const retryDelay = options.retryDelay ?? constants_1.DEFAULT_LOCK_RETRY_DELAY;
130
+ const maxRetries = options.maxRetries ?? Math.ceil(timeout / retryDelay);
131
+ const lockPath = (0, exports.getLockPath)(statePath);
132
+ const metadata = createLockMetadata(statePath, operation);
133
+ const startTime = Date.now();
134
+ let attempt = 0;
135
+ while (attempt <= maxRetries) {
136
+ // Check if lock file exists
137
+ const existingLock = readLockFile(lockPath);
138
+ if (!existingLock) {
139
+ // No lock exists, try to acquire
140
+ try {
141
+ writeLockFile(lockPath, metadata);
142
+ // Verify we got the lock by reading it back
143
+ const verifyLock = readLockFile(lockPath);
144
+ if (verifyLock && verifyLock.id === metadata.id) {
145
+ return metadata;
146
+ }
147
+ }
148
+ catch {
149
+ // Failed to write lock, will retry
150
+ }
151
+ }
152
+ else {
153
+ // Lock exists, check if it's stale
154
+ if (isLockStale(existingLock)) {
155
+ // Lock is stale, but we don't auto-remove it
156
+ // User must use force-unlock
157
+ throw new LockError(`State is currently locked (stale lock detected).\n${(0, exports.formatLockInfo)(existingLock)}\nThis lock appears to be stale. If you are certain no other operation is running, use:\n si force-unlock ${existingLock.id}`, existingLock);
158
+ }
159
+ // Check if timeout exceeded
160
+ if (Date.now() - startTime >= timeout) {
161
+ throw new LockError(`Failed to acquire lock after ${timeout / 1000} seconds.\n${(0, exports.formatLockInfo)(existingLock)}\nIf you are certain no other operation is running, use:\n si force-unlock ${existingLock.id}`, existingLock);
162
+ }
163
+ }
164
+ // Wait before retrying with exponential backoff
165
+ const delay = Math.min(retryDelay * Math.pow(2, attempt), 30000); // Cap at 30 seconds
166
+ await sleep(delay);
167
+ attempt++;
168
+ }
169
+ // This shouldn't be reached, but just in case
170
+ const existingLock = readLockFile(lockPath);
171
+ throw new LockError(`Failed to acquire lock.\n${existingLock ? (0, exports.formatLockInfo)(existingLock) : ''}\nIf you are certain no other operation is running, use:\n si force-unlock ${existingLock?.id || 'unknown'}`, existingLock || undefined);
172
+ };
173
+ const releaseLockInternal = (statePath, lockId) => {
174
+ const lockPath = (0, exports.getLockPath)(statePath);
175
+ const existingLock = readLockFile(lockPath);
176
+ // Only release if the lock ID matches
177
+ if (existingLock && existingLock.id === lockId) {
178
+ removeLockFile(lockPath);
179
+ }
180
+ };
181
+ const forceUnlock = (statePath, lockId) => {
182
+ const lockPath = (0, exports.getLockPath)(statePath);
183
+ const existingLock = readLockFile(lockPath);
184
+ if (!existingLock) {
185
+ return false; // No lock to remove
186
+ }
187
+ if (existingLock.id !== lockId) {
188
+ throw new Error(`Lock ID mismatch. Current lock ID is ${existingLock.id}, but you provided ${lockId}`);
189
+ }
190
+ removeLockFile(lockPath);
191
+ return true;
192
+ };
193
+ exports.forceUnlock = forceUnlock;
194
+ const withLock = async (statePath, operation, fn, options) => {
195
+ let lock = null;
196
+ try {
197
+ lock = await acquireLockInternal(statePath, operation, options);
198
+ return await fn();
199
+ }
200
+ finally {
201
+ if (lock) {
202
+ releaseLockInternal(statePath, lock.id);
203
+ }
204
+ }
205
+ };
206
+ exports.withLock = withLock;
207
+ // Export only for forceUnlock command which needs to read lock info
208
+ const readLockFileForCommand = (statePath) => {
209
+ const lockPath = (0, exports.getLockPath)(statePath);
210
+ return readLockFile(lockPath);
211
+ };
212
+ exports.readLockFileForCommand = readLockFileForCommand;
@@ -5,11 +5,94 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.logger = void 0;
7
7
  const pino_1 = __importDefault(require("pino"));
8
- const logger = (0, pino_1.default)({
8
+ const pino_pretty_1 = __importDefault(require("pino-pretty"));
9
+ const child_process_1 = require("child_process");
10
+ const iconv_lite_1 = __importDefault(require("iconv-lite"));
11
+ const stream_1 = require("stream");
12
+ const CODE_PAGE_TO_ENCODING = {
13
+ 932: 'shift_jis', // Japanese
14
+ 936: 'gbk', // Simplified Chinese
15
+ 949: 'euc-kr', // Korean
16
+ 950: 'big5', // Traditional Chinese
17
+ 1250: 'windows-1250', // Central European
18
+ 1251: 'windows-1251', // Cyrillic
19
+ 1252: 'windows-1252', // Latin I
20
+ 1253: 'windows-1253', // Greek
21
+ 1254: 'windows-1254', // Turkish
22
+ 1255: 'windows-1255', // Hebrew
23
+ 1256: 'windows-1256', // Arabic
24
+ 1257: 'windows-1257', // Baltic
25
+ 1258: 'windows-1258', // Vietnamese
26
+ 65001: 'utf8', // UTF-8
27
+ 1200: 'utf16le', // UTF-16 LE
28
+ 1201: 'utf16be', // UTF-16 BE
29
+ 20127: 'ascii', // ASCII
30
+ 28591: 'iso-8859-1', // Latin-1
31
+ };
32
+ const getSystemEncoding = () => {
33
+ if (process.platform === 'win32') {
34
+ try {
35
+ const codePageOutput = (0, child_process_1.execSync)('chcp', {
36
+ encoding: 'utf8',
37
+ stdio: ['pipe', 'pipe', 'pipe'],
38
+ }).toString();
39
+ const codePageMatch = codePageOutput.match(/(\d+)\s*$/m);
40
+ if (codePageMatch) {
41
+ const codePage = parseInt(codePageMatch[1], 10);
42
+ return CODE_PAGE_TO_ENCODING[codePage] || 'utf8';
43
+ }
44
+ }
45
+ catch {
46
+ // fallback to environment variable detection
47
+ }
48
+ }
49
+ const langEnv = (process.env.LANG ||
50
+ process.env.LC_ALL ||
51
+ process.env.LC_CTYPE ||
52
+ '').toLowerCase();
53
+ if (['utf8', 'utf-8'].find((lang) => langEnv.includes(lang))) {
54
+ return 'utf8';
55
+ }
56
+ if (['gbk', 'gb2312'].find((lang) => langEnv.includes(lang))) {
57
+ return 'gbk';
58
+ }
59
+ if (['shift_jis', 'sjis'].find((lang) => langEnv.includes(lang))) {
60
+ return 'shift_jis';
61
+ }
62
+ if (langEnv.includes('big5')) {
63
+ return 'big5';
64
+ }
65
+ return 'utf8';
66
+ };
67
+ class EncodingTransformStream extends stream_1.Writable {
68
+ constructor(encoding) {
69
+ super();
70
+ this.encoding = encoding;
71
+ this.formatLog = pino_pretty_1.default.prettyFactory({
72
+ colorize: true,
73
+ translateTime: 'HH:MM:ss',
74
+ ignore: 'pid,hostname',
75
+ messageFormat: '{msg}',
76
+ });
77
+ }
78
+ _write(chunk, encoding, callback) {
79
+ try {
80
+ const stringChunk = typeof chunk === 'string' ? chunk : chunk.toString();
81
+ const formattedChunk = this.formatLog(stringChunk);
82
+ if (this.encoding !== 'utf8' && iconv_lite_1.default.encodingExists(this.encoding)) {
83
+ process.stdout.write(iconv_lite_1.default.toEncoding(formattedChunk, 'utf8'));
84
+ }
85
+ else {
86
+ process.stdout.write(formattedChunk);
87
+ }
88
+ callback();
89
+ }
90
+ catch (error) {
91
+ callback(error);
92
+ }
93
+ }
94
+ }
95
+ exports.logger = (0, pino_1.default)({
9
96
  name: 'ServerlessInsight',
10
97
  level: ['ServerlessInsight', '*'].includes(process.env.DEBUG || '') ? 'debug' : 'info',
11
- transport: {
12
- target: 'pino-pretty',
13
- },
14
- });
15
- exports.logger = logger;
98
+ }, new EncodingTransformStream(getSystemEncoding()));
@@ -5,7 +5,6 @@ var ProviderEnum;
5
5
  (function (ProviderEnum) {
6
6
  ProviderEnum["HUAWEI"] = "huawei";
7
7
  ProviderEnum["ALIYUN"] = "aliyun";
8
- // TENCENT = 'TENCENT',
9
- // AWS = 'AZURE',
10
- // AZURE = 'AZURE',
8
+ ProviderEnum["TENCENT"] = "tencent";
9
+ ProviderEnum["AWS"] = "aws";
11
10
  })(ProviderEnum || (exports.ProviderEnum = ProviderEnum = {}));
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSupportedRuntimes = exports.isRuntimeSupported = exports.mapRuntime = exports.StandardRuntime = void 0;
4
+ const providerEnum_1 = require("./providerEnum");
5
+ var StandardRuntime;
6
+ (function (StandardRuntime) {
7
+ StandardRuntime["NODEJS24"] = "nodejs24";
8
+ StandardRuntime["NODEJS22"] = "nodejs22";
9
+ StandardRuntime["NODEJS20"] = "nodejs20";
10
+ StandardRuntime["NODEJS18"] = "nodejs18";
11
+ StandardRuntime["NODEJS16"] = "nodejs16";
12
+ StandardRuntime["NODEJS14"] = "nodejs14";
13
+ StandardRuntime["NODEJS12"] = "nodejs12";
14
+ StandardRuntime["NODEJS10"] = "nodejs10";
15
+ StandardRuntime["PYTHON3_14"] = "python3.14";
16
+ StandardRuntime["PYTHON3_13"] = "python3.13";
17
+ StandardRuntime["PYTHON3_12"] = "python3.12";
18
+ StandardRuntime["PYTHON3_11"] = "python3.11";
19
+ StandardRuntime["PYTHON3_10"] = "python3.10";
20
+ StandardRuntime["PYTHON3_9"] = "python3.9";
21
+ StandardRuntime["PYTHON3_7"] = "python3.7";
22
+ StandardRuntime["PYTHON3_6"] = "python3.6";
23
+ StandardRuntime["JAVA25"] = "java25";
24
+ StandardRuntime["JAVA21"] = "java21";
25
+ StandardRuntime["JAVA17"] = "java17";
26
+ StandardRuntime["JAVA11"] = "java11";
27
+ StandardRuntime["JAVA8"] = "java8";
28
+ StandardRuntime["PHP8_0"] = "php8.0";
29
+ StandardRuntime["PHP7_4"] = "php7.4";
30
+ StandardRuntime["PHP7_2"] = "php7.2";
31
+ StandardRuntime["PHP5_6"] = "php5.6";
32
+ StandardRuntime["GO1"] = "go1";
33
+ StandardRuntime["DOTNET_CORE3_1"] = "dotnet_core3.1";
34
+ })(StandardRuntime || (exports.StandardRuntime = StandardRuntime = {}));
35
+ const runtimeMappings = {
36
+ [StandardRuntime.NODEJS24]: {
37
+ [providerEnum_1.ProviderEnum.AWS]: 'nodejs24.x',
38
+ },
39
+ [StandardRuntime.NODEJS22]: {
40
+ [providerEnum_1.ProviderEnum.AWS]: 'nodejs22.x',
41
+ },
42
+ [StandardRuntime.NODEJS20]: {
43
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs20',
44
+ [providerEnum_1.ProviderEnum.AWS]: 'nodejs20.x',
45
+ },
46
+ [StandardRuntime.NODEJS18]: {
47
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs18',
48
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Nodejs18.15',
49
+ },
50
+ [StandardRuntime.NODEJS16]: {
51
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs16',
52
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Nodejs16.13',
53
+ },
54
+ [StandardRuntime.NODEJS14]: {
55
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs14',
56
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Nodejs14.18',
57
+ },
58
+ [StandardRuntime.NODEJS12]: {
59
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs12',
60
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Nodejs12.16',
61
+ },
62
+ [StandardRuntime.NODEJS10]: {
63
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'nodejs10',
64
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Nodejs10.15',
65
+ },
66
+ [StandardRuntime.PYTHON3_14]: {
67
+ [providerEnum_1.ProviderEnum.AWS]: 'python3.14',
68
+ },
69
+ [StandardRuntime.PYTHON3_13]: {
70
+ [providerEnum_1.ProviderEnum.AWS]: 'python3.13',
71
+ },
72
+ [StandardRuntime.PYTHON3_12]: {
73
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'python3.12',
74
+ [providerEnum_1.ProviderEnum.AWS]: 'python3.12',
75
+ },
76
+ [StandardRuntime.PYTHON3_11]: {
77
+ [providerEnum_1.ProviderEnum.AWS]: 'python3.11',
78
+ },
79
+ [StandardRuntime.PYTHON3_10]: {
80
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'python3.10',
81
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Python3.10',
82
+ [providerEnum_1.ProviderEnum.AWS]: 'python3.10',
83
+ },
84
+ [StandardRuntime.PYTHON3_9]: {
85
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'python3.9',
86
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Python3.9',
87
+ },
88
+ [StandardRuntime.PYTHON3_7]: {
89
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Python3.7',
90
+ },
91
+ [StandardRuntime.PYTHON3_6]: {
92
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'python3.6',
93
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Python3.6',
94
+ },
95
+ [StandardRuntime.JAVA25]: {
96
+ [providerEnum_1.ProviderEnum.AWS]: 'java25',
97
+ },
98
+ [StandardRuntime.JAVA21]: {
99
+ [providerEnum_1.ProviderEnum.AWS]: 'java21',
100
+ },
101
+ [StandardRuntime.JAVA17]: {
102
+ [providerEnum_1.ProviderEnum.AWS]: 'java17',
103
+ },
104
+ [StandardRuntime.JAVA11]: {
105
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'java11',
106
+ [providerEnum_1.ProviderEnum.AWS]: 'java11',
107
+ },
108
+ [StandardRuntime.JAVA8]: {
109
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'java8',
110
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Java8',
111
+ [providerEnum_1.ProviderEnum.AWS]: 'java8.al2',
112
+ },
113
+ [StandardRuntime.PHP8_0]: {
114
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Php8.0',
115
+ },
116
+ [StandardRuntime.PHP7_4]: {
117
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Php7.4',
118
+ },
119
+ [StandardRuntime.PHP7_2]: {
120
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'php7.2',
121
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Php7.2',
122
+ },
123
+ [StandardRuntime.PHP5_6]: {
124
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Php5.6',
125
+ },
126
+ [StandardRuntime.GO1]: {
127
+ [providerEnum_1.ProviderEnum.ALIYUN]: 'go 1.x',
128
+ [providerEnum_1.ProviderEnum.TENCENT]: 'Go1',
129
+ },
130
+ [StandardRuntime.DOTNET_CORE3_1]: {
131
+ [providerEnum_1.ProviderEnum.ALIYUN]: '.NET Core 3.1',
132
+ },
133
+ };
134
+ const mapRuntime = (standardRuntime, provider) => {
135
+ const mapping = runtimeMappings[standardRuntime];
136
+ if (!mapping) {
137
+ throw new Error(`Unsupported standard runtime: ${standardRuntime}`);
138
+ }
139
+ const providerRuntime = mapping[provider];
140
+ if (!providerRuntime) {
141
+ throw new Error(`Runtime ${standardRuntime} is not supported for provider ${provider}. ` +
142
+ `Supported providers for this runtime: ${Object.keys(mapping).join(', ')}`);
143
+ }
144
+ return providerRuntime;
145
+ };
146
+ exports.mapRuntime = mapRuntime;
147
+ const isRuntimeSupported = (standardRuntime, provider) => {
148
+ const mapping = runtimeMappings[standardRuntime];
149
+ return !!mapping && !!mapping[provider];
150
+ };
151
+ exports.isRuntimeSupported = isRuntimeSupported;
152
+ const getSupportedRuntimes = (provider) => {
153
+ if (!provider) {
154
+ return Object.values(StandardRuntime);
155
+ }
156
+ return Object.entries(runtimeMappings)
157
+ .filter(([, mapping]) => !!mapping[provider])
158
+ .map(([runtime]) => runtime);
159
+ };
160
+ exports.getSupportedRuntimes = getSupportedRuntimes;
@@ -0,0 +1,84 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createTdsqlcClient = exports.createTencentCloudClient = void 0;
40
+ const tencentcloud = __importStar(require("tencentcloud-sdk-nodejs-scf"));
41
+ const cynosdb = __importStar(require("tencentcloud-sdk-nodejs-cynosdb"));
42
+ const cos_nodejs_sdk_v5_1 = __importDefault(require("cos-nodejs-sdk-v5"));
43
+ const ScfClient = tencentcloud.scf.v20180416.Client;
44
+ const CynosdbClient = cynosdb.cynosdb.v20190107.Client;
45
+ const createTencentCloudClient = (context) => {
46
+ const scfClientConfig = {
47
+ credential: {
48
+ secretId: context.accessKeyId,
49
+ secretKey: context.accessKeySecret,
50
+ },
51
+ region: context.region,
52
+ profile: {
53
+ httpProfile: {
54
+ endpoint: 'scf.tencentcloudapi.com',
55
+ },
56
+ },
57
+ };
58
+ const scfClient = new ScfClient(scfClientConfig);
59
+ const cosClient = new cos_nodejs_sdk_v5_1.default({
60
+ SecretId: context.accessKeyId,
61
+ SecretKey: context.accessKeySecret,
62
+ });
63
+ return {
64
+ scf: scfClient,
65
+ cos: cosClient,
66
+ };
67
+ };
68
+ exports.createTencentCloudClient = createTencentCloudClient;
69
+ const createTdsqlcClient = (context) => {
70
+ const clientConfig = {
71
+ credential: {
72
+ secretId: context.accessKeyId,
73
+ secretKey: context.accessKeySecret,
74
+ },
75
+ region: context.region,
76
+ profile: {
77
+ httpProfile: {
78
+ endpoint: 'cynosdb.tencentcloudapi.com',
79
+ },
80
+ },
81
+ };
82
+ return new CynosdbClient(clientConfig);
83
+ };
84
+ exports.createTdsqlcClient = createTdsqlcClient;
@@ -0,0 +1,107 @@
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.getRoleArnFromState = exports.getAllResources = exports.removeResource = exports.setResource = exports.getResource = exports.saveStateWithLock = exports.saveState = exports.loadState = exports.ensureStateDir = exports.getStatePath = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const types_1 = require("../types");
10
+ const lockManager_1 = require("./lockManager");
11
+ const STATE_DIR = '.serverlessinsight';
12
+ const STATE_FILE = 'state.json';
13
+ const getStatePath = (baseDir = process.cwd()) => {
14
+ return node_path_1.default.join(baseDir, STATE_DIR, STATE_FILE);
15
+ };
16
+ exports.getStatePath = getStatePath;
17
+ const ensureStateDir = (baseDir = process.cwd()) => {
18
+ const stateDir = node_path_1.default.join(baseDir, STATE_DIR);
19
+ if (!node_fs_1.default.existsSync(stateDir)) {
20
+ node_fs_1.default.mkdirSync(stateDir, { recursive: true });
21
+ }
22
+ };
23
+ exports.ensureStateDir = ensureStateDir;
24
+ /**
25
+ * Load state file.
26
+ */
27
+ const loadState = (provider, baseDir = process.cwd()) => {
28
+ const statePath = (0, exports.getStatePath)(baseDir);
29
+ try {
30
+ if (node_fs_1.default.existsSync(statePath)) {
31
+ const content = node_fs_1.default.readFileSync(statePath, 'utf-8');
32
+ const state = JSON.parse(content);
33
+ return state;
34
+ }
35
+ // If file doesn't exist or is invalid, return empty state
36
+ }
37
+ catch {
38
+ // Ignore error
39
+ }
40
+ return { version: types_1.CURRENT_STATE_VERSION, provider, resources: {} };
41
+ };
42
+ exports.loadState = loadState;
43
+ const saveState = (state, baseDir = process.cwd()) => {
44
+ (0, exports.ensureStateDir)(baseDir);
45
+ const statePath = (0, exports.getStatePath)(baseDir);
46
+ // Ensure we always save with current version
47
+ const stateToSave = {
48
+ ...state,
49
+ version: types_1.CURRENT_STATE_VERSION,
50
+ };
51
+ node_fs_1.default.writeFileSync(statePath, JSON.stringify(stateToSave, null, 2), 'utf-8');
52
+ };
53
+ exports.saveState = saveState;
54
+ /**
55
+ * Save state with automatic locking.
56
+ * This should be used by high-level operations like deploy/destroy.
57
+ */
58
+ const saveStateWithLock = async (state, operation, baseDir = process.cwd(), options) => {
59
+ const statePath = (0, exports.getStatePath)(baseDir);
60
+ await (0, lockManager_1.withLock)(statePath, operation, async () => {
61
+ (0, exports.saveState)(state, baseDir);
62
+ }, options);
63
+ };
64
+ exports.saveStateWithLock = saveStateWithLock;
65
+ const getResource = (state, resourceId) => {
66
+ return state.resources[resourceId];
67
+ };
68
+ exports.getResource = getResource;
69
+ const setResource = (state, resourceId, resourceState) => {
70
+ return {
71
+ ...state,
72
+ resources: {
73
+ ...state.resources,
74
+ [resourceId]: resourceState,
75
+ },
76
+ };
77
+ };
78
+ exports.setResource = setResource;
79
+ const removeResource = (state, resourceId) => {
80
+ const { [resourceId]: _, ...remainingResources } = state.resources;
81
+ return {
82
+ ...state,
83
+ resources: remainingResources,
84
+ };
85
+ };
86
+ exports.removeResource = removeResource;
87
+ const getAllResources = (state) => {
88
+ return state.resources;
89
+ };
90
+ exports.getAllResources = getAllResources;
91
+ /**
92
+ * Extract role ARN from function state for event resources.
93
+ * Looks through all function resources to find a RAM role instance and returns its ARN.
94
+ */
95
+ const getRoleArnFromState = (state) => {
96
+ const allResources = (0, exports.getAllResources)(state);
97
+ for (const [logicalId, resourceState] of Object.entries(allResources)) {
98
+ if (logicalId.startsWith('functions.')) {
99
+ const ramRoleInstance = resourceState.instances?.find((i) => i.type === 'ALIYUN_RAM_ROLE');
100
+ if (ramRoleInstance?.arn) {
101
+ return ramRoleInstance.arn;
102
+ }
103
+ }
104
+ }
105
+ return undefined;
106
+ };
107
+ exports.getRoleArnFromState = getRoleArnFromState;