sst 2.0.0-rc.64 → 2.0.0-rc.65

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.
@@ -153,6 +153,7 @@ export const dev = (program) => program.command(["dev", "start"], "Work on your
153
153
  deploy(assembly);
154
154
  }
155
155
  catch (ex) {
156
+ isWorking = false;
156
157
  spinner.fail();
157
158
  Colors.line(ex.stack
158
159
  .split("\n")
package/cli/sst.js CHANGED
@@ -38,8 +38,10 @@ consoleCommand(program);
38
38
  diff(program);
39
39
  version(program);
40
40
  telemetry(program);
41
- // @ts-expect-error
42
- process.setSourceMapsEnabled(true);
41
+ if ("setSourceMapsEnabled" in process) {
42
+ // @ts-expect-error
43
+ process.setSourceMapsEnabled(true);
44
+ }
43
45
  process.removeAllListeners("uncaughtException");
44
46
  process.on("uncaughtException", (err) => {
45
47
  Logger.debug(err);
@@ -9,6 +9,7 @@ import * as apigV1AccessLog from "./util/apiGatewayV1AccessLog.js";
9
9
  import { Bucket } from "./Bucket.js";
10
10
  import { Duration } from "./util/duration.js";
11
11
  import { SSTConstruct } from "./Construct.js";
12
+ import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
12
13
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
13
14
  import { Permissions } from "./util/permission.js";
14
15
  export interface ApiGatewayV1ApiAccessLogProps extends apigV1AccessLog.AccessLogProps {
@@ -491,7 +492,7 @@ export declare class ApiGatewayV1Api<Authorizers extends Record<string, ApiGatew
491
492
  /**
492
493
  * The internally created certificate
493
494
  */
494
- certificate?: acm.Certificate | acm.DnsValidatedCertificate;
495
+ certificate?: acm.Certificate | DnsValidatedCertificate;
495
496
  };
496
497
  private _deployment?;
497
498
  private _customDomainUrl?;
@@ -9,6 +9,7 @@ import * as apigV1AccessLog from "./util/apiGatewayV1AccessLog.js";
9
9
  import { Stack } from "./Stack.js";
10
10
  import { toCdkDuration } from "./util/duration.js";
11
11
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
12
+ import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
12
13
  import { Function as Fn, } from "./Function.js";
13
14
  const allowedMethods = [
14
15
  "ANY",
@@ -447,7 +448,7 @@ export class ApiGatewayV1Api extends Construct {
447
448
  /////////////////////
448
449
  if (!apigDomainName && !certificate) {
449
450
  if (endpointType === "edge") {
450
- certificate = new acm.DnsValidatedCertificate(this, "CrossRegionCertificate", {
451
+ certificate = new DnsValidatedCertificate(this, "CrossRegionCertificate", {
451
452
  domainName: domainName,
452
453
  hostedZone: hostedZone,
453
454
  region: "us-east-1",
@@ -1,6 +1,6 @@
1
- import * as route53 from "aws-cdk-lib/aws-route53";
2
- import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
3
- import * as acm from "aws-cdk-lib/aws-certificatemanager";
1
+ import { IHostedZone } from "aws-cdk-lib/aws-route53";
2
+ import { ErrorResponse, DistributionProps, BehaviorOptions, IOrigin } from "aws-cdk-lib/aws-cloudfront";
3
+ import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
4
4
  /**
5
5
  * The customDomain for this website. SST supports domains that are hosted either on [Route 53](https://aws.amazon.com/route53/) or externally.
6
6
  *
@@ -61,13 +61,13 @@ export interface BaseSiteDomainProps {
61
61
  /**
62
62
  * Import the underlying Route 53 hosted zone.
63
63
  */
64
- hostedZone?: route53.IHostedZone;
64
+ hostedZone?: IHostedZone;
65
65
  /**
66
66
  * Import the certificate for the domain. By default, SST will create a certificate with the domain name. The certificate will be created in the `us-east-1`(N. Virginia) region as required by AWS CloudFront.
67
67
  *
68
68
  * Set this option if you have an existing certificate in the `us-east-1` region in AWS Certificate Manager you want to use.
69
69
  */
70
- certificate?: acm.ICertificate;
70
+ certificate?: ICertificate;
71
71
  };
72
72
  }
73
73
  export interface BaseSiteEnvironmentOutputsInfo {
@@ -82,11 +82,11 @@ export interface BaseSiteReplaceProps {
82
82
  search: string;
83
83
  replace: string;
84
84
  }
85
- export declare function buildErrorResponsesForRedirectToIndex(indexPage: string): cloudfront.ErrorResponse[];
86
- export declare function buildErrorResponsesFor404ErrorPage(errorPage: string): cloudfront.ErrorResponse[];
87
- export interface BaseSiteCdkDistributionProps extends Omit<cloudfront.DistributionProps, "defaultBehavior"> {
88
- defaultBehavior?: Omit<cloudfront.BehaviorOptions, "origin"> & {
89
- origin?: cloudfront.IOrigin;
85
+ export declare function buildErrorResponsesForRedirectToIndex(indexPage: string): ErrorResponse[];
86
+ export declare function buildErrorResponsesFor404ErrorPage(errorPage: string): ErrorResponse[];
87
+ export interface BaseSiteCdkDistributionProps extends Omit<DistributionProps, "defaultBehavior"> {
88
+ defaultBehavior?: Omit<BehaviorOptions, "origin"> & {
89
+ origin?: IOrigin;
90
90
  };
91
91
  }
92
92
  export declare function getBuildCmdEnvironment(siteEnvironment?: {
@@ -1,4 +1,4 @@
1
- import * as cdk from "aws-cdk-lib";
1
+ import { Token } from "aws-cdk-lib";
2
2
  export function buildErrorResponsesForRedirectToIndex(indexPage) {
3
3
  return [
4
4
  {
@@ -35,7 +35,7 @@ export function getBuildCmdEnvironment(siteEnvironment) {
35
35
  //
36
36
  const buildCmdEnvironment = {};
37
37
  Object.entries(siteEnvironment || {}).forEach(([key, value]) => {
38
- buildCmdEnvironment[key] = cdk.Token.isUnresolved(value)
38
+ buildCmdEnvironment[key] = Token.isUnresolved(value)
39
39
  ? `{{ ${key} }}`
40
40
  : value;
41
41
  });
@@ -183,7 +183,7 @@ export class EventBus extends Construct {
183
183
  eventBusName: this.cdk.eventBus.eventBusName,
184
184
  rules: Object.entries(this.targetsData).map(([ruleName, rule]) => ({
185
185
  key: ruleName,
186
- targets: Object.values(rule).map(getFunctionRef),
186
+ targets: Object.values(rule).map(getFunctionRef).filter(Boolean),
187
187
  targetNames: Object.keys(rule),
188
188
  })),
189
189
  },
@@ -13,15 +13,15 @@ import { Function, Code, Runtime, FunctionUrlAuthType, } from "aws-cdk-lib/aws-l
13
13
  import { HostedZone, ARecord, AaaaRecord, RecordTarget, } from "aws-cdk-lib/aws-route53";
14
14
  import { Asset } from "aws-cdk-lib/aws-s3-assets";
15
15
  import { Distribution, ViewerProtocolPolicy, AllowedMethods, CachedMethods, LambdaEdgeEventType, CachePolicy, CacheQueryStringBehavior, CacheHeaderBehavior, CacheCookieBehavior, } from "aws-cdk-lib/aws-cloudfront";
16
- import { DnsValidatedCertificate, } from "aws-cdk-lib/aws-certificatemanager";
17
16
  import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
18
17
  import { S3Origin, HttpOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
19
18
  import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
20
- import { HttpsRedirect } from "aws-cdk-lib/aws-route53-patterns";
21
19
  import { Stack } from "./Stack.js";
22
20
  import { Logger } from "../logger.js";
23
21
  import { isCDKConstruct } from "./Construct.js";
24
22
  import { getBuildCmdEnvironment, } from "./BaseSite.js";
23
+ import { HttpsRedirect } from "./cdk/website-redirect.js";
24
+ import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
25
25
  import { attachPermissionsToRole } from "./util/permission.js";
26
26
  import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
27
27
  import { SiteEnv } from "../site-env.js";
@@ -7,17 +7,17 @@ import { Construct } from "constructs";
7
7
  import { Token, Duration, CfnOutput, RemovalPolicy, CustomResource, } from "aws-cdk-lib";
8
8
  import * as s3 from "aws-cdk-lib/aws-s3";
9
9
  import * as s3Assets from "aws-cdk-lib/aws-s3-assets";
10
- import * as acm from "aws-cdk-lib/aws-certificatemanager";
11
10
  import * as iam from "aws-cdk-lib/aws-iam";
12
11
  import * as lambda from "aws-cdk-lib/aws-lambda";
13
12
  import * as route53 from "aws-cdk-lib/aws-route53";
14
- import * as route53Patterns from "aws-cdk-lib/aws-route53-patterns";
15
13
  import * as route53Targets from "aws-cdk-lib/aws-route53-targets";
16
14
  import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
17
15
  import * as cfOrigins from "aws-cdk-lib/aws-cloudfront-origins";
18
16
  import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
19
17
  import { Stack } from "./Stack.js";
20
18
  import { getBuildCmdEnvironment, buildErrorResponsesFor404ErrorPage, buildErrorResponsesForRedirectToIndex, } from "./BaseSite.js";
19
+ import { HttpsRedirect } from "./cdk/website-redirect.js";
20
+ import { DnsValidatedCertificate } from "./cdk/dns-validated-certificate.js";
21
21
  import { isCDKConstruct } from "./Construct.js";
22
22
  import { ENVIRONMENT_PLACEHOLDER, getParameterPath, } from "./util/functionBinding.js";
23
23
  import { gray } from "colorette";
@@ -519,7 +519,7 @@ interface ImportMeta {
519
519
  // HostedZone is set for Route 53 domains
520
520
  if (this.hostedZone) {
521
521
  if (typeof customDomain === "string") {
522
- acmCertificate = new acm.DnsValidatedCertificate(this, "Certificate", {
522
+ acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
523
523
  domainName: customDomain,
524
524
  hostedZone: this.hostedZone,
525
525
  region: "us-east-1",
@@ -529,7 +529,7 @@ interface ImportMeta {
529
529
  acmCertificate = customDomain.cdk.certificate;
530
530
  }
531
531
  else {
532
- acmCertificate = new acm.DnsValidatedCertificate(this, "Certificate", {
532
+ acmCertificate = new DnsValidatedCertificate(this, "Certificate", {
533
533
  domainName: customDomain.domainName,
534
534
  hostedZone: this.hostedZone,
535
535
  region: "us-east-1",
@@ -568,7 +568,7 @@ interface ImportMeta {
568
568
  new route53.AaaaRecord(this, "AliasRecordAAAA", recordProps);
569
569
  // Create Alias redirect record
570
570
  if (domainAlias) {
571
- new route53Patterns.HttpsRedirect(this, "Redirect", {
571
+ new HttpsRedirect(this, "Redirect", {
572
572
  zone: this.hostedZone,
573
573
  recordNames: [domainAlias],
574
574
  targetDomain: recordName,
@@ -0,0 +1,18 @@
1
+ import { Metric, MetricOptions } from "aws-cdk-lib/aws-cloudwatch";
2
+ import { Resource } from "aws-cdk-lib";
3
+ import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
4
+ /**
5
+ * Shared implementation details of ICertificate implementations.
6
+ *
7
+ * @internal
8
+ */
9
+ export declare abstract class CertificateBase extends Resource implements ICertificate {
10
+ abstract readonly certificateArn: string;
11
+ /**
12
+ * If the certificate is provisionned in a different region than the
13
+ * containing stack, this should be the region in which the certificate lives
14
+ * so we can correctly create `Metric` instances.
15
+ */
16
+ protected readonly region?: string;
17
+ metricDaysToExpiry(props?: MetricOptions): Metric;
18
+ }
@@ -0,0 +1,26 @@
1
+ import { Metric, Stats } from "aws-cdk-lib/aws-cloudwatch";
2
+ import { Duration, Resource } from "aws-cdk-lib";
3
+ /**
4
+ * Shared implementation details of ICertificate implementations.
5
+ *
6
+ * @internal
7
+ */
8
+ export class CertificateBase extends Resource {
9
+ /**
10
+ * If the certificate is provisionned in a different region than the
11
+ * containing stack, this should be the region in which the certificate lives
12
+ * so we can correctly create `Metric` instances.
13
+ */
14
+ region;
15
+ metricDaysToExpiry(props) {
16
+ return new Metric({
17
+ period: Duration.days(1),
18
+ ...props,
19
+ dimensionsMap: { CertificateArn: this.certificateArn },
20
+ metricName: "DaysToExpiry",
21
+ namespace: "AWS/CertificateManager",
22
+ region: this.region,
23
+ statistic: Stats.MINIMUM,
24
+ });
25
+ }
26
+ }
@@ -0,0 +1,77 @@
1
+ import { Construct } from "constructs";
2
+ import { ITaggable, TagManager, RemovalPolicy } from "aws-cdk-lib";
3
+ import { CertificateProps, ICertificate } from "aws-cdk-lib/aws-certificatemanager";
4
+ import * as iam from "aws-cdk-lib/aws-iam";
5
+ import * as route53 from "aws-cdk-lib/aws-route53";
6
+ import { CertificateBase } from "./certificate-base.js";
7
+ /**
8
+ * Properties to create a DNS validated certificate managed by AWS Certificate Manager
9
+ *
10
+ */
11
+ export interface DnsValidatedCertificateProps extends CertificateProps {
12
+ /**
13
+ * Route 53 Hosted Zone used to perform DNS validation of the request. The zone
14
+ * must be authoritative for the domain name specified in the Certificate Request.
15
+ */
16
+ readonly hostedZone: route53.IHostedZone;
17
+ /**
18
+ * AWS region that will host the certificate. This is needed especially
19
+ * for certificates used for CloudFront distributions, which require the region
20
+ * to be us-east-1.
21
+ *
22
+ * @default the region the stack is deployed in.
23
+ */
24
+ readonly region?: string;
25
+ /**
26
+ * An endpoint of Route53 service, which is not necessary as AWS SDK could figure
27
+ * out the right endpoints for most regions, but for some regions such as those in
28
+ * aws-cn partition, the default endpoint is not working now, hence the right endpoint
29
+ * need to be specified through this prop.
30
+ *
31
+ * Route53 is not been officially launched in China, it is only available for AWS
32
+ * internal accounts now. To make DnsValidatedCertificate work for internal accounts
33
+ * now, a special endpoint needs to be provided.
34
+ *
35
+ * @default - The AWS SDK will determine the Route53 endpoint to use based on region
36
+ */
37
+ readonly route53Endpoint?: string;
38
+ /**
39
+ * Role to use for the custom resource that creates the validated certificate
40
+ *
41
+ * @default - A new role will be created
42
+ */
43
+ readonly customResourceRole?: iam.IRole;
44
+ /**
45
+ * When set to true, when the DnsValidatedCertificate is deleted,
46
+ * the associated Route53 validation records are removed.
47
+ *
48
+ * CAUTION: If multiple certificates share the same domains (and same validation records),
49
+ * this can cause the other certificates to fail renewal and/or not validate.
50
+ * Not recommended for production use.
51
+ *
52
+ * @default false
53
+ */
54
+ readonly cleanupRoute53Records?: boolean;
55
+ }
56
+ /**
57
+ * A certificate managed by AWS Certificate Manager. Will be automatically
58
+ * validated using DNS validation against the specified Route 53 hosted zone.
59
+ *
60
+ * @resource AWS::CertificateManager::Certificate
61
+ */
62
+ export declare class DnsValidatedCertificate extends CertificateBase implements ICertificate, ITaggable {
63
+ readonly certificateArn: string;
64
+ /**
65
+ * Resource Tags.
66
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-certificatemanager-certificate.html#cfn-certificatemanager-certificate-tags
67
+ */
68
+ readonly tags: TagManager;
69
+ protected readonly region?: string;
70
+ private normalizedZoneName;
71
+ private hostedZoneId;
72
+ private domainName;
73
+ private _removalPolicy?;
74
+ constructor(scope: Construct, id: string, props: DnsValidatedCertificateProps);
75
+ applyRemovalPolicy(policy: RemovalPolicy): void;
76
+ private validateDnsValidatedCertificate;
77
+ }
@@ -0,0 +1,125 @@
1
+ import url from "url";
2
+ import * as path from "path";
3
+ import { Token, TagManager, TagType, Duration, Stack, CustomResource, Lazy, } from "aws-cdk-lib";
4
+ import * as iam from "aws-cdk-lib/aws-iam";
5
+ import * as lambda from "aws-cdk-lib/aws-lambda";
6
+ import { CertificateBase } from "./certificate-base.js";
7
+ const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
8
+ /**
9
+ * A certificate managed by AWS Certificate Manager. Will be automatically
10
+ * validated using DNS validation against the specified Route 53 hosted zone.
11
+ *
12
+ * @resource AWS::CertificateManager::Certificate
13
+ */
14
+ export class DnsValidatedCertificate extends CertificateBase {
15
+ certificateArn;
16
+ /**
17
+ * Resource Tags.
18
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-certificatemanager-certificate.html#cfn-certificatemanager-certificate-tags
19
+ */
20
+ tags;
21
+ region;
22
+ normalizedZoneName;
23
+ hostedZoneId;
24
+ domainName;
25
+ _removalPolicy;
26
+ constructor(scope, id, props) {
27
+ super(scope, id);
28
+ this.region = props.region;
29
+ this.domainName = props.domainName;
30
+ // check if domain name is 64 characters or less
31
+ if (!Token.isUnresolved(props.domainName) && props.domainName.length > 64) {
32
+ throw new Error("Domain name must be 64 characters or less");
33
+ }
34
+ this.normalizedZoneName = props.hostedZone.zoneName;
35
+ // Remove trailing `.` from zone name
36
+ if (this.normalizedZoneName.endsWith(".")) {
37
+ this.normalizedZoneName = this.normalizedZoneName.substring(0, this.normalizedZoneName.length - 1);
38
+ }
39
+ // Remove any `/hostedzone/` prefix from the Hosted Zone ID
40
+ this.hostedZoneId = props.hostedZone.hostedZoneId.replace(/^\/hostedzone\//, "");
41
+ this.tags = new TagManager(TagType.MAP, "AWS::CertificateManager::Certificate");
42
+ let certificateTransparencyLoggingPreference;
43
+ if (props.transparencyLoggingEnabled !== undefined) {
44
+ certificateTransparencyLoggingPreference =
45
+ props.transparencyLoggingEnabled ? "ENABLED" : "DISABLED";
46
+ }
47
+ const requestorFunction = new lambda.Function(this, "CertificateRequestorFunction", {
48
+ code: lambda.Code.fromAsset(path.join(__dirname, "../../support/certificate-requestor")),
49
+ handler: "index.certificateRequestHandler",
50
+ runtime: lambda.Runtime.NODEJS_14_X,
51
+ timeout: Duration.minutes(15),
52
+ role: props.customResourceRole,
53
+ });
54
+ requestorFunction.addToRolePolicy(new iam.PolicyStatement({
55
+ actions: [
56
+ "acm:RequestCertificate",
57
+ "acm:DescribeCertificate",
58
+ "acm:DeleteCertificate",
59
+ "acm:AddTagsToCertificate",
60
+ ],
61
+ resources: ["*"],
62
+ }));
63
+ requestorFunction.addToRolePolicy(new iam.PolicyStatement({
64
+ actions: ["route53:GetChange"],
65
+ resources: ["*"],
66
+ }));
67
+ requestorFunction.addToRolePolicy(new iam.PolicyStatement({
68
+ actions: ["route53:changeResourceRecordSets"],
69
+ resources: [
70
+ `arn:${Stack.of(requestorFunction).partition}:route53:::hostedzone/${this.hostedZoneId}`,
71
+ ],
72
+ conditions: {
73
+ "ForAllValues:StringEquals": {
74
+ "route53:ChangeResourceRecordSetsRecordTypes": ["CNAME"],
75
+ "route53:ChangeResourceRecordSetsActions": props.cleanupRoute53Records ? ["UPSERT", "DELETE"] : ["UPSERT"],
76
+ },
77
+ "ForAllValues:StringLike": {
78
+ "route53:ChangeResourceRecordSetsNormalizedRecordNames": [
79
+ addWildcard(props.domainName),
80
+ ...(props.subjectAlternativeNames ?? []).map((d) => addWildcard(d)),
81
+ ],
82
+ },
83
+ },
84
+ }));
85
+ const certificate = new CustomResource(this, "CertificateRequestorResource", {
86
+ serviceToken: requestorFunction.functionArn,
87
+ properties: {
88
+ DomainName: props.domainName,
89
+ SubjectAlternativeNames: Lazy.list({ produce: () => props.subjectAlternativeNames }, { omitEmpty: true }),
90
+ CertificateTransparencyLoggingPreference: certificateTransparencyLoggingPreference,
91
+ HostedZoneId: this.hostedZoneId,
92
+ Region: props.region,
93
+ Route53Endpoint: props.route53Endpoint,
94
+ RemovalPolicy: Lazy.any({ produce: () => this._removalPolicy }),
95
+ // Custom resources properties are always converted to strings; might as well be explict here.
96
+ CleanupRecords: props.cleanupRoute53Records ? "true" : undefined,
97
+ Tags: Lazy.list({ produce: () => this.tags.renderTags() }),
98
+ },
99
+ });
100
+ this.certificateArn = certificate.getAtt("Arn").toString();
101
+ this.node.addValidation({
102
+ validate: () => this.validateDnsValidatedCertificate(),
103
+ });
104
+ }
105
+ applyRemovalPolicy(policy) {
106
+ this._removalPolicy = policy;
107
+ }
108
+ validateDnsValidatedCertificate() {
109
+ const errors = [];
110
+ // Ensure the zone name is a parent zone of the certificate domain name
111
+ if (!Token.isUnresolved(this.normalizedZoneName) &&
112
+ this.domainName !== this.normalizedZoneName &&
113
+ !this.domainName.endsWith("." + this.normalizedZoneName)) {
114
+ errors.push(`DNS zone ${this.normalizedZoneName} is not authoritative for certificate domain name ${this.domainName}`);
115
+ }
116
+ return errors;
117
+ }
118
+ }
119
+ // https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/specifying-rrset-conditions.html
120
+ function addWildcard(domainName) {
121
+ if (domainName.startsWith("*.")) {
122
+ return domainName;
123
+ }
124
+ return `*.${domainName}`;
125
+ }
@@ -0,0 +1,53 @@
1
+ import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
2
+ import { IHostedZone } from "aws-cdk-lib/aws-route53";
3
+ import { Construct } from "constructs";
4
+ /**
5
+ * Properties to configure an HTTPS Redirect
6
+ */
7
+ export interface HttpsRedirectProps {
8
+ /**
9
+ * Hosted zone of the domain which will be used to create alias record(s) from
10
+ * domain names in the hosted zone to the target domain. The hosted zone must
11
+ * contain entries for the domain name(s) supplied through `recordNames` that
12
+ * will redirect to the target domain.
13
+ *
14
+ * Domain names in the hosted zone can include a specific domain (example.com)
15
+ * and its subdomains (acme.example.com, zenith.example.com).
16
+ *
17
+ */
18
+ readonly zone: IHostedZone;
19
+ /**
20
+ * The redirect target fully qualified domain name (FQDN). An alias record
21
+ * will be created that points to your CloudFront distribution. Root domain
22
+ * or sub-domain can be supplied.
23
+ */
24
+ readonly targetDomain: string;
25
+ /**
26
+ * The domain names that will redirect to `targetDomain`
27
+ *
28
+ * @default - the domain name of the hosted zone
29
+ */
30
+ readonly recordNames?: string[];
31
+ /**
32
+ * The AWS Certificate Manager (ACM) certificate that will be associated with
33
+ * the CloudFront distribution that will be created. If provided, the certificate must be
34
+ * stored in us-east-1 (N. Virginia)
35
+ *
36
+ * @default - A new certificate is created in us-east-1 (N. Virginia)
37
+ */
38
+ readonly certificate?: ICertificate;
39
+ }
40
+ /**
41
+ * Allows creating a domainA -> domainB redirect using CloudFront and S3.
42
+ * You can specify multiple domains to be redirected.
43
+ */
44
+ export declare class HttpsRedirect extends Construct {
45
+ constructor(scope: Construct, id: string, props: HttpsRedirectProps);
46
+ /**
47
+ * Creates a certificate.
48
+ *
49
+ * This is also safe to upgrade since the new certificate will be created and updated
50
+ * on the CloudFront distribution before the old one is deleted.
51
+ */
52
+ private createCertificate;
53
+ }
@@ -0,0 +1,77 @@
1
+ import { CloudFrontWebDistribution, OriginProtocolPolicy, PriceClass, ViewerCertificate, ViewerProtocolPolicy, } from "aws-cdk-lib/aws-cloudfront";
2
+ import { ARecord, AaaaRecord, RecordTarget, } from "aws-cdk-lib/aws-route53";
3
+ import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
4
+ import { BlockPublicAccess, Bucket, RedirectProtocol, } from "aws-cdk-lib/aws-s3";
5
+ import { ArnFormat, RemovalPolicy, Stack, Token } from "aws-cdk-lib";
6
+ import cdkHelpers from "aws-cdk-lib/core/lib/helpers-internal";
7
+ import { Construct } from "constructs";
8
+ import { DnsValidatedCertificate } from "./dns-validated-certificate.js";
9
+ const { md5hash } = cdkHelpers;
10
+ /**
11
+ * Allows creating a domainA -> domainB redirect using CloudFront and S3.
12
+ * You can specify multiple domains to be redirected.
13
+ */
14
+ export class HttpsRedirect extends Construct {
15
+ constructor(scope, id, props) {
16
+ super(scope, id);
17
+ const domainNames = props.recordNames ?? [props.zone.zoneName];
18
+ if (props.certificate) {
19
+ const certificateRegion = Stack.of(this).splitArn(props.certificate.certificateArn, ArnFormat.SLASH_RESOURCE_NAME).region;
20
+ if (!Token.isUnresolved(certificateRegion) &&
21
+ certificateRegion !== "us-east-1") {
22
+ throw new Error(`The certificate must be in the us-east-1 region and the certificate you provided is in ${certificateRegion}.`);
23
+ }
24
+ }
25
+ const redirectCert = props.certificate ?? this.createCertificate(domainNames, props.zone);
26
+ const redirectBucket = new Bucket(this, "RedirectBucket", {
27
+ websiteRedirect: {
28
+ hostName: props.targetDomain,
29
+ protocol: RedirectProtocol.HTTPS,
30
+ },
31
+ removalPolicy: RemovalPolicy.DESTROY,
32
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
33
+ });
34
+ const redirectDist = new CloudFrontWebDistribution(this, "RedirectDistribution", {
35
+ defaultRootObject: "",
36
+ originConfigs: [
37
+ {
38
+ behaviors: [{ isDefaultBehavior: true }],
39
+ customOriginSource: {
40
+ domainName: redirectBucket.bucketWebsiteDomainName,
41
+ originProtocolPolicy: OriginProtocolPolicy.HTTP_ONLY,
42
+ },
43
+ },
44
+ ],
45
+ viewerCertificate: ViewerCertificate.fromAcmCertificate(redirectCert, {
46
+ aliases: domainNames,
47
+ }),
48
+ comment: `Redirect to ${props.targetDomain} from ${domainNames.join(", ")}`,
49
+ priceClass: PriceClass.PRICE_CLASS_ALL,
50
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
51
+ });
52
+ domainNames.forEach((domainName) => {
53
+ const hash = md5hash(domainName).slice(0, 6);
54
+ const aliasProps = {
55
+ recordName: domainName,
56
+ zone: props.zone,
57
+ target: RecordTarget.fromAlias(new CloudFrontTarget(redirectDist)),
58
+ };
59
+ new ARecord(this, `RedirectAliasRecord${hash}`, aliasProps);
60
+ new AaaaRecord(this, `RedirectAliasRecordSix${hash}`, aliasProps);
61
+ });
62
+ }
63
+ /**
64
+ * Creates a certificate.
65
+ *
66
+ * This is also safe to upgrade since the new certificate will be created and updated
67
+ * on the CloudFront distribution before the old one is deleted.
68
+ */
69
+ createCertificate(domainNames, zone) {
70
+ return new DnsValidatedCertificate(this, "RedirectCertificate", {
71
+ domainName: domainNames[0],
72
+ subjectAlternativeNames: domainNames,
73
+ hostedZone: zone,
74
+ region: "us-east-1",
75
+ });
76
+ }
77
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.0.0-rc.64",
3
+ "version": "2.0.0-rc.65",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },
@@ -109,7 +109,7 @@
109
109
  "@types/ws": "^8.5.3",
110
110
  "@types/yargs": "^17.0.13",
111
111
  "tsx": "^3.12.1",
112
- "vitest": "^0.15.1"
112
+ "vitest": "^0.28.3"
113
113
  },
114
114
  "peerDependencies": {
115
115
  "@sls-next/lambda-at-edge": "^3.7.0"
package/pothos.js CHANGED
@@ -77,6 +77,7 @@ export async function extractSchema(opts) {
77
77
  if (!types.isMemberExpression(callPath.node.callee) ||
78
78
  !types.isIdentifier(callPath.node.callee.object) ||
79
79
  !types.isIdentifier(callPath.node.callee.property) ||
80
+ !schemaBuilder ||
80
81
  (callPath.node.callee.object.name !==
81
82
  schemaBuilder.node.id.name &&
82
83
  callPath.node.callee.property.name !== "implement")) {
package/sst.mjs CHANGED
@@ -5556,7 +5556,7 @@ async function extractSchema(opts) {
5556
5556
  }
5557
5557
  },
5558
5558
  CallExpression(callPath) {
5559
- if (!types.isMemberExpression(callPath.node.callee) || !types.isIdentifier(callPath.node.callee.object) || !types.isIdentifier(callPath.node.callee.property) || callPath.node.callee.object.name !== schemaBuilder.node.id.name && callPath.node.callee.property.name !== "implement") {
5559
+ if (!types.isMemberExpression(callPath.node.callee) || !types.isIdentifier(callPath.node.callee.object) || !types.isIdentifier(callPath.node.callee.property) || !schemaBuilder || callPath.node.callee.object.name !== schemaBuilder.node.id.name && callPath.node.callee.property.name !== "implement") {
5560
5560
  return;
5561
5561
  }
5562
5562
  callPath.traverse({
@@ -6357,6 +6357,7 @@ var dev = (program2) => program2.command(
6357
6357
  }
6358
6358
  deploy3(assembly);
6359
6359
  } catch (ex) {
6360
+ isWorking = false;
6360
6361
  spinner.fail();
6361
6362
  Colors.line(
6362
6363
  ex.stack.split("\n").map((line) => " " + line).join("\n")
@@ -7195,7 +7196,9 @@ consoleCommand(program);
7195
7196
  diff2(program);
7196
7197
  version(program);
7197
7198
  telemetry(program);
7198
- process.setSourceMapsEnabled(true);
7199
+ if ("setSourceMapsEnabled" in process) {
7200
+ process.setSourceMapsEnabled(true);
7201
+ }
7199
7202
  process.removeAllListeners("uncaughtException");
7200
7203
  process.on("uncaughtException", (err) => {
7201
7204
  Logger.debug(err);
@@ -16,7 +16,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);if(!(this instanceof be))r
16
16
  `));var r=e.pax;if(r)for(var i in r)t+=To(" "+i+"="+r[i]+`
17
17
  `);return Buffer.from(t)};br.decodePax=function(e){for(var t={};e.length;){for(var r=0;r<e.length&&e[r]!==32;)r++;var i=parseInt(e.slice(0,r).toString(),10);if(!i)return t;var n=e.slice(r+1,i-1).toString(),s=n.indexOf("=");if(s===-1)return t;t[n.slice(0,s)]=n.slice(s+1),e=e.slice(i)}return t};br.encode=function(e){var t=cE(512),r=e.name,i="";if(e.typeflag===5&&r[r.length-1]!=="/"&&(r+="/"),Buffer.byteLength(r)!==r.length)return null;for(;Buffer.byteLength(r)>100;){var n=r.indexOf("/");if(n===-1)return null;i+=i?"/"+r.slice(0,n):r.slice(0,n),r=r.slice(n+1)}return Buffer.byteLength(r)>100||Buffer.byteLength(i)>155||e.linkname&&Buffer.byteLength(e.linkname)>100?null:(t.write(r),t.write(wt(e.mode&mE,6),100),t.write(wt(e.uid,6),108),t.write(wt(e.gid,6),116),t.write(wt(e.size,11),124),t.write(wt(e.mtime.getTime()/1e3|0,11),136),t[156]=kd+wE(e.type),e.linkname&&t.write(e.linkname,157),Bd.copy(t,fi),gE.copy(t,xo),e.uname&&t.write(e.uname,265),e.gname&&t.write(e.gname,297),t.write(wt(e.devmajor||0,6),329),t.write(wt(e.devminor||0,6),337),i&&t.write(i,345),t.write(wt(Gd(t),6),148),t)};br.decode=function(e,t,r){var i=e[156]===0?0:e[156]-kd,n=_r(e,0,100,t),s=St(e,100,8),o=St(e,108,8),u=St(e,116,8),l=St(e,124,12),d=St(e,136,12),p=bE(i),m=e[157]===0?null:_r(e,157,100,t),g=_r(e,265,32),y=_r(e,297,32),b=St(e,329,8),A=St(e,337,8),E=Gd(e);if(E===8*32)return null;if(E!==St(e,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(Bd.compare(e,fi,fi+6)===0)e[345]&&(n=_r(e,345,155,t)+"/"+n);else if(!(yE.compare(e,fi,fi+6)===0&&vE.compare(e,xo,xo+2)===0)){if(!r)throw new Error("Invalid tar header: unknown format.")}return i===0&&n&&n[n.length-1]==="/"&&(i=5),{name:n,mode:s,uid:o,gid:u,size:l,mtime:new Date(1e3*d),type:p,linkname:m,uname:g,gname:y,devmajor:b,devminor:A}}});var Qd=L((gx,Vd)=>{var Wd=D("util"),EE=jd(),li=Ro(),Hd=We().Writable,$d=We().PassThrough,Zd=a(function(){},"noop"),zd=a(function(e){return e&=511,e&&512-e},"overflow"),OE=a(function(e,t){var r=new Gn(e,t);return r.end(),r},"emptyStream"),TE=a(function(e,t){return t.path&&(e.name=t.path),t.linkpath&&(e.linkname=t.linkpath),t.size&&(e.size=parseInt(t.size,10)),e.pax=t,e},"mixinPax"),Gn=a(function(e,t){this._parent=e,this.offset=t,$d.call(this,{autoDestroy:!1})},"Source");Wd.inherits(Gn,$d);Gn.prototype.destroy=function(e){this._parent.destroy(e)};var it=a(function(e){if(!(this instanceof it))return new it(e);Hd.call(this,e),e=e||{},this._offset=0,this._buffer=EE(),this._missing=0,this._partial=!1,this._onparse=Zd,this._header=null,this._stream=null,this._overflow=null,this._cb=null,this._locked=!1,this._destroyed=!1,this._pax=null,this._paxGlobal=null,this._gnuLongPath=null,this._gnuLongLinkPath=null;var t=this,r=t._buffer,i=a(function(){t._continue()},"oncontinue"),n=a(function(g){if(t._locked=!1,g)return t.destroy(g);t._stream||i()},"onunlock"),s=a(function(){t._stream=null;var g=zd(t._header.size);g?t._parse(g,o):t._parse(512,m),t._locked||i()},"onstreamend"),o=a(function(){t._buffer.consume(zd(t._header.size)),t._parse(512,m),i()},"ondrain"),u=a(function(){var g=t._header.size;t._paxGlobal=li.decodePax(r.slice(0,g)),r.consume(g),s()},"onpaxglobalheader"),l=a(function(){var g=t._header.size;t._pax=li.decodePax(r.slice(0,g)),t._paxGlobal&&(t._pax=Object.assign({},t._paxGlobal,t._pax)),r.consume(g),s()},"onpaxheader"),d=a(function(){var g=t._header.size;this._gnuLongPath=li.decodeLongPath(r.slice(0,g),e.filenameEncoding),r.consume(g),s()},"ongnulongpath"),p=a(function(){var g=t._header.size;this._gnuLongLinkPath=li.decodeLongPath(r.slice(0,g),e.filenameEncoding),r.consume(g),s()},"ongnulonglinkpath"),m=a(function(){var g=t._offset,y;try{y=t._header=li.decode(r.slice(0,512),e.filenameEncoding,e.allowUnknownFormat)}catch(b){t.emit("error",b)}if(r.consume(512),!y){t._parse(512,m),i();return}if(y.type==="gnu-long-path"){t._parse(y.size,d),i();return}if(y.type==="gnu-long-link-path"){t._parse(y.size,p),i();return}if(y.type==="pax-global-header"){t._parse(y.size,u),i();return}if(y.type==="pax-header"){t._parse(y.size,l),i();return}if(t._gnuLongPath&&(y.name=t._gnuLongPath,t._gnuLongPath=null),t._gnuLongLinkPath&&(y.linkname=t._gnuLongLinkPath,t._gnuLongLinkPath=null),t._pax&&(t._header=y=TE(y,t._pax),t._pax=null),t._locked=!0,!y.size||y.type==="directory"){t._parse(512,m),t.emit("entry",y,OE(t,g),n);return}t._stream=new Gn(t,g),t.emit("entry",y,t._stream,n),t._parse(y.size,s),i()},"onheader");this._onheader=m,this._parse(512,m)},"Extract");Wd.inherits(it,Hd);it.prototype.destroy=function(e){this._destroyed||(this._destroyed=!0,e&&this.emit("error",e),this.emit("close"),this._stream&&this._stream.emit("close"))};it.prototype._parse=function(e,t){this._destroyed||(this._offset+=e,this._missing=e,t===this._onheader&&(this._partial=!1),this._onparse=t)};it.prototype._continue=function(){if(!this._destroyed){var e=this._cb;this._cb=Zd,this._overflow?this._write(this._overflow,void 0,e):e()}};it.prototype._write=function(e,t,r){if(!this._destroyed){var i=this._stream,n=this._buffer,s=this._missing;if(e.length&&(this._partial=!0),e.length<s)return this._missing-=e.length,this._overflow=null,i?i.write(e,r):(n.append(e),r());this._cb=r,this._missing=0;var o=null;e.length>s&&(o=e.slice(s),e=e.slice(0,s)),i?i.end(e):n.append(e),this._overflow=o,this._onparse()}};it.prototype._final=function(e){if(this._partial)return this.destroy(new Error("Unexpected end of data"));e()};Vd.exports=it});var Kd=L((vx,Yd)=>{Yd.exports=D("fs").constants||D("constants")});var ep=L((mx,Jd)=>{var xE=Yr(),RE=a(function(){},"noop"),AE=a(function(e){return e.setHeader&&typeof e.abort=="function"},"isRequest"),IE=a(function(e){return e.stdio&&Array.isArray(e.stdio)&&e.stdio.length===3},"isChildProcess"),Xd=a(function(e,t,r){if(typeof t=="function")return Xd(e,null,t);t||(t={}),r=xE(r||RE);var i=e._writableState,n=e._readableState,s=t.readable||t.readable!==!1&&e.readable,o=t.writable||t.writable!==!1&&e.writable,u=!1,l=a(function(){e.writable||d()},"onlegacyfinish"),d=a(function(){o=!1,s||r.call(e)},"onfinish"),p=a(function(){s=!1,o||r.call(e)},"onend"),m=a(function(E){r.call(e,E?new Error("exited with error code: "+E):null)},"onexit"),g=a(function(E){r.call(e,E)},"onerror"),y=a(function(){process.nextTick(b)},"onclose"),b=a(function(){if(!u){if(s&&!(n&&n.ended&&!n.destroyed))return r.call(e,new Error("premature close"));if(o&&!(i&&i.ended&&!i.destroyed))return r.call(e,new Error("premature close"))}},"onclosenexttick"),A=a(function(){e.req.on("finish",d)},"onrequest");return AE(e)?(e.on("complete",d),e.on("abort",y),e.req?A():e.on("request",A)):o&&!i&&(e.on("end",l),e.on("close",l)),IE(e)&&e.on("exit",m),e.on("end",p),e.on("finish",d),t.error!==!1&&e.on("error",g),e.on("close",y),function(){u=!0,e.removeListener("complete",d),e.removeListener("abort",y),e.removeListener("request",A),e.req&&e.req.removeListener("finish",d),e.removeListener("end",l),e.removeListener("close",l),e.removeListener("finish",d),e.removeListener("exit",m),e.removeListener("end",p),e.removeListener("error",g),e.removeListener("close",y)}},"eos");Jd.exports=Xd});var ap=L((bx,np)=>{var wr=Kd(),tp=ep(),Wn=Me(),LE=Buffer.alloc,rp=We().Readable,Sr=We().Writable,ME=D("string_decoder").StringDecoder,zn=Ro(),DE=parseInt("755",8),CE=parseInt("644",8),ip=LE(1024),Io=a(function(){},"noop"),Ao=a(function(e,t){t&=511,t&&e.push(ip.slice(0,512-t))},"overflow");function PE(e){switch(e&wr.S_IFMT){case wr.S_IFBLK:return"block-device";case wr.S_IFCHR:return"character-device";case wr.S_IFDIR:return"directory";case wr.S_IFIFO:return"fifo";case wr.S_IFLNK:return"symlink"}return"file"}a(PE,"modeToType");var Hn=a(function(e){Sr.call(this),this.written=0,this._to=e,this._destroyed=!1},"Sink");Wn(Hn,Sr);Hn.prototype._write=function(e,t,r){if(this.written+=e.length,this._to.push(e))return r();this._to._drain=r};Hn.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var $n=a(function(){Sr.call(this),this.linkname="",this._decoder=new ME("utf-8"),this._destroyed=!1},"LinkSink");Wn($n,Sr);$n.prototype._write=function(e,t,r){this.linkname+=this._decoder.write(e),r()};$n.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var hi=a(function(){Sr.call(this),this._destroyed=!1},"Void");Wn(hi,Sr);hi.prototype._write=function(e,t,r){r(new Error("No body allowed for this entry"))};hi.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.emit("close"))};var Ye=a(function(e){if(!(this instanceof Ye))return new Ye(e);rp.call(this,e),this._drain=Io,this._finalized=!1,this._finalizing=!1,this._destroyed=!1,this._stream=null},"Pack");Wn(Ye,rp);Ye.prototype.entry=function(e,t,r){if(this._stream)throw new Error("already piping an entry");if(!(this._finalized||this._destroyed)){typeof t=="function"&&(r=t,t=null),r||(r=Io);var i=this;if((!e.size||e.type==="symlink")&&(e.size=0),e.type||(e.type=PE(e.mode)),e.mode||(e.mode=e.type==="directory"?DE:CE),e.uid||(e.uid=0),e.gid||(e.gid=0),e.mtime||(e.mtime=new Date),typeof t=="string"&&(t=Buffer.from(t)),Buffer.isBuffer(t)){e.size=t.length,this._encode(e);var n=this.push(t);return Ao(i,e.size),n?process.nextTick(r):this._drain=r,new hi}if(e.type==="symlink"&&!e.linkname){var s=new $n;return tp(s,function(u){if(u)return i.destroy(),r(u);e.linkname=s.linkname,i._encode(e),r()}),s}if(this._encode(e),e.type!=="file"&&e.type!=="contiguous-file")return process.nextTick(r),new hi;var o=new Hn(this);return this._stream=o,tp(o,function(u){if(i._stream=null,u)return i.destroy(),r(u);if(o.written!==e.size)return i.destroy(),r(new Error("size mismatch"));Ao(i,e.size),i._finalizing&&i.finalize(),r()}),o}};Ye.prototype.finalize=function(){if(this._stream){this._finalizing=!0;return}this._finalized||(this._finalized=!0,this.push(ip),this.push(null))};Ye.prototype.destroy=function(e){this._destroyed||(this._destroyed=!0,e&&this.emit("error",e),this.emit("close"),this._stream&&this._stream.destroy&&this._stream.destroy())};Ye.prototype._encode=function(e){if(!e.pax){var t=zn.encode(e);if(t){this.push(t);return}}this._encodePax(e)};Ye.prototype._encodePax=function(e){var t=zn.encodePax({name:e.name,linkname:e.linkname,pax:e.pax}),r={name:"PaxHeader",mode:e.mode,uid:e.uid,gid:e.gid,size:t.length,mtime:e.mtime,type:"pax-header",linkname:e.linkname&&"PaxHeader",uname:e.uname,gname:e.gname,devmajor:e.devmajor,devminor:e.devminor};this.push(zn.encode(r)),this.push(t),Ao(this,t.length),r.size=e.size,r.type=e.type,this.push(zn.encode(r))};Ye.prototype._read=function(e){var t=this._drain;this._drain=Io,t()};np.exports=Ye});var sp=L(Lo=>{Lo.extract=Qd();Lo.pack=ap()});var fp=L((Ex,up)=>{var NE=D("zlib"),qE=sp(),op=dr(),nt=a(function(e){if(!(this instanceof nt))return new nt(e);e=this.options=op.defaults(e,{gzip:!1}),typeof e.gzipOptions!="object"&&(e.gzipOptions={}),this.supports={directory:!0,symlink:!0},this.engine=qE.pack(e),this.compressor=!1,e.gzip&&(this.compressor=NE.createGzip(e.gzipOptions),this.compressor.on("error",this._onCompressorError.bind(this)))},"Tar");nt.prototype._onCompressorError=function(e){this.engine.emit("error",e)};nt.prototype.append=function(e,t,r){var i=this;t.mtime=t.date;function n(o,u){if(o){r(o);return}i.engine.entry(t,u,function(l){r(l,t)})}if(a(n,"append"),t.sourceType==="buffer")n(null,e);else if(t.sourceType==="stream"&&t.stats){t.size=t.stats.size;var s=i.engine.entry(t,function(o){r(o,t)});e.pipe(s)}else t.sourceType==="stream"&&op.collectStream(e,n)};nt.prototype.finalize=function(){this.engine.finalize()};nt.prototype.on=function(){return this.engine.on.apply(this.engine,arguments)};nt.prototype.pipe=function(e,t){return this.compressor?this.engine.pipe.apply(this.engine,[this.compressor]).pipe(e,t):this.engine.pipe.apply(this.engine,arguments)};nt.prototype.unpipe=function(){return this.compressor?this.compressor.unpipe.apply(this.compressor,arguments):this.engine.unpipe.apply(this.engine,arguments)};up.exports=nt});var dp=L((Tx,cp)=>{var FE=D("util").inherits,lp=We().Transform,jE=vo(),hp=dr(),Et=a(function(e){if(!(this instanceof Et))return new Et(e);e=this.options=hp.defaults(e,{}),lp.call(this,e),this.supports={directory:!0,symlink:!0},this.files=[]},"Json");FE(Et,lp);Et.prototype._transform=function(e,t,r){r(null,e)};Et.prototype._writeStringified=function(){var e=JSON.stringify(this.files);this.write(e)};Et.prototype.append=function(e,t,r){var i=this;t.crc32=0;function n(s,o){if(s){r(s);return}t.size=o.length||0,t.crc32=jE.unsigned(o),i.files.push(t),r(null,t)}a(n,"onend"),t.sourceType==="buffer"?n(null,e):t.sourceType==="stream"&&hp.collectStream(e,n)};Et.prototype.finalize=function(){this._writeStringified(),this.end()};cp.exports=Et});var gp=L((Rx,pp)=>{var kE=Jc(),ci={},Ot=a(function(e,t){return Ot.create(e,t)},"vending");Ot.create=function(e,t){if(ci[e]){var r=new kE(e,t);return r.setFormat(e),r.setModule(new ci[e](t)),r}else throw new Error("create("+e+"): format not registered")};Ot.registerFormat=function(e,t){if(ci[e])throw new Error("register("+e+"): format already registered");if(typeof t!="function")throw new Error("register("+e+"): format module invalid");if(typeof t.prototype.append!="function"||typeof t.prototype.finalize!="function")throw new Error("register("+e+"): format module missing methods");ci[e]=t};Ot.isRegisteredFormat=function(e){return!!ci[e]};Ot.registerFormat("zip",Pd());Ot.registerFormat("tar",fp());Ot.registerFormat("json",dp());pp.exports=Ot});var Do=L(Tt=>{Tt.setopts=HE;Tt.ownProp=yp;Tt.makeAbs=di;Tt.finish=$E;Tt.mark=ZE;Tt.isIgnored=mp;Tt.childrenIgnored=VE;function yp(e,t){return Object.prototype.hasOwnProperty.call(e,t)}a(yp,"ownProp");var BE=D("fs"),Wt=D("path"),UE=Mr(),vp=D("path").isAbsolute,Mo=UE.Minimatch;function GE(e,t){return e.localeCompare(t,"en")}a(GE,"alphasort");function zE(e,t){e.ignore=t.ignore||[],Array.isArray(e.ignore)||(e.ignore=[e.ignore]),e.ignore.length&&(e.ignore=e.ignore.map(WE))}a(zE,"setupIgnores");function WE(e){var t=null;if(e.slice(-3)==="/**"){var r=e.replace(/(\/\*\*)+$/,"");t=new Mo(r,{dot:!0})}return{matcher:new Mo(e,{dot:!0}),gmatcher:t}}a(WE,"ignoreMap");function HE(e,t,r){if(r||(r={}),r.matchBase&&t.indexOf("/")===-1){if(r.noglobstar)throw new Error("base matching requires globstar");t="**/"+t}e.silent=!!r.silent,e.pattern=t,e.strict=r.strict!==!1,e.realpath=!!r.realpath,e.realpathCache=r.realpathCache||Object.create(null),e.follow=!!r.follow,e.dot=!!r.dot,e.mark=!!r.mark,e.nodir=!!r.nodir,e.nodir&&(e.mark=!0),e.sync=!!r.sync,e.nounique=!!r.nounique,e.nonull=!!r.nonull,e.nosort=!!r.nosort,e.nocase=!!r.nocase,e.stat=!!r.stat,e.noprocess=!!r.noprocess,e.absolute=!!r.absolute,e.fs=r.fs||BE,e.maxLength=r.maxLength||1/0,e.cache=r.cache||Object.create(null),e.statCache=r.statCache||Object.create(null),e.symlinks=r.symlinks||Object.create(null),zE(e,r),e.changedCwd=!1;var i=process.cwd();yp(r,"cwd")?(e.cwd=Wt.resolve(r.cwd),e.changedCwd=e.cwd!==i):e.cwd=Wt.resolve(i),e.root=r.root||Wt.resolve(e.cwd,"/"),e.root=Wt.resolve(e.root),e.cwdAbs=vp(e.cwd)?e.cwd:di(e,e.cwd),e.nomount=!!r.nomount,process.platform==="win32"&&(e.root=e.root.replace(/\\/g,"/"),e.cwd=e.cwd.replace(/\\/g,"/"),e.cwdAbs=e.cwdAbs.replace(/\\/g,"/")),r.nonegate=!0,r.nocomment=!0,r.allowWindowsEscape=!0,e.minimatch=new Mo(t,r),e.options=e.minimatch.options}a(HE,"setopts");function $E(e){for(var t=e.nounique,r=t?[]:Object.create(null),i=0,n=e.matches.length;i<n;i++){var s=e.matches[i];if(!s||Object.keys(s).length===0){if(e.nonull){var o=e.minimatch.globSet[i];t?r.push(o):r[o]=!0}}else{var u=Object.keys(s);t?r.push.apply(r,u):u.forEach(function(l){r[l]=!0})}}if(t||(r=Object.keys(r)),e.nosort||(r=r.sort(GE)),e.mark){for(var i=0;i<r.length;i++)r[i]=e._mark(r[i]);e.nodir&&(r=r.filter(function(l){var d=!/\/$/.test(l),p=e.cache[l]||e.cache[di(e,l)];return d&&p&&(d=p!=="DIR"&&!Array.isArray(p)),d}))}e.ignore.length&&(r=r.filter(function(l){return!mp(e,l)})),e.found=r}a($E,"finish");function ZE(e,t){var r=di(e,t),i=e.cache[r],n=t;if(i){var s=i==="DIR"||Array.isArray(i),o=t.slice(-1)==="/";if(s&&!o?n+="/":!s&&o&&(n=n.slice(0,-1)),n!==t){var u=di(e,n);e.statCache[u]=e.statCache[r],e.cache[u]=e.cache[r]}}return n}a(ZE,"mark");function di(e,t){var r=t;return t.charAt(0)==="/"?r=Wt.join(e.root,t):vp(t)||t===""?r=t:e.changedCwd?r=Wt.resolve(e.cwd,t):r=Wt.resolve(t),process.platform==="win32"&&(r=r.replace(/\\/g,"/")),r}a(di,"makeAbs");function mp(e,t){return e.ignore.length?e.ignore.some(function(r){return r.matcher.match(t)||!!(r.gmatcher&&r.gmatcher.match(t))}):!1}a(mp,"isIgnored");function VE(e,t){return e.ignore.length?e.ignore.some(function(r){return!!(r.gmatcher&&r.gmatcher.match(t))}):!1}a(VE,"childrenIgnored")});var Ep=L((Px,Sp)=>{Sp.exports=wp;wp.GlobSync=we;var QE=Zr(),_p=Mr(),Mx=_p.Minimatch,Dx=No().Glob,Cx=D("util"),Co=D("path"),bp=D("assert"),Zn=D("path").isAbsolute,Ht=Do(),YE=Ht.setopts,Po=Ht.ownProp,KE=Ht.childrenIgnored,XE=Ht.isIgnored;function wp(e,t){if(typeof t=="function"||arguments.length===3)throw new TypeError(`callback provided to sync glob
18
18
  See: https://github.com/isaacs/node-glob/issues/167`);return new we(e,t).found}a(wp,"globSync");function we(e,t){if(!e)throw new Error("must provide pattern");if(typeof t=="function"||arguments.length===3)throw new TypeError(`callback provided to sync glob
19
- See: https://github.com/isaacs/node-glob/issues/167`);if(!(this instanceof we))return new we(e,t);if(YE(this,e,t),this.noprocess)return this;var r=this.minimatch.set.length;this.matches=new Array(r);for(var i=0;i<r;i++)this._process(this.minimatch.set[i],i,!1);this._finish()}a(we,"GlobSync");we.prototype._finish=function(){if(bp.ok(this instanceof we),this.realpath){var e=this;this.matches.forEach(function(t,r){var i=e.matches[r]=Object.create(null);for(var n in t)try{n=e._makeAbs(n);var s=QE.realpathSync(n,e.realpathCache);i[s]=!0}catch(o){if(o.syscall==="stat")i[e._makeAbs(n)]=!0;else throw o}})}Ht.finish(this)};we.prototype._process=function(e,t,r){bp.ok(this instanceof we);for(var i=0;typeof e[i]=="string";)i++;var n;switch(i){case e.length:this._processSimple(e.join("/"),t);return;case 0:n=null;break;default:n=e.slice(0,i).join("/");break}var s=e.slice(i),o;n===null?o=".":((Zn(n)||Zn(e.map(function(d){return typeof d=="string"?d:"[*]"}).join("/")))&&(!n||!Zn(n))&&(n="/"+n),o=n);var u=this._makeAbs(o);if(!KE(this,o)){var l=s[0]===_p.GLOBSTAR;l?this._processGlobStar(n,o,u,s,t,r):this._processReaddir(n,o,u,s,t,r)}};we.prototype._processReaddir=function(e,t,r,i,n,s){var o=this._readdir(r,s);if(o){for(var u=i[0],l=!!this.minimatch.negate,d=u._glob,p=this.dot||d.charAt(0)===".",m=[],g=0;g<o.length;g++){var y=o[g];if(y.charAt(0)!=="."||p){var b;l&&!e?b=!y.match(u):b=y.match(u),b&&m.push(y)}}var A=m.length;if(A!==0){if(i.length===1&&!this.mark&&!this.stat){this.matches[n]||(this.matches[n]=Object.create(null));for(var g=0;g<A;g++){var y=m[g];e&&(e.slice(-1)!=="/"?y=e+"/"+y:y=e+y),y.charAt(0)==="/"&&!this.nomount&&(y=Co.join(this.root,y)),this._emitMatch(n,y)}return}i.shift();for(var g=0;g<A;g++){var y=m[g],E;e?E=[e,y]:E=[y],this._process(E.concat(i),n,s)}}}};we.prototype._emitMatch=function(e,t){if(!XE(this,t)){var r=this._makeAbs(t);if(this.mark&&(t=this._mark(t)),this.absolute&&(t=r),!this.matches[e][t]){if(this.nodir){var i=this.cache[r];if(i==="DIR"||Array.isArray(i))return}this.matches[e][t]=!0,this.stat&&this._stat(t)}}};we.prototype._readdirInGlobStar=function(e){if(this.follow)return this._readdir(e,!1);var t,r,i;try{r=this.fs.lstatSync(e)}catch(s){if(s.code==="ENOENT")return null}var n=r&&r.isSymbolicLink();return this.symlinks[e]=n,!n&&r&&!r.isDirectory()?this.cache[e]="FILE":t=this._readdir(e,!1),t};we.prototype._readdir=function(e,t){var r;if(t&&!Po(this.symlinks,e))return this._readdirInGlobStar(e);if(Po(this.cache,e)){var i=this.cache[e];if(!i||i==="FILE")return null;if(Array.isArray(i))return i}try{return this._readdirEntries(e,this.fs.readdirSync(e))}catch(n){return this._readdirError(e,n),null}};we.prototype._readdirEntries=function(e,t){if(!this.mark&&!this.stat)for(var r=0;r<t.length;r++){var i=t[r];e==="/"?i=e+i:i=e+"/"+i,this.cache[i]=!0}return this.cache[e]=t,t};we.prototype._readdirError=function(e,t){switch(t.code){case"ENOTSUP":case"ENOTDIR":var r=this._makeAbs(e);if(this.cache[r]="FILE",r===this.cwdAbs){var i=new Error(t.code+" invalid cwd "+this.cwd);throw i.path=this.cwd,i.code=t.code,i}break;case"ENOENT":case"ELOOP":case"ENAMETOOLONG":case"UNKNOWN":this.cache[this._makeAbs(e)]=!1;break;default:if(this.cache[this._makeAbs(e)]=!1,this.strict)throw t;this.silent||console.error("glob error",t);break}};we.prototype._processGlobStar=function(e,t,r,i,n,s){var o=this._readdir(r,s);if(o){var u=i.slice(1),l=e?[e]:[],d=l.concat(u);this._process(d,n,!1);var p=o.length,m=this.symlinks[r];if(!(m&&s))for(var g=0;g<p;g++){var y=o[g];if(!(y.charAt(0)==="."&&!this.dot)){var b=l.concat(o[g],u);this._process(b,n,!0);var A=l.concat(o[g],i);this._process(A,n,!0)}}}};we.prototype._processSimple=function(e,t){var r=this._stat(e);if(this.matches[t]||(this.matches[t]=Object.create(null)),!!r){if(e&&Zn(e)&&!this.nomount){var i=/[\/\\]$/.test(e);e.charAt(0)==="/"?e=Co.join(this.root,e):(e=Co.resolve(this.root,e),i&&(e+="/"))}process.platform==="win32"&&(e=e.replace(/\\/g,"/")),this._emitMatch(t,e)}};we.prototype._stat=function(e){var t=this._makeAbs(e),r=e.slice(-1)==="/";if(e.length>this.maxLength)return!1;if(!this.stat&&Po(this.cache,t)){var o=this.cache[t];if(Array.isArray(o)&&(o="DIR"),!r||o==="DIR")return o;if(r&&o==="FILE")return!1}var i,n=this.statCache[t];if(!n){var s;try{s=this.fs.lstatSync(t)}catch(u){if(u&&(u.code==="ENOENT"||u.code==="ENOTDIR"))return this.statCache[t]=!1,!1}if(s&&s.isSymbolicLink())try{n=this.fs.statSync(t)}catch{n=s}else n=s}this.statCache[t]=n;var o=!0;return n&&(o=n.isDirectory()?"DIR":"FILE"),this.cache[t]=this.cache[t]||o,r&&o==="FILE"?!1:o};we.prototype._mark=function(e){return Ht.mark(this,e)};we.prototype._makeAbs=function(e){return Ht.makeAbs(this,e)}});var No=L((jx,Tp)=>{Tp.exports=$t;var JE=Zr(),Op=Mr(),qx=Op.Minimatch,e1=Me(),t1=D("events").EventEmitter,qo=D("path"),Fo=D("assert"),pi=D("path").isAbsolute,ko=Ep(),Zt=Do(),r1=Zt.setopts,jo=Zt.ownProp,Bo=Ss(),Fx=D("util"),i1=Zt.childrenIgnored,n1=Zt.isIgnored,a1=Yr();function $t(e,t,r){if(typeof t=="function"&&(r=t,t={}),t||(t={}),t.sync){if(r)throw new TypeError("callback provided to sync glob");return ko(e,t)}return new le(e,t,r)}a($t,"glob");$t.sync=ko;var s1=$t.GlobSync=ko.GlobSync;$t.glob=$t;function o1(e,t){if(t===null||typeof t!="object")return e;for(var r=Object.keys(t),i=r.length;i--;)e[r[i]]=t[r[i]];return e}a(o1,"extend");$t.hasMagic=function(e,t){var r=o1({},t);r.noprocess=!0;var i=new le(e,r),n=i.minimatch.set;if(!e)return!1;if(n.length>1)return!0;for(var s=0;s<n[0].length;s++)if(typeof n[0][s]!="string")return!0;return!1};$t.Glob=le;e1(le,t1);function le(e,t,r){if(typeof t=="function"&&(r=t,t=null),t&&t.sync){if(r)throw new TypeError("callback provided to sync glob");return new s1(e,t)}if(!(this instanceof le))return new le(e,t,r);r1(this,e,t),this._didRealPath=!1;var i=this.minimatch.set.length;this.matches=new Array(i),typeof r=="function"&&(r=a1(r),this.on("error",r),this.on("end",function(l){r(null,l)}));var n=this;if(this._processing=0,this._emitQueue=[],this._processQueue=[],this.paused=!1,this.noprocess)return this;if(i===0)return u();for(var s=!0,o=0;o<i;o++)this._process(this.minimatch.set[o],o,!1,u);s=!1;function u(){--n._processing,n._processing<=0&&(s?process.nextTick(function(){n._finish()}):n._finish())}a(u,"done")}a(le,"Glob");le.prototype._finish=function(){if(Fo(this instanceof le),!this.aborted){if(this.realpath&&!this._didRealpath)return this._realpath();Zt.finish(this),this.emit("end",this.found)}};le.prototype._realpath=function(){if(this._didRealpath)return;this._didRealpath=!0;var e=this.matches.length;if(e===0)return this._finish();for(var t=this,r=0;r<this.matches.length;r++)this._realpathSet(r,i);function i(){--e===0&&t._finish()}a(i,"next")};le.prototype._realpathSet=function(e,t){var r=this.matches[e];if(!r)return t();var i=Object.keys(r),n=this,s=i.length;if(s===0)return t();var o=this.matches[e]=Object.create(null);i.forEach(function(u,l){u=n._makeAbs(u),JE.realpath(u,n.realpathCache,function(d,p){d?d.syscall==="stat"?o[u]=!0:n.emit("error",d):o[p]=!0,--s===0&&(n.matches[e]=o,t())})})};le.prototype._mark=function(e){return Zt.mark(this,e)};le.prototype._makeAbs=function(e){return Zt.makeAbs(this,e)};le.prototype.abort=function(){this.aborted=!0,this.emit("abort")};le.prototype.pause=function(){this.paused||(this.paused=!0,this.emit("pause"))};le.prototype.resume=function(){if(this.paused){if(this.emit("resume"),this.paused=!1,this._emitQueue.length){var e=this._emitQueue.slice(0);this._emitQueue.length=0;for(var t=0;t<e.length;t++){var r=e[t];this._emitMatch(r[0],r[1])}}if(this._processQueue.length){var i=this._processQueue.slice(0);this._processQueue.length=0;for(var t=0;t<i.length;t++){var n=i[t];this._processing--,this._process(n[0],n[1],n[2],n[3])}}}};le.prototype._process=function(e,t,r,i){if(Fo(this instanceof le),Fo(typeof i=="function"),!this.aborted){if(this._processing++,this.paused){this._processQueue.push([e,t,r,i]);return}for(var n=0;typeof e[n]=="string";)n++;var s;switch(n){case e.length:this._processSimple(e.join("/"),t,i);return;case 0:s=null;break;default:s=e.slice(0,n).join("/");break}var o=e.slice(n),u;s===null?u=".":((pi(s)||pi(e.map(function(p){return typeof p=="string"?p:"[*]"}).join("/")))&&(!s||!pi(s))&&(s="/"+s),u=s);var l=this._makeAbs(u);if(i1(this,u))return i();var d=o[0]===Op.GLOBSTAR;d?this._processGlobStar(s,u,l,o,t,r,i):this._processReaddir(s,u,l,o,t,r,i)}};le.prototype._processReaddir=function(e,t,r,i,n,s,o){var u=this;this._readdir(r,s,function(l,d){return u._processReaddir2(e,t,r,i,n,s,d,o)})};le.prototype._processReaddir2=function(e,t,r,i,n,s,o,u){if(!o)return u();for(var l=i[0],d=!!this.minimatch.negate,p=l._glob,m=this.dot||p.charAt(0)===".",g=[],y=0;y<o.length;y++){var b=o[y];if(b.charAt(0)!=="."||m){var A;d&&!e?A=!b.match(l):A=b.match(l),A&&g.push(b)}}var E=g.length;if(E===0)return u();if(i.length===1&&!this.mark&&!this.stat){this.matches[n]||(this.matches[n]=Object.create(null));for(var y=0;y<E;y++){var b=g[y];e&&(e!=="/"?b=e+"/"+b:b=e+b),b.charAt(0)==="/"&&!this.nomount&&(b=qo.join(this.root,b)),this._emitMatch(n,b)}return u()}i.shift();for(var y=0;y<E;y++){var b=g[y],x;e&&(e!=="/"?b=e+"/"+b:b=e+b),this._process([b].concat(i),n,s,u)}u()};le.prototype._emitMatch=function(e,t){if(!this.aborted&&!n1(this,t)){if(this.paused){this._emitQueue.push([e,t]);return}var r=pi(t)?t:this._makeAbs(t);if(this.mark&&(t=this._mark(t)),this.absolute&&(t=r),!this.matches[e][t]){if(this.nodir){var i=this.cache[r];if(i==="DIR"||Array.isArray(i))return}this.matches[e][t]=!0;var n=this.statCache[r];n&&this.emit("stat",t,n),this.emit("match",t)}}};le.prototype._readdirInGlobStar=function(e,t){if(this.aborted)return;if(this.follow)return this._readdir(e,!1,t);var r="lstat\0"+e,i=this,n=Bo(r,s);n&&i.fs.lstat(e,n);function s(o,u){if(o&&o.code==="ENOENT")return t();var l=u&&u.isSymbolicLink();i.symlinks[e]=l,!l&&u&&!u.isDirectory()?(i.cache[e]="FILE",t()):i._readdir(e,!1,t)}a(s,"lstatcb_")};le.prototype._readdir=function(e,t,r){if(!this.aborted&&(r=Bo("readdir\0"+e+"\0"+t,r),!!r)){if(t&&!jo(this.symlinks,e))return this._readdirInGlobStar(e,r);if(jo(this.cache,e)){var i=this.cache[e];if(!i||i==="FILE")return r();if(Array.isArray(i))return r(null,i)}var n=this;n.fs.readdir(e,u1(this,e,r))}};function u1(e,t,r){return function(i,n){i?e._readdirError(t,i,r):e._readdirEntries(t,n,r)}}a(u1,"readdirCb");le.prototype._readdirEntries=function(e,t,r){if(!this.aborted){if(!this.mark&&!this.stat)for(var i=0;i<t.length;i++){var n=t[i];e==="/"?n=e+n:n=e+"/"+n,this.cache[n]=!0}return this.cache[e]=t,r(null,t)}};le.prototype._readdirError=function(e,t,r){if(!this.aborted){switch(t.code){case"ENOTSUP":case"ENOTDIR":var i=this._makeAbs(e);if(this.cache[i]="FILE",i===this.cwdAbs){var n=new Error(t.code+" invalid cwd "+this.cwd);n.path=this.cwd,n.code=t.code,this.emit("error",n),this.abort()}break;case"ENOENT":case"ELOOP":case"ENAMETOOLONG":case"UNKNOWN":this.cache[this._makeAbs(e)]=!1;break;default:this.cache[this._makeAbs(e)]=!1,this.strict&&(this.emit("error",t),this.abort()),this.silent||console.error("glob error",t);break}return r()}};le.prototype._processGlobStar=function(e,t,r,i,n,s,o){var u=this;this._readdir(r,s,function(l,d){u._processGlobStar2(e,t,r,i,n,s,d,o)})};le.prototype._processGlobStar2=function(e,t,r,i,n,s,o,u){if(!o)return u();var l=i.slice(1),d=e?[e]:[],p=d.concat(l);this._process(p,n,!1,u);var m=this.symlinks[r],g=o.length;if(m&&s)return u();for(var y=0;y<g;y++){var b=o[y];if(!(b.charAt(0)==="."&&!this.dot)){var A=d.concat(o[y],l);this._process(A,n,!0,u);var E=d.concat(o[y],i);this._process(E,n,!0,u)}}u()};le.prototype._processSimple=function(e,t,r){var i=this;this._stat(e,function(n,s){i._processSimple2(e,t,n,s,r)})};le.prototype._processSimple2=function(e,t,r,i,n){if(this.matches[t]||(this.matches[t]=Object.create(null)),!i)return n();if(e&&pi(e)&&!this.nomount){var s=/[\/\\]$/.test(e);e.charAt(0)==="/"?e=qo.join(this.root,e):(e=qo.resolve(this.root,e),s&&(e+="/"))}process.platform==="win32"&&(e=e.replace(/\\/g,"/")),this._emitMatch(t,e),n()};le.prototype._stat=function(e,t){var r=this._makeAbs(e),i=e.slice(-1)==="/";if(e.length>this.maxLength)return t();if(!this.stat&&jo(this.cache,r)){var n=this.cache[r];if(Array.isArray(n)&&(n="DIR"),!i||n==="DIR")return t(null,n);if(i&&n==="FILE")return t()}var s,o=this.statCache[r];if(o!==void 0){if(o===!1)return t(null,o);var u=o.isDirectory()?"DIR":"FILE";return i&&u==="FILE"?t():t(null,u,o)}var l=this,d=Bo("stat\0"+r,p);d&&l.fs.lstat(r,d);function p(m,g){if(g&&g.isSymbolicLink())return l.fs.stat(r,function(y,b){y?l._stat2(e,r,null,g,t):l._stat2(e,r,y,b,t)});l._stat2(e,r,m,g,t)}a(p,"lstatcb_")};le.prototype._stat2=function(e,t,r,i,n){if(r&&(r.code==="ENOENT"||r.code==="ENOTDIR"))return this.statCache[t]=!1,n();var s=e.slice(-1)==="/";if(this.statCache[t]=i,t.slice(-1)==="/"&&i&&!i.isDirectory())return n(null,!1,i);var o=!0;return i&&(o=i.isDirectory()?"DIR":"FILE"),this.cache[t]=this.cache[t]||o,s&&o==="FILE"?n():n(null,o,i)}});var p1=L(()=>{process.on("unhandledRejection",e=>{throw e});var Vn=D("path"),Qn=D("fs/promises"),f1=D("fs"),l1=gp(),h1=No(),Uo=process.argv.slice(2),Ip=Uo[0],xp=Uo[1],Lp=Uo[2],Rp=Lp*1024*1024,c1={dot:!0,nodir:!0,follow:!0,cwd:Ip},Ap=h1.sync("**",c1);d1().catch(()=>{process.exit(1)});function d1(){return new Promise(async(e,t)=>{let r,i,n,s=[];async function o(){let l=s.length,d=Vn.join(xp,`part${l}.zip`);await Qn.mkdir(Vn.dirname(d),{recursive:!0}),r=f1.createWriteStream(d),i=l1("zip"),n=0,s.push({output:r,archive:i,isOutputClosed:!1}),i.on("warning",t),i.on("error",t),r.once("close",()=>{s[l].isOutputClosed=!0,s.every(({isOutputClosed:p})=>p)&&e()}),i.pipe(r)}a(o,"openZip"),await o();for(let l of Ap){let d=Vn.join(Ip,l),[p,m]=await Promise.all([Qn.readFile(d),Qn.stat(d)]),g=m.size;if(g>Rp)throw new Error(`Cannot package file "${d}". The file is larger than ${Lp}MB.`);n+g>Rp&&(await i.finalize(),o()),i.append(p,{name:l,date:new Date("1980-01-01T00:00:00.000Z"),mode:m.mode}),n+=g}await i.finalize();let u=Vn.join(xp,"filenames");await Qn.writeFile(u,Ap.join(`
19
+ See: https://github.com/isaacs/node-glob/issues/167`);if(!(this instanceof we))return new we(e,t);if(YE(this,e,t),this.noprocess)return this;var r=this.minimatch.set.length;this.matches=new Array(r);for(var i=0;i<r;i++)this._process(this.minimatch.set[i],i,!1);this._finish()}a(we,"GlobSync");we.prototype._finish=function(){if(bp.ok(this instanceof we),this.realpath){var e=this;this.matches.forEach(function(t,r){var i=e.matches[r]=Object.create(null);for(var n in t)try{n=e._makeAbs(n);var s=QE.realpathSync(n,e.realpathCache);i[s]=!0}catch(o){if(o.syscall==="stat")i[e._makeAbs(n)]=!0;else throw o}})}Ht.finish(this)};we.prototype._process=function(e,t,r){bp.ok(this instanceof we);for(var i=0;typeof e[i]=="string";)i++;var n;switch(i){case e.length:this._processSimple(e.join("/"),t);return;case 0:n=null;break;default:n=e.slice(0,i).join("/");break}var s=e.slice(i),o;n===null?o=".":((Zn(n)||Zn(e.map(function(d){return typeof d=="string"?d:"[*]"}).join("/")))&&(!n||!Zn(n))&&(n="/"+n),o=n);var u=this._makeAbs(o);if(!KE(this,o)){var l=s[0]===_p.GLOBSTAR;l?this._processGlobStar(n,o,u,s,t,r):this._processReaddir(n,o,u,s,t,r)}};we.prototype._processReaddir=function(e,t,r,i,n,s){var o=this._readdir(r,s);if(o){for(var u=i[0],l=!!this.minimatch.negate,d=u._glob,p=this.dot||d.charAt(0)===".",m=[],g=0;g<o.length;g++){var y=o[g];if(y.charAt(0)!=="."||p){var b;l&&!e?b=!y.match(u):b=y.match(u),b&&m.push(y)}}var A=m.length;if(A!==0){if(i.length===1&&!this.mark&&!this.stat){this.matches[n]||(this.matches[n]=Object.create(null));for(var g=0;g<A;g++){var y=m[g];e&&(e.slice(-1)!=="/"?y=e+"/"+y:y=e+y),y.charAt(0)==="/"&&!this.nomount&&(y=Co.join(this.root,y)),this._emitMatch(n,y)}return}i.shift();for(var g=0;g<A;g++){var y=m[g],E;e?E=[e,y]:E=[y],this._process(E.concat(i),n,s)}}}};we.prototype._emitMatch=function(e,t){if(!XE(this,t)){var r=this._makeAbs(t);if(this.mark&&(t=this._mark(t)),this.absolute&&(t=r),!this.matches[e][t]){if(this.nodir){var i=this.cache[r];if(i==="DIR"||Array.isArray(i))return}this.matches[e][t]=!0,this.stat&&this._stat(t)}}};we.prototype._readdirInGlobStar=function(e){if(this.follow)return this._readdir(e,!1);var t,r,i;try{r=this.fs.lstatSync(e)}catch(s){if(s.code==="ENOENT")return null}var n=r&&r.isSymbolicLink();return this.symlinks[e]=n,!n&&r&&!r.isDirectory()?this.cache[e]="FILE":t=this._readdir(e,!1),t};we.prototype._readdir=function(e,t){var r;if(t&&!Po(this.symlinks,e))return this._readdirInGlobStar(e);if(Po(this.cache,e)){var i=this.cache[e];if(!i||i==="FILE")return null;if(Array.isArray(i))return i}try{return this._readdirEntries(e,this.fs.readdirSync(e))}catch(n){return this._readdirError(e,n),null}};we.prototype._readdirEntries=function(e,t){if(!this.mark&&!this.stat)for(var r=0;r<t.length;r++){var i=t[r];e==="/"?i=e+i:i=e+"/"+i,this.cache[i]=!0}return this.cache[e]=t,t};we.prototype._readdirError=function(e,t){switch(t.code){case"ENOTSUP":case"ENOTDIR":var r=this._makeAbs(e);if(this.cache[r]="FILE",r===this.cwdAbs){var i=new Error(t.code+" invalid cwd "+this.cwd);throw i.path=this.cwd,i.code=t.code,i}break;case"ENOENT":case"ELOOP":case"ENAMETOOLONG":case"UNKNOWN":this.cache[this._makeAbs(e)]=!1;break;default:if(this.cache[this._makeAbs(e)]=!1,this.strict)throw t;this.silent||console.error("glob error",t);break}};we.prototype._processGlobStar=function(e,t,r,i,n,s){var o=this._readdir(r,s);if(o){var u=i.slice(1),l=e?[e]:[],d=l.concat(u);this._process(d,n,!1);var p=o.length,m=this.symlinks[r];if(!(m&&s))for(var g=0;g<p;g++){var y=o[g];if(!(y.charAt(0)==="."&&!this.dot)){var b=l.concat(o[g],u);this._process(b,n,!0);var A=l.concat(o[g],i);this._process(A,n,!0)}}}};we.prototype._processSimple=function(e,t){var r=this._stat(e);if(this.matches[t]||(this.matches[t]=Object.create(null)),!!r){if(e&&Zn(e)&&!this.nomount){var i=/[\/\\]$/.test(e);e.charAt(0)==="/"?e=Co.join(this.root,e):(e=Co.resolve(this.root,e),i&&(e+="/"))}process.platform==="win32"&&(e=e.replace(/\\/g,"/")),this._emitMatch(t,e)}};we.prototype._stat=function(e){var t=this._makeAbs(e),r=e.slice(-1)==="/";if(e.length>this.maxLength)return!1;if(!this.stat&&Po(this.cache,t)){var o=this.cache[t];if(Array.isArray(o)&&(o="DIR"),!r||o==="DIR")return o;if(r&&o==="FILE")return!1}var i,n=this.statCache[t];if(!n){var s;try{s=this.fs.lstatSync(t)}catch(u){if(u&&(u.code==="ENOENT"||u.code==="ENOTDIR"))return this.statCache[t]=!1,!1}if(s&&s.isSymbolicLink())try{n=this.fs.statSync(t)}catch{n=s}else n=s}this.statCache[t]=n;var o=!0;return n&&(o=n.isDirectory()?"DIR":"FILE"),this.cache[t]=this.cache[t]||o,r&&o==="FILE"?!1:o};we.prototype._mark=function(e){return Ht.mark(this,e)};we.prototype._makeAbs=function(e){return Ht.makeAbs(this,e)}});var No=L((jx,Tp)=>{Tp.exports=$t;var JE=Zr(),Op=Mr(),qx=Op.Minimatch,e1=Me(),t1=D("events").EventEmitter,qo=D("path"),Fo=D("assert"),pi=D("path").isAbsolute,ko=Ep(),Zt=Do(),r1=Zt.setopts,jo=Zt.ownProp,Bo=Ss(),Fx=D("util"),i1=Zt.childrenIgnored,n1=Zt.isIgnored,a1=Yr();function $t(e,t,r){if(typeof t=="function"&&(r=t,t={}),t||(t={}),t.sync){if(r)throw new TypeError("callback provided to sync glob");return ko(e,t)}return new le(e,t,r)}a($t,"glob");$t.sync=ko;var s1=$t.GlobSync=ko.GlobSync;$t.glob=$t;function o1(e,t){if(t===null||typeof t!="object")return e;for(var r=Object.keys(t),i=r.length;i--;)e[r[i]]=t[r[i]];return e}a(o1,"extend");$t.hasMagic=function(e,t){var r=o1({},t);r.noprocess=!0;var i=new le(e,r),n=i.minimatch.set;if(!e)return!1;if(n.length>1)return!0;for(var s=0;s<n[0].length;s++)if(typeof n[0][s]!="string")return!0;return!1};$t.Glob=le;e1(le,t1);function le(e,t,r){if(typeof t=="function"&&(r=t,t=null),t&&t.sync){if(r)throw new TypeError("callback provided to sync glob");return new s1(e,t)}if(!(this instanceof le))return new le(e,t,r);r1(this,e,t),this._didRealPath=!1;var i=this.minimatch.set.length;this.matches=new Array(i),typeof r=="function"&&(r=a1(r),this.on("error",r),this.on("end",function(l){r(null,l)}));var n=this;if(this._processing=0,this._emitQueue=[],this._processQueue=[],this.paused=!1,this.noprocess)return this;if(i===0)return u();for(var s=!0,o=0;o<i;o++)this._process(this.minimatch.set[o],o,!1,u);s=!1;function u(){--n._processing,n._processing<=0&&(s?process.nextTick(function(){n._finish()}):n._finish())}a(u,"done")}a(le,"Glob");le.prototype._finish=function(){if(Fo(this instanceof le),!this.aborted){if(this.realpath&&!this._didRealpath)return this._realpath();Zt.finish(this),this.emit("end",this.found)}};le.prototype._realpath=function(){if(this._didRealpath)return;this._didRealpath=!0;var e=this.matches.length;if(e===0)return this._finish();for(var t=this,r=0;r<this.matches.length;r++)this._realpathSet(r,i);function i(){--e===0&&t._finish()}a(i,"next")};le.prototype._realpathSet=function(e,t){var r=this.matches[e];if(!r)return t();var i=Object.keys(r),n=this,s=i.length;if(s===0)return t();var o=this.matches[e]=Object.create(null);i.forEach(function(u,l){u=n._makeAbs(u),JE.realpath(u,n.realpathCache,function(d,p){d?d.syscall==="stat"?o[u]=!0:n.emit("error",d):o[p]=!0,--s===0&&(n.matches[e]=o,t())})})};le.prototype._mark=function(e){return Zt.mark(this,e)};le.prototype._makeAbs=function(e){return Zt.makeAbs(this,e)};le.prototype.abort=function(){this.aborted=!0,this.emit("abort")};le.prototype.pause=function(){this.paused||(this.paused=!0,this.emit("pause"))};le.prototype.resume=function(){if(this.paused){if(this.emit("resume"),this.paused=!1,this._emitQueue.length){var e=this._emitQueue.slice(0);this._emitQueue.length=0;for(var t=0;t<e.length;t++){var r=e[t];this._emitMatch(r[0],r[1])}}if(this._processQueue.length){var i=this._processQueue.slice(0);this._processQueue.length=0;for(var t=0;t<i.length;t++){var n=i[t];this._processing--,this._process(n[0],n[1],n[2],n[3])}}}};le.prototype._process=function(e,t,r,i){if(Fo(this instanceof le),Fo(typeof i=="function"),!this.aborted){if(this._processing++,this.paused){this._processQueue.push([e,t,r,i]);return}for(var n=0;typeof e[n]=="string";)n++;var s;switch(n){case e.length:this._processSimple(e.join("/"),t,i);return;case 0:s=null;break;default:s=e.slice(0,n).join("/");break}var o=e.slice(n),u;s===null?u=".":((pi(s)||pi(e.map(function(p){return typeof p=="string"?p:"[*]"}).join("/")))&&(!s||!pi(s))&&(s="/"+s),u=s);var l=this._makeAbs(u);if(i1(this,u))return i();var d=o[0]===Op.GLOBSTAR;d?this._processGlobStar(s,u,l,o,t,r,i):this._processReaddir(s,u,l,o,t,r,i)}};le.prototype._processReaddir=function(e,t,r,i,n,s,o){var u=this;this._readdir(r,s,function(l,d){return u._processReaddir2(e,t,r,i,n,s,d,o)})};le.prototype._processReaddir2=function(e,t,r,i,n,s,o,u){if(!o)return u();for(var l=i[0],d=!!this.minimatch.negate,p=l._glob,m=this.dot||p.charAt(0)===".",g=[],y=0;y<o.length;y++){var b=o[y];if(b.charAt(0)!=="."||m){var A;d&&!e?A=!b.match(l):A=b.match(l),A&&g.push(b)}}var E=g.length;if(E===0)return u();if(i.length===1&&!this.mark&&!this.stat){this.matches[n]||(this.matches[n]=Object.create(null));for(var y=0;y<E;y++){var b=g[y];e&&(e!=="/"?b=e+"/"+b:b=e+b),b.charAt(0)==="/"&&!this.nomount&&(b=qo.join(this.root,b)),this._emitMatch(n,b)}return u()}i.shift();for(var y=0;y<E;y++){var b=g[y],x;e&&(e!=="/"?b=e+"/"+b:b=e+b),this._process([b].concat(i),n,s,u)}u()};le.prototype._emitMatch=function(e,t){if(!this.aborted&&!n1(this,t)){if(this.paused){this._emitQueue.push([e,t]);return}var r=pi(t)?t:this._makeAbs(t);if(this.mark&&(t=this._mark(t)),this.absolute&&(t=r),!this.matches[e][t]){if(this.nodir){var i=this.cache[r];if(i==="DIR"||Array.isArray(i))return}this.matches[e][t]=!0;var n=this.statCache[r];n&&this.emit("stat",t,n),this.emit("match",t)}}};le.prototype._readdirInGlobStar=function(e,t){if(this.aborted)return;if(this.follow)return this._readdir(e,!1,t);var r="lstat\0"+e,i=this,n=Bo(r,s);n&&i.fs.lstat(e,n);function s(o,u){if(o&&o.code==="ENOENT")return t();var l=u&&u.isSymbolicLink();i.symlinks[e]=l,!l&&u&&!u.isDirectory()?(i.cache[e]="FILE",t()):i._readdir(e,!1,t)}a(s,"lstatcb_")};le.prototype._readdir=function(e,t,r){if(!this.aborted&&(r=Bo("readdir\0"+e+"\0"+t,r),!!r)){if(t&&!jo(this.symlinks,e))return this._readdirInGlobStar(e,r);if(jo(this.cache,e)){var i=this.cache[e];if(!i||i==="FILE")return r();if(Array.isArray(i))return r(null,i)}var n=this;n.fs.readdir(e,u1(this,e,r))}};function u1(e,t,r){return function(i,n){i?e._readdirError(t,i,r):e._readdirEntries(t,n,r)}}a(u1,"readdirCb");le.prototype._readdirEntries=function(e,t,r){if(!this.aborted){if(!this.mark&&!this.stat)for(var i=0;i<t.length;i++){var n=t[i];e==="/"?n=e+n:n=e+"/"+n,this.cache[n]=!0}return this.cache[e]=t,r(null,t)}};le.prototype._readdirError=function(e,t,r){if(!this.aborted){switch(t.code){case"ENOTSUP":case"ENOTDIR":var i=this._makeAbs(e);if(this.cache[i]="FILE",i===this.cwdAbs){var n=new Error(t.code+" invalid cwd "+this.cwd);n.path=this.cwd,n.code=t.code,this.emit("error",n),this.abort()}break;case"ENOENT":case"ELOOP":case"ENAMETOOLONG":case"UNKNOWN":this.cache[this._makeAbs(e)]=!1;break;default:this.cache[this._makeAbs(e)]=!1,this.strict&&(this.emit("error",t),this.abort()),this.silent||console.error("glob error",t);break}return r()}};le.prototype._processGlobStar=function(e,t,r,i,n,s,o){var u=this;this._readdir(r,s,function(l,d){u._processGlobStar2(e,t,r,i,n,s,d,o)})};le.prototype._processGlobStar2=function(e,t,r,i,n,s,o,u){if(!o)return u();var l=i.slice(1),d=e?[e]:[],p=d.concat(l);this._process(p,n,!1,u);var m=this.symlinks[r],g=o.length;if(m&&s)return u();for(var y=0;y<g;y++){var b=o[y];if(!(b.charAt(0)==="."&&!this.dot)){var A=d.concat(o[y],l);this._process(A,n,!0,u);var E=d.concat(o[y],i);this._process(E,n,!0,u)}}u()};le.prototype._processSimple=function(e,t,r){var i=this;this._stat(e,function(n,s){i._processSimple2(e,t,n,s,r)})};le.prototype._processSimple2=function(e,t,r,i,n){if(this.matches[t]||(this.matches[t]=Object.create(null)),!i)return n();if(e&&pi(e)&&!this.nomount){var s=/[\/\\]$/.test(e);e.charAt(0)==="/"?e=qo.join(this.root,e):(e=qo.resolve(this.root,e),s&&(e+="/"))}process.platform==="win32"&&(e=e.replace(/\\/g,"/")),this._emitMatch(t,e),n()};le.prototype._stat=function(e,t){var r=this._makeAbs(e),i=e.slice(-1)==="/";if(e.length>this.maxLength)return t();if(!this.stat&&jo(this.cache,r)){var n=this.cache[r];if(Array.isArray(n)&&(n="DIR"),!i||n==="DIR")return t(null,n);if(i&&n==="FILE")return t()}var s,o=this.statCache[r];if(o!==void 0){if(o===!1)return t(null,o);var u=o.isDirectory()?"DIR":"FILE";return i&&u==="FILE"?t():t(null,u,o)}var l=this,d=Bo("stat\0"+r,p);d&&l.fs.lstat(r,d);function p(m,g){if(g&&g.isSymbolicLink())return l.fs.stat(r,function(y,b){y?l._stat2(e,r,null,g,t):l._stat2(e,r,y,b,t)});l._stat2(e,r,m,g,t)}a(p,"lstatcb_")};le.prototype._stat2=function(e,t,r,i,n){if(r&&(r.code==="ENOENT"||r.code==="ENOTDIR"))return this.statCache[t]=!1,n();var s=e.slice(-1)==="/";if(this.statCache[t]=i,t.slice(-1)==="/"&&i&&!i.isDirectory())return n(null,!1,i);var o=!0;return i&&(o=i.isDirectory()?"DIR":"FILE"),this.cache[t]=this.cache[t]||o,s&&o==="FILE"?n():n(null,o,i)}});var p1=L(()=>{process.on("unhandledRejection",e=>{throw e});var Vn=D("path"),Qn=D("fs/promises"),f1=D("fs"),l1=gp(),h1=No(),Uo=process.argv.slice(2),Ip=Uo[0],xp=Uo[1],Lp=Uo[2],Rp=Lp*1024*1024,c1={dot:!0,nodir:!0,follow:!0,cwd:Ip},Ap=h1.sync("**",c1);d1().catch(()=>{process.exit(1)});function d1(){return new Promise(async(e,t)=>{let r,i,n,s=[];async function o(){let l=s.length,d=Vn.join(xp,`part${l}.zip`);await Qn.mkdir(Vn.dirname(d),{recursive:!0}),r=f1.createWriteStream(d),i=l1("zip"),n=0,s.push({output:r,archive:i,isOutputClosed:!1}),i.on("warning",t),i.on("error",t),r.once("close",()=>{s[l].isOutputClosed=!0,s.every(({isOutputClosed:p})=>p)&&e()}),i.pipe(r)}a(o,"openZip"),await o();for(let l of Ap){let d=Vn.join(Ip,l),[p,m]=await Promise.all([Qn.readFile(d),Qn.stat(d)]),g=m.size;if(g>Rp)throw new Error(`Cannot package file "${d}". The file is larger than ${Lp}MB.`);n+g>Rp&&(await i.finalize(),await o()),i.append(p,{name:l,date:new Date("1980-01-01T00:00:00.000Z"),mode:m.mode}),n+=g}await i.finalize();let u=Vn.join(xp,"filenames");await Qn.writeFile(u,Ap.join(`
20
20
  `))})}a(d1,"generateZips")});export default p1();
21
21
  /*! Bundled license information:
22
22
 
@@ -0,0 +1,549 @@
1
+ "use strict";
2
+
3
+ const aws = require("aws-sdk");
4
+
5
+ const defaultSleep = function (ms) {
6
+ return new Promise((resolve) => setTimeout(resolve, ms));
7
+ };
8
+
9
+ // These are used for test purposes only
10
+ let defaultResponseURL;
11
+ let waiter;
12
+ let sleep = defaultSleep;
13
+ let random = Math.random;
14
+ let maxAttempts = 10;
15
+
16
+ /**
17
+ * Upload a CloudFormation response object to S3.
18
+ *
19
+ * @param {object} event the Lambda event payload received by the handler function
20
+ * @param {object} context the Lambda context received by the handler function
21
+ * @param {string} responseStatus the response status, either 'SUCCESS' or 'FAILED'
22
+ * @param {string} physicalResourceId CloudFormation physical resource ID
23
+ * @param {object} [responseData] arbitrary response data object
24
+ * @param {string} [reason] reason for failure, if any, to convey to the user
25
+ * @returns {Promise} Promise that is resolved on success, or rejected on connection error or HTTP error response
26
+ */
27
+ let report = function (
28
+ event,
29
+ context,
30
+ responseStatus,
31
+ physicalResourceId,
32
+ responseData,
33
+ reason
34
+ ) {
35
+ return new Promise((resolve, reject) => {
36
+ const https = require("https");
37
+ const { URL } = require("url");
38
+
39
+ var responseBody = JSON.stringify({
40
+ Status: responseStatus,
41
+ Reason: reason,
42
+ PhysicalResourceId: physicalResourceId || context.logStreamName,
43
+ StackId: event.StackId,
44
+ RequestId: event.RequestId,
45
+ LogicalResourceId: event.LogicalResourceId,
46
+ Data: responseData,
47
+ });
48
+
49
+ const parsedUrl = new URL(event.ResponseURL || defaultResponseURL);
50
+ const options = {
51
+ hostname: parsedUrl.hostname,
52
+ port: 443,
53
+ path: parsedUrl.pathname + parsedUrl.search,
54
+ method: "PUT",
55
+ headers: {
56
+ "Content-Type": "",
57
+ "Content-Length": responseBody.length,
58
+ },
59
+ };
60
+
61
+ https
62
+ .request(options)
63
+ .on("error", reject)
64
+ .on("response", (res) => {
65
+ res.resume();
66
+ if (res.statusCode >= 400) {
67
+ reject(
68
+ new Error(
69
+ `Server returned error ${res.statusCode}: ${res.statusMessage}`
70
+ )
71
+ );
72
+ } else {
73
+ resolve();
74
+ }
75
+ })
76
+ .end(responseBody, "utf8");
77
+ });
78
+ };
79
+
80
+ /**
81
+ * Adds tags to an existing certificate
82
+ *
83
+ * @param {string} certificateArn the ARN of the certificate to add tags to
84
+ * @param {string} region the region the certificate exists in
85
+ * @param {map} tags Tags to add to the requested certificate
86
+ */
87
+ const addTags = async function (certificateArn, region, tags) {
88
+ const result = Array.from(Object.entries(tags)).map(([Key, Value]) => ({
89
+ Key,
90
+ Value,
91
+ }));
92
+ const acm = new aws.ACM({ region });
93
+
94
+ await acm
95
+ .addTagsToCertificate({
96
+ CertificateArn: certificateArn,
97
+ Tags: result,
98
+ })
99
+ .promise();
100
+ };
101
+
102
+ /**
103
+ * Requests a public certificate from AWS Certificate Manager, using DNS validation.
104
+ * The hosted zone ID must refer to a **public** Route53-managed DNS zone that is authoritative
105
+ * for the suffix of the certificate's Common Name (CN). For example, if the CN is
106
+ * `*.example.com`, the hosted zone ID must point to a Route 53 zone authoritative
107
+ * for `example.com`.
108
+ *
109
+ * @param {string} requestId the CloudFormation request ID
110
+ * @param {string} domainName the Common Name (CN) field for the requested certificate
111
+ * @param {string} hostedZoneId the Route53 Hosted Zone ID
112
+ * @returns {string} Validated certificate ARN
113
+ */
114
+ const requestCertificate = async function (
115
+ requestId,
116
+ domainName,
117
+ subjectAlternativeNames,
118
+ certificateTransparencyLoggingPreference,
119
+ hostedZoneId,
120
+ region,
121
+ route53Endpoint
122
+ ) {
123
+ const crypto = require("crypto");
124
+ const acm = new aws.ACM({ region });
125
+ const route53 = route53Endpoint
126
+ ? new aws.Route53({ endpoint: route53Endpoint })
127
+ : new aws.Route53();
128
+ if (waiter) {
129
+ // Used by the test suite, since waiters aren't mockable yet
130
+ route53.waitFor = acm.waitFor = waiter;
131
+ }
132
+
133
+ console.log(`Requesting certificate for ${domainName}`);
134
+
135
+ const reqCertResponse = await acm
136
+ .requestCertificate({
137
+ DomainName: domainName,
138
+ SubjectAlternativeNames: subjectAlternativeNames,
139
+ Options: {
140
+ CertificateTransparencyLoggingPreference:
141
+ certificateTransparencyLoggingPreference,
142
+ },
143
+ IdempotencyToken: crypto
144
+ .createHash("sha256")
145
+ .update(requestId)
146
+ .digest("hex")
147
+ .slice(0, 32),
148
+ ValidationMethod: "DNS",
149
+ })
150
+ .promise();
151
+
152
+ console.log(`Certificate ARN: ${reqCertResponse.CertificateArn}`);
153
+
154
+ console.log("Waiting for ACM to provide DNS records for validation...");
155
+
156
+ let records = [];
157
+ for (let attempt = 0; attempt < maxAttempts && !records.length; attempt++) {
158
+ const { Certificate } = await acm
159
+ .describeCertificate({
160
+ CertificateArn: reqCertResponse.CertificateArn,
161
+ })
162
+ .promise();
163
+
164
+ records = getDomainValidationRecords(Certificate);
165
+ if (!records.length) {
166
+ // Exponential backoff with jitter based on 200ms base
167
+ // component of backoff fixed to ensure minimum total wait time on
168
+ // slow targets.
169
+ const base = Math.pow(2, attempt);
170
+ await sleep(random() * base * 50 + base * 150);
171
+ }
172
+ }
173
+ if (!records.length) {
174
+ throw new Error(
175
+ `Response from describeCertificate did not contain DomainValidationOptions after ${maxAttempts} attempts.`
176
+ );
177
+ }
178
+
179
+ console.log(
180
+ `Upserting ${records.length} DNS records into zone ${hostedZoneId}:`
181
+ );
182
+
183
+ await commitRoute53Records(route53, records, hostedZoneId);
184
+
185
+ console.log("Waiting for validation...");
186
+ await acm
187
+ .waitFor("certificateValidated", {
188
+ // Wait up to 9 minutes and 30 seconds
189
+ $waiter: {
190
+ delay: 30,
191
+ maxAttempts: 19,
192
+ },
193
+ CertificateArn: reqCertResponse.CertificateArn,
194
+ })
195
+ .promise();
196
+
197
+ return reqCertResponse.CertificateArn;
198
+ };
199
+
200
+ /**
201
+ * Deletes a certificate from AWS Certificate Manager (ACM) by its ARN.
202
+ * If the certificate does not exist, the function will return normally.
203
+ *
204
+ * @param {string} arn The certificate ARN
205
+ */
206
+ const deleteCertificate = async function (
207
+ arn,
208
+ region,
209
+ hostedZoneId,
210
+ route53Endpoint,
211
+ cleanupRecords
212
+ ) {
213
+ const acm = new aws.ACM({ region });
214
+ const route53 = route53Endpoint
215
+ ? new aws.Route53({ endpoint: route53Endpoint })
216
+ : new aws.Route53();
217
+ if (waiter) {
218
+ // Used by the test suite, since waiters aren't mockable yet
219
+ route53.waitFor = acm.waitFor = waiter;
220
+ }
221
+
222
+ try {
223
+ console.log(`Waiting for certificate ${arn} to become unused`);
224
+
225
+ let inUseByResources;
226
+ let records = [];
227
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
228
+ const { Certificate } = await acm
229
+ .describeCertificate({
230
+ CertificateArn: arn,
231
+ })
232
+ .promise();
233
+
234
+ if (cleanupRecords) {
235
+ records = getDomainValidationRecords(Certificate);
236
+ }
237
+ inUseByResources = Certificate.InUseBy || [];
238
+
239
+ if (inUseByResources.length || !records.length) {
240
+ // Exponential backoff with jitter based on 200ms base
241
+ // component of backoff fixed to ensure minimum total wait time on
242
+ // slow targets.
243
+ const base = Math.pow(2, attempt);
244
+ await sleep(random() * base * 50 + base * 150);
245
+ } else {
246
+ break;
247
+ }
248
+ }
249
+
250
+ if (inUseByResources.length) {
251
+ throw new Error(
252
+ `Response from describeCertificate did not contain an empty InUseBy list after ${maxAttempts} attempts.`
253
+ );
254
+ }
255
+ if (cleanupRecords && !records.length) {
256
+ throw new Error(
257
+ `Response from describeCertificate did not contain DomainValidationOptions after ${maxAttempts} attempts.`
258
+ );
259
+ }
260
+
261
+ console.log(`Deleting certificate ${arn}`);
262
+
263
+ await acm
264
+ .deleteCertificate({
265
+ CertificateArn: arn,
266
+ })
267
+ .promise();
268
+
269
+ if (cleanupRecords) {
270
+ console.log(
271
+ `Deleting ${records.length} DNS records from zone ${hostedZoneId}:`
272
+ );
273
+
274
+ await commitRoute53Records(route53, records, hostedZoneId, "DELETE");
275
+ }
276
+ } catch (err) {
277
+ if (err.name !== "ResourceNotFoundException") {
278
+ throw err;
279
+ }
280
+ }
281
+ };
282
+
283
+ /**
284
+ * Retrieve the unique domain validation options as records to be upserted (or deleted) from Route53.
285
+ *
286
+ * Returns an empty array ([]) if the domain validation options is empty or the records are not yet ready.
287
+ */
288
+ function getDomainValidationRecords(certificate) {
289
+ const options = certificate.DomainValidationOptions || [];
290
+ // Ensure all records are ready; there is (at least a theory there's) a chance of a partial response here in rare cases.
291
+ if (
292
+ options.length > 0 &&
293
+ options.every((opt) => opt && !!opt.ResourceRecord)
294
+ ) {
295
+ // some alternative names will produce the same validation record
296
+ // as the main domain (eg. example.com + *.example.com)
297
+ // filtering duplicates to avoid errors with adding the same record
298
+ // to the route53 zone twice
299
+ const unique = options
300
+ .map((val) => val.ResourceRecord)
301
+ .reduce((acc, cur) => {
302
+ acc[cur.Name] = cur;
303
+ return acc;
304
+ }, {});
305
+ return Object.keys(unique)
306
+ .sort()
307
+ .map((key) => unique[key]);
308
+ }
309
+ return [];
310
+ }
311
+
312
+ /**
313
+ * Execute Route53 ChangeResourceRecordSets for a set of records within a Hosted Zone,
314
+ * and wait for the records to commit. Defaults to an 'UPSERT' action.
315
+ */
316
+ async function commitRoute53Records(
317
+ route53,
318
+ records,
319
+ hostedZoneId,
320
+ action = "UPSERT"
321
+ ) {
322
+ const changeBatch = await route53
323
+ .changeResourceRecordSets({
324
+ ChangeBatch: {
325
+ Changes: records.map((record) => {
326
+ console.log(`${record.Name} ${record.Type} ${record.Value}`);
327
+ return {
328
+ Action: action,
329
+ ResourceRecordSet: {
330
+ Name: record.Name,
331
+ Type: record.Type,
332
+ TTL: 60,
333
+ ResourceRecords: [
334
+ {
335
+ Value: record.Value,
336
+ },
337
+ ],
338
+ },
339
+ };
340
+ }),
341
+ },
342
+ HostedZoneId: hostedZoneId,
343
+ })
344
+ .promise();
345
+
346
+ console.log("Waiting for DNS records to commit...");
347
+ await route53
348
+ .waitFor("resourceRecordSetsChanged", {
349
+ // Wait up to 5 minutes
350
+ $waiter: {
351
+ delay: 30,
352
+ maxAttempts: 10,
353
+ },
354
+ Id: changeBatch.ChangeInfo.Id,
355
+ })
356
+ .promise();
357
+ }
358
+
359
+ /**
360
+ * Determines whether an update request should request a new certificate
361
+ *
362
+ * @param {map} oldParams the previously process request parameters
363
+ * @param {map} newParams the current process request parameters
364
+ * @param {string} physicalResourceId the physicalResourceId
365
+ * @returns {boolean} whether or not to request a new certificate
366
+ */
367
+ function shouldUpdate(oldParams, newParams, physicalResourceId) {
368
+ if (!oldParams) return true;
369
+ if (oldParams.DomainName !== newParams.DomainName) return true;
370
+ if (oldParams.SubjectAlternativeNames !== newParams.SubjectAlternativeNames)
371
+ return true;
372
+ if (
373
+ oldParams.CertificateTransparencyLoggingPreference !==
374
+ newParams.CertificateTransparencyLoggingPreference
375
+ )
376
+ return true;
377
+ if (oldParams.HostedZoneId !== newParams.HostedZoneId) return true;
378
+ if (oldParams.Region !== newParams.Region) return true;
379
+ if (!physicalResourceId || !physicalResourceId.startsWith("arn:"))
380
+ return true;
381
+ return false;
382
+ }
383
+
384
+ /**
385
+ * Main handler, invoked by Lambda
386
+ */
387
+ exports.certificateRequestHandler = async function (event, context) {
388
+ var responseData = {};
389
+ var physicalResourceId;
390
+ var certificateArn;
391
+ async function processRequest() {
392
+ certificateArn = await requestCertificate(
393
+ event.RequestId,
394
+ event.ResourceProperties.DomainName,
395
+ event.ResourceProperties.SubjectAlternativeNames,
396
+ event.ResourceProperties.CertificateTransparencyLoggingPreference,
397
+ event.ResourceProperties.HostedZoneId,
398
+ event.ResourceProperties.Region,
399
+ event.ResourceProperties.Route53Endpoint
400
+ );
401
+ responseData.Arn = physicalResourceId = certificateArn;
402
+ }
403
+
404
+ try {
405
+ switch (event.RequestType) {
406
+ case "Create":
407
+ await processRequest();
408
+ if (
409
+ event.ResourceProperties.Tags &&
410
+ physicalResourceId.startsWith("arn:")
411
+ ) {
412
+ await addTags(
413
+ physicalResourceId,
414
+ event.ResourceProperties.Region,
415
+ event.ResourceProperties.Tags
416
+ );
417
+ }
418
+ break;
419
+ case "Update":
420
+ if (
421
+ shouldUpdate(
422
+ event.OldResourceProperties,
423
+ event.ResourceProperties,
424
+ event.PhysicalResourceId
425
+ )
426
+ ) {
427
+ await processRequest();
428
+ } else {
429
+ responseData.Arn = physicalResourceId = event.PhysicalResourceId;
430
+ }
431
+ if (
432
+ event.ResourceProperties.Tags &&
433
+ physicalResourceId.startsWith("arn:")
434
+ ) {
435
+ await addTags(
436
+ physicalResourceId,
437
+ event.ResourceProperties.Region,
438
+ event.ResourceProperties.Tags
439
+ );
440
+ }
441
+ break;
442
+ case "Delete":
443
+ physicalResourceId = event.PhysicalResourceId;
444
+ const removalPolicy =
445
+ event.ResourceProperties.RemovalPolicy ?? "destroy";
446
+ // If the resource didn't create correctly, the physical resource ID won't be the
447
+ // certificate ARN, so don't try to delete it in that case.
448
+ if (
449
+ physicalResourceId.startsWith("arn:") &&
450
+ removalPolicy === "destroy"
451
+ ) {
452
+ await deleteCertificate(
453
+ physicalResourceId,
454
+ event.ResourceProperties.Region,
455
+ event.ResourceProperties.HostedZoneId,
456
+ event.ResourceProperties.Route53Endpoint,
457
+ event.ResourceProperties.CleanupRecords === "true"
458
+ );
459
+ }
460
+ break;
461
+ default:
462
+ throw new Error(`Unsupported request type ${event.RequestType}`);
463
+ }
464
+
465
+ console.log(`Uploading SUCCESS response to S3...`);
466
+ await report(event, context, "SUCCESS", physicalResourceId, responseData);
467
+ console.log("Done.");
468
+ } catch (err) {
469
+ console.log(`Caught error ${err}. Uploading FAILED message to S3.`);
470
+ await report(
471
+ event,
472
+ context,
473
+ "FAILED",
474
+ physicalResourceId,
475
+ null,
476
+ err.message
477
+ );
478
+ }
479
+ };
480
+
481
+ /**
482
+ * @private
483
+ */
484
+ exports.withReporter = function (reporter) {
485
+ report = reporter;
486
+ };
487
+
488
+ /**
489
+ * @private
490
+ */
491
+ exports.withDefaultResponseURL = function (url) {
492
+ defaultResponseURL = url;
493
+ };
494
+
495
+ /**
496
+ * @private
497
+ */
498
+ exports.withWaiter = function (w) {
499
+ waiter = w;
500
+ };
501
+
502
+ /**
503
+ * @private
504
+ */
505
+ exports.resetWaiter = function () {
506
+ waiter = undefined;
507
+ };
508
+
509
+ /**
510
+ * @private
511
+ */
512
+ exports.withSleep = function (s) {
513
+ sleep = s;
514
+ };
515
+
516
+ /**
517
+ * @private
518
+ */
519
+ exports.resetSleep = function () {
520
+ sleep = defaultSleep;
521
+ };
522
+
523
+ /**
524
+ * @private
525
+ */
526
+ exports.withRandom = function (r) {
527
+ random = r;
528
+ };
529
+
530
+ /**
531
+ * @private
532
+ */
533
+ exports.resetRandom = function () {
534
+ random = Math.random;
535
+ };
536
+
537
+ /**
538
+ * @private
539
+ */
540
+ exports.withMaxAttempts = function (ma) {
541
+ maxAttempts = ma;
542
+ };
543
+
544
+ /**
545
+ * @private
546
+ */
547
+ exports.resetMaxAttempts = function () {
548
+ maxAttempts = 10;
549
+ };