@geek-fun/serverlessinsight 0.6.15 → 0.7.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 (44) hide show
  1. package/AGENTS.md +405 -10
  2. package/README.md +1 -0
  3. package/dist/package.json +8 -2
  4. package/dist/src/commands/deploy.js +4 -0
  5. package/dist/src/commands/destroy.js +4 -0
  6. package/dist/src/common/credentials.js +12 -0
  7. package/dist/src/common/providerEnum.js +1 -0
  8. package/dist/src/common/runtimeMapper.js +24 -3
  9. package/dist/src/common/volcengineClient/apigwOperations.js +271 -0
  10. package/dist/src/common/volcengineClient/iamOperations.js +349 -0
  11. package/dist/src/common/volcengineClient/index.js +99 -0
  12. package/dist/src/common/volcengineClient/tlsOperations.js +256 -0
  13. package/dist/src/common/volcengineClient/tosOperations.js +440 -0
  14. package/dist/src/common/volcengineClient/types.js +26 -0
  15. package/dist/src/common/volcengineClient/vefaasOperations.js +386 -0
  16. package/dist/src/lang/en.js +120 -0
  17. package/dist/src/lang/zh-CN.js +119 -0
  18. package/dist/src/stack/deploy.js +4 -0
  19. package/dist/src/stack/volcengineStack/apigwExecutor.js +87 -0
  20. package/dist/src/stack/volcengineStack/apigwPlanner.js +110 -0
  21. package/dist/src/stack/volcengineStack/apigwResource.js +302 -0
  22. package/dist/src/stack/volcengineStack/apigwTypes.js +106 -0
  23. package/dist/src/stack/volcengineStack/deployer.js +59 -0
  24. package/dist/src/stack/volcengineStack/destroyer.js +72 -0
  25. package/dist/src/stack/volcengineStack/index.js +44 -0
  26. package/dist/src/stack/volcengineStack/planner.js +27 -0
  27. package/dist/src/stack/volcengineStack/tosExecutor.js +106 -0
  28. package/dist/src/stack/volcengineStack/tosPlanner.js +96 -0
  29. package/dist/src/stack/volcengineStack/tosResource.js +103 -0
  30. package/dist/src/stack/volcengineStack/tosTypes.js +65 -0
  31. package/dist/src/stack/volcengineStack/vefaasExecutor.js +102 -0
  32. package/dist/src/stack/volcengineStack/vefaasPlanner.js +84 -0
  33. package/dist/src/stack/volcengineStack/vefaasResource.js +513 -0
  34. package/dist/src/stack/volcengineStack/vefaasTypes.js +75 -0
  35. package/dist/src/types/domains/state.js +3 -0
  36. package/dist/src/validator/functionSchema.js +13 -0
  37. package/dist/src/validator/rootSchema.js +1 -1
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +8 -2
  40. package/samples/volcengine-poc-advanced.yml +59 -0
  41. package/samples/volcengine-poc-api.yml +31 -0
  42. package/samples/volcengine-poc-bucket.yml +17 -0
  43. package/samples/volcengine-poc-function.yml +19 -0
  44. package/samples/volcengine-poc-vpc.yml +34 -0
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.destroyVolcengineStack = void 0;
4
+ const common_1 = require("../../common");
5
+ const stateManager_1 = require("../../common/stateManager");
6
+ const lang_1 = require("../../lang");
7
+ const tosResource_1 = require("./tosResource");
8
+ const vefaasResource_1 = require("./vefaasResource");
9
+ const apigwResource_1 = require("./apigwResource");
10
+ const destroyVolcengineStack = async (backend) => {
11
+ const context = (0, common_1.getContext)();
12
+ const providerName = common_1.ProviderEnum.VOLCENGINE;
13
+ common_1.logger.info(lang_1.lang.__('DESTROYING_STACK', {
14
+ provider: context.provider,
15
+ region: context.region,
16
+ }));
17
+ let state = await backend.loadState(providerName, context.app, context.service, context.stage);
18
+ const allResources = (0, stateManager_1.getAllResources)(state);
19
+ const eventEntries = Object.entries(allResources).filter(([logicalId, resourceState]) => logicalId.startsWith('events.') &&
20
+ resourceState.instances?.some((i) => i.type === 'VOLCENGINE_APIGW_GROUP' || i.type === 'VOLCENGINE_APIGW_API'));
21
+ for (const [logicalId] of eventEntries) {
22
+ try {
23
+ common_1.logger.info(lang_1.lang.__('DELETING_RESOURCE', { resourceType: 'API Gateway', name: logicalId }));
24
+ state = await (0, apigwResource_1.deleteApigwResource)(context, logicalId, state);
25
+ common_1.logger.info(lang_1.lang.__('RESOURCE_DELETED', { resourceType: 'API Gateway', name: logicalId }));
26
+ }
27
+ catch (error) {
28
+ common_1.logger.error(lang_1.lang.__('VOLCENGINE_APIGW_DELETE_FAILED', {
29
+ logicalId,
30
+ error: error instanceof Error ? error.message : String(error),
31
+ }));
32
+ }
33
+ }
34
+ const bucketEntries = Object.entries(allResources).filter(([logicalId, resourceState]) => logicalId.startsWith('buckets.') &&
35
+ resourceState.instances?.some((i) => i.type === 'VOLCENGINE_TOS_BUCKET'));
36
+ for (const [logicalId, resourceState] of bucketEntries) {
37
+ const bucketName = resourceState.definition.bucketName;
38
+ if (bucketName) {
39
+ try {
40
+ common_1.logger.info(lang_1.lang.__('DELETING_RESOURCE', { resourceType: 'bucket', name: bucketName }));
41
+ state = await (0, tosResource_1.deleteResource)(context, bucketName, logicalId, state);
42
+ common_1.logger.info(lang_1.lang.__('RESOURCE_DELETED', { resourceType: 'bucket', name: bucketName }));
43
+ }
44
+ catch (error) {
45
+ common_1.logger.error(lang_1.lang.__('VOLCENGINE_BUCKET_DELETE_FAILED', {
46
+ bucketName,
47
+ error: error instanceof Error ? error.message : String(error),
48
+ }));
49
+ }
50
+ }
51
+ }
52
+ const functionEntries = Object.entries(allResources).filter(([logicalId, resourceState]) => logicalId.startsWith('functions.') &&
53
+ resourceState.instances?.some((i) => i.type === 'VOLCENGINE_VEFAAS_FUNCTION'));
54
+ for (const [logicalId, resourceState] of functionEntries) {
55
+ const functionName = resourceState.definition.functionName;
56
+ if (functionName) {
57
+ try {
58
+ common_1.logger.info(lang_1.lang.__('DELETING_RESOURCE', { resourceType: 'function', name: functionName }));
59
+ state = await (0, vefaasResource_1.deleteResource)(context, functionName, logicalId, state);
60
+ common_1.logger.info(lang_1.lang.__('RESOURCE_DELETED', { resourceType: 'function', name: functionName }));
61
+ }
62
+ catch (error) {
63
+ common_1.logger.error(lang_1.lang.__('VOLCENGINE_FUNCTION_DELETE_FAILED', {
64
+ functionName,
65
+ error: error instanceof Error ? error.message : String(error),
66
+ }));
67
+ }
68
+ }
69
+ }
70
+ await backend.saveState(state, context.app, context.service, context.stage);
71
+ };
72
+ exports.destroyVolcengineStack = destroyVolcengineStack;
@@ -0,0 +1,44 @@
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
+ exports.deleteApigwResource = exports.updateApigwResource = exports.readApigwResource = exports.createApigwResource = exports.deleteTosResource = exports.updateTosResource = exports.readTosResource = exports.createTosResource = exports.deleteVefaasResource = exports.updateVefaasResource = exports.readVefaasResource = exports.createVefaasResource = void 0;
18
+ __exportStar(require("./planner"), exports);
19
+ __exportStar(require("./deployer"), exports);
20
+ __exportStar(require("./destroyer"), exports);
21
+ __exportStar(require("./vefaasTypes"), exports);
22
+ var vefaasResource_1 = require("./vefaasResource");
23
+ Object.defineProperty(exports, "createVefaasResource", { enumerable: true, get: function () { return vefaasResource_1.createResource; } });
24
+ Object.defineProperty(exports, "readVefaasResource", { enumerable: true, get: function () { return vefaasResource_1.readResource; } });
25
+ Object.defineProperty(exports, "updateVefaasResource", { enumerable: true, get: function () { return vefaasResource_1.updateResource; } });
26
+ Object.defineProperty(exports, "deleteVefaasResource", { enumerable: true, get: function () { return vefaasResource_1.deleteResource; } });
27
+ __exportStar(require("./vefaasPlanner"), exports);
28
+ __exportStar(require("./vefaasExecutor"), exports);
29
+ __exportStar(require("./tosTypes"), exports);
30
+ var tosResource_1 = require("./tosResource");
31
+ Object.defineProperty(exports, "createTosResource", { enumerable: true, get: function () { return tosResource_1.createResource; } });
32
+ Object.defineProperty(exports, "readTosResource", { enumerable: true, get: function () { return tosResource_1.readResource; } });
33
+ Object.defineProperty(exports, "updateTosResource", { enumerable: true, get: function () { return tosResource_1.updateResource; } });
34
+ Object.defineProperty(exports, "deleteTosResource", { enumerable: true, get: function () { return tosResource_1.deleteResource; } });
35
+ __exportStar(require("./tosPlanner"), exports);
36
+ __exportStar(require("./tosExecutor"), exports);
37
+ __exportStar(require("./apigwTypes"), exports);
38
+ var apigwResource_1 = require("./apigwResource");
39
+ Object.defineProperty(exports, "createApigwResource", { enumerable: true, get: function () { return apigwResource_1.createApigwResource; } });
40
+ Object.defineProperty(exports, "readApigwResource", { enumerable: true, get: function () { return apigwResource_1.readApigwResource; } });
41
+ Object.defineProperty(exports, "updateApigwResource", { enumerable: true, get: function () { return apigwResource_1.updateApigwResource; } });
42
+ Object.defineProperty(exports, "deleteApigwResource", { enumerable: true, get: function () { return apigwResource_1.deleteApigwResource; } });
43
+ __exportStar(require("./apigwPlanner"), exports);
44
+ __exportStar(require("./apigwExecutor"), exports);
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateVolcenginePlan = void 0;
4
+ const common_1 = require("../../common");
5
+ const lang_1 = require("../../lang");
6
+ const vefaasPlanner_1 = require("./vefaasPlanner");
7
+ const tosPlanner_1 = require("./tosPlanner");
8
+ const apigwPlanner_1 = require("./apigwPlanner");
9
+ const generateVolcenginePlan = async (iac, backend) => {
10
+ const context = (0, common_1.getContext)();
11
+ const state = await backend.loadState('volcengine', context.app, context.service, context.stage);
12
+ const functionPlan = await (0, vefaasPlanner_1.generateFunctionPlan)(context, state, iac.functions);
13
+ const bucketPlan = await (0, tosPlanner_1.generateBucketPlan)(context, state, iac.buckets);
14
+ const apigwPlan = await (0, apigwPlanner_1.generateApigwPlan)(context, state, iac.events, iac.service);
15
+ const allItems = [...functionPlan.items, ...bucketPlan.items, ...apigwPlan.items];
16
+ const dependencyInfo = (0, common_1.getDependencyInfo)(allItems);
17
+ if (dependencyInfo.cycleError) {
18
+ throw new Error(`${lang_1.lang.__('CYCLE_DETECTED')}: ${dependencyInfo.cycleError.cycle.join(' -> ')}`);
19
+ }
20
+ return {
21
+ items: dependencyInfo.order,
22
+ levels: dependencyInfo.levels,
23
+ graph: dependencyInfo.graph,
24
+ dotGraph: (0, common_1.toDotFormat)(dependencyInfo.graph),
25
+ };
26
+ };
27
+ exports.generateVolcenginePlan = generateVolcenginePlan;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeBucketPlan = void 0;
4
+ const types_1 = require("../../types");
5
+ const tosResource_1 = require("./tosResource");
6
+ const common_1 = require("../../common");
7
+ const stateManager_1 = require("../../common/stateManager");
8
+ const lang_1 = require("../../lang");
9
+ const executeCreateAction = async (context, bucket, currentState) => {
10
+ common_1.logger.info(lang_1.lang.__('CREATING_RESOURCE', { resourceType: 'bucket', name: bucket.name }));
11
+ const newState = await (0, tosResource_1.createResource)(context, bucket, currentState);
12
+ common_1.logger.info(lang_1.lang.__('RESOURCE_CREATED', { resourceType: 'bucket', name: bucket.name }));
13
+ return newState;
14
+ };
15
+ const executeUpdateAction = async (context, bucket, currentState) => {
16
+ common_1.logger.info(lang_1.lang.__('UPDATING_RESOURCE', { resourceType: 'bucket', name: bucket.name }));
17
+ const newState = await (0, tosResource_1.updateResource)(context, bucket, currentState);
18
+ common_1.logger.info(lang_1.lang.__('RESOURCE_UPDATED', { resourceType: 'bucket', name: bucket.name }));
19
+ return newState;
20
+ };
21
+ const executeDeleteAction = async (context, bucketName, logicalId, currentState) => {
22
+ common_1.logger.info(lang_1.lang.__('DELETING_RESOURCE', { resourceType: 'bucket', name: bucketName }));
23
+ const newState = await (0, tosResource_1.deleteResource)(context, bucketName, logicalId, currentState);
24
+ common_1.logger.info(lang_1.lang.__('RESOURCE_DELETED', { resourceType: 'bucket', name: bucketName }));
25
+ return newState;
26
+ };
27
+ const executeSingleItem = async (context, item, bucketsMap, currentState) => {
28
+ switch (item.action) {
29
+ case 'noop':
30
+ common_1.logger.info(lang_1.lang.__('NO_CHANGESForResource', { logicalId: item.logicalId }));
31
+ return null;
32
+ case 'create': {
33
+ const bucket = bucketsMap.get(item.logicalId);
34
+ if (!bucket) {
35
+ throw new Error(`Bucket not found for logical ID: ${item.logicalId}`);
36
+ }
37
+ return executeCreateAction(context, bucket, currentState);
38
+ }
39
+ case 'update': {
40
+ const bucket = bucketsMap.get(item.logicalId);
41
+ if (!bucket) {
42
+ throw new Error(`Bucket not found for logical ID: ${item.logicalId}`);
43
+ }
44
+ return executeUpdateAction(context, bucket, currentState);
45
+ }
46
+ case 'delete': {
47
+ const state = (0, stateManager_1.getResource)(currentState, item.logicalId);
48
+ if (!state) {
49
+ common_1.logger.warn(lang_1.lang.__('STATE_NOT_FOUND_SKIPPING', { logicalId: item.logicalId }));
50
+ return null;
51
+ }
52
+ const bucketName = state.definition.bucketName;
53
+ return executeDeleteAction(context, bucketName, item.logicalId, currentState);
54
+ }
55
+ default:
56
+ common_1.logger.warn(lang_1.lang.__('UNKNOWN_ACTION_FOR_RESOURCE', { action: item.action, logicalId: item.logicalId }));
57
+ return null;
58
+ }
59
+ };
60
+ const executeBucketPlan = async (context, plan, buckets, initialState, onStateChange) => {
61
+ const bucketsMap = new Map(buckets?.map((bucket) => [`buckets.${bucket.key}`, bucket]) ?? []);
62
+ const successfulItems = [];
63
+ let currentState = initialState;
64
+ for (const item of plan.items) {
65
+ try {
66
+ const newState = await executeSingleItem(context, item, bucketsMap, 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
+ if (error instanceof types_1.PartialResourceError) {
81
+ const updatedState = error.updatedState;
82
+ if (onStateChange) {
83
+ onStateChange(updatedState);
84
+ }
85
+ return {
86
+ state: updatedState,
87
+ partialFailure: {
88
+ failedItem: item,
89
+ error: error.cause,
90
+ successfulItems,
91
+ },
92
+ };
93
+ }
94
+ return {
95
+ state: currentState,
96
+ partialFailure: {
97
+ failedItem: item,
98
+ error: error instanceof Error ? error : new Error(String(error)),
99
+ successfulItems,
100
+ },
101
+ };
102
+ }
103
+ }
104
+ return { state: currentState };
105
+ };
106
+ exports.executeBucketPlan = executeBucketPlan;
@@ -0,0 +1,96 @@
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.generateBucketPlan = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const volcengineClient_1 = require("../../common/volcengineClient");
9
+ const tosTypes_1 = require("./tosTypes");
10
+ const stateManager_1 = require("../../common/stateManager");
11
+ const common_1 = require("../../common");
12
+ const planBucketDeletion = (logicalId, definition) => ({
13
+ logicalId,
14
+ action: 'delete',
15
+ resourceType: 'VOLCENGINE_TOS_BUCKET',
16
+ changes: { before: definition },
17
+ });
18
+ const generateBucketPlan = async (context, state, buckets) => {
19
+ if (!buckets || buckets.length === 0) {
20
+ const allStates = (0, stateManager_1.getAllResources)(state);
21
+ const items = Object.entries(allStates)
22
+ .filter(([logicalId]) => logicalId.startsWith('buckets.'))
23
+ .map(([logicalId, resourceState]) => planBucketDeletion(logicalId, resourceState.definition));
24
+ return { items };
25
+ }
26
+ const desiredLogicalIds = new Set(buckets.map((bucket) => `buckets.${bucket.key}`));
27
+ const bucketItems = await Promise.all(buckets.map(async (bucket) => {
28
+ const logicalId = `buckets.${bucket.key}`;
29
+ const currentState = (0, stateManager_1.getResource)(state, logicalId);
30
+ const config = (0, tosTypes_1.bucketToTosConfig)(bucket);
31
+ const websiteCodeHash = (() => {
32
+ if (!bucket.website?.code)
33
+ return undefined;
34
+ try {
35
+ return (0, common_1.computeDirectoryHash)(node_path_1.default.resolve(process.cwd(), bucket.website.code));
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ })();
41
+ const desiredDefinition = (0, tosTypes_1.extractTosBucketDefinition)(config, websiteCodeHash);
42
+ if (!currentState) {
43
+ return {
44
+ logicalId,
45
+ action: 'create',
46
+ resourceType: 'VOLCENGINE_TOS_BUCKET',
47
+ changes: { after: desiredDefinition },
48
+ };
49
+ }
50
+ try {
51
+ const client = (0, volcengineClient_1.createVolcengineClient)(context);
52
+ const remoteBucket = await client.tos.getBucket(bucket.name);
53
+ if (!remoteBucket) {
54
+ return {
55
+ logicalId,
56
+ action: 'create',
57
+ resourceType: 'VOLCENGINE_TOS_BUCKET',
58
+ changes: {
59
+ before: currentState.definition,
60
+ after: desiredDefinition,
61
+ },
62
+ drifted: true,
63
+ };
64
+ }
65
+ const currentDefinition = currentState.definition || {};
66
+ const definitionChanged = !(0, common_1.attributesEqual)(currentDefinition, desiredDefinition);
67
+ if (definitionChanged) {
68
+ return {
69
+ logicalId,
70
+ action: 'update',
71
+ resourceType: 'VOLCENGINE_TOS_BUCKET',
72
+ changes: { before: currentDefinition, after: desiredDefinition },
73
+ drifted: true,
74
+ };
75
+ }
76
+ return { logicalId, action: 'noop', resourceType: 'VOLCENGINE_TOS_BUCKET' };
77
+ }
78
+ catch {
79
+ return {
80
+ logicalId,
81
+ action: 'create',
82
+ resourceType: 'VOLCENGINE_TOS_BUCKET',
83
+ changes: {
84
+ before: currentState.definition,
85
+ after: desiredDefinition,
86
+ },
87
+ };
88
+ }
89
+ }));
90
+ const allStates = (0, stateManager_1.getAllResources)(state);
91
+ const deletionItems = Object.entries(allStates)
92
+ .filter(([logicalId]) => logicalId.startsWith('buckets.') && !desiredLogicalIds.has(logicalId))
93
+ .map(([logicalId, resourceState]) => planBucketDeletion(logicalId, resourceState.definition));
94
+ return { items: [...bucketItems, ...deletionItems] };
95
+ };
96
+ exports.generateBucketPlan = generateBucketPlan;
@@ -0,0 +1,103 @@
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.deleteResource = exports.updateResource = exports.readResource = exports.createResource = void 0;
7
+ const volcengineClient_1 = require("../../common/volcengineClient");
8
+ const common_1 = require("../../common");
9
+ const tosTypes_1 = require("./tosTypes");
10
+ const logger_1 = require("../../common/logger");
11
+ const lang_1 = require("../../lang");
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ const createResource = async (context, bucket, state) => {
14
+ const config = (0, tosTypes_1.bucketToTosConfig)(bucket);
15
+ const client = (0, volcengineClient_1.createVolcengineClient)(context);
16
+ const bucketInfo = await client.tos.createBucket(config);
17
+ const sid = (0, common_1.buildSid)('volcengine', 'tos', context.stage, bucket.name);
18
+ const logicalId = `buckets.${bucket.key}`;
19
+ const websiteCodeHash = bucket.website?.code
20
+ ? (0, common_1.computeDirectoryHash)(node_path_1.default.resolve(process.cwd(), bucket.website.code))
21
+ : undefined;
22
+ const instances = [(0, tosTypes_1.buildTosInstanceFromProvider)(bucketInfo, sid)];
23
+ if (bucket.website?.code) {
24
+ try {
25
+ const codePath = node_path_1.default.resolve(process.cwd(), bucket.website.code);
26
+ await client.tos.uploadFiles(bucket.name, codePath);
27
+ const refreshedInfo = await client.tos.getBucket(bucket.name);
28
+ if (refreshedInfo) {
29
+ instances[0] = (0, tosTypes_1.buildTosInstanceFromProvider)(refreshedInfo, sid);
30
+ }
31
+ }
32
+ catch (error) {
33
+ logger_1.logger.error(lang_1.lang.__('TOS_BUCKET_FILE_UPLOAD_FAILED_STATE_SAVED', {
34
+ error: error instanceof Error ? error.message : String(error),
35
+ }));
36
+ logger_1.logger.info(lang_1.lang.__('TOS_BUCKET_TRACKED_CAN_RETRY'));
37
+ }
38
+ }
39
+ const resourceState = {
40
+ mode: 'managed',
41
+ region: context.region,
42
+ definition: (0, tosTypes_1.extractTosBucketDefinition)(config, websiteCodeHash),
43
+ instances,
44
+ lastUpdated: new Date().toISOString(),
45
+ };
46
+ return (0, common_1.setResource)(state, logicalId, resourceState);
47
+ };
48
+ exports.createResource = createResource;
49
+ const readResource = async (context, bucketName) => {
50
+ const client = (0, volcengineClient_1.createVolcengineClient)(context);
51
+ return await client.tos.getBucket(bucketName);
52
+ };
53
+ exports.readResource = readResource;
54
+ const updateResource = async (context, bucket, state) => {
55
+ const config = (0, tosTypes_1.bucketToTosConfig)(bucket);
56
+ const client = (0, volcengineClient_1.createVolcengineClient)(context);
57
+ if (config.acl) {
58
+ await client.tos.updateBucketAcl(bucket.name, config.acl);
59
+ }
60
+ if (config.websiteConfig) {
61
+ await client.tos.updateBucketWebsite(bucket.name, config.websiteConfig);
62
+ }
63
+ if (bucket.website?.code) {
64
+ const codePath = node_path_1.default.resolve(process.cwd(), bucket.website.code);
65
+ await client.tos.uploadFiles(bucket.name, codePath);
66
+ }
67
+ const bucketInfo = await client.tos.getBucket(bucket.name);
68
+ if (!bucketInfo) {
69
+ throw new Error(lang_1.lang.__('RESOURCE_NOT_FOUND_PROVIDER', { resourceType: 'Bucket', name: bucket.name }));
70
+ }
71
+ const sid = (0, common_1.buildSid)('volcengine', 'tos', context.stage, bucket.name);
72
+ const logicalId = `buckets.${bucket.key}`;
73
+ const websiteCodeHash = bucket.website?.code
74
+ ? (0, common_1.computeDirectoryHash)(node_path_1.default.resolve(process.cwd(), bucket.website.code))
75
+ : undefined;
76
+ const instances = [(0, tosTypes_1.buildTosInstanceFromProvider)(bucketInfo, sid)];
77
+ const resourceState = {
78
+ mode: 'managed',
79
+ region: context.region,
80
+ definition: (0, tosTypes_1.extractTosBucketDefinition)(config, websiteCodeHash),
81
+ instances,
82
+ lastUpdated: new Date().toISOString(),
83
+ };
84
+ return (0, common_1.setResource)(state, logicalId, resourceState);
85
+ };
86
+ exports.updateResource = updateResource;
87
+ const deleteResource = async (context, bucketName, logicalId, state) => {
88
+ const client = (0, volcengineClient_1.createVolcengineClient)(context);
89
+ try {
90
+ await client.tos.deleteBucket(bucketName);
91
+ }
92
+ catch (err) {
93
+ const errorCode = err?.code;
94
+ if (errorCode === 'NoSuchBucket' || errorCode === 'ResourceNotFound') {
95
+ logger_1.logger.warn(lang_1.lang.__('RESOURCE_NOT_FOUND_PROVIDER', { resourceType: 'Bucket', name: bucketName }));
96
+ }
97
+ else {
98
+ throw err;
99
+ }
100
+ }
101
+ return (0, common_1.removeResource)(state, logicalId);
102
+ };
103
+ exports.deleteResource = deleteResource;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildTosInstanceFromProvider = exports.extractTosBucketDefinition = exports.bucketToTosConfig = void 0;
4
+ const aclMap = {
5
+ PRIVATE: 'private',
6
+ PUBLIC_READ: 'public-read',
7
+ PUBLIC_READ_WRITE: 'public-read-write',
8
+ };
9
+ const bucketToTosConfig = (bucket) => {
10
+ const config = {
11
+ bucketName: bucket.name,
12
+ };
13
+ if (bucket.security?.acl) {
14
+ config.acl = aclMap[bucket.security.acl];
15
+ }
16
+ if (bucket.storage?.class) {
17
+ config.storageClass = bucket.storage.class;
18
+ }
19
+ if (bucket.website) {
20
+ config.websiteConfig = {
21
+ indexDocument: bucket.website.index,
22
+ };
23
+ if (bucket.website.error_page) {
24
+ config.websiteConfig.errorDocument = bucket.website.error_page;
25
+ }
26
+ }
27
+ return config;
28
+ };
29
+ exports.bucketToTosConfig = bucketToTosConfig;
30
+ const extractTosBucketDefinition = (config, websiteCodeHash) => {
31
+ return {
32
+ bucketName: config.bucketName,
33
+ acl: config.acl ?? null,
34
+ storageClass: config.storageClass ?? null,
35
+ websiteConfiguration: config.websiteConfig
36
+ ? {
37
+ indexDocument: config.websiteConfig.indexDocument,
38
+ errorDocument: config.websiteConfig.errorDocument ?? null,
39
+ }
40
+ : null,
41
+ websiteCodeHash: websiteCodeHash ?? null,
42
+ };
43
+ };
44
+ exports.extractTosBucketDefinition = extractTosBucketDefinition;
45
+ const buildTosInstanceFromProvider = (info, sid) => {
46
+ return {
47
+ type: 'VOLCENGINE_TOS_BUCKET',
48
+ sid,
49
+ id: info.name,
50
+ bucketName: info.name,
51
+ location: info.location ?? null,
52
+ creationDate: info.creationDate ?? null,
53
+ storageClass: info.storageClass ?? null,
54
+ extranetEndpoint: info.extranetEndpoint ?? null,
55
+ intranetEndpoint: info.intranetEndpoint ?? null,
56
+ acl: info.acl ?? null,
57
+ websiteConfig: info.websiteConfig
58
+ ? {
59
+ indexDocument: info.websiteConfig.indexDocument ?? null,
60
+ errorDocument: info.websiteConfig.errorDocument ?? null,
61
+ }
62
+ : null,
63
+ };
64
+ };
65
+ exports.buildTosInstanceFromProvider = buildTosInstanceFromProvider;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeFunctionPlan = void 0;
4
+ const types_1 = require("../../types");
5
+ const vefaasResource_1 = require("./vefaasResource");
6
+ const common_1 = require("../../common");
7
+ const stateManager_1 = require("../../common/stateManager");
8
+ const lang_1 = require("../../lang");
9
+ const executeCreateAction = async (context, fn, currentState) => {
10
+ common_1.logger.info(lang_1.lang.__('CREATING_RESOURCE', { resourceType: 'function', name: fn.name }));
11
+ const newState = await (0, vefaasResource_1.createResource)(context, fn, currentState);
12
+ common_1.logger.info(lang_1.lang.__('RESOURCE_CREATED', { resourceType: 'function', name: fn.name }));
13
+ return newState;
14
+ };
15
+ const executeUpdateAction = async (context, fn, currentState) => {
16
+ common_1.logger.info(lang_1.lang.__('UPDATING_RESOURCE', { resourceType: 'function', name: fn.name }));
17
+ const newState = await (0, vefaasResource_1.updateResource)(context, fn, currentState);
18
+ common_1.logger.info(lang_1.lang.__('RESOURCE_UPDATED', { resourceType: 'function', name: fn.name }));
19
+ return newState;
20
+ };
21
+ const executeDeleteAction = async (context, functionName, logicalId, currentState) => {
22
+ common_1.logger.info(lang_1.lang.__('DELETING_RESOURCE', { resourceType: 'function', name: functionName }));
23
+ const newState = await (0, vefaasResource_1.deleteResource)(context, functionName, logicalId, currentState);
24
+ common_1.logger.info(lang_1.lang.__('RESOURCE_DELETED', { resourceType: 'function', name: functionName }));
25
+ return newState;
26
+ };
27
+ const executeSingleItem = async (context, item, functionsMap, currentState) => {
28
+ switch (item.action) {
29
+ case 'noop':
30
+ common_1.logger.info(lang_1.lang.__('NO_CHANGESForResource', { logicalId: item.logicalId }));
31
+ return null;
32
+ case 'create': {
33
+ const fn = functionsMap.get(item.logicalId);
34
+ if (!fn) {
35
+ throw new Error(`Function not found for logical ID: ${item.logicalId}`);
36
+ }
37
+ return executeCreateAction(context, fn, currentState);
38
+ }
39
+ case 'update': {
40
+ const fn = functionsMap.get(item.logicalId);
41
+ if (!fn) {
42
+ throw new Error(`Function not found for logical ID: ${item.logicalId}`);
43
+ }
44
+ return executeUpdateAction(context, fn, currentState);
45
+ }
46
+ case 'delete': {
47
+ const state = (0, stateManager_1.getResource)(currentState, item.logicalId);
48
+ if (!state) {
49
+ common_1.logger.warn(lang_1.lang.__('STATE_NOT_FOUND_SKIPPING', { logicalId: item.logicalId }));
50
+ return null;
51
+ }
52
+ const functionName = state.definition.functionName;
53
+ return executeDeleteAction(context, functionName, item.logicalId, currentState);
54
+ }
55
+ default:
56
+ common_1.logger.warn(lang_1.lang.__('UNKNOWN_ACTION_FOR_RESOURCE', { action: item.action, logicalId: item.logicalId }));
57
+ return null;
58
+ }
59
+ };
60
+ const executeFunctionPlan = async (context, plan, functions, initialState, onStateChange) => {
61
+ const functionsMap = new Map(functions?.map((fn) => [`functions.${fn.key}`, fn]) ?? []);
62
+ const successfulItems = [];
63
+ let currentState = initialState;
64
+ for (const item of plan.items) {
65
+ try {
66
+ const newState = await executeSingleItem(context, item, functionsMap, currentState);
67
+ if (newState !== null) {
68
+ currentState = newState;
69
+ successfulItems.push(item);
70
+ if (onStateChange) {
71
+ onStateChange(currentState);
72
+ }
73
+ }
74
+ }
75
+ catch (error) {
76
+ if (error instanceof types_1.PartialResourceError) {
77
+ const updatedState = error.updatedState;
78
+ if (onStateChange) {
79
+ onStateChange(updatedState);
80
+ }
81
+ return {
82
+ state: updatedState,
83
+ partialFailure: {
84
+ failedItem: item,
85
+ error: error.cause,
86
+ successfulItems,
87
+ },
88
+ };
89
+ }
90
+ return {
91
+ state: currentState,
92
+ partialFailure: {
93
+ failedItem: item,
94
+ error: error instanceof Error ? error : new Error(String(error)),
95
+ successfulItems,
96
+ },
97
+ };
98
+ }
99
+ }
100
+ return { state: currentState };
101
+ };
102
+ exports.executeFunctionPlan = executeFunctionPlan;