@awsless/cli 0.0.46-next.0 → 0.0.46-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1418,6 +1418,9 @@ var activateDeployment = async (props) => {
1418
1418
  });
1419
1419
  return id;
1420
1420
  };
1421
+ var promoteAppDeployment = (props) => {
1422
+ return activateDeployment({ ...props, rejectStale: true });
1423
+ };
1421
1424
  var rollbackAppDeployment = (props) => {
1422
1425
  return withAppReleaseLock(props.appConfig, () => activateDeployment(props));
1423
1426
  };
@@ -2153,6 +2156,7 @@ var RouterDefaultSchema = z20.record(
2153
2156
  z20.object({
2154
2157
  domain: ResourceIdSchema.describe("The domain id to link your Router.").optional(),
2155
2158
  subDomain: z20.string().optional(),
2159
+ redirectWww: z20.boolean().default(false).describe("Redirect all www subdomain requests to your root domain."),
2156
2160
  waf: WafSettingsSchema.optional(),
2157
2161
  geoRestrictions: z20.array(z20.string().length(2).toUpperCase()).default([]).describe("Specifies a blacklist of countries that should be blocked."),
2158
2162
  errors: z20.object({
@@ -2241,6 +2245,21 @@ var RouterDefaultSchema = z20.record(
2241
2245
  }).optional().describe(
2242
2246
  "Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
2243
2247
  )
2248
+ }).superRefine((props, ctx) => {
2249
+ if (props.redirectWww && !props.domain) {
2250
+ ctx.addIssue({
2251
+ code: z20.ZodIssueCode.custom,
2252
+ path: ["redirectWww"],
2253
+ message: "The redirectWww option requires a domain to be set."
2254
+ });
2255
+ }
2256
+ if (props.redirectWww && props.subDomain) {
2257
+ ctx.addIssue({
2258
+ code: z20.ZodIssueCode.custom,
2259
+ path: ["redirectWww"],
2260
+ message: `The redirectWww option can't be combined with a subDomain, because the domain certificate only covers single level subdomains.`
2261
+ });
2262
+ }
2244
2263
  })
2245
2264
  ).optional().describe(`Define the global Router. Backed by AWS CloudFront.`);
2246
2265
 
@@ -4329,6 +4348,7 @@ var cacheFeature = defineFeature({
4329
4348
  {
4330
4349
  name,
4331
4350
  engine: "valkey",
4351
+ networkType: "dual_stack",
4332
4352
  dailySnapshotTime: "02:00",
4333
4353
  majorEngineVersion: "8",
4334
4354
  snapshotRetentionLimit: props.snapshotRetentionLimit,
@@ -4354,7 +4374,9 @@ var cacheFeature = defineFeature({
4354
4374
  },
4355
4375
  {
4356
4376
  retainOnDelete: ctx.appConfig.removal === "retain",
4357
- import: ctx.import ? name : void 0
4377
+ import: ctx.import ? name : void 0,
4378
+ // The network type can only be set at creation time.
4379
+ replaceOnChanges: ["networkType"]
4358
4380
  }
4359
4381
  );
4360
4382
  const masterHost = cache.endpoint.pipe((v) => v.at(0).address);
@@ -5893,12 +5915,15 @@ var pubsubFeature = defineFeature({
5893
5915
  {
5894
5916
  name: cacheName,
5895
5917
  engine: "valkey",
5918
+ networkType: "dual_stack",
5896
5919
  majorEngineVersion: "8",
5897
5920
  securityGroupIds: [cacheSecurityGroup.id],
5898
5921
  subnetIds: ctx.shared.get("vpc", "private-subnets")
5899
5922
  },
5900
5923
  {
5901
- import: ctx.import ? cacheName : void 0
5924
+ import: ctx.import ? cacheName : void 0,
5925
+ // The network type can only be set at creation time.
5926
+ replaceOnChanges: ["networkType"]
5902
5927
  }
5903
5928
  );
5904
5929
  const redisHost = cache.endpoint.pipe((v) => v.at(0).address);
@@ -6484,7 +6509,7 @@ var searchFeature = defineFeature({
6484
6509
  {
6485
6510
  domainName: name,
6486
6511
  engineVersion: `OpenSearch_${props.version}`,
6487
- ipAddressType: "ipv4",
6512
+ ipAddressType: "dualstack",
6488
6513
  clusterConfig: {
6489
6514
  instanceType: `${props.type}.search`,
6490
6515
  instanceCount: props.count
@@ -6539,7 +6564,7 @@ var searchFeature = defineFeature({
6539
6564
  import: ctx.import ? name : void 0
6540
6565
  }
6541
6566
  );
6542
- ctx.addEnv(`SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`, openSearch.endpoint);
6567
+ ctx.addEnv(`SEARCH_${constantCase8(ctx.stack.name)}_${constantCase8(id)}_DOMAIN`, openSearch.endpointV2);
6543
6568
  ctx.addStackPermission({
6544
6569
  actions: ["es:ESHttp*"],
6545
6570
  resources: [
@@ -9083,6 +9108,7 @@ var getViewerRequestFunctionCode = (props) => {
9083
9108
  return CODE(
9084
9109
  [
9085
9110
  props.blockDirectAccess ? BLOCK_DIRECT_ACCESS_TO_CLOUDFRONT : "",
9111
+ props.redirectWww ? REDIRECT_WWW : "",
9086
9112
  props.passwordAuth ?? props.basicAuth ? AUTH_WRAPPER(
9087
9113
  [
9088
9114
  //
@@ -9101,6 +9127,38 @@ if (headers.host && headers.host.value.includes('cloudfront.net')) {
9101
9127
  statusDescription: 'Forbidden'
9102
9128
  };
9103
9129
  }`;
9130
+ var REDIRECT_WWW = `
9131
+ if (headers.host && headers.host.value.startsWith('www.')) {
9132
+ let location = 'https://' + headers.host.value.slice(4) + request.uri;
9133
+ const query = [];
9134
+
9135
+ for(const key in request.querystring) {
9136
+ const item = request.querystring[key];
9137
+
9138
+ if(item.multiValue) {
9139
+ for(const i in item.multiValue) {
9140
+ query.push(key + '=' + item.multiValue[i].value);
9141
+ }
9142
+ } else if(item.value === '') {
9143
+ query.push(key);
9144
+ } else {
9145
+ query.push(key + '=' + item.value);
9146
+ }
9147
+ }
9148
+
9149
+ if(query.length > 0) {
9150
+ location += '?' + query.join('&');
9151
+ }
9152
+
9153
+ return {
9154
+ statusCode: 301,
9155
+ statusDescription: 'Moved Permanently',
9156
+ headers: {
9157
+ 'location': { value: location },
9158
+ 'strict-transport-security': { value: 'max-age=31536000; includeSubdomains; preload' }
9159
+ }
9160
+ };
9161
+ }`;
9104
9162
  var BASIC_AUTH_CHECK = (username, password) => `
9105
9163
  authMethods.push('Basic realm="Protected"');
9106
9164
 
@@ -9416,6 +9474,7 @@ var routerFeature = defineFeature({
9416
9474
  code: getViewerRequestFunctionCode({
9417
9475
  router: id,
9418
9476
  blockDirectAccess: !!props.domain,
9477
+ redirectWww: !!props.domain && props.redirectWww,
9419
9478
  basicAuth: props.basicAuth,
9420
9479
  passwordAuth: props.passwordAuth
9421
9480
  }),
@@ -9746,6 +9805,7 @@ var routerFeature = defineFeature({
9746
9805
  },
9747
9806
  comment: `${name} preview`,
9748
9807
  enabled: true,
9808
+ isIpv6Enabled: true,
9749
9809
  waitForDeployment: true,
9750
9810
  origin: [
9751
9811
  {
@@ -9864,29 +9924,50 @@ var routerFeature = defineFeature({
9864
9924
  distributionIds.push(distribution.id);
9865
9925
  if (props.domain) {
9866
9926
  const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
9927
+ const wwwDomainName = props.redirectWww ? `www.${domainName}` : void 0;
9867
9928
  const certificateArn = ctx.shared.entry("domain", `global-certificate-arn`, props.domain);
9868
9929
  const zoneId = ctx.shared.entry("domain", "zone-id", props.domain);
9869
9930
  const connectionGroup = new aws30.cloudfront.ConnectionGroup(group, "connection-group", {
9870
- name
9931
+ name,
9932
+ ipv6Enabled: true
9871
9933
  });
9872
9934
  new aws30.cloudfront.DistributionTenant(group, `tenant`, {
9873
9935
  name,
9874
9936
  enabled: true,
9875
9937
  distributionId: distribution.id,
9876
9938
  connectionGroupId: connectionGroup.id,
9877
- domain: [{ domain: domainName }],
9939
+ domain: [
9940
+ //
9941
+ { domain: domainName },
9942
+ ...wwwDomainName ? [{ domain: wwwDomainName }] : []
9943
+ ],
9878
9944
  customizations: [{ certificate: [{ arn: certificateArn }] }]
9879
9945
  });
9880
- new aws30.route53.Record(group, `record`, {
9881
- zoneId,
9882
- type: "A",
9883
- name: domainName,
9884
- alias: {
9885
- name: connectionGroup.routingEndpoint,
9886
- zoneId: "Z2FDTNDATAQYW2",
9887
- evaluateTargetHealth: false
9888
- }
9889
- });
9946
+ for (const [recordId, recordName] of [
9947
+ ["record", domainName],
9948
+ ...wwwDomainName ? [["www-record", wwwDomainName]] : []
9949
+ ]) {
9950
+ new aws30.route53.Record(group, recordId, {
9951
+ zoneId,
9952
+ type: "A",
9953
+ name: recordName,
9954
+ alias: {
9955
+ name: connectionGroup.routingEndpoint,
9956
+ zoneId: "Z2FDTNDATAQYW2",
9957
+ evaluateTargetHealth: false
9958
+ }
9959
+ });
9960
+ new aws30.route53.Record(group, `${recordId}-ipv6`, {
9961
+ zoneId,
9962
+ type: "AAAA",
9963
+ name: recordName,
9964
+ alias: {
9965
+ name: connectionGroup.routingEndpoint,
9966
+ zoneId: "Z2FDTNDATAQYW2",
9967
+ evaluateTargetHealth: false
9968
+ }
9969
+ });
9970
+ }
9890
9971
  ctx.bind(`ROUTER_${constantCase15(id)}_ENDPOINT`, domainName);
9891
9972
  }
9892
9973
  }
@@ -11391,6 +11472,10 @@ var deploy = (program2) => {
11391
11472
  appConfig,
11392
11473
  id: deployment.id
11393
11474
  });
11475
+ await promoteAppDeployment({
11476
+ appConfig,
11477
+ id: deployment.id
11478
+ });
11394
11479
  return deployments3;
11395
11480
  } finally {
11396
11481
  await release();
@@ -560,6 +560,7 @@ var RouterDefaultSchema = z16.record(
560
560
  z16.object({
561
561
  domain: ResourceIdSchema.describe("The domain id to link your Router.").optional(),
562
562
  subDomain: z16.string().optional(),
563
+ redirectWww: z16.boolean().default(false).describe("Redirect all www subdomain requests to your root domain."),
563
564
  waf: WafSettingsSchema.optional(),
564
565
  geoRestrictions: z16.array(z16.string().length(2).toUpperCase()).default([]).describe("Specifies a blacklist of countries that should be blocked."),
565
566
  errors: z16.object({
@@ -648,6 +649,21 @@ var RouterDefaultSchema = z16.record(
648
649
  }).optional().describe(
649
650
  "Specifies the cookies, headers, and query values that CloudFront includes in the cache key."
650
651
  )
652
+ }).superRefine((props, ctx) => {
653
+ if (props.redirectWww && !props.domain) {
654
+ ctx.addIssue({
655
+ code: z16.ZodIssueCode.custom,
656
+ path: ["redirectWww"],
657
+ message: "The redirectWww option requires a domain to be set."
658
+ });
659
+ }
660
+ if (props.redirectWww && props.subDomain) {
661
+ ctx.addIssue({
662
+ code: z16.ZodIssueCode.custom,
663
+ path: ["redirectWww"],
664
+ message: `The redirectWww option can't be combined with a subDomain, because the domain certificate only covers single level subdomains.`
665
+ });
666
+ }
651
667
  })
652
668
  ).optional().describe(`Define the global Router. Backed by AWS CloudFront.`);
653
669
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/cli",
3
- "version": "0.0.46-next.0",
3
+ "version": "0.0.46-next.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -82,24 +82,24 @@
82
82
  "zip-a-folder": "^3.1.6",
83
83
  "zod": "^3.24.2",
84
84
  "zod-to-json-schema": "^3.24.3",
85
- "@awsless/cloudwatch": "^0.0.1",
86
85
  "@awsless/big-float": "^0.1.7",
86
+ "@awsless/clui": "^0.0.8",
87
+ "@awsless/cloudwatch": "^0.0.1",
87
88
  "@awsless/duration": "^0.0.4",
88
89
  "@awsless/dynamodb": "^0.3.21",
89
90
  "@awsless/iot": "^0.0.5",
90
91
  "@awsless/json": "^0.0.11",
91
92
  "@awsless/lambda": "^0.0.44",
92
- "@awsless/redis": "^0.1.13",
93
- "@awsless/scheduler": "^0.0.4",
94
93
  "@awsless/s3": "^0.0.21",
94
+ "@awsless/redis": "^0.1.13",
95
95
  "@awsless/size": "^0.0.2",
96
96
  "@awsless/sns": "^0.0.10",
97
+ "@awsless/sqs": "^0.0.24",
97
98
  "@awsless/ts-file-cache": "^0.0.16",
98
- "@awsless/clui": "^0.0.8",
99
+ "@awsless/weak-cache": "^0.0.1",
99
100
  "@awsless/validate": "^0.1.7",
100
101
  "awsless": "^0.0.15-next.0",
101
- "@awsless/weak-cache": "^0.0.1",
102
- "@awsless/sqs": "^0.0.24"
102
+ "@awsless/scheduler": "^0.0.4"
103
103
  },
104
104
  "devDependencies": {
105
105
  "@hono/node-server": "1.19.9",