@geek-fun/serverlessinsight 0.4.1 → 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 +41 -5
- package/dist/src/commands/local.js +10 -1
- package/dist/src/commands/plan.js +33 -0
- package/dist/src/commands/template.js +1 -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 +6 -1
- package/dist/src/common/context.js +13 -3
- package/dist/src/common/credentials.js +30 -6
- 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 +6 -2
- package/dist/src/common/lockManager.js +212 -0
- package/dist/src/common/logger.js +87 -10
- 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 +35 -1
- package/dist/src/validator/rootSchema.js +1 -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 +4 -7
- 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 -12
- package/dist/src/common/rosAssets.js +0 -178
- package/dist/src/common/rosClient.js +0 -201
- 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 -64
- package/layers/si-bootstrap-sdk/package-lock.json +0 -881
- package/layers/si-bootstrap-sdk/package.json +0 -33
- package/layers/si-bootstrap-sdk/support/operation-collection/README.md +0 -47
- package/layers/si-bootstrap-sdk/support/operation-collection/package-lock.json +0 -298
- package/layers/si-bootstrap-sdk/support/operation-collection/package.json +0 -18
- package/layers/si-bootstrap-sdk/support/operation-collection/publish.js +0 -257
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toDotFormat = exports.getDependencyInfo = exports.getParallelExecutionPlan = exports.getExecutionOrder = exports.topologicalSort = exports.validateGraph = exports.detectCycle = exports.buildDependencyGraph = void 0;
|
|
4
|
+
const RESOURCE_TYPE_PREFIX_MAP = {
|
|
5
|
+
// Aliyun resource types (as emitted by planners)
|
|
6
|
+
ALIYUN_FC3: 'functions',
|
|
7
|
+
ALIYUN_OSS_BUCKET: 'buckets',
|
|
8
|
+
ALIYUN_APIGW: 'events',
|
|
9
|
+
ALIYUN_APIGW_GROUP: 'events',
|
|
10
|
+
ALIYUN_APIGW_API: 'events',
|
|
11
|
+
ALIYUN_APIGW_DEPLOYMENT: 'events',
|
|
12
|
+
ALIYUN_RDS_SERVERLESS: 'databases',
|
|
13
|
+
ALIYUN_ES_SERVERLESS: 'databases',
|
|
14
|
+
ALIYUN_TABLESTORE_TABLE: 'tables',
|
|
15
|
+
// Tencent resource types (as emitted by planners)
|
|
16
|
+
SCF: 'functions',
|
|
17
|
+
COS_BUCKET: 'buckets',
|
|
18
|
+
TDSQL_C_SERVERLESS: 'databases',
|
|
19
|
+
};
|
|
20
|
+
const RESOURCE_DEPENDENCY_ORDER = {
|
|
21
|
+
databases: 0,
|
|
22
|
+
buckets: 1,
|
|
23
|
+
functions: 2,
|
|
24
|
+
tables: 3,
|
|
25
|
+
events: 4,
|
|
26
|
+
};
|
|
27
|
+
const getResourcePrefix = (logicalId) => logicalId.split('.')[0];
|
|
28
|
+
const getResourceTypeOrder = (resourceType) => {
|
|
29
|
+
const prefix = RESOURCE_TYPE_PREFIX_MAP[resourceType] || 'unknown';
|
|
30
|
+
return RESOURCE_DEPENDENCY_ORDER[prefix] ?? 99;
|
|
31
|
+
};
|
|
32
|
+
const getPrefixOrder = (prefix) => RESOURCE_DEPENDENCY_ORDER[prefix] ?? 99;
|
|
33
|
+
const extractReferencedResources = (changes) => {
|
|
34
|
+
if (!changes)
|
|
35
|
+
return [];
|
|
36
|
+
const isValidResourceReference = (ref) => {
|
|
37
|
+
const validPrefixes = ['functions', 'events', 'databases', 'buckets', 'tables'];
|
|
38
|
+
const prefix = ref.split('.')[0];
|
|
39
|
+
return validPrefixes.includes(prefix);
|
|
40
|
+
};
|
|
41
|
+
const findReferences = (obj) => {
|
|
42
|
+
if (typeof obj === 'string') {
|
|
43
|
+
const matches = obj.match(/\$\{([^}]+)\}/g) || [];
|
|
44
|
+
return matches.map((m) => m.replace(/\$\{|\}/g, '')).filter(isValidResourceReference);
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(obj)) {
|
|
47
|
+
return obj.flatMap(findReferences);
|
|
48
|
+
}
|
|
49
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
50
|
+
return Object.values(obj).flatMap(findReferences);
|
|
51
|
+
}
|
|
52
|
+
return [];
|
|
53
|
+
};
|
|
54
|
+
const afterRefs = findReferences(changes.after);
|
|
55
|
+
return [...new Set(afterRefs)];
|
|
56
|
+
};
|
|
57
|
+
const inferDependenciesFromType = (item, allItems) => {
|
|
58
|
+
const sourcePrefix = getResourcePrefix(item.logicalId);
|
|
59
|
+
const sourceOrder = getPrefixOrder(sourcePrefix);
|
|
60
|
+
return allItems
|
|
61
|
+
.filter((other) => {
|
|
62
|
+
if (other.logicalId === item.logicalId)
|
|
63
|
+
return false;
|
|
64
|
+
const targetPrefix = getResourcePrefix(other.logicalId);
|
|
65
|
+
const targetOrder = getPrefixOrder(targetPrefix);
|
|
66
|
+
return targetOrder < sourceOrder && other.action !== 'delete' && other.action !== 'noop';
|
|
67
|
+
})
|
|
68
|
+
.map((dep) => dep.logicalId);
|
|
69
|
+
};
|
|
70
|
+
const findDependencies = (item, allItems) => {
|
|
71
|
+
const itemsByLogicalId = new Map(allItems.map((i) => [i.logicalId, i]));
|
|
72
|
+
const explicitRefs = extractReferencedResources(item.changes);
|
|
73
|
+
const explicitDeps = explicitRefs
|
|
74
|
+
.filter((ref) => itemsByLogicalId.has(ref))
|
|
75
|
+
.filter((ref) => {
|
|
76
|
+
const depItem = itemsByLogicalId.get(ref);
|
|
77
|
+
return depItem && depItem.action !== 'delete' && depItem.action !== 'noop';
|
|
78
|
+
});
|
|
79
|
+
const implicitDeps = item.action !== 'delete' ? inferDependenciesFromType(item, allItems) : [];
|
|
80
|
+
return [...new Set([...explicitDeps, ...implicitDeps])];
|
|
81
|
+
};
|
|
82
|
+
const findDestroyDependencies = (item, allItems) => {
|
|
83
|
+
const sourcePrefix = getResourcePrefix(item.logicalId);
|
|
84
|
+
const sourceOrder = getPrefixOrder(sourcePrefix);
|
|
85
|
+
return allItems
|
|
86
|
+
.filter((other) => {
|
|
87
|
+
if (other.logicalId === item.logicalId)
|
|
88
|
+
return false;
|
|
89
|
+
if (other.action !== 'delete')
|
|
90
|
+
return false;
|
|
91
|
+
const targetPrefix = getResourcePrefix(other.logicalId);
|
|
92
|
+
const targetOrder = getPrefixOrder(targetPrefix);
|
|
93
|
+
return targetOrder > sourceOrder;
|
|
94
|
+
})
|
|
95
|
+
.map((dep) => dep.logicalId);
|
|
96
|
+
};
|
|
97
|
+
const buildDependencyGraph = (items) => {
|
|
98
|
+
const nodes = new Map();
|
|
99
|
+
const edges = [];
|
|
100
|
+
items.forEach((item) => {
|
|
101
|
+
nodes.set(item.logicalId, {
|
|
102
|
+
id: item.logicalId,
|
|
103
|
+
planItem: item,
|
|
104
|
+
dependencies: [],
|
|
105
|
+
dependents: [],
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
items.forEach((item) => {
|
|
109
|
+
const deps = item.action === 'delete'
|
|
110
|
+
? findDestroyDependencies(item, items)
|
|
111
|
+
: findDependencies(item, items);
|
|
112
|
+
deps.forEach((depId) => {
|
|
113
|
+
const node = nodes.get(item.logicalId);
|
|
114
|
+
const depNode = nodes.get(depId);
|
|
115
|
+
if (node && depNode) {
|
|
116
|
+
node.dependencies.push(depId);
|
|
117
|
+
depNode.dependents.push(item.logicalId);
|
|
118
|
+
edges.push({ from: depId, to: item.logicalId });
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return { nodes, edges };
|
|
123
|
+
};
|
|
124
|
+
exports.buildDependencyGraph = buildDependencyGraph;
|
|
125
|
+
const detectCycle = (graph) => {
|
|
126
|
+
const visited = new Set();
|
|
127
|
+
const recursionStack = new Set();
|
|
128
|
+
const path = [];
|
|
129
|
+
const dfs = (nodeId) => {
|
|
130
|
+
visited.add(nodeId);
|
|
131
|
+
recursionStack.add(nodeId);
|
|
132
|
+
path.push(nodeId);
|
|
133
|
+
const node = graph.nodes.get(nodeId);
|
|
134
|
+
if (node) {
|
|
135
|
+
for (const depId of node.dependents) {
|
|
136
|
+
if (!visited.has(depId)) {
|
|
137
|
+
const cycle = dfs(depId);
|
|
138
|
+
if (cycle)
|
|
139
|
+
return cycle;
|
|
140
|
+
}
|
|
141
|
+
else if (recursionStack.has(depId)) {
|
|
142
|
+
const cycleStart = path.indexOf(depId);
|
|
143
|
+
return [...path.slice(cycleStart), depId];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
path.pop();
|
|
148
|
+
recursionStack.delete(nodeId);
|
|
149
|
+
return null;
|
|
150
|
+
};
|
|
151
|
+
for (const nodeId of graph.nodes.keys()) {
|
|
152
|
+
if (!visited.has(nodeId)) {
|
|
153
|
+
const cycle = dfs(nodeId);
|
|
154
|
+
if (cycle)
|
|
155
|
+
return cycle;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
};
|
|
160
|
+
exports.detectCycle = detectCycle;
|
|
161
|
+
const validateGraph = (graph) => {
|
|
162
|
+
const cycle = (0, exports.detectCycle)(graph);
|
|
163
|
+
if (cycle) {
|
|
164
|
+
return {
|
|
165
|
+
message: `Circular dependency detected: ${cycle.join(' -> ')}`,
|
|
166
|
+
cycle,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
};
|
|
171
|
+
exports.validateGraph = validateGraph;
|
|
172
|
+
const topologicalSort = (graph) => {
|
|
173
|
+
const inDegree = new Map();
|
|
174
|
+
const remaining = new Set();
|
|
175
|
+
graph.nodes.forEach((node, id) => {
|
|
176
|
+
inDegree.set(id, node.dependencies.length);
|
|
177
|
+
remaining.add(id);
|
|
178
|
+
});
|
|
179
|
+
const levels = [];
|
|
180
|
+
let level = 0;
|
|
181
|
+
while (remaining.size > 0) {
|
|
182
|
+
const currentLevel = [];
|
|
183
|
+
remaining.forEach((id) => {
|
|
184
|
+
if (inDegree.get(id) === 0) {
|
|
185
|
+
const node = graph.nodes.get(id);
|
|
186
|
+
if (node) {
|
|
187
|
+
currentLevel.push(node.planItem);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
if (currentLevel.length === 0) {
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
currentLevel.sort((a, b) => getResourceTypeOrder(a.resourceType) - getResourceTypeOrder(b.resourceType));
|
|
195
|
+
levels.push({ level, items: currentLevel });
|
|
196
|
+
currentLevel.forEach((item) => {
|
|
197
|
+
remaining.delete(item.logicalId);
|
|
198
|
+
const node = graph.nodes.get(item.logicalId);
|
|
199
|
+
if (node) {
|
|
200
|
+
node.dependents.forEach((depId) => {
|
|
201
|
+
const deg = inDegree.get(depId) ?? 0;
|
|
202
|
+
inDegree.set(depId, deg - 1);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
level++;
|
|
207
|
+
}
|
|
208
|
+
return levels;
|
|
209
|
+
};
|
|
210
|
+
exports.topologicalSort = topologicalSort;
|
|
211
|
+
const getExecutionOrder = (items) => {
|
|
212
|
+
if (items.length === 0)
|
|
213
|
+
return [];
|
|
214
|
+
const graph = (0, exports.buildDependencyGraph)(items);
|
|
215
|
+
const cycleError = (0, exports.validateGraph)(graph);
|
|
216
|
+
if (cycleError) {
|
|
217
|
+
throw new Error(cycleError.message);
|
|
218
|
+
}
|
|
219
|
+
const levels = (0, exports.topologicalSort)(graph);
|
|
220
|
+
return levels.flatMap((level) => level.items);
|
|
221
|
+
};
|
|
222
|
+
exports.getExecutionOrder = getExecutionOrder;
|
|
223
|
+
const getParallelExecutionPlan = (items) => {
|
|
224
|
+
if (items.length === 0)
|
|
225
|
+
return [];
|
|
226
|
+
const graph = (0, exports.buildDependencyGraph)(items);
|
|
227
|
+
const cycleError = (0, exports.validateGraph)(graph);
|
|
228
|
+
if (cycleError) {
|
|
229
|
+
throw new Error(cycleError.message);
|
|
230
|
+
}
|
|
231
|
+
return (0, exports.topologicalSort)(graph);
|
|
232
|
+
};
|
|
233
|
+
exports.getParallelExecutionPlan = getParallelExecutionPlan;
|
|
234
|
+
const getDependencyInfo = (items) => {
|
|
235
|
+
const graph = (0, exports.buildDependencyGraph)(items);
|
|
236
|
+
const cycleError = (0, exports.validateGraph)(graph);
|
|
237
|
+
if (cycleError) {
|
|
238
|
+
return {
|
|
239
|
+
graph,
|
|
240
|
+
order: [],
|
|
241
|
+
levels: [],
|
|
242
|
+
cycleError,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
const levels = (0, exports.topologicalSort)(graph);
|
|
246
|
+
const order = levels.flatMap((level) => level.items);
|
|
247
|
+
return {
|
|
248
|
+
graph,
|
|
249
|
+
order,
|
|
250
|
+
levels,
|
|
251
|
+
cycleError: null,
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
exports.getDependencyInfo = getDependencyInfo;
|
|
255
|
+
const escapeDotString = (str) => str.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
256
|
+
const toDotFormat = (graph) => {
|
|
257
|
+
const lines = ['digraph DependencyGraph {', ' rankdir=TB;', ' node [shape=box];', ''];
|
|
258
|
+
graph.nodes.forEach((node) => {
|
|
259
|
+
const escapedId = escapeDotString(node.id);
|
|
260
|
+
const escapedLogicalId = escapeDotString(node.planItem.logicalId);
|
|
261
|
+
const label = `${escapedLogicalId}\\n[${node.planItem.action}]`;
|
|
262
|
+
const color = node.planItem.action === 'create'
|
|
263
|
+
? 'green'
|
|
264
|
+
: node.planItem.action === 'delete'
|
|
265
|
+
? 'red'
|
|
266
|
+
: node.planItem.action === 'update'
|
|
267
|
+
? 'orange'
|
|
268
|
+
: 'gray';
|
|
269
|
+
lines.push(` "${escapedId}" [label="${label}", color="${color}"];`);
|
|
270
|
+
});
|
|
271
|
+
lines.push('');
|
|
272
|
+
graph.edges.forEach((edge) => {
|
|
273
|
+
const escapedFrom = escapeDotString(edge.from);
|
|
274
|
+
const escapedTo = escapeDotString(edge.to);
|
|
275
|
+
lines.push(` "${escapedFrom}" -> "${escapedTo}";`);
|
|
276
|
+
});
|
|
277
|
+
lines.push('}');
|
|
278
|
+
return lines.join('\n');
|
|
279
|
+
};
|
|
280
|
+
exports.toDotFormat = toDotFormat;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./graph"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
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.readFile = exports.readFileAsBase64 = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const readFileAsBase64 = (filePath) => {
|
|
9
|
+
const buffer = node_fs_1.default.readFileSync(filePath);
|
|
10
|
+
return buffer.toString('base64');
|
|
11
|
+
};
|
|
12
|
+
exports.readFileAsBase64 = readFileAsBase64;
|
|
13
|
+
const readFile = (filePath) => {
|
|
14
|
+
return node_fs_1.default.readFileSync(filePath);
|
|
15
|
+
};
|
|
16
|
+
exports.readFile = readFile;
|
|
@@ -0,0 +1,121 @@
|
|
|
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.diffAttributes = exports.attributesEqual = exports.computeFileHash = void 0;
|
|
7
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
/**
|
|
10
|
+
* Compute SHA-256 hash of a file.
|
|
11
|
+
* Used for tracking external artifacts like function code zip files.
|
|
12
|
+
* @param filePath - Path to the file to hash
|
|
13
|
+
* @returns Hex-encoded SHA-256 hash of the file contents
|
|
14
|
+
*/
|
|
15
|
+
const computeFileHash = (filePath) => {
|
|
16
|
+
const fileBuffer = node_fs_1.default.readFileSync(filePath);
|
|
17
|
+
return node_crypto_1.default.createHash('sha256').update(fileBuffer).digest('hex');
|
|
18
|
+
};
|
|
19
|
+
exports.computeFileHash = computeFileHash;
|
|
20
|
+
/**
|
|
21
|
+
* Deep equality comparison for two values.
|
|
22
|
+
* Handles primitives, objects, arrays, null, and undefined.
|
|
23
|
+
* @param a - First value
|
|
24
|
+
* @param b - Second value
|
|
25
|
+
* @returns True if values are deeply equal, false otherwise
|
|
26
|
+
*/
|
|
27
|
+
const deepEqual = (a, b) => {
|
|
28
|
+
// Handle primitives and null/undefined
|
|
29
|
+
if (a === b) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
// Handle type mismatches
|
|
33
|
+
if (typeof a !== typeof b) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Handle null (typeof null === 'object')
|
|
37
|
+
if (a === null || b === null) {
|
|
38
|
+
return false; // One is null, other is not (would have matched above if both null)
|
|
39
|
+
}
|
|
40
|
+
// Handle non-objects (primitives that didn't match above)
|
|
41
|
+
if (typeof a !== 'object') {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// Both are objects/arrays at this point
|
|
45
|
+
const objA = a;
|
|
46
|
+
const objB = b;
|
|
47
|
+
// Handle arrays
|
|
48
|
+
if (Array.isArray(objA) && Array.isArray(objB)) {
|
|
49
|
+
if (objA.length !== objB.length) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
for (let i = 0; i < objA.length; i++) {
|
|
53
|
+
if (!deepEqual(objA[i], objB[i])) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// If one is array and other is not, they're not equal
|
|
60
|
+
if (Array.isArray(objA) || Array.isArray(objB)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// Compare object keys
|
|
64
|
+
const keysA = Object.keys(objA);
|
|
65
|
+
const keysB = Object.keys(objB);
|
|
66
|
+
if (keysA.length !== keysB.length) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// Check all keys exist in both and have equal values
|
|
70
|
+
for (const key of keysA) {
|
|
71
|
+
if (!Object.prototype.hasOwnProperty.call(objB, key)) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (!deepEqual(objA[key], objB[key])) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Compare two ResourceAttributes objects for equality.
|
|
82
|
+
* Returns true if all keys and values match.
|
|
83
|
+
* @param a - First attributes object
|
|
84
|
+
* @param b - Second attributes object
|
|
85
|
+
* @returns True if objects are equal, false otherwise
|
|
86
|
+
*/
|
|
87
|
+
const attributesEqual = (a, b) => {
|
|
88
|
+
return deepEqual(a, b);
|
|
89
|
+
};
|
|
90
|
+
exports.attributesEqual = attributesEqual;
|
|
91
|
+
/**
|
|
92
|
+
* Find differences between two ResourceAttributes objects.
|
|
93
|
+
* Returns an object with changed keys and their before/after values.
|
|
94
|
+
* @param before - Previous attributes
|
|
95
|
+
* @param after - New attributes
|
|
96
|
+
* @returns Object with changed, added, and removed keys
|
|
97
|
+
*/
|
|
98
|
+
const diffAttributes = (before, after) => {
|
|
99
|
+
const changed = {};
|
|
100
|
+
const added = {};
|
|
101
|
+
const removed = {};
|
|
102
|
+
const allKeys = new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
103
|
+
for (const key of allKeys) {
|
|
104
|
+
const beforeVal = before[key];
|
|
105
|
+
const afterVal = after[key];
|
|
106
|
+
if (!(key in before)) {
|
|
107
|
+
added[key] = afterVal;
|
|
108
|
+
}
|
|
109
|
+
else if (!(key in after)) {
|
|
110
|
+
removed[key] = beforeVal;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
// Both exist - check if they're different using deep equality
|
|
114
|
+
if (!deepEqual(beforeVal, afterVal)) {
|
|
115
|
+
changed[key] = { before: beforeVal, after: afterVal };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return { changed, added, removed };
|
|
120
|
+
};
|
|
121
|
+
exports.diffAttributes = diffAttributes;
|
|
@@ -1,50 +1,15 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.splitDomain = exports.
|
|
6
|
+
exports.splitDomain = exports.getIacDefinition = exports.calcValue = exports.readCodeSize = exports.resolveCode = void 0;
|
|
40
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
41
8
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
42
|
-
const ros = __importStar(require("@alicloud/ros-cdk-core"));
|
|
43
|
-
const ossDeployment = __importStar(require("@alicloud/ros-cdk-ossdeployment"));
|
|
44
|
-
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
45
9
|
const lodash_1 = require("lodash");
|
|
46
10
|
const parser_1 = require("../parser");
|
|
47
11
|
const logger_1 = require("./logger");
|
|
12
|
+
const lang_1 = require("../lang");
|
|
48
13
|
const resolveCode = (location) => {
|
|
49
14
|
const filePath = node_path_1.default.resolve(process.cwd(), location);
|
|
50
15
|
const fileContent = node_fs_1.default.readFileSync(filePath);
|
|
@@ -57,59 +22,33 @@ const readCodeSize = (location) => {
|
|
|
57
22
|
return stats.size;
|
|
58
23
|
};
|
|
59
24
|
exports.readCodeSize = readCodeSize;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
if (node_fs_1.default.lstatSync(filePath).isDirectory()) {
|
|
63
|
-
throw new Error('The provided path is a directory, not a file.');
|
|
64
|
-
}
|
|
65
|
-
const hash = node_crypto_1.default.createHash('md5').update(node_fs_1.default.readFileSync(filePath)).digest('hex');
|
|
66
|
-
const objectKey = `${fcName}/${hash}-${filePath.split('/').pop()}`;
|
|
67
|
-
const source = ossDeployment.Source.asset(filePath, { deployTime: true }, `${fcName}/${hash}-`);
|
|
68
|
-
return { source, objectKey };
|
|
25
|
+
const getParam = (key, records) => {
|
|
26
|
+
return records?.find((param) => param.key === key)?.value;
|
|
69
27
|
};
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
const containsStage = rawValue.match(/\$\{ctx.\w+}/);
|
|
74
|
-
const matchVar = rawValue.match(/^\$\{vars\.(\w+)}$/);
|
|
75
|
-
const containsVar = rawValue.match(/\$\{vars\.(\w+)}/);
|
|
76
|
-
const matchMap = rawValue.match(/^\$\{stages\.(\w+)}$/);
|
|
77
|
-
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
78
|
-
const matchFn = rawValue.match(/^\$\{functions\.(\w+(\.\w+)?)}$/);
|
|
79
|
-
let value = rawValue;
|
|
80
|
-
if (containsStage) {
|
|
81
|
-
value = value.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
82
|
-
}
|
|
83
|
-
if (matchVar?.length) {
|
|
84
|
-
return ros.Fn.ref(matchVar[1]);
|
|
85
|
-
}
|
|
86
|
-
if (matchMap?.length) {
|
|
87
|
-
return ros.Fn.findInMap('stages', ctx.stage, matchMap[1]);
|
|
88
|
-
}
|
|
89
|
-
if (matchFn?.length) {
|
|
90
|
-
return ros.Fn.getAtt(matchFn[1], 'FunctionName');
|
|
91
|
-
}
|
|
92
|
-
if (containsMap?.length || containsVar?.length) {
|
|
93
|
-
value = ros.Fn.sub(rawValue.replace(/\$\{stages\.(\w+)}/g, '${$1}').replace(/\$\{vars\.(\w+)}/g, '${$1}'));
|
|
94
|
-
}
|
|
28
|
+
// Attempt to infer the type of the value if it was a template reference
|
|
29
|
+
const inferType = (value, wasTemplateRef) => {
|
|
30
|
+
if (!wasTemplateRef) {
|
|
95
31
|
return value;
|
|
96
32
|
}
|
|
97
|
-
|
|
98
|
-
|
|
33
|
+
// Try to parse as number
|
|
34
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
35
|
+
return Number(value);
|
|
99
36
|
}
|
|
100
|
-
|
|
101
|
-
|
|
37
|
+
// Try to parse as boolean
|
|
38
|
+
if (value === 'true') {
|
|
39
|
+
return true;
|
|
102
40
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return records?.find((param) => param.key === key)?.value;
|
|
41
|
+
if (value === 'false') {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
108
45
|
};
|
|
109
46
|
const calcValue = (rawValue, ctx, iacVars) => {
|
|
110
47
|
const containsStage = rawValue.match(/\$\{ctx.stage}/);
|
|
111
48
|
const containsVar = rawValue.match(/\$\{vars.\w+}/);
|
|
112
49
|
const containsMap = rawValue.match(/\$\{stages\.(\w+)}/);
|
|
50
|
+
// Check if the entire value is a single template reference (for type inference)
|
|
51
|
+
const isExactTemplateRef = /^\$\{(vars|stages|ctx)\.[^}]+\}$/.test(rawValue);
|
|
113
52
|
let value = rawValue;
|
|
114
53
|
if (containsStage?.length) {
|
|
115
54
|
value = rawValue.replace(/\$\{ctx.stage}/g, ctx.stage);
|
|
@@ -124,7 +63,7 @@ const calcValue = (rawValue, ctx, iacVars) => {
|
|
|
124
63
|
value = value.replace(/\$\{vars\.(\w+)}/g, (_, key) => {
|
|
125
64
|
const paramValue = getParam(key, mergedParams);
|
|
126
65
|
if (!paramValue) {
|
|
127
|
-
logger_1.logger.warn(
|
|
66
|
+
logger_1.logger.warn(lang_1.lang.__('VARIABLE_NOT_FOUND', { key }));
|
|
128
67
|
}
|
|
129
68
|
return paramValue || '';
|
|
130
69
|
});
|
|
@@ -133,12 +72,15 @@ const calcValue = (rawValue, ctx, iacVars) => {
|
|
|
133
72
|
value = value.replace(/\$\{stages\.(\w+)}/g, (_, key) => {
|
|
134
73
|
const stageValue = getParam(key, (0, lodash_1.get)(ctx.stages, `${ctx.stage}`));
|
|
135
74
|
if (!stageValue) {
|
|
136
|
-
logger_1.logger.warn(
|
|
75
|
+
logger_1.logger.warn(lang_1.lang.__('STAGE_VARIABLE_NOT_FOUND', {
|
|
76
|
+
key,
|
|
77
|
+
stage: ctx.stage,
|
|
78
|
+
}));
|
|
137
79
|
}
|
|
138
80
|
return stageValue || '';
|
|
139
81
|
});
|
|
140
82
|
}
|
|
141
|
-
return value;
|
|
83
|
+
return inferType(value, isExactTemplateRef);
|
|
142
84
|
};
|
|
143
85
|
exports.calcValue = calcValue;
|
|
144
86
|
const getIacDefinition = (iac, rawValue) => {
|
|
@@ -149,20 +91,6 @@ const getIacDefinition = (iac, rawValue) => {
|
|
|
149
91
|
return iac.functions?.find((fc) => fc.key === rawValue);
|
|
150
92
|
};
|
|
151
93
|
exports.getIacDefinition = getIacDefinition;
|
|
152
|
-
const formatRosId = (id) => {
|
|
153
|
-
// Insert underscore before uppercase letters, but only when they follow a lowercase letter
|
|
154
|
-
let result = id.replace(/([a-z])([A-Z])/g, '$1_$2');
|
|
155
|
-
// Convert to lowercase
|
|
156
|
-
result = result.toLowerCase();
|
|
157
|
-
// Replace special characters with underscores
|
|
158
|
-
result = result.replace(/[/*,/#,-]/g, '_');
|
|
159
|
-
// Remove any number of underscores to single one
|
|
160
|
-
result = result.replace(/_+/g, '_');
|
|
161
|
-
// Remove leading underscores
|
|
162
|
-
result = result.replace(/^_/, '');
|
|
163
|
-
return result;
|
|
164
|
-
};
|
|
165
|
-
exports.formatRosId = formatRosId;
|
|
166
94
|
const splitDomain = (domain) => {
|
|
167
95
|
const parts = domain.split('.');
|
|
168
96
|
const rr = parts.length > 2 ? parts[0] : '@';
|
|
@@ -36,7 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.getIamInfo = void 0;
|
|
37
37
|
const ims20190815_1 = __importStar(require("@alicloud/ims20190815")), ims20190815 = ims20190815_1;
|
|
38
38
|
const openApi = __importStar(require("@alicloud/openapi-client"));
|
|
39
|
+
const providerEnum_1 = require("./providerEnum");
|
|
39
40
|
const getIamInfo = async (context) => {
|
|
41
|
+
if (context.provider !== providerEnum_1.ProviderEnum.ALIYUN) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
40
44
|
const imsClient = new ims20190815_1.default(new openApi.Config({
|
|
41
45
|
accessKeyId: context.accessKeyId,
|
|
42
46
|
accessKeySecret: context.accessKeySecret,
|
package/dist/src/common/index.js
CHANGED
|
@@ -17,12 +17,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./providerEnum"), exports);
|
|
18
18
|
__exportStar(require("./logger"), exports);
|
|
19
19
|
__exportStar(require("./getVersion"), exports);
|
|
20
|
-
__exportStar(require("./rosClient"), exports);
|
|
21
20
|
__exportStar(require("./context"), exports);
|
|
22
21
|
__exportStar(require("./iacHelper"), exports);
|
|
23
22
|
__exportStar(require("./constants"), exports);
|
|
24
23
|
__exportStar(require("./imsClient"), exports);
|
|
25
24
|
__exportStar(require("./base64"), exports);
|
|
26
|
-
__exportStar(require("./rosAssets"), exports);
|
|
27
25
|
__exportStar(require("./requestHelper"), exports);
|
|
28
26
|
__exportStar(require("./credentials"), exports);
|
|
27
|
+
__exportStar(require("./stateManager"), exports);
|
|
28
|
+
__exportStar(require("./lockManager"), exports);
|
|
29
|
+
__exportStar(require("./scfClient"), exports);
|
|
30
|
+
__exportStar(require("./runtimeMapper"), exports);
|
|
31
|
+
__exportStar(require("./hashUtils"), exports);
|
|
32
|
+
__exportStar(require("./dependencyGraph"), exports);
|