@geek-fun/serverlessinsight 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/.gitattributes +1 -0
  2. package/README.md +108 -8
  3. package/README.zh-CN.md +52 -8
  4. package/dist/package.json +37 -35
  5. package/dist/src/commands/deploy.js +17 -7
  6. package/dist/src/commands/destroy.js +27 -4
  7. package/dist/src/commands/forceUnlock.js +61 -0
  8. package/dist/src/commands/index.js +86 -14
  9. package/dist/src/commands/local.js +10 -1
  10. package/dist/src/commands/plan.js +33 -0
  11. package/dist/src/commands/template.js +3 -1
  12. package/dist/src/commands/validate.js +2 -1
  13. package/dist/src/common/aliyunClient/apigwOperations.js +652 -0
  14. package/dist/src/common/aliyunClient/dnsOperations.js +90 -0
  15. package/dist/src/common/aliyunClient/ecsOperations.js +141 -0
  16. package/dist/src/common/aliyunClient/esOperations.js +219 -0
  17. package/dist/src/common/aliyunClient/fc3Operations.js +270 -0
  18. package/dist/src/common/aliyunClient/index.js +141 -0
  19. package/dist/src/common/aliyunClient/nasOperations.js +233 -0
  20. package/dist/src/common/aliyunClient/ossOperations.js +237 -0
  21. package/dist/src/common/aliyunClient/ramOperations.js +205 -0
  22. package/dist/src/common/aliyunClient/rdsOperations.js +206 -0
  23. package/dist/src/common/aliyunClient/slsOperations.js +218 -0
  24. package/dist/src/common/aliyunClient/tablestoreOperations.js +199 -0
  25. package/dist/src/common/aliyunClient/types.js +2 -0
  26. package/dist/src/common/constants.js +7 -1
  27. package/dist/src/common/context.js +32 -14
  28. package/dist/src/common/credentials.js +39 -0
  29. package/dist/src/common/dependencyGraph/graph.js +280 -0
  30. package/dist/src/common/dependencyGraph/index.js +18 -0
  31. package/dist/src/common/dependencyGraph/types.js +2 -0
  32. package/dist/src/common/fileUtils.js +16 -0
  33. package/dist/src/common/hashUtils.js +121 -0
  34. package/dist/src/common/iacHelper.js +25 -97
  35. package/dist/src/common/imsClient.js +4 -0
  36. package/dist/src/common/index.js +7 -2
  37. package/dist/src/common/lockManager.js +212 -0
  38. package/dist/src/common/logger.js +89 -6
  39. package/dist/src/common/providerEnum.js +2 -3
  40. package/dist/src/common/runtimeMapper.js +160 -0
  41. package/dist/src/common/scfClient.js +84 -0
  42. package/dist/src/common/stateManager.js +107 -0
  43. package/dist/src/common/tencentClient/cosOperations.js +287 -0
  44. package/dist/src/common/tencentClient/esOperations.js +156 -0
  45. package/dist/src/common/tencentClient/index.js +116 -0
  46. package/dist/src/common/tencentClient/scfOperations.js +141 -0
  47. package/dist/src/common/tencentClient/tdsqlcOperations.js +211 -0
  48. package/dist/src/common/tencentClient/types.js +17 -0
  49. package/dist/src/lang/en.js +254 -0
  50. package/dist/src/lang/index.js +28 -8
  51. package/dist/src/lang/zh-CN.js +229 -0
  52. package/dist/src/parser/bucketParser.js +25 -12
  53. package/dist/src/parser/databaseParser.js +14 -10
  54. package/dist/src/parser/functionParser.js +19 -6
  55. package/dist/src/parser/parseUtils.js +74 -0
  56. package/dist/src/parser/tableParser.js +19 -17
  57. package/dist/src/stack/aliyunStack/apigwExecutor.js +84 -0
  58. package/dist/src/stack/aliyunStack/apigwPlanner.js +118 -0
  59. package/dist/src/stack/aliyunStack/apigwResource.js +339 -0
  60. package/dist/src/stack/aliyunStack/apigwTypes.js +125 -0
  61. package/dist/src/stack/aliyunStack/databaseExecutor.js +112 -0
  62. package/dist/src/stack/aliyunStack/databasePlanner.js +128 -0
  63. package/dist/src/stack/aliyunStack/databaseResource.js +228 -0
  64. package/dist/src/stack/aliyunStack/deployer.js +133 -0
  65. package/dist/src/stack/aliyunStack/destroyer.js +114 -0
  66. package/dist/src/stack/aliyunStack/esServerlessTypes.js +141 -0
  67. package/dist/src/stack/aliyunStack/fc3Executor.js +91 -0
  68. package/dist/src/stack/aliyunStack/fc3Planner.js +77 -0
  69. package/dist/src/stack/aliyunStack/fc3Resource.js +511 -0
  70. package/dist/src/stack/aliyunStack/fc3Types.js +76 -0
  71. package/dist/src/stack/aliyunStack/index.js +40 -0
  72. package/dist/src/stack/aliyunStack/ossExecutor.js +91 -0
  73. package/dist/src/stack/aliyunStack/ossPlanner.js +76 -0
  74. package/dist/src/stack/aliyunStack/ossResource.js +196 -0
  75. package/dist/src/stack/aliyunStack/ossTypes.js +50 -0
  76. package/dist/src/stack/aliyunStack/planner.js +37 -0
  77. package/dist/src/stack/aliyunStack/rdsTypes.js +217 -0
  78. package/dist/src/stack/aliyunStack/tablestoreExecutor.js +92 -0
  79. package/dist/src/stack/aliyunStack/tablestorePlanner.js +94 -0
  80. package/dist/src/stack/aliyunStack/tablestoreResource.js +120 -0
  81. package/dist/src/stack/aliyunStack/tablestoreTypes.js +77 -0
  82. package/dist/src/stack/bucketTypes.js +17 -0
  83. package/dist/src/stack/deploy.js +24 -77
  84. package/dist/src/stack/localStack/bucket.js +11 -6
  85. package/dist/src/stack/localStack/event.js +10 -5
  86. package/dist/src/stack/localStack/function.js +13 -7
  87. package/dist/src/stack/localStack/functionRunner.js +1 -1
  88. package/dist/src/stack/localStack/localServer.js +7 -6
  89. package/dist/src/stack/scfStack/cosExecutor.js +91 -0
  90. package/dist/src/stack/scfStack/cosPlanner.js +76 -0
  91. package/dist/src/stack/scfStack/cosResource.js +126 -0
  92. package/dist/src/stack/scfStack/cosTypes.js +46 -0
  93. package/dist/src/stack/scfStack/deployer.js +91 -0
  94. package/dist/src/stack/scfStack/destroyer.js +88 -0
  95. package/dist/src/stack/scfStack/esServerlessExecutor.js +105 -0
  96. package/dist/src/stack/scfStack/esServerlessPlanner.js +86 -0
  97. package/dist/src/stack/scfStack/esServerlessResource.js +94 -0
  98. package/dist/src/stack/scfStack/esServerlessTypes.js +48 -0
  99. package/dist/src/stack/scfStack/index.js +35 -0
  100. package/dist/src/stack/scfStack/planner.js +91 -0
  101. package/dist/src/stack/scfStack/scfExecutor.js +91 -0
  102. package/dist/src/stack/scfStack/scfPlanner.js +78 -0
  103. package/dist/src/stack/scfStack/scfResource.js +216 -0
  104. package/dist/src/stack/scfStack/scfTypes.js +41 -0
  105. package/dist/src/stack/scfStack/tdsqlcExecutor.js +105 -0
  106. package/dist/src/stack/scfStack/tdsqlcPlanner.js +90 -0
  107. package/dist/src/stack/scfStack/tdsqlcResource.js +146 -0
  108. package/dist/src/stack/scfStack/tdsqlcTypes.js +59 -0
  109. package/dist/src/types/domains/lock.js +2 -0
  110. package/dist/src/types/domains/resolvable.js +2 -0
  111. package/dist/src/types/domains/state.js +19 -0
  112. package/dist/src/types/index.js +4 -0
  113. package/dist/src/validator/bucketSchema.js +4 -10
  114. package/dist/src/validator/databaseSchema.js +36 -36
  115. package/dist/src/validator/eventSchema.js +3 -2
  116. package/dist/src/validator/functionSchema.js +51 -46
  117. package/dist/src/validator/iacSchema.js +52 -3
  118. package/dist/src/validator/rootSchema.js +47 -1
  119. package/dist/src/validator/tableschema.js +9 -8
  120. package/dist/src/validator/templateRefSchema.js +23 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -1
  122. package/package.json +37 -35
  123. package/samples/README_TENCENT_COS.md +486 -0
  124. package/samples/README_TENCENT_SCF.md +272 -0
  125. package/samples/aliyun-poc-api.yml +1 -1
  126. package/samples/aliyun-poc-bucket.yml +0 -1
  127. package/samples/aliyun-poc-domain.yml +0 -1
  128. package/samples/aliyun-poc-es.yml +14 -13
  129. package/samples/aliyun-poc-rds.yml +0 -2
  130. package/samples/aliyun-poc-table.yml +1 -3
  131. package/samples/tencent-poc-cos.yml +20 -0
  132. package/samples/tencent-poc-scf.yml +36 -0
  133. package/dist/src/commands/index.d.ts +0 -2
  134. package/dist/src/common/index.d.ts +0 -11
  135. package/dist/src/common/rosAssets.js +0 -178
  136. package/dist/src/common/rosClient.js +0 -198
  137. package/dist/src/index.d.ts +0 -1
  138. package/dist/src/lang/index.d.ts +0 -3
  139. package/dist/src/parser/index.d.ts +0 -3
  140. package/dist/src/stack/index.d.ts +0 -1
  141. package/dist/src/stack/localStack/index.d.ts +0 -5
  142. package/dist/src/stack/rfsStack/index.d.ts +0 -9
  143. package/dist/src/stack/rosStack/bootstrap.js +0 -187
  144. package/dist/src/stack/rosStack/bucket.js +0 -127
  145. package/dist/src/stack/rosStack/database.js +0 -313
  146. package/dist/src/stack/rosStack/event.js +0 -143
  147. package/dist/src/stack/rosStack/function.js +0 -259
  148. package/dist/src/stack/rosStack/index.d.ts +0 -7
  149. package/dist/src/stack/rosStack/index.js +0 -75
  150. package/dist/src/stack/rosStack/stage.js +0 -46
  151. package/dist/src/stack/rosStack/table.js +0 -95
  152. package/dist/src/stack/rosStack/tag.js +0 -11
  153. package/dist/src/stack/rosStack/vars.js +0 -49
  154. package/dist/src/types/index.d.ts +0 -55
  155. package/dist/src/types/localStack/index.d.ts +0 -81
  156. package/dist/src/validator/index.d.ts +0 -1
  157. package/layers/si-bootstrap-sdk/Dockerfile-aliyuncli +0 -12
  158. package/layers/si-bootstrap-sdk/README.md +0 -1
  159. package/layers/si-bootstrap-sdk/package-lock.json +0 -875
  160. package/layers/si-bootstrap-sdk/package.json +0 -33
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeTablePlan = void 0;
4
+ const tablestoreResource_1 = require("./tablestoreResource");
5
+ const common_1 = require("../../common");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const lang_1 = require("../../lang");
8
+ const executeCreateAction = async (context, table, currentState) => {
9
+ common_1.logger.info(`Creating table: ${table.collection}/${table.name}`);
10
+ const newState = await (0, tablestoreResource_1.createTableResource)(context, table, currentState);
11
+ common_1.logger.info(`Successfully created table: ${table.collection}/${table.name}`);
12
+ return newState;
13
+ };
14
+ const executeUpdateAction = async (context, table, currentState) => {
15
+ common_1.logger.info(`Updating table: ${table.collection}/${table.name}`);
16
+ const newState = await (0, tablestoreResource_1.updateTableResource)(context, table, currentState);
17
+ common_1.logger.info(`Successfully updated table: ${table.collection}/${table.name}`);
18
+ return newState;
19
+ };
20
+ const executeDeleteAction = async (context, instanceName, tableName, logicalId, currentState) => {
21
+ common_1.logger.info(`Deleting table: ${instanceName}/${tableName}`);
22
+ const newState = await (0, tablestoreResource_1.deleteTableResource)(context, instanceName, tableName, logicalId, currentState);
23
+ common_1.logger.info(`Successfully deleted table: ${instanceName}/${tableName}`);
24
+ return newState;
25
+ };
26
+ const executeSingleItem = async (context, item, tablesMap, 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 table = tablesMap.get(item.logicalId);
33
+ if (!table) {
34
+ throw new Error(`Table not found for logical ID: ${item.logicalId}`);
35
+ }
36
+ return executeCreateAction(context, table, currentState);
37
+ }
38
+ case 'update': {
39
+ const table = tablesMap.get(item.logicalId);
40
+ if (!table) {
41
+ throw new Error(`Table not found for logical ID: ${item.logicalId}`);
42
+ }
43
+ return executeUpdateAction(context, table, 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 instanceName = state.definition.instanceName;
52
+ const tableName = state.definition.tableName;
53
+ return executeDeleteAction(context, instanceName, tableName, item.logicalId, currentState);
54
+ }
55
+ default:
56
+ common_1.logger.warn(`Unknown action: ${item.action} for ${item.logicalId}`);
57
+ return null;
58
+ }
59
+ };
60
+ const executeTablePlan = async (context, plan, tables, initialState, onStateChange) => {
61
+ const tablesMap = new Map(tables?.map((table) => [`tables.${table.key}`, table]) ?? []);
62
+ const successfulItems = [];
63
+ let currentState = initialState;
64
+ for (const item of plan.items) {
65
+ try {
66
+ const newState = await executeSingleItem(context, item, tablesMap, currentState);
67
+ if (newState !== null) {
68
+ currentState = newState;
69
+ successfulItems.push(item);
70
+ if (onStateChange) {
71
+ onStateChange(currentState);
72
+ common_1.logger.debug(lang_1.lang.__('STATE_PERSISTED_AFTER_OPERATION', {
73
+ action: item.action,
74
+ resourceId: item.logicalId,
75
+ }));
76
+ }
77
+ }
78
+ }
79
+ catch (error) {
80
+ return {
81
+ state: currentState,
82
+ partialFailure: {
83
+ failedItem: item,
84
+ error: error instanceof Error ? error : new Error(String(error)),
85
+ successfulItems,
86
+ },
87
+ };
88
+ }
89
+ }
90
+ return { state: currentState };
91
+ };
92
+ exports.executeTablePlan = executeTablePlan;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateTablePlan = void 0;
4
+ const aliyunClient_1 = require("../../common/aliyunClient");
5
+ const tablestoreTypes_1 = require("./tablestoreTypes");
6
+ const stateManager_1 = require("../../common/stateManager");
7
+ const hashUtils_1 = require("../../common/hashUtils");
8
+ const planTableDeletion = (logicalId, definition) => ({
9
+ logicalId,
10
+ action: 'delete',
11
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
12
+ changes: { before: definition },
13
+ });
14
+ const generateTablePlan = async (context, state, tables) => {
15
+ if (!tables || tables.length === 0) {
16
+ const allStates = (0, stateManager_1.getAllResources)(state);
17
+ const items = Object.entries(allStates)
18
+ .filter(([logicalId]) => logicalId.startsWith('tables.'))
19
+ .map(([logicalId, resourceState]) => planTableDeletion(logicalId, resourceState.definition));
20
+ return { items };
21
+ }
22
+ const desiredLogicalIds = new Set(tables.map((table) => `tables.${table.key}`));
23
+ const tableItems = await Promise.all(tables.map(async (table) => {
24
+ const logicalId = `tables.${table.key}`;
25
+ const currentState = (0, stateManager_1.getResource)(state, logicalId);
26
+ const config = (0, tablestoreTypes_1.tableToTableStoreConfig)(table);
27
+ const desiredDefinition = (0, tablestoreTypes_1.extractTableStoreDefinition)(config);
28
+ if (!currentState) {
29
+ return {
30
+ logicalId,
31
+ action: 'create',
32
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
33
+ changes: { after: desiredDefinition },
34
+ };
35
+ }
36
+ try {
37
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
38
+ const tablestoreClient = client.tablestore(config.instanceName);
39
+ const remoteTable = await tablestoreClient.getTable(config.tableName);
40
+ if (!remoteTable) {
41
+ return {
42
+ logicalId,
43
+ action: 'create',
44
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
45
+ changes: { before: currentState.definition, after: desiredDefinition },
46
+ drifted: true,
47
+ };
48
+ }
49
+ const currentDefinition = currentState.definition || {};
50
+ const definitionChanged = !(0, hashUtils_1.attributesEqual)(currentDefinition, desiredDefinition);
51
+ if (definitionChanged) {
52
+ // Check if primary keys changed (not updatable in TableStore)
53
+ const currentPrimaryKey = JSON.stringify(currentDefinition.primaryKey || []);
54
+ const desiredPrimaryKey = JSON.stringify(desiredDefinition.primaryKey || []);
55
+ if (currentPrimaryKey !== desiredPrimaryKey) {
56
+ // Primary key changes require table recreation (delete + create)
57
+ // For now, we plan it as an update action with drift detection
58
+ // The user should manually recreate the table if primary keys need to change
59
+ return {
60
+ logicalId,
61
+ action: 'update',
62
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
63
+ changes: { before: currentDefinition, after: desiredDefinition },
64
+ drifted: true,
65
+ };
66
+ }
67
+ // Only throughput and table options changes can be applied via update
68
+ return {
69
+ logicalId,
70
+ action: 'update',
71
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
72
+ changes: { before: currentDefinition, after: desiredDefinition },
73
+ drifted: true,
74
+ };
75
+ }
76
+ return { logicalId, action: 'noop', resourceType: 'ALIYUN_TABLESTORE_TABLE' };
77
+ }
78
+ catch {
79
+ // If we can't check remote state, assume we need to create
80
+ return {
81
+ logicalId,
82
+ action: 'create',
83
+ resourceType: 'ALIYUN_TABLESTORE_TABLE',
84
+ changes: { before: currentState.definition, after: desiredDefinition },
85
+ };
86
+ }
87
+ }));
88
+ const allStates = (0, stateManager_1.getAllResources)(state);
89
+ const deletionItems = Object.entries(allStates)
90
+ .filter(([logicalId]) => logicalId.startsWith('tables.') && !desiredLogicalIds.has(logicalId))
91
+ .map(([logicalId, resourceState]) => planTableDeletion(logicalId, resourceState.definition));
92
+ return { items: [...tableItems, ...deletionItems] };
93
+ };
94
+ exports.generateTablePlan = generateTablePlan;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteTableResource = exports.updateTableResource = exports.readTableResource = exports.createTableResource = void 0;
4
+ const aliyunClient_1 = require("../../common/aliyunClient");
5
+ const common_1 = require("../../common");
6
+ const tablestoreTypes_1 = require("./tablestoreTypes");
7
+ const buildTableStoreInstanceFromProvider = (info, arn, instanceName, clusterType) => {
8
+ return {
9
+ type: 'ALIYUN_TABLESTORE_TABLE',
10
+ arn,
11
+ id: `${instanceName}/${info.tableName}`,
12
+ instanceName,
13
+ tableName: info.tableName,
14
+ clusterType,
15
+ primaryKey: info.primaryKey || [],
16
+ reservedThroughput: info.reservedThroughputDetails
17
+ ? {
18
+ capacityUnit: info.reservedThroughputDetails.capacityUnit,
19
+ lastIncreaseTime: info.reservedThroughputDetails.lastIncreaseTime ?? null,
20
+ lastDecreaseTime: info.reservedThroughputDetails.lastDecreaseTime ?? null,
21
+ }
22
+ : undefined,
23
+ tableOptions: info.tableOptions
24
+ ? {
25
+ timeToLive: info.tableOptions.timeToLive ?? null,
26
+ maxVersions: info.tableOptions.maxVersions ?? null,
27
+ maxTimeDeviation: info.tableOptions.maxTimeDeviation ?? null,
28
+ allowUpdate: info.tableOptions.allowUpdate ?? null,
29
+ }
30
+ : undefined,
31
+ streamDetails: info.streamDetails
32
+ ? {
33
+ enableStream: info.streamDetails.enableStream ?? null,
34
+ streamId: info.streamDetails.streamId ?? null,
35
+ expirationTime: info.streamDetails.expirationTime ?? null,
36
+ lastEnableTime: info.streamDetails.lastEnableTime ?? null,
37
+ }
38
+ : undefined,
39
+ };
40
+ };
41
+ const createTableResource = async (context, table, state) => {
42
+ const config = (0, tablestoreTypes_1.tableToTableStoreConfig)(table);
43
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
44
+ const tablestoreClient = client.tablestore(config.instanceName);
45
+ // Create table
46
+ await tablestoreClient.createTable({
47
+ tableName: config.tableName,
48
+ primaryKey: config.primaryKey,
49
+ reservedThroughput: config.reservedThroughput,
50
+ tableOptions: config.tableOptions,
51
+ });
52
+ // Wait for table to be ready
53
+ await tablestoreClient.waitForTableReady(config.tableName);
54
+ // Refresh state from provider to get all attributes
55
+ const tableInfo = await tablestoreClient.getTable(config.tableName);
56
+ if (!tableInfo) {
57
+ throw new Error(`Failed to refresh state for table: ${config.tableName}`);
58
+ }
59
+ const definition = (0, tablestoreTypes_1.extractTableStoreDefinition)(config);
60
+ const arn = `arn:acs:ots:${context.region}:${context.accountId}:instance/${config.instanceName}/table/${config.tableName}`;
61
+ const resourceState = {
62
+ mode: 'managed',
63
+ region: context.region,
64
+ definition,
65
+ instances: [
66
+ buildTableStoreInstanceFromProvider(tableInfo, arn, config.instanceName, config.clusterType),
67
+ ],
68
+ lastUpdated: new Date().toISOString(),
69
+ };
70
+ const logicalId = `tables.${table.key}`;
71
+ return (0, common_1.setResource)(state, logicalId, resourceState);
72
+ };
73
+ exports.createTableResource = createTableResource;
74
+ const readTableResource = async (context, instanceName, tableName) => {
75
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
76
+ const tablestoreClient = client.tablestore(instanceName);
77
+ return await tablestoreClient.getTable(tableName);
78
+ };
79
+ exports.readTableResource = readTableResource;
80
+ const updateTableResource = async (context, table, state) => {
81
+ const config = (0, tablestoreTypes_1.tableToTableStoreConfig)(table);
82
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
83
+ const tablestoreClient = client.tablestore(config.instanceName);
84
+ // Update table (only reserved throughput and table options can be updated)
85
+ // Note: Primary keys cannot be changed in TableStore
86
+ await tablestoreClient.updateTable({
87
+ tableName: config.tableName,
88
+ primaryKey: config.primaryKey, // Required by SDK but not used for updates
89
+ reservedThroughput: config.reservedThroughput,
90
+ tableOptions: config.tableOptions,
91
+ });
92
+ // Wait for table to be ready
93
+ await tablestoreClient.waitForTableReady(config.tableName);
94
+ // Refresh state from provider to get all attributes
95
+ const tableInfo = await tablestoreClient.getTable(config.tableName);
96
+ if (!tableInfo) {
97
+ throw new Error(`Failed to refresh state for table: ${config.tableName}`);
98
+ }
99
+ const definition = (0, tablestoreTypes_1.extractTableStoreDefinition)(config);
100
+ const arn = `arn:acs:ots:${context.region}:${context.accountId}:instance/${config.instanceName}/table/${config.tableName}`;
101
+ const resourceState = {
102
+ mode: 'managed',
103
+ region: context.region,
104
+ definition,
105
+ instances: [
106
+ buildTableStoreInstanceFromProvider(tableInfo, arn, config.instanceName, config.clusterType),
107
+ ],
108
+ lastUpdated: new Date().toISOString(),
109
+ };
110
+ const logicalId = `tables.${table.key}`;
111
+ return (0, common_1.setResource)(state, logicalId, resourceState);
112
+ };
113
+ exports.updateTableResource = updateTableResource;
114
+ const deleteTableResource = async (context, instanceName, tableName, logicalId, state) => {
115
+ const client = (0, aliyunClient_1.createAliyunClient)(context);
116
+ const tablestoreClient = client.tablestore(instanceName);
117
+ await tablestoreClient.deleteTable(tableName);
118
+ return (0, common_1.removeResource)(state, logicalId);
119
+ };
120
+ exports.deleteTableResource = deleteTableResource;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractTableStoreDefinition = exports.tableToTableStoreConfig = void 0;
4
+ const types_1 = require("../../types");
5
+ // Map from TableStore cluster type to TableEnum
6
+ const clusterTypeMap = new Map([
7
+ ["TABLE_STORE_C" /* TableEnum.TABLE_STORE_C */, 'HYBRID'],
8
+ ["TABLE_STORE_H" /* TableEnum.TABLE_STORE_H */, 'SSD'],
9
+ ]);
10
+ // Map from domain attribute type to TableStore primary key type
11
+ const attributeTypeToTableStoreType = (type) => {
12
+ switch (type) {
13
+ case types_1.AttributeTypeEnum.INTEGER:
14
+ return 'INTEGER';
15
+ case types_1.AttributeTypeEnum.STRING:
16
+ return 'STRING';
17
+ case types_1.AttributeTypeEnum.BINARY:
18
+ return 'BINARY';
19
+ // For types not directly supported as primary keys, default to STRING
20
+ case types_1.AttributeTypeEnum.DOUBLE:
21
+ case types_1.AttributeTypeEnum.BOOLEAN:
22
+ default:
23
+ return 'STRING';
24
+ }
25
+ };
26
+ const tableToTableStoreConfig = (table) => {
27
+ const clusterType = clusterTypeMap.get(table.type);
28
+ if (!clusterType) {
29
+ throw new Error(`Unsupported table type: ${table.type}`);
30
+ }
31
+ // Extract primary keys from keySchema
32
+ const primaryKey = table.keySchema.map((key) => {
33
+ const attribute = table.attributes.find((attr) => attr.name === key.name);
34
+ if (!attribute) {
35
+ throw new Error(`Attribute not found for key: ${key.name}`);
36
+ }
37
+ return {
38
+ name: key.name,
39
+ type: attributeTypeToTableStoreType(attribute.type),
40
+ };
41
+ });
42
+ const config = {
43
+ instanceName: table.collection,
44
+ tableName: table.name,
45
+ clusterType,
46
+ primaryKey,
47
+ network: table.network,
48
+ };
49
+ // Add reserved throughput if specified
50
+ if (table.throughput?.reserved) {
51
+ config.reservedThroughput = {
52
+ capacityUnit: {
53
+ read: table.throughput.reserved.read,
54
+ write: table.throughput.reserved.write,
55
+ },
56
+ };
57
+ }
58
+ // Default table options
59
+ config.tableOptions = {
60
+ timeToLive: -1, // -1 means never expire
61
+ maxVersions: 1, // Keep only the latest version
62
+ };
63
+ return config;
64
+ };
65
+ exports.tableToTableStoreConfig = tableToTableStoreConfig;
66
+ const extractTableStoreDefinition = (config) => {
67
+ return {
68
+ instanceName: config.instanceName,
69
+ tableName: config.tableName,
70
+ clusterType: config.clusterType,
71
+ primaryKey: config.primaryKey,
72
+ reservedThroughput: config.reservedThroughput ?? null,
73
+ tableOptions: config.tableOptions ?? null,
74
+ network: config.network ?? null,
75
+ };
76
+ };
77
+ exports.extractTableStoreDefinition = extractTableStoreDefinition;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ /**
3
+ * Shared bucket types for OSS and COS providers.
4
+ * Both Aliyun OSS and Tencent COS share similar bucket concepts.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BucketACL = void 0;
8
+ /**
9
+ * Bucket ACL (Access Control List) values.
10
+ * Common across cloud providers.
11
+ */
12
+ var BucketACL;
13
+ (function (BucketACL) {
14
+ BucketACL["PRIVATE"] = "private";
15
+ BucketACL["PUBLIC_READ"] = "public-read";
16
+ BucketACL["PUBLIC_READ_WRITE"] = "public-read-write";
17
+ })(BucketACL || (exports.BucketACL = BucketACL = {}));
@@ -1,63 +1,11 @@
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
2
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.generateStackTemplate = exports.deployStack = exports.generateRfsStackTemplate = exports.generateRosStackTemplate = void 0;
40
- const ros = __importStar(require("@alicloud/ros-cdk-core"));
41
- const node_fs_1 = __importDefault(require("node:fs"));
3
+ exports.generateStackTemplate = exports.deployStack = exports.generateRfsStackTemplate = void 0;
42
4
  const common_1 = require("../common");
43
- const rosStack_1 = require("./rosStack");
44
5
  const rfsStack_1 = require("./rfsStack");
45
- const lodash_1 = require("lodash");
46
- const generateRosStackTemplate = (stackName, iac) => {
47
- const context = (0, common_1.getContext)();
48
- const app = new ros.App();
49
- new rosStack_1.RosStack(app, iac, context);
50
- const assembly = app.synth();
51
- const { template } = assembly.getStackByName(stackName);
52
- const assetFolderPath = (0, lodash_1.get)(assembly.tryGetArtifact(`${stackName}.assets`), 'file', '');
53
- const assetsFileBody = node_fs_1.default.readFileSync(assetFolderPath);
54
- const assets = {
55
- rootPath: assembly.directory,
56
- ...JSON.parse(assetsFileBody.toString('utf-8').trim()),
57
- };
58
- return { template, assets };
59
- };
60
- exports.generateRosStackTemplate = generateRosStackTemplate;
6
+ const scfStack_1 = require("./scfStack");
7
+ const aliyunStack_1 = require("./aliyunStack");
8
+ const lang_1 = require("../lang");
61
9
  const generateRfsStackTemplate = (stackName, iac) => {
62
10
  const stack = new rfsStack_1.RfsStack(iac);
63
11
  const hcl = stack.toHclTerraform();
@@ -65,39 +13,38 @@ const generateRfsStackTemplate = (stackName, iac) => {
65
13
  return { template: hcl };
66
14
  };
67
15
  exports.generateRfsStackTemplate = generateRfsStackTemplate;
16
+ const deployHuawei = async (stackName, iac) => {
17
+ // For now, Huawei uses the same approach as Aliyun but with different stack
18
+ const { template } = (0, exports.generateRfsStackTemplate)(stackName, iac);
19
+ common_1.logger.info(lang_1.lang.__('DEPLOYING_STACK_PUBLISHING_ASSETS'));
20
+ // TODO: Implement Huawei-specific deployment logic
21
+ console.log('HCL:', template);
22
+ common_1.logger.info(lang_1.lang.__('STACK_DEPLOYED'));
23
+ };
68
24
  const deployStack = async (stackName, iac) => {
69
- const { template, assets } = (0, exports.generateRosStackTemplate)(stackName, iac);
70
- await (0, rosStack_1.prepareBootstrapStack)();
71
- common_1.logger.info(`Deploying stack, publishing assets...`);
72
- const constructedAssets = await (0, common_1.constructAssets)(assets);
73
- try {
74
- await (0, common_1.publishAssets)(constructedAssets);
75
- common_1.logger.info(`Assets published! 🎉`);
76
- await (0, common_1.rosStackDeploy)(stackName, template);
25
+ if (iac.provider.name === common_1.ProviderEnum.TENCENT) {
26
+ await (0, scfStack_1.deployTencentStack)(iac);
77
27
  }
78
- catch (e) {
79
- common_1.logger.error(`Failed to deploy stack: ${e}`);
80
- throw e;
28
+ else if (iac.provider.name === common_1.ProviderEnum.ALIYUN) {
29
+ await (0, aliyunStack_1.deployAliyunStack)(iac);
81
30
  }
82
- finally {
83
- try {
84
- common_1.logger.info(`Cleaning up temporary Assets...`);
85
- await (0, common_1.cleanupAssets)(constructedAssets);
86
- common_1.logger.info(`Assets cleaned up!♻️`);
87
- }
88
- catch (e) {
89
- common_1.logger.error(`Failed to cleanup assets, it wont affect the deployment result, but to avoid potential cost, you can delete the temporary bucket : ${constructedAssets?.[0].bucketName}, error details:${e}`);
90
- }
31
+ else if (iac.provider.name === common_1.ProviderEnum.HUAWEI) {
32
+ await deployHuawei(stackName, iac);
91
33
  }
92
34
  };
93
35
  exports.deployStack = deployStack;
94
36
  const generateStackTemplate = (stackName, iac) => {
95
37
  if (iac.provider.name === common_1.ProviderEnum.ALIYUN) {
96
- return (0, exports.generateRosStackTemplate)(stackName, iac);
38
+ // Aliyun now uses state-based deployment, no template generation needed
39
+ return { template: {} };
97
40
  }
98
41
  else if (iac.provider.name === common_1.ProviderEnum.HUAWEI) {
99
42
  return (0, exports.generateRfsStackTemplate)(stackName, iac);
100
43
  }
44
+ else if (iac.provider.name === common_1.ProviderEnum.TENCENT) {
45
+ // Tencent uses state-based deployment, no template generation needed
46
+ return { template: {} };
47
+ }
101
48
  return { template: '' };
102
49
  };
103
50
  exports.generateStackTemplate = generateStackTemplate;
@@ -7,6 +7,7 @@ exports.bucketsHandler = void 0;
7
7
  const common_1 = require("../../common");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const node_fs_1 = __importDefault(require("node:fs"));
10
+ const lang_1 = require("../../lang");
10
11
  const TEXT_MIME_TYPES = new Set([
11
12
  'text/plain',
12
13
  'text/html',
@@ -58,7 +59,7 @@ const listDirectory = (dirPath, bucketPath) => {
58
59
  });
59
60
  }
60
61
  catch (error) {
61
- common_1.logger.error(`Error listing directory: ${error}`);
62
+ common_1.logger.error(lang_1.lang.__('ERROR_LISTING_DIRECTORY', { error: String(error) }));
62
63
  return [];
63
64
  }
64
65
  };
@@ -85,12 +86,16 @@ const getAllFiles = (dirPath, bucketPath, fileList = []) => {
85
86
  return fileList;
86
87
  }
87
88
  catch (error) {
88
- common_1.logger.error(`Error getting all files: ${error}`);
89
+ common_1.logger.error(lang_1.lang.__('ERROR_GETTING_ALL_FILES', { error: String(error) }));
89
90
  return fileList;
90
91
  }
91
92
  };
92
93
  const bucketsHandler = async (req, parsed, iac) => {
93
- common_1.logger.info(`Bucket request received by local server -> ${req.method} ${parsed.identifier ?? '/'} ${parsed.url}`);
94
+ common_1.logger.info(lang_1.lang.__('BUCKET_REQUEST_RECEIVED', {
95
+ method: req.method || '',
96
+ identifier: parsed.identifier ?? '/',
97
+ url: parsed.url || '',
98
+ }));
94
99
  // Find the bucket definition
95
100
  const bucketDef = iac.buckets?.find((bucket) => bucket.key === parsed.identifier);
96
101
  if (!bucketDef) {
@@ -136,7 +141,7 @@ const bucketsHandler = async (req, parsed, iac) => {
136
141
  };
137
142
  }
138
143
  catch (error) {
139
- common_1.logger.error(`Error listing bucket files: ${error}`);
144
+ common_1.logger.error(lang_1.lang.__('ERROR_LISTING_BUCKET_FILES', { error: String(error) }));
140
145
  return {
141
146
  statusCode: 500,
142
147
  body: {
@@ -187,7 +192,7 @@ const bucketsHandler = async (req, parsed, iac) => {
187
192
  };
188
193
  }
189
194
  catch (error) {
190
- common_1.logger.error(`Error listing directory: ${error}`);
195
+ common_1.logger.error(lang_1.lang.__('ERROR_LISTING_DIRECTORY', { error: String(error) }));
191
196
  return {
192
197
  statusCode: 500,
193
198
  body: {
@@ -213,7 +218,7 @@ const bucketsHandler = async (req, parsed, iac) => {
213
218
  };
214
219
  }
215
220
  catch (error) {
216
- common_1.logger.error(`Error reading file: ${error}`);
221
+ common_1.logger.error(lang_1.lang.__('ERROR_READING_FILE', { error: String(error) }));
217
222
  return {
218
223
  statusCode: 500,
219
224
  body: {
@@ -13,6 +13,7 @@ const functionRunner_1 = require("./functionRunner");
13
13
  const node_path_1 = __importDefault(require("node:path"));
14
14
  const node_fs_1 = __importDefault(require("node:fs"));
15
15
  const utils_1 = require("./utils");
16
+ const lang_1 = require("../../lang");
16
17
  const matchTrigger = (req, trigger) => {
17
18
  if (req.method !== 'ANY' && req.method !== trigger.method) {
18
19
  return false;
@@ -47,7 +48,11 @@ const servEvent = async (req, parsed, iac) => {
47
48
  body: { error: 'API Gateway event not found', event: parsed.identifier },
48
49
  };
49
50
  }
50
- common_1.logger.info(`Event trigger ${JSON.stringify(event.triggers)}, req method: ${req.method}, req url${req.url}`);
51
+ common_1.logger.info(lang_1.lang.__('EVENT_TRIGGER', {
52
+ triggers: JSON.stringify(event.triggers),
53
+ method: req.method || '',
54
+ url: req.url || '',
55
+ }));
51
56
  const matchedTrigger = event.triggers.find((trigger) => matchTrigger({ method: parsed.method, path: parsed.url }, trigger));
52
57
  if (!matchedTrigger) {
53
58
  const endTime = new Date();
@@ -90,13 +95,13 @@ const servEvent = async (req, parsed, iac) => {
90
95
  functionKey: backendDef.key,
91
96
  handler: backendDef.code.handler,
92
97
  servicePath: '',
93
- timeout: backendDef.timeout * 1000,
98
+ timeout: (backendDef.timeout ?? 3) * 1000,
94
99
  };
95
- const aliyunContext = (0, aliyunFc_1.createAliyunContextSerializable)(iac, backendDef.name, backendDef.code.handler, backendDef.memory, backendDef.timeout, requestId);
100
+ const aliyunContext = (0, aliyunFc_1.createAliyunContextSerializable)(iac, backendDef.name, backendDef.code.handler, backendDef.memory ?? 128, backendDef.timeout ?? 3, requestId);
96
101
  const env = {
97
102
  ...backendDef.environment,
98
103
  };
99
- common_1.logger.debug(`Invoking FC function with Aliyun event format`);
104
+ common_1.logger.debug(lang_1.lang.__('INVOKING_FC_FUNCTION_WITH_ALIYUN_EVENT'));
100
105
  const result = await (0, functionRunner_1.invokeFunction)(funOptions, env, aliyunEvent, aliyunContext);
101
106
  const endTime = new Date();
102
107
  const transformed = (0, aliyunFc_1.transformFCResponse)(result);
@@ -111,7 +116,7 @@ const servEvent = async (req, parsed, iac) => {
111
116
  catch (error) {
112
117
  const endTime = new Date();
113
118
  (0, aliyunFc_1.logApiGatewayRequest)(requestId, parsed.url, 500, startTime, endTime, sourceIp);
114
- common_1.logger.error(`Function execution error: ${error}`);
119
+ common_1.logger.error(lang_1.lang.__('FUNCTION_EXECUTION_ERROR', { error: String(error) }));
115
120
  return {
116
121
  statusCode: 500,
117
122
  body: {