@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.
Files changed (164) 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 +41 -5
  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 +1 -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 +6 -1
  27. package/dist/src/common/context.js +13 -3
  28. package/dist/src/common/credentials.js +30 -6
  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 +6 -2
  37. package/dist/src/common/lockManager.js +212 -0
  38. package/dist/src/common/logger.js +87 -10
  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 +35 -1
  118. package/dist/src/validator/rootSchema.js +1 -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 +4 -7
  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 -12
  135. package/dist/src/common/rosAssets.js +0 -178
  136. package/dist/src/common/rosClient.js +0 -201
  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 -64
  159. package/layers/si-bootstrap-sdk/package-lock.json +0 -881
  160. package/layers/si-bootstrap-sdk/package.json +0 -33
  161. package/layers/si-bootstrap-sdk/support/operation-collection/README.md +0 -47
  162. package/layers/si-bootstrap-sdk/support/operation-collection/package-lock.json +0 -298
  163. package/layers/si-bootstrap-sdk/support/operation-collection/package.json +0 -18
  164. package/layers/si-bootstrap-sdk/support/operation-collection/publish.js +0 -257
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.destroyAliyunStack = void 0;
4
+ const common_1 = require("../../common");
5
+ const lang_1 = require("../../lang");
6
+ const fc3Planner_1 = require("./fc3Planner");
7
+ const fc3Executor_1 = require("./fc3Executor");
8
+ const ossPlanner_1 = require("./ossPlanner");
9
+ const ossExecutor_1 = require("./ossExecutor");
10
+ const databasePlanner_1 = require("./databasePlanner");
11
+ const databaseExecutor_1 = require("./databaseExecutor");
12
+ const tablestorePlanner_1 = require("./tablestorePlanner");
13
+ const tablestoreExecutor_1 = require("./tablestoreExecutor");
14
+ const apigwPlanner_1 = require("./apigwPlanner");
15
+ const apigwExecutor_1 = require("./apigwExecutor");
16
+ const createSaveStateFn = (baseDir) => (state) => {
17
+ (0, common_1.saveState)(state, baseDir);
18
+ };
19
+ const handlePartialFailure = (failure) => {
20
+ const error = failure.error;
21
+ error.isPartialFailure = true;
22
+ common_1.logger.error(`${lang_1.lang.__('FAILED_TO_EXECUTE_ACTION', {
23
+ action: failure.failedItem.action,
24
+ logicalId: failure.failedItem.logicalId,
25
+ error: error.message,
26
+ })}\n\n${lang_1.lang.__('PARTIAL_DEPLOYMENT_FAILURE', {
27
+ successCount: String(failure.successfulItems.length),
28
+ failedResource: failure.failedItem.logicalId,
29
+ })}\n${lang_1.lang.__('PARTIAL_FAILURE_STATE_SAVED')}\n${lang_1.lang.__('PARTIAL_FAILURE_NEXT_STEPS')}`);
30
+ throw error;
31
+ };
32
+ const collectSuccessfulItems = (results) => results.flatMap((result) => result.partialFailure?.successfulItems ?? []);
33
+ const destroyAliyunStack = async () => {
34
+ const context = (0, common_1.getContext)();
35
+ const baseDir = process.cwd();
36
+ const providerName = common_1.ProviderEnum.ALIYUN;
37
+ let state = (0, common_1.loadState)(providerName, baseDir);
38
+ const onStateChange = createSaveStateFn(baseDir);
39
+ // Set minimal IAC for destruction (function resolution not needed)
40
+ (0, common_1.setIac)({ version: '1.0', service: '', provider: { name: providerName, region: context.region } });
41
+ const functionPlan = await (0, fc3Planner_1.generateFunctionPlan)(context, state, undefined);
42
+ const bucketPlan = await (0, ossPlanner_1.generateBucketPlan)(context, state, undefined);
43
+ const databasePlan = await (0, databasePlanner_1.generateDatabasePlan)(context, state, undefined);
44
+ const tablePlan = await (0, tablestorePlanner_1.generateTablePlan)(context, state, undefined);
45
+ // For destroy, service name is not used (deletion uses state only)
46
+ const eventPlan = await (0, apigwPlanner_1.generateApigwPlan)(context, state, undefined, '');
47
+ const combinedPlan = {
48
+ items: [
49
+ ...functionPlan.items,
50
+ ...bucketPlan.items,
51
+ ...databasePlan.items,
52
+ ...tablePlan.items,
53
+ ...eventPlan.items,
54
+ ],
55
+ };
56
+ common_1.logger.info(`${lang_1.lang.__('PLAN_GENERATED')}: ${combinedPlan.items.length} ${lang_1.lang.__('ACTIONS')}`);
57
+ combinedPlan.items.forEach((item) => {
58
+ common_1.logger.info(` - ${item.action.toUpperCase()}: ${item.logicalId} (${item.resourceType})`);
59
+ });
60
+ // Delete events before functions (events depend on functions)
61
+ const roleArn = (0, common_1.getRoleArnFromState)(state);
62
+ const eventResult = await (0, apigwExecutor_1.executeApigwPlan)(context, eventPlan, undefined, '', // service name not needed for deletion
63
+ roleArn, state, onStateChange);
64
+ state = eventResult.state;
65
+ if (eventResult.partialFailure) {
66
+ handlePartialFailure(eventResult.partialFailure);
67
+ }
68
+ const functionResult = await (0, fc3Executor_1.executeFunctionPlan)(context, functionPlan, undefined, state, onStateChange);
69
+ state = functionResult.state;
70
+ if (functionResult.partialFailure) {
71
+ handlePartialFailure({
72
+ ...functionResult.partialFailure,
73
+ successfulItems: [
74
+ ...collectSuccessfulItems([eventResult]),
75
+ ...functionResult.partialFailure.successfulItems,
76
+ ],
77
+ });
78
+ }
79
+ const bucketResult = await (0, ossExecutor_1.executeBucketPlan)(context, bucketPlan, undefined, state, onStateChange);
80
+ state = bucketResult.state;
81
+ if (bucketResult.partialFailure) {
82
+ handlePartialFailure({
83
+ ...bucketResult.partialFailure,
84
+ successfulItems: [
85
+ ...collectSuccessfulItems([functionResult]),
86
+ ...bucketResult.partialFailure.successfulItems,
87
+ ],
88
+ });
89
+ }
90
+ const databaseResult = await (0, databaseExecutor_1.executeDatabasePlan)(context, databasePlan, undefined, state, onStateChange);
91
+ state = databaseResult.state;
92
+ if (databaseResult.partialFailure) {
93
+ handlePartialFailure({
94
+ ...databaseResult.partialFailure,
95
+ successfulItems: [
96
+ ...collectSuccessfulItems([functionResult, bucketResult]),
97
+ ...databaseResult.partialFailure.successfulItems,
98
+ ],
99
+ });
100
+ }
101
+ const tableResult = await (0, tablestoreExecutor_1.executeTablePlan)(context, tablePlan, undefined, state, onStateChange);
102
+ state = tableResult.state;
103
+ if (tableResult.partialFailure) {
104
+ handlePartialFailure({
105
+ ...tableResult.partialFailure,
106
+ successfulItems: [
107
+ ...collectSuccessfulItems([functionResult, bucketResult, databaseResult]),
108
+ ...tableResult.partialFailure.successfulItems,
109
+ ],
110
+ });
111
+ }
112
+ (0, common_1.saveState)(state, baseDir);
113
+ };
114
+ exports.destroyAliyunStack = destroyAliyunStack;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractEsDefinition = exports.databaseToEsConfig = void 0;
4
+ // Map database versions to ES versions
5
+ const esVersionMap = new Map([
6
+ [
7
+ `${"ELASTICSEARCH_SERVERLESS" /* DatabaseEnum.ELASTICSEARCH_SERVERLESS */}-${"ES_SEARCH_7.10" /* DatabaseVersionEnum['ES_SEARCH_7.10'] */}`,
8
+ {
9
+ version: '7.10',
10
+ category: 'STANDARD',
11
+ quota: { minCu: 2, maxCu: 8 },
12
+ },
13
+ ],
14
+ [
15
+ `${"ELASTICSEARCH_SERVERLESS" /* DatabaseEnum.ELASTICSEARCH_SERVERLESS */}-${"ES_TIME_SERIES_7.10" /* DatabaseVersionEnum['ES_TIME_SERIES_7.10'] */}`,
16
+ {
17
+ version: '7.10',
18
+ category: 'TRIAL',
19
+ quota: { minCu: 2, maxCu: 8 },
20
+ },
21
+ ],
22
+ ]);
23
+ const databaseToEsConfig = (database) => {
24
+ const engineConfig = esVersionMap.get(`${database.type}-${database.version}`);
25
+ if (!engineConfig) {
26
+ throw new Error(`Unsupported ES database type/version: ${database.type}-${database.version}`);
27
+ }
28
+ const { version, category } = engineConfig;
29
+ const config = {
30
+ appName: database.name,
31
+ appVersion: version,
32
+ authentication: {
33
+ basicAuth: [
34
+ {
35
+ password: database.security.basicAuth.password,
36
+ username: database.security.basicAuth.username || 'elastic',
37
+ },
38
+ ],
39
+ },
40
+ quotaInfo: {
41
+ appType: category,
42
+ cu: database.cu.min,
43
+ storage: database.storage.min,
44
+ },
45
+ description: `Elasticsearch serverless app: ${database.name}`,
46
+ chargeType: 'POSTPAY',
47
+ };
48
+ // Add network configuration for public access
49
+ if (database.network.type === 'PUBLIC' && database.network.ingressRules.length > 0) {
50
+ config.network = [
51
+ {
52
+ type: 'PUBLIC_ES',
53
+ enabled: true,
54
+ whiteIpGroup: [
55
+ {
56
+ groupName: 'default',
57
+ ips: database.network.ingressRules,
58
+ },
59
+ ],
60
+ },
61
+ ];
62
+ }
63
+ // Add private network configuration
64
+ if (database.network.type === 'PRIVATE' && database.network.vpcId) {
65
+ config.privateNetwork = [
66
+ {
67
+ type: 'PRIVATE_ES',
68
+ enabled: true,
69
+ vpcId: database.network.vpcId,
70
+ whiteIpGroup: database.network.ingressRules.length > 0
71
+ ? [
72
+ {
73
+ groupName: 'default',
74
+ ips: database.network.ingressRules,
75
+ },
76
+ ]
77
+ : undefined,
78
+ },
79
+ ];
80
+ }
81
+ return config;
82
+ };
83
+ exports.databaseToEsConfig = databaseToEsConfig;
84
+ const extractEsDefinition = (config) => {
85
+ return {
86
+ appName: config.appName,
87
+ appVersion: config.appVersion,
88
+ authentication: config.authentication
89
+ ? {
90
+ basicAuth: config.authentication.basicAuth?.map(() => ({
91
+ password: '***',
92
+ username: '***',
93
+ })),
94
+ }
95
+ : null,
96
+ quotaInfo: config.quotaInfo
97
+ ? {
98
+ appType: config.quotaInfo.appType ?? null,
99
+ cu: config.quotaInfo.cu ?? null,
100
+ storage: config.quotaInfo.storage ?? null,
101
+ }
102
+ : null,
103
+ description: config.description ?? null,
104
+ chargeType: config.chargeType ?? null,
105
+ network: config.network
106
+ ? config.network.map((n) => ({
107
+ type: n.type ?? null,
108
+ enabled: n.enabled ?? null,
109
+ domain: n.domain ?? null,
110
+ port: n.port ?? null,
111
+ whiteIpGroup: n.whiteIpGroup
112
+ ? n.whiteIpGroup.map((w) => ({
113
+ groupName: w.groupName ?? null,
114
+ ips: w.ips ?? [],
115
+ }))
116
+ : null,
117
+ }))
118
+ : null,
119
+ privateNetwork: config.privateNetwork
120
+ ? config.privateNetwork.map((n) => ({
121
+ type: n.type ?? null,
122
+ enabled: n.enabled ?? null,
123
+ vpcId: n.vpcId ?? null,
124
+ pvlEndpointId: n.pvlEndpointId ?? null,
125
+ whiteIpGroup: n.whiteIpGroup
126
+ ? n.whiteIpGroup.map((w) => ({
127
+ groupName: w.groupName ?? null,
128
+ ips: w.ips ?? [],
129
+ }))
130
+ : null,
131
+ }))
132
+ : null,
133
+ tags: config.tags
134
+ ? config.tags.map((t) => ({
135
+ key: t.key ?? null,
136
+ value: t.value ?? null,
137
+ }))
138
+ : null,
139
+ };
140
+ };
141
+ exports.extractEsDefinition = extractEsDefinition;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeFunctionPlan = void 0;
4
+ const fc3Resource_1 = require("./fc3Resource");
5
+ const common_1 = require("../../common");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const lang_1 = require("../../lang");
8
+ const executeCreateAction = async (context, fn, currentState) => {
9
+ common_1.logger.info(`Creating function: ${fn.name}`);
10
+ const newState = await (0, fc3Resource_1.createResource)(context, fn, currentState);
11
+ common_1.logger.info(`Successfully created function: ${fn.name}`);
12
+ return newState;
13
+ };
14
+ const executeUpdateAction = async (context, fn, currentState) => {
15
+ common_1.logger.info(`Updating function: ${fn.name}`);
16
+ const newState = await (0, fc3Resource_1.updateResource)(context, fn, currentState);
17
+ common_1.logger.info(`Successfully updated function: ${fn.name}`);
18
+ return newState;
19
+ };
20
+ const executeDeleteAction = async (context, functionName, logicalId, currentState) => {
21
+ common_1.logger.info(`Deleting function: ${functionName}`);
22
+ const newState = await (0, fc3Resource_1.deleteResource)(context, functionName, logicalId, currentState);
23
+ common_1.logger.info(`Successfully deleted function: ${functionName}`);
24
+ return newState;
25
+ };
26
+ const executeSingleItem = async (context, item, functionsMap, currentState) => {
27
+ switch (item.action) {
28
+ case 'noop':
29
+ common_1.logger.info(`No changes for ${item.logicalId}`);
30
+ return null;
31
+ case 'create': {
32
+ const fn = functionsMap.get(item.logicalId);
33
+ if (!fn) {
34
+ throw new Error(`Function not found for logical ID: ${item.logicalId}`);
35
+ }
36
+ return executeCreateAction(context, fn, currentState);
37
+ }
38
+ case 'update': {
39
+ const fn = functionsMap.get(item.logicalId);
40
+ if (!fn) {
41
+ throw new Error(`Function not found for logical ID: ${item.logicalId}`);
42
+ }
43
+ return executeUpdateAction(context, fn, currentState);
44
+ }
45
+ case 'delete': {
46
+ const state = (0, stateManager_1.getResource)(currentState, item.logicalId);
47
+ if (!state) {
48
+ common_1.logger.warn(`State not found for ${item.logicalId}, skipping deletion`);
49
+ return null;
50
+ }
51
+ const functionName = state.definition.functionName;
52
+ return executeDeleteAction(context, functionName, item.logicalId, currentState);
53
+ }
54
+ default:
55
+ common_1.logger.warn(`Unknown action: ${item.action} for ${item.logicalId}`);
56
+ return null;
57
+ }
58
+ };
59
+ const executeFunctionPlan = async (context, plan, functions, initialState, onStateChange) => {
60
+ const functionsMap = new Map(functions?.map((fn) => [`functions.${fn.key}`, fn]) ?? []);
61
+ const successfulItems = [];
62
+ let currentState = initialState;
63
+ for (const item of plan.items) {
64
+ try {
65
+ const newState = await executeSingleItem(context, item, functionsMap, currentState);
66
+ if (newState !== null) {
67
+ currentState = newState;
68
+ successfulItems.push(item);
69
+ if (onStateChange) {
70
+ onStateChange(currentState);
71
+ common_1.logger.debug(lang_1.lang.__('STATE_PERSISTED_AFTER_OPERATION', {
72
+ action: item.action,
73
+ resourceId: item.logicalId,
74
+ }));
75
+ }
76
+ }
77
+ }
78
+ catch (error) {
79
+ return {
80
+ state: currentState,
81
+ partialFailure: {
82
+ failedItem: item,
83
+ error: error instanceof Error ? error : new Error(String(error)),
84
+ successfulItems,
85
+ },
86
+ };
87
+ }
88
+ }
89
+ return { state: currentState };
90
+ };
91
+ exports.executeFunctionPlan = executeFunctionPlan;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateFunctionPlan = void 0;
4
+ const common_1 = require("../../common");
5
+ const aliyunClient_1 = require("../../common/aliyunClient");
6
+ const fc3Types_1 = require("./fc3Types");
7
+ const planFunctionDeletion = (logicalId, definition) => ({
8
+ logicalId,
9
+ action: 'delete',
10
+ resourceType: 'ALIYUN_FC3',
11
+ changes: { before: definition },
12
+ });
13
+ const generateFunctionPlan = async (context, state, functions) => {
14
+ if (!functions || functions.length === 0) {
15
+ const allStates = (0, common_1.getAllResources)(state);
16
+ const items = Object.entries(allStates)
17
+ .filter(([logicalId]) => logicalId.startsWith('functions.'))
18
+ .map(([logicalId, resourceState]) => planFunctionDeletion(logicalId, resourceState.definition));
19
+ return { items };
20
+ }
21
+ const desiredLogicalIds = new Set(functions.map((fn) => `functions.${fn.key}`));
22
+ const functionItems = await Promise.all(functions.map(async (fn) => {
23
+ const logicalId = `functions.${fn.key}`;
24
+ const currentState = (0, common_1.getResource)(state, logicalId);
25
+ const config = (0, fc3Types_1.functionToFc3Config)(fn);
26
+ const codePath = fn.code.path;
27
+ const desiredCodeHash = (0, common_1.computeFileHash)(codePath);
28
+ const desiredDefinition = (0, fc3Types_1.extractFc3Definition)(config, desiredCodeHash);
29
+ if (!currentState) {
30
+ return {
31
+ logicalId,
32
+ action: 'create',
33
+ resourceType: 'ALIYUN_FC3',
34
+ changes: { after: desiredDefinition },
35
+ };
36
+ }
37
+ try {
38
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
39
+ const remoteFunction = await client.fc3.getFunction(fn.name);
40
+ if (!remoteFunction) {
41
+ return {
42
+ logicalId,
43
+ action: 'create',
44
+ resourceType: 'ALIYUN_FC3',
45
+ changes: { before: currentState.definition, after: desiredDefinition },
46
+ drifted: true,
47
+ };
48
+ }
49
+ const currentDefinition = currentState.definition || {};
50
+ const definitionChanged = !(0, common_1.attributesEqual)(currentDefinition, desiredDefinition);
51
+ if (definitionChanged) {
52
+ return {
53
+ logicalId,
54
+ action: 'update',
55
+ resourceType: 'ALIYUN_FC3',
56
+ changes: { before: currentDefinition, after: desiredDefinition },
57
+ drifted: true,
58
+ };
59
+ }
60
+ return { logicalId, action: 'noop', resourceType: 'ALIYUN_FC3' };
61
+ }
62
+ catch {
63
+ return {
64
+ logicalId,
65
+ action: 'create',
66
+ resourceType: 'ALIYUN_FC3',
67
+ changes: { before: currentState.definition, after: desiredDefinition },
68
+ };
69
+ }
70
+ }));
71
+ const allStates = (0, common_1.getAllResources)(state);
72
+ const deletionItems = Object.entries(allStates)
73
+ .filter(([logicalId]) => logicalId.startsWith('functions.') && !desiredLogicalIds.has(logicalId))
74
+ .map(([logicalId, resourceState]) => planFunctionDeletion(logicalId, resourceState.definition));
75
+ return { items: [...functionItems, ...deletionItems] };
76
+ };
77
+ exports.generateFunctionPlan = generateFunctionPlan;