@geek-fun/serverlessinsight 0.6.7 → 0.6.9

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.
@@ -8,6 +8,7 @@ const common_1 = require("../../common");
8
8
  const certUtils_1 = require("../../common/certUtils");
9
9
  const logger_1 = require("../../common/logger");
10
10
  const lang_1 = require("../../lang");
11
+ const domainUtils_1 = require("../../common/domainUtils");
11
12
  const resolveBucketDomainCertificate = (bucket) => {
12
13
  const website = bucket.website;
13
14
  if (!website)
@@ -133,31 +134,56 @@ const createBucketResource = async (context, bucket, state) => {
133
134
  let cnameInfo;
134
135
  if (bucket.website?.domain) {
135
136
  const resolved = resolveBucketDomainCertificate(bucket);
137
+ const primaryDomain = bucket.website.domain;
138
+ const wwwBindApex = bucket.website.www_bind_apex ?? false;
136
139
  logger_1.logger.info(lang_1.lang.__('BINDING_CUSTOM_DOMAIN_TO_BUCKET', {
137
- domain: bucket.website.domain,
140
+ domain: primaryDomain,
138
141
  bucketName: bucket.name,
139
142
  }));
140
- cnameInfo = await client.cos.bindCustomDomain(bucket.name, bucket.website.domain);
143
+ cnameInfo = await client.cos.bindCustomDomain(bucket.name, primaryDomain);
141
144
  if (cnameInfo) {
142
- const instanceId = cnameInfo.dnsRecordId ?? bucket.website.domain;
145
+ const instanceId = cnameInfo.dnsRecordId ?? primaryDomain;
143
146
  const dnsInstance = {
144
147
  sid: (0, common_1.buildSid)('tencent', 'dnspod', context.stage, instanceId),
145
148
  id: instanceId,
146
149
  type: types_1.ResourceTypeEnum.COS_DNS_CNAME,
147
- domain: bucket.website.domain,
150
+ domain: primaryDomain,
148
151
  cname: cnameInfo.cname,
149
152
  ...(cnameInfo.dnsRecordId ? { dnsRecordId: cnameInfo.dnsRecordId } : {}),
150
153
  };
151
154
  instances.push(dnsInstance);
152
- // Refresh bucket info to capture auto-added CORS rule
153
- const refreshedInfo = await client.cos.getBucket(bucket.name, context.region);
154
- if (refreshedInfo) {
155
- instances[0] = buildCosInstanceFromProvider(refreshedInfo, sid);
156
- }
157
155
  if (resolved && cnameInfo.bucketDomainBound) {
158
- await deployCertificateToCosDomain(client, resolved, bucket.name, bucket.website.domain, context.region);
156
+ await deployCertificateToCosDomain(client, resolved, bucket.name, primaryDomain, context.region);
157
+ }
158
+ }
159
+ const wwwDomain = wwwBindApex ? (0, domainUtils_1.deriveWwwDomain)(primaryDomain) : null;
160
+ if (wwwDomain) {
161
+ logger_1.logger.info(lang_1.lang.__('BINDING_CUSTOM_DOMAIN_TO_BUCKET', {
162
+ domain: wwwDomain,
163
+ bucketName: bucket.name,
164
+ }));
165
+ const wwwCnameInfo = await client.cos.bindCustomDomain(bucket.name, wwwDomain);
166
+ if (wwwCnameInfo) {
167
+ const wwwInstanceId = wwwCnameInfo.dnsRecordId ?? wwwDomain;
168
+ const wwwDnsInstance = {
169
+ sid: (0, common_1.buildSid)('tencent', 'dnspod', context.stage, wwwInstanceId),
170
+ id: wwwInstanceId,
171
+ type: types_1.ResourceTypeEnum.COS_DNS_CNAME,
172
+ domain: wwwDomain,
173
+ cname: wwwCnameInfo.cname,
174
+ isWwwVariant: true,
175
+ ...(wwwCnameInfo.dnsRecordId ? { dnsRecordId: wwwCnameInfo.dnsRecordId } : {}),
176
+ };
177
+ instances.push(wwwDnsInstance);
178
+ if (resolved && wwwCnameInfo.bucketDomainBound) {
179
+ await deployCertificateToCosDomain(client, resolved, bucket.name, wwwDomain, context.region);
180
+ }
159
181
  }
160
182
  }
183
+ const refreshedInfo = await client.cos.getBucket(bucket.name, context.region);
184
+ if (refreshedInfo) {
185
+ instances[0] = buildCosInstanceFromProvider(refreshedInfo, sid);
186
+ }
161
187
  }
162
188
  const resourceState = {
163
189
  mode: 'managed',
@@ -194,41 +220,75 @@ const updateBucketResource = async (context, bucket, state) => {
194
220
  buildCosInstanceFromProvider(bucketInfo, sid),
195
221
  ];
196
222
  const existingState = state.resources[logicalId];
197
- const existingDnsInstance = existingState?.instances?.find((i) => i.type === types_1.ResourceTypeEnum.COS_DNS_CNAME);
223
+ const existingDnsInstances = existingState?.instances?.filter((i) => i.type === types_1.ResourceTypeEnum.COS_DNS_CNAME);
224
+ const existingPrimaryDnsInstance = existingDnsInstances?.find((i) => !i.isWwwVariant);
225
+ const existingWwwDnsInstance = existingDnsInstances?.find((i) => i.isWwwVariant);
198
226
  if (bucket.website?.domain) {
199
- const domainChanged = existingDnsInstance?.domain !== bucket.website.domain;
200
- if (domainChanged && existingDnsInstance) {
201
- await client.cos.unbindCustomDomain(bucket.name, existingDnsInstance.domain, existingDnsInstance.dnsRecordId);
227
+ const primaryDomain = bucket.website.domain;
228
+ const wwwBindApex = bucket.website.www_bind_apex ?? false;
229
+ const domainChanged = existingPrimaryDnsInstance?.domain !== primaryDomain;
230
+ if (domainChanged && existingDnsInstances) {
231
+ for (const instance of existingDnsInstances) {
232
+ await client.cos.unbindCustomDomain(bucket.name, instance.domain, instance.dnsRecordId);
233
+ }
202
234
  }
203
235
  const resolved = resolveBucketDomainCertificate(bucket);
204
236
  logger_1.logger.info(lang_1.lang.__('BINDING_CUSTOM_DOMAIN_TO_BUCKET', {
205
- domain: bucket.website.domain,
237
+ domain: primaryDomain,
206
238
  bucketName: bucket.name,
207
239
  }));
208
- const cnameInfo = await client.cos.bindCustomDomain(bucket.name, bucket.website.domain);
240
+ const cnameInfo = await client.cos.bindCustomDomain(bucket.name, primaryDomain);
209
241
  if (cnameInfo) {
210
- const instanceId = cnameInfo.dnsRecordId ?? bucket.website.domain;
242
+ const instanceId = cnameInfo.dnsRecordId ?? primaryDomain;
211
243
  const dnsInstance = {
212
244
  sid: (0, common_1.buildSid)('tencent', 'dnspod', context.stage, instanceId),
213
245
  id: instanceId,
214
246
  type: types_1.ResourceTypeEnum.COS_DNS_CNAME,
215
- domain: bucket.website.domain,
247
+ domain: primaryDomain,
216
248
  cname: cnameInfo.cname,
217
249
  ...(cnameInfo.dnsRecordId ? { dnsRecordId: cnameInfo.dnsRecordId } : {}),
218
250
  };
219
251
  instances.push(dnsInstance);
220
- // Refresh bucket info to capture auto-added CORS rule
221
- const refreshedInfo = await client.cos.getBucket(bucket.name, context.region);
222
- if (refreshedInfo) {
223
- instances[0] = buildCosInstanceFromProvider(refreshedInfo, sid);
224
- }
225
252
  if (resolved && cnameInfo.bucketDomainBound) {
226
- await deployCertificateToCosDomain(client, resolved, bucket.name, bucket.website.domain, context.region);
253
+ await deployCertificateToCosDomain(client, resolved, bucket.name, primaryDomain, context.region);
227
254
  }
228
255
  }
256
+ const wwwDomain = wwwBindApex ? (0, domainUtils_1.deriveWwwDomain)(primaryDomain) : null;
257
+ if (wwwDomain) {
258
+ logger_1.logger.info(lang_1.lang.__('BINDING_CUSTOM_DOMAIN_TO_BUCKET', {
259
+ domain: wwwDomain,
260
+ bucketName: bucket.name,
261
+ }));
262
+ const wwwCnameInfo = await client.cos.bindCustomDomain(bucket.name, wwwDomain);
263
+ if (wwwCnameInfo) {
264
+ const wwwInstanceId = wwwCnameInfo.dnsRecordId ?? wwwDomain;
265
+ const wwwDnsInstance = {
266
+ sid: (0, common_1.buildSid)('tencent', 'dnspod', context.stage, wwwInstanceId),
267
+ id: wwwInstanceId,
268
+ type: types_1.ResourceTypeEnum.COS_DNS_CNAME,
269
+ domain: wwwDomain,
270
+ cname: wwwCnameInfo.cname,
271
+ isWwwVariant: true,
272
+ ...(wwwCnameInfo.dnsRecordId ? { dnsRecordId: wwwCnameInfo.dnsRecordId } : {}),
273
+ };
274
+ instances.push(wwwDnsInstance);
275
+ if (resolved && wwwCnameInfo.bucketDomainBound) {
276
+ await deployCertificateToCosDomain(client, resolved, bucket.name, wwwDomain, context.region);
277
+ }
278
+ }
279
+ }
280
+ else if (existingWwwDnsInstance && !wwwBindApex) {
281
+ await client.cos.unbindCustomDomain(bucket.name, existingWwwDnsInstance.domain, existingWwwDnsInstance.dnsRecordId);
282
+ }
283
+ const refreshedInfo = await client.cos.getBucket(bucket.name, context.region);
284
+ if (refreshedInfo) {
285
+ instances[0] = buildCosInstanceFromProvider(refreshedInfo, sid);
286
+ }
229
287
  }
230
- else if (existingDnsInstance) {
231
- await client.cos.unbindCustomDomain(bucket.name, existingDnsInstance.domain, existingDnsInstance.dnsRecordId);
288
+ else if (existingDnsInstances) {
289
+ for (const instance of existingDnsInstances) {
290
+ await client.cos.unbindCustomDomain(bucket.name, instance.domain, instance.dnsRecordId);
291
+ }
232
292
  }
233
293
  const resourceState = {
234
294
  mode: 'managed',
@@ -243,9 +303,11 @@ exports.updateBucketResource = updateBucketResource;
243
303
  const deleteBucketResource = async (context, bucketName, region, logicalId, state) => {
244
304
  const client = (0, tencentClient_1.createTencentClient)(context);
245
305
  const existingState = state.resources[logicalId];
246
- const dnsInstance = existingState?.instances?.find((i) => i.type === types_1.ResourceTypeEnum.COS_DNS_CNAME);
247
- if (dnsInstance) {
248
- await client.cos.unbindCustomDomain(bucketName, dnsInstance.domain, dnsInstance.dnsRecordId);
306
+ const dnsInstances = existingState?.instances?.filter((i) => i.type === types_1.ResourceTypeEnum.COS_DNS_CNAME);
307
+ if (dnsInstances) {
308
+ for (const dnsInstance of dnsInstances) {
309
+ await client.cos.unbindCustomDomain(bucketName, dnsInstance.domain, dnsInstance.dnsRecordId);
310
+ }
249
311
  }
250
312
  try {
251
313
  await client.cos.deleteBucket(bucketName, region);
@@ -26,6 +26,33 @@ const bucketToCosBucketConfig = (bucket, region) => {
26
26
  Key: bucket.website.error_page,
27
27
  };
28
28
  }
29
+ if (bucket.website.domain) {
30
+ config.Domain = bucket.website.domain;
31
+ }
32
+ if (bucket.website.www_bind_apex !== undefined) {
33
+ config.WwwBindApex = bucket.website.www_bind_apex;
34
+ }
35
+ if (bucket.website.domain_certificate_id) {
36
+ config.DomainCertificateId = bucket.website.domain_certificate_id;
37
+ }
38
+ if (bucket.website.domain_certificate_body) {
39
+ config.DomainCertificateBody = bucket.website.domain_certificate_body;
40
+ }
41
+ if (bucket.website.domain_certificate_private_key) {
42
+ config.DomainCertificatePrivateKey = bucket.website.domain_certificate_private_key;
43
+ }
44
+ if (bucket.website.domain_protocol) {
45
+ config.DomainProtocol = bucket.website.domain_protocol;
46
+ }
47
+ }
48
+ if (bucket.versioning?.status) {
49
+ config.VersioningStatus = bucket.versioning.status;
50
+ }
51
+ if (bucket.security?.sse_algorithm) {
52
+ config.SseAlgorithm = bucket.security.sse_algorithm;
53
+ }
54
+ if (bucket.security?.sse_kms_master_key_id) {
55
+ config.SseKmsMasterKeyId = bucket.security.sse_kms_master_key_id;
29
56
  }
30
57
  return config;
31
58
  };
@@ -41,6 +68,15 @@ const extractCosBucketDefinition = (config) => {
41
68
  errorDocument: config.WebsiteConfiguration.ErrorDocument?.Key ?? null,
42
69
  }
43
70
  : {},
71
+ domain: config.Domain ?? null,
72
+ wwwBindApex: config.WwwBindApex ?? false,
73
+ domainCertificateId: config.DomainCertificateId ?? null,
74
+ domainCertificateBody: config.DomainCertificateBody ?? null,
75
+ domainCertificatePrivateKey: config.DomainCertificatePrivateKey ? '(managed)' : null,
76
+ domainProtocol: config.DomainProtocol ?? null,
77
+ versioningStatus: config.VersioningStatus ?? null,
78
+ sseAlgorithm: config.SseAlgorithm ?? null,
79
+ sseKmsMasterKeyId: config.SseKmsMasterKeyId ?? null,
44
80
  };
45
81
  };
46
82
  exports.extractCosBucketDefinition = extractCosBucketDefinition;
@@ -18,6 +18,31 @@ const functionToScfConfig = (fn) => {
18
18
  })),
19
19
  };
20
20
  }
21
+ if (fn.network) {
22
+ config.VpcConfig = {
23
+ VpcId: fn.network.vpc_id,
24
+ SubnetId: fn.network.subnet_ids[0],
25
+ };
26
+ }
27
+ if (fn.storage?.disk) {
28
+ config.DiskSize = fn.storage.disk;
29
+ }
30
+ if (fn.storage?.nas && fn.storage.nas.length > 0) {
31
+ config.CfsConfig = {
32
+ CfsInsList: fn.storage.nas.map((nas) => ({
33
+ LocalMountDir: nas.mount_path,
34
+ RemoteMountDir: '/',
35
+ })),
36
+ };
37
+ }
38
+ if (fn.gpu) {
39
+ config.UseGpu = 'TRUE';
40
+ }
41
+ if (fn.container) {
42
+ config.ImageConfig = {
43
+ ImageUri: fn.container.image,
44
+ };
45
+ }
21
46
  return config;
22
47
  };
23
48
  exports.functionToScfConfig = functionToScfConfig;
@@ -31,6 +56,11 @@ const extractScfDefinition = (config, codeHash) => {
31
56
  timeout: config.Timeout,
32
57
  environment: envMap,
33
58
  codeHash,
59
+ vpcConfig: config.VpcConfig ?? null,
60
+ diskSize: config.DiskSize ?? null,
61
+ cfsConfig: config.CfsConfig ?? null,
62
+ useGpu: config.UseGpu ?? null,
63
+ imageConfig: config.ImageConfig ?? null,
34
64
  };
35
65
  };
36
66
  exports.extractScfDefinition = extractScfDefinition;
@@ -73,6 +73,7 @@ exports.bucketSchema = {
73
73
  },
74
74
  ],
75
75
  },
76
+ www_bind_apex: { type: 'boolean' },
76
77
  },
77
78
  required: ['domain_name'],
78
79
  additionalProperties: false,
@@ -110,6 +111,7 @@ exports.bucketSchema = {
110
111
  type: 'string',
111
112
  },
112
113
  error_code: templateRefSchema_1.resolvableNumber,
114
+ www_bind_apex: templateRefSchema_1.resolvableBoolean,
113
115
  },
114
116
  required: ['code'],
115
117
  additionalProperties: false,
@@ -40,6 +40,7 @@ exports.eventSchema = {
40
40
  },
41
41
  ],
42
42
  },
43
+ www_bind_apex: { type: 'boolean' },
43
44
  },
44
45
  oneOf: [
45
46
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geek-fun/serverlessinsight",
3
- "version": "0.6.7",
3
+ "version": "0.6.9",
4
4
  "description": "Full life cycle cross providers serverless application management for your fast-growing business.",
5
5
  "homepage": "https://serverlessinsight.geekfun.club",
6
6
  "main": "dist/src/index.js",