@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.
- package/.gitattributes +1 -0
- package/README.md +108 -8
- package/README.zh-CN.md +52 -8
- package/dist/package.json +37 -35
- package/dist/src/commands/deploy.js +17 -7
- package/dist/src/commands/destroy.js +27 -4
- package/dist/src/commands/forceUnlock.js +61 -0
- package/dist/src/commands/index.js +86 -14
- package/dist/src/commands/local.js +10 -1
- package/dist/src/commands/plan.js +33 -0
- package/dist/src/commands/template.js +3 -1
- package/dist/src/commands/validate.js +2 -1
- package/dist/src/common/aliyunClient/apigwOperations.js +652 -0
- package/dist/src/common/aliyunClient/dnsOperations.js +90 -0
- package/dist/src/common/aliyunClient/ecsOperations.js +141 -0
- package/dist/src/common/aliyunClient/esOperations.js +219 -0
- package/dist/src/common/aliyunClient/fc3Operations.js +270 -0
- package/dist/src/common/aliyunClient/index.js +141 -0
- package/dist/src/common/aliyunClient/nasOperations.js +233 -0
- package/dist/src/common/aliyunClient/ossOperations.js +237 -0
- package/dist/src/common/aliyunClient/ramOperations.js +205 -0
- package/dist/src/common/aliyunClient/rdsOperations.js +206 -0
- package/dist/src/common/aliyunClient/slsOperations.js +218 -0
- package/dist/src/common/aliyunClient/tablestoreOperations.js +199 -0
- package/dist/src/common/aliyunClient/types.js +2 -0
- package/dist/src/common/constants.js +7 -1
- package/dist/src/common/context.js +32 -14
- package/dist/src/common/credentials.js +39 -0
- package/dist/src/common/dependencyGraph/graph.js +280 -0
- package/dist/src/common/dependencyGraph/index.js +18 -0
- package/dist/src/common/dependencyGraph/types.js +2 -0
- package/dist/src/common/fileUtils.js +16 -0
- package/dist/src/common/hashUtils.js +121 -0
- package/dist/src/common/iacHelper.js +25 -97
- package/dist/src/common/imsClient.js +4 -0
- package/dist/src/common/index.js +7 -2
- package/dist/src/common/lockManager.js +212 -0
- package/dist/src/common/logger.js +89 -6
- package/dist/src/common/providerEnum.js +2 -3
- package/dist/src/common/runtimeMapper.js +160 -0
- package/dist/src/common/scfClient.js +84 -0
- package/dist/src/common/stateManager.js +107 -0
- package/dist/src/common/tencentClient/cosOperations.js +287 -0
- package/dist/src/common/tencentClient/esOperations.js +156 -0
- package/dist/src/common/tencentClient/index.js +116 -0
- package/dist/src/common/tencentClient/scfOperations.js +141 -0
- package/dist/src/common/tencentClient/tdsqlcOperations.js +211 -0
- package/dist/src/common/tencentClient/types.js +17 -0
- package/dist/src/lang/en.js +254 -0
- package/dist/src/lang/index.js +28 -8
- package/dist/src/lang/zh-CN.js +229 -0
- package/dist/src/parser/bucketParser.js +25 -12
- package/dist/src/parser/databaseParser.js +14 -10
- package/dist/src/parser/functionParser.js +19 -6
- package/dist/src/parser/parseUtils.js +74 -0
- package/dist/src/parser/tableParser.js +19 -17
- package/dist/src/stack/aliyunStack/apigwExecutor.js +84 -0
- package/dist/src/stack/aliyunStack/apigwPlanner.js +118 -0
- package/dist/src/stack/aliyunStack/apigwResource.js +339 -0
- package/dist/src/stack/aliyunStack/apigwTypes.js +125 -0
- package/dist/src/stack/aliyunStack/databaseExecutor.js +112 -0
- package/dist/src/stack/aliyunStack/databasePlanner.js +128 -0
- package/dist/src/stack/aliyunStack/databaseResource.js +228 -0
- package/dist/src/stack/aliyunStack/deployer.js +133 -0
- package/dist/src/stack/aliyunStack/destroyer.js +114 -0
- package/dist/src/stack/aliyunStack/esServerlessTypes.js +141 -0
- package/dist/src/stack/aliyunStack/fc3Executor.js +91 -0
- package/dist/src/stack/aliyunStack/fc3Planner.js +77 -0
- package/dist/src/stack/aliyunStack/fc3Resource.js +511 -0
- package/dist/src/stack/aliyunStack/fc3Types.js +76 -0
- package/dist/src/stack/aliyunStack/index.js +40 -0
- package/dist/src/stack/aliyunStack/ossExecutor.js +91 -0
- package/dist/src/stack/aliyunStack/ossPlanner.js +76 -0
- package/dist/src/stack/aliyunStack/ossResource.js +196 -0
- package/dist/src/stack/aliyunStack/ossTypes.js +50 -0
- package/dist/src/stack/aliyunStack/planner.js +37 -0
- package/dist/src/stack/aliyunStack/rdsTypes.js +217 -0
- package/dist/src/stack/aliyunStack/tablestoreExecutor.js +92 -0
- package/dist/src/stack/aliyunStack/tablestorePlanner.js +94 -0
- package/dist/src/stack/aliyunStack/tablestoreResource.js +120 -0
- package/dist/src/stack/aliyunStack/tablestoreTypes.js +77 -0
- package/dist/src/stack/bucketTypes.js +17 -0
- package/dist/src/stack/deploy.js +24 -77
- package/dist/src/stack/localStack/bucket.js +11 -6
- package/dist/src/stack/localStack/event.js +10 -5
- package/dist/src/stack/localStack/function.js +13 -7
- package/dist/src/stack/localStack/functionRunner.js +1 -1
- package/dist/src/stack/localStack/localServer.js +7 -6
- package/dist/src/stack/scfStack/cosExecutor.js +91 -0
- package/dist/src/stack/scfStack/cosPlanner.js +76 -0
- package/dist/src/stack/scfStack/cosResource.js +126 -0
- package/dist/src/stack/scfStack/cosTypes.js +46 -0
- package/dist/src/stack/scfStack/deployer.js +91 -0
- package/dist/src/stack/scfStack/destroyer.js +88 -0
- package/dist/src/stack/scfStack/esServerlessExecutor.js +105 -0
- package/dist/src/stack/scfStack/esServerlessPlanner.js +86 -0
- package/dist/src/stack/scfStack/esServerlessResource.js +94 -0
- package/dist/src/stack/scfStack/esServerlessTypes.js +48 -0
- package/dist/src/stack/scfStack/index.js +35 -0
- package/dist/src/stack/scfStack/planner.js +91 -0
- package/dist/src/stack/scfStack/scfExecutor.js +91 -0
- package/dist/src/stack/scfStack/scfPlanner.js +78 -0
- package/dist/src/stack/scfStack/scfResource.js +216 -0
- package/dist/src/stack/scfStack/scfTypes.js +41 -0
- package/dist/src/stack/scfStack/tdsqlcExecutor.js +105 -0
- package/dist/src/stack/scfStack/tdsqlcPlanner.js +90 -0
- package/dist/src/stack/scfStack/tdsqlcResource.js +146 -0
- package/dist/src/stack/scfStack/tdsqlcTypes.js +59 -0
- package/dist/src/types/domains/lock.js +2 -0
- package/dist/src/types/domains/resolvable.js +2 -0
- package/dist/src/types/domains/state.js +19 -0
- package/dist/src/types/index.js +4 -0
- package/dist/src/validator/bucketSchema.js +4 -10
- package/dist/src/validator/databaseSchema.js +36 -36
- package/dist/src/validator/eventSchema.js +3 -2
- package/dist/src/validator/functionSchema.js +51 -46
- package/dist/src/validator/iacSchema.js +52 -3
- package/dist/src/validator/rootSchema.js +47 -1
- package/dist/src/validator/tableschema.js +9 -8
- package/dist/src/validator/templateRefSchema.js +23 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -35
- package/samples/README_TENCENT_COS.md +486 -0
- package/samples/README_TENCENT_SCF.md +272 -0
- package/samples/aliyun-poc-api.yml +1 -1
- package/samples/aliyun-poc-bucket.yml +0 -1
- package/samples/aliyun-poc-domain.yml +0 -1
- package/samples/aliyun-poc-es.yml +14 -13
- package/samples/aliyun-poc-rds.yml +0 -2
- package/samples/aliyun-poc-table.yml +1 -3
- package/samples/tencent-poc-cos.yml +20 -0
- package/samples/tencent-poc-scf.yml +36 -0
- package/dist/src/commands/index.d.ts +0 -2
- package/dist/src/common/index.d.ts +0 -11
- package/dist/src/common/rosAssets.js +0 -178
- package/dist/src/common/rosClient.js +0 -198
- package/dist/src/index.d.ts +0 -1
- package/dist/src/lang/index.d.ts +0 -3
- package/dist/src/parser/index.d.ts +0 -3
- package/dist/src/stack/index.d.ts +0 -1
- package/dist/src/stack/localStack/index.d.ts +0 -5
- package/dist/src/stack/rfsStack/index.d.ts +0 -9
- package/dist/src/stack/rosStack/bootstrap.js +0 -187
- package/dist/src/stack/rosStack/bucket.js +0 -127
- package/dist/src/stack/rosStack/database.js +0 -313
- package/dist/src/stack/rosStack/event.js +0 -143
- package/dist/src/stack/rosStack/function.js +0 -259
- package/dist/src/stack/rosStack/index.d.ts +0 -7
- package/dist/src/stack/rosStack/index.js +0 -75
- package/dist/src/stack/rosStack/stage.js +0 -46
- package/dist/src/stack/rosStack/table.js +0 -95
- package/dist/src/stack/rosStack/tag.js +0 -11
- package/dist/src/stack/rosStack/vars.js +0 -49
- package/dist/src/types/index.d.ts +0 -55
- package/dist/src/types/localStack/index.d.ts +0 -81
- package/dist/src/validator/index.d.ts +0 -1
- package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +0 -12
- package/layers/si-bootstrap-sdk/README.md +0 -1
- package/layers/si-bootstrap-sdk/package-lock.json +0 -875
- 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
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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;
|