@openhi/constructs 0.0.120 → 0.0.122

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/lib/index.mjs CHANGED
@@ -134,6 +134,16 @@ var require_lib2 = __commonJS({
134
134
  }
135
135
  });
136
136
 
137
+ // src/app/compute-branch-hash.ts
138
+ import { hashString } from "@codedrifters/utils";
139
+ var computeBranchHash = (options) => {
140
+ const { appName, deploymentTargetRole, account, region, branchName } = options;
141
+ return hashString(
142
+ [appName, deploymentTargetRole, account, region, branchName].join("-"),
143
+ 6
144
+ );
145
+ };
146
+
137
147
  // src/app/open-hi-app.ts
138
148
  var import_config2 = __toESM(require_lib2());
139
149
  import { App } from "aws-cdk-lib";
@@ -345,7 +355,7 @@ var import_config3 = __toESM(require_lib2());
345
355
  import {
346
356
  findGitBranch,
347
357
  findGitRepoName,
348
- hashString
358
+ hashString as hashString2
349
359
  } from "@codedrifters/utils";
350
360
  import { RemovalPolicy, Stack, Tags } from "aws-cdk-lib";
351
361
  import { paramCase } from "change-case";
@@ -376,17 +386,18 @@ var OpenHiService = class extends Stack {
376
386
  const repoName = props.repoName ?? findGitRepoName();
377
387
  const defaultReleaseBranch = props.defaultReleaseBranch ?? "main";
378
388
  const branchName = props.branchName ?? (process.env.JEST_WORKER_ID ? "test-branch" : process.env.GIT_BRANCH_NAME?.trim() || (ohEnv.ohStage.stageType === import_config3.OPEN_HI_STAGE.DEV ? findGitBranch() : defaultReleaseBranch));
379
- const environmentHash = hashString(
389
+ const environmentHash = hashString2(
380
390
  [appName, ohEnv.deploymentTargetRole, account, region].join("-"),
381
391
  6
382
392
  );
383
- const branchHash = hashString(
384
- [appName, ohEnv.deploymentTargetRole, account, region, branchName].join(
385
- "-"
386
- ),
387
- 6
388
- );
389
- const releaseBranchHash = hashString(
393
+ const branchHash = computeBranchHash({
394
+ appName,
395
+ deploymentTargetRole: ohEnv.deploymentTargetRole,
396
+ account,
397
+ region,
398
+ branchName
399
+ });
400
+ const releaseBranchHash = hashString2(
390
401
  [
391
402
  appName,
392
403
  ohEnv.deploymentTargetRole,
@@ -396,7 +407,7 @@ var OpenHiService = class extends Stack {
396
407
  ].join("-"),
397
408
  6
398
409
  );
399
- const stackHash = hashString(
410
+ const stackHash = hashString2(
400
411
  [
401
412
  appName,
402
413
  ohEnv.deploymentTargetRole,
@@ -681,7 +692,10 @@ var CognitoUserPoolClient = class extends UserPoolClient {
681
692
  authorizationCodeGrant: true,
682
693
  implicitCodeGrant: true
683
694
  },
684
- callbackUrls: [`https://localhost:3000/oauth/callback`]
695
+ callbackUrls: [
696
+ `http://localhost:3000/oauth/callback`,
697
+ `https://localhost:3000/oauth/callback`
698
+ ]
685
699
  },
686
700
  /**
687
701
  * Overrideable props
@@ -1343,6 +1357,7 @@ var DataStorePostgresReplica = class extends Construct6 {
1343
1357
  this.databaseName = props.databaseName ?? DEFAULT_DATABASE_NAME;
1344
1358
  this.schemaName = getPostgresReplicaSchemaName(props.branchHash);
1345
1359
  const region = Stack3.of(this).region;
1360
+ const ownsVpc = props.vpc === void 0;
1346
1361
  this.vpc = props.vpc ?? new ec2.Vpc(this, "Vpc", {
1347
1362
  availabilityZones: [`${region}a`, `${region}b`],
1348
1363
  natGateways: 0,
@@ -1354,6 +1369,14 @@ var DataStorePostgresReplica = class extends Construct6 {
1354
1369
  }
1355
1370
  ]
1356
1371
  });
1372
+ if (ownsVpc) {
1373
+ new ec2.InterfaceVpcEndpoint(this, "SecretsManagerEndpoint", {
1374
+ vpc: this.vpc,
1375
+ service: ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER,
1376
+ subnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
1377
+ privateDnsEnabled: true
1378
+ });
1379
+ }
1357
1380
  this.cluster = new rds.DatabaseCluster(this, "Cluster", {
1358
1381
  clusterIdentifier: `openhi-dstore-pg-${props.stackHash}`,
1359
1382
  engine: rds.DatabaseClusterEngine.auroraPostgres({
@@ -1504,11 +1527,13 @@ import {
1504
1527
  CacheQueryStringBehavior,
1505
1528
  Distribution,
1506
1529
  LambdaEdgeEventType,
1530
+ OriginProtocolPolicy,
1531
+ OriginRequestPolicy,
1507
1532
  S3OriginAccessControl,
1508
1533
  Signing,
1509
1534
  ViewerProtocolPolicy
1510
1535
  } from "aws-cdk-lib/aws-cloudfront";
1511
- import { S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
1536
+ import { HttpOrigin, S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
1512
1537
  import { Runtime as Runtime6 } from "aws-cdk-lib/aws-lambda";
1513
1538
  import { NodejsFunction as NodejsFunction6 } from "aws-cdk-lib/aws-lambda-nodejs";
1514
1539
  import { LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
@@ -1578,6 +1603,10 @@ var _StaticHosting = class _StaticHosting extends Construct9 {
1578
1603
  originAccessLevels: [AccessLevel.READ]
1579
1604
  });
1580
1605
  const hasCustomDomain = props.certificate !== void 0 && props.hostedZone !== void 0 && props.domainNames !== void 0 && props.domainNames.length > 0;
1606
+ const additionalBehaviors = this.buildRestApiBehaviors(
1607
+ stack.branchHash,
1608
+ props.restApi
1609
+ );
1581
1610
  this.distribution = new Distribution(this, "distribution", {
1582
1611
  comment: `Static hosting distribution for ${props.description ?? id}`,
1583
1612
  ...hasCustomDomain ? {
@@ -1598,6 +1627,7 @@ var _StaticHosting = class _StaticHosting extends Construct9 {
1598
1627
  }
1599
1628
  ]
1600
1629
  },
1630
+ ...additionalBehaviors !== void 0 && { additionalBehaviors },
1601
1631
  ...props.distributionProps
1602
1632
  });
1603
1633
  if (hasCustomDomain) {
@@ -1636,6 +1666,51 @@ var _StaticHosting = class _StaticHosting extends Construct9 {
1636
1666
  description: `Static hosting distribution ID (${props.description ?? id})`
1637
1667
  });
1638
1668
  }
1669
+ /**
1670
+ * Builds the `/api/*` and `/api/control/runtime-config` behaviors backed
1671
+ * by the REST API custom-domain origin. Returns `undefined` when no
1672
+ * `restApi` prop is supplied so the Distribution stays S3-only.
1673
+ */
1674
+ buildRestApiBehaviors(branchHash, restApi) {
1675
+ if (restApi === void 0) {
1676
+ return void 0;
1677
+ }
1678
+ const apiOrigin = new HttpOrigin(restApi.domainName, {
1679
+ protocolPolicy: OriginProtocolPolicy.HTTPS_ONLY
1680
+ });
1681
+ const runtimeConfigCachePolicy = new CachePolicy(
1682
+ this,
1683
+ "runtime-config-cache-policy",
1684
+ {
1685
+ cachePolicyName: `static-hosting-runtime-config-${branchHash}`,
1686
+ comment: "/api/control/runtime-config: cache key includes only `v` so the bundle's deploy-hash bust works automatically.",
1687
+ defaultTtl: restApi.runtimeConfigCacheTtl?.defaultTtl ?? Duration5.minutes(5),
1688
+ minTtl: Duration5.seconds(0),
1689
+ maxTtl: restApi.runtimeConfigCacheTtl?.maxTtl ?? Duration5.hours(1),
1690
+ headerBehavior: CacheHeaderBehavior.none(),
1691
+ queryStringBehavior: CacheQueryStringBehavior.allowList("v"),
1692
+ cookieBehavior: CacheCookieBehavior.none(),
1693
+ enableAcceptEncodingGzip: true,
1694
+ enableAcceptEncodingBrotli: true
1695
+ }
1696
+ );
1697
+ return {
1698
+ "/api/control/runtime-config": {
1699
+ origin: apiOrigin,
1700
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1701
+ allowedMethods: AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
1702
+ cachePolicy: runtimeConfigCachePolicy,
1703
+ originRequestPolicy: OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER
1704
+ },
1705
+ "/api/*": {
1706
+ origin: apiOrigin,
1707
+ viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1708
+ allowedMethods: AllowedMethods.ALLOW_ALL,
1709
+ cachePolicy: CachePolicy.CACHING_DISABLED,
1710
+ originRequestPolicy: OriginRequestPolicy.ALL_VIEWER_EXCEPT_HOST_HEADER
1711
+ }
1712
+ };
1713
+ }
1639
1714
  };
1640
1715
  /**
1641
1716
  * SSM parameter name for the S3 bucket ARN.
@@ -2598,6 +2673,7 @@ import {
2598
2673
  } from "aws-cdk-lib/aws-route53";
2599
2674
  import { ApiGatewayv2DomainProperties } from "aws-cdk-lib/aws-route53-targets";
2600
2675
  import { Duration as Duration10 } from "aws-cdk-lib/core";
2676
+ import { Construct as Construct20 } from "constructs";
2601
2677
 
2602
2678
  // src/data/lambda/cors-options-lambda.ts
2603
2679
  import fs11 from "fs";
@@ -2654,7 +2730,8 @@ var RestApiLambda = class extends Construct19 {
2654
2730
  OPENHI_PG_CLUSTER_ARN: props.postgresClusterArn,
2655
2731
  OPENHI_PG_SECRET_ARN: props.postgresSecretArn,
2656
2732
  OPENHI_PG_DATABASE: props.postgresDatabase,
2657
- OPENHI_PG_SCHEMA: props.postgresSchema
2733
+ OPENHI_PG_SCHEMA: props.postgresSchema,
2734
+ ...props.extraEnvironment
2658
2735
  },
2659
2736
  bundling: {
2660
2737
  minify: true,
@@ -2666,6 +2743,7 @@ var RestApiLambda = class extends Construct19 {
2666
2743
 
2667
2744
  // src/services/open-hi-rest-api-service.ts
2668
2745
  var REST_API_BASE_URL_SSM_NAME = "REST_API_BASE_URL";
2746
+ var REST_API_DOMAIN_NAME_SSM_NAME = "REST_API_DOMAIN_NAME";
2669
2747
  var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2670
2748
  /**
2671
2749
  * Returns an IHttpApi by looking up the REST API stack's HTTP API ID from SSM.
@@ -2687,6 +2765,18 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2687
2765
  serviceType: _OpenHiRestApiService.SERVICE_TYPE
2688
2766
  });
2689
2767
  }
2768
+ /**
2769
+ * Returns the REST API's custom domain name (bare hostname, no scheme — e.g.
2770
+ * `api.example.com`) by looking it up from SSM. Use as the host for a
2771
+ * CloudFront `HttpOrigin` so the website's distribution can proxy `/api/*`
2772
+ * to this stack's API Gateway without per-branch DNS knowledge.
2773
+ */
2774
+ static restApiDomainNameFromConstruct(scope) {
2775
+ return DiscoverableStringParameter.valueForLookupName(scope, {
2776
+ ssmParamName: REST_API_DOMAIN_NAME_SSM_NAME,
2777
+ serviceType: _OpenHiRestApiService.SERVICE_TYPE
2778
+ });
2779
+ }
2690
2780
  get serviceType() {
2691
2781
  return _OpenHiRestApiService.SERVICE_TYPE;
2692
2782
  }
@@ -2698,6 +2788,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2698
2788
  const certificate = this.createCertificate();
2699
2789
  const apiDomainName = this.createApiDomainNameString(hostedZone);
2700
2790
  this.createRestApiBaseUrlParameter(apiDomainName);
2791
+ this.createRestApiDomainNameParameter(apiDomainName);
2701
2792
  const domainName = this.createDomainName(hostedZone, certificate);
2702
2793
  this.rootHttpApi = this.createRootHttpApi(domainName);
2703
2794
  this.createRestApiLambdaAndRoutes(hostedZone, domainName);
@@ -2756,6 +2847,20 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2756
2847
  description: "REST API base URL for this deployment (E2E, scripts)"
2757
2848
  });
2758
2849
  }
2850
+ /**
2851
+ * Creates the SSM parameter exposing the REST API's custom domain (bare
2852
+ * hostname, no scheme). Consumed by the website service as the CloudFront
2853
+ * `/api/*` origin host.
2854
+ * Look up via {@link OpenHiRestApiService.restApiDomainNameFromConstruct}.
2855
+ * Override to customize.
2856
+ */
2857
+ createRestApiDomainNameParameter(apiDomainName) {
2858
+ new DiscoverableStringParameter(this, "rest-api-domain-name-param", {
2859
+ ssmParamName: REST_API_DOMAIN_NAME_SSM_NAME,
2860
+ stringValue: apiDomainName,
2861
+ description: "REST API custom domain name (bare hostname) for cross-stack CloudFront origin lookup"
2862
+ });
2863
+ }
2759
2864
  /**
2760
2865
  * Creates the API Gateway custom domain name resource.
2761
2866
  * Override to customize.
@@ -2777,6 +2882,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2777
2882
  const postgresSecretArn = DataStorePostgresReplica.secretArnFromConstruct(this);
2778
2883
  const postgresDatabase = DataStorePostgresReplica.databaseNameFromConstruct(this);
2779
2884
  const postgresSchema = getPostgresReplicaSchemaName(this.branchHash);
2885
+ const extraEnvironment = this.resolveRuntimeConfigEnvVars();
2780
2886
  const { lambda } = new RestApiLambda(this, {
2781
2887
  dynamoTableName: dataStoreTable.tableName,
2782
2888
  branchTagValue: this.branchName,
@@ -2784,7 +2890,8 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2784
2890
  postgresClusterArn,
2785
2891
  postgresSecretArn,
2786
2892
  postgresDatabase,
2787
- postgresSchema
2893
+ postgresSchema,
2894
+ ...extraEnvironment !== void 0 && { extraEnvironment }
2788
2895
  });
2789
2896
  lambda.addToRolePolicy(
2790
2897
  new PolicyStatement7({
@@ -2925,6 +3032,32 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
2925
3032
  });
2926
3033
  return rootHttpApi;
2927
3034
  }
3035
+ /**
3036
+ * Builds the `OPENHI_RUNTIME_CONFIG_*` env-var map the REST API Lambda
3037
+ * exposes through `GET /control/runtime-config`. Returns `undefined` when
3038
+ * the `runtimeConfig` prop is omitted so no env vars are set.
3039
+ *
3040
+ * The three Cognito IDs are resolved via SSM lookups against the auth
3041
+ * stack from a dedicated sub-scope (`runtime-config`) so they don't
3042
+ * collide with the user-pool / user-pool-client constructs already
3043
+ * created in {@link createRootHttpApi}.
3044
+ */
3045
+ resolveRuntimeConfigEnvVars() {
3046
+ if (this.props.runtimeConfig === void 0) {
3047
+ return void 0;
3048
+ }
3049
+ const cognitoScope = new Construct20(this, "runtime-config");
3050
+ const userPool = OpenHiAuthService.userPoolFromConstruct(cognitoScope);
3051
+ const userPoolClient = OpenHiAuthService.userPoolClientFromConstruct(cognitoScope);
3052
+ const userPoolDomain = OpenHiAuthService.userPoolDomainFromConstruct(cognitoScope);
3053
+ return {
3054
+ OPENHI_RUNTIME_CONFIG_COGNITO_USER_POOL_ID: userPool.userPoolId,
3055
+ OPENHI_RUNTIME_CONFIG_COGNITO_USER_POOL_CLIENT_ID: userPoolClient.userPoolClientId,
3056
+ OPENHI_RUNTIME_CONFIG_COGNITO_DOMAIN: userPoolDomain.domainName,
3057
+ OPENHI_RUNTIME_CONFIG_COGNITO_REDIRECT_URI: this.props.runtimeConfig.cognitoRedirectUri,
3058
+ OPENHI_RUNTIME_CONFIG_API_BASE_URL: this.props.runtimeConfig.apiBaseUrl
3059
+ };
3060
+ }
2928
3061
  };
2929
3062
  _OpenHiRestApiService.SERVICE_TYPE = "rest-api";
2930
3063
  var OpenHiRestApiService = _OpenHiRestApiService;
@@ -3042,7 +3175,8 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
3042
3175
  this.createFullDomainParameter();
3043
3176
  }
3044
3177
  if (props.createStaticContent !== false) {
3045
- this.staticContent = this.createStaticContent();
3178
+ const bucket = this.resolveStaticHostingBucket();
3179
+ this.staticContent = this.createStaticContent(bucket);
3046
3180
  }
3047
3181
  }
3048
3182
  /**
@@ -3093,14 +3227,26 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
3093
3227
  * Lambda@Edge + 4 SSM params + DNS).
3094
3228
  */
3095
3229
  createStaticHosting(deps) {
3230
+ const restApi = this.props.restApi === true ? this.resolveRestApi() : void 0;
3096
3231
  return new StaticHosting(this, "static-hosting", {
3097
3232
  serviceType: _OpenHiWebsiteService.SERVICE_TYPE,
3098
3233
  certificate: deps.certificate,
3099
3234
  hostedZone: deps.hostedZone,
3100
3235
  domainNames: [this.fullDomain],
3101
- description: `OpenHI website (${this.fullDomain})`
3236
+ description: `OpenHI website (${this.fullDomain})`,
3237
+ ...restApi !== void 0 && { restApi }
3102
3238
  });
3103
3239
  }
3240
+ /**
3241
+ * Resolves the REST API custom-domain hostname from the rest-api stack's
3242
+ * `REST_API_DOMAIN_NAME` SSM parameter. Wrapped in a private method so
3243
+ * it can be overridden / stubbed in subclasses and tests.
3244
+ */
3245
+ resolveRestApi() {
3246
+ return {
3247
+ domainName: OpenHiRestApiService.restApiDomainNameFromConstruct(this)
3248
+ };
3249
+ }
3104
3250
  /**
3105
3251
  * Creates the SSM parameter that publishes the website's full domain.
3106
3252
  * Look up via {@link OpenHiWebsiteService.fullDomainFromConstruct}.
@@ -3114,21 +3260,18 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
3114
3260
  });
3115
3261
  }
3116
3262
  /**
3117
- * Creates the StaticContent uploader. Always created so feature-branch
3118
- * deploys can publish content to their own sub-domain folder against the
3119
- * release-branch bucket.
3120
- *
3121
- * The destination bucket is resolved here so the construct never has to
3122
- * branch on release-vs-feature: on the release branch we pass the
3123
- * just-created {@link staticHosting} bucket directly (no SSM round-trip
3124
- * within a single stack); on every other branch we look up the bucket
3125
- * ARN published by the release-branch deploy, addressed against
3126
- * {@link OpenHiService.releaseBranchHash}.
3127
- */
3128
- createStaticContent() {
3263
+ * Creates the StaticContent uploader. Receives the resolved static-hosting
3264
+ * bucket from the constructor on the release-branch deploy this is the
3265
+ * just-created {@link staticHosting} bucket (no SSM round-trip within a
3266
+ * single stack); on every other deploy it is imported from the bucket ARN
3267
+ * the release-branch deploy publishes to SSM, addressed against
3268
+ * {@link OpenHiService.releaseBranchHash}. See
3269
+ * {@link resolveStaticHostingBucket}.
3270
+ */
3271
+ createStaticContent(bucket) {
3129
3272
  const { contentSourceDirectory, contentDestinationDirectory } = this.props;
3130
3273
  return new StaticContent(this, "static-content", {
3131
- bucket: this.resolveStaticHostingBucket(),
3274
+ bucket,
3132
3275
  contentSourceDirectory,
3133
3276
  contentDestinationDirectory,
3134
3277
  fullDomain: this.fullDomain
@@ -3136,7 +3279,7 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
3136
3279
  }
3137
3280
  /**
3138
3281
  * Returns an {@link IBucket} pointing at the static-hosting bucket the
3139
- * uploader writes to. On the release-branch deploy this is the bucket
3282
+ * uploaders write to. On the release-branch deploy this is the bucket
3140
3283
  * just provisioned by {@link staticHosting}; on every other deploy it's
3141
3284
  * imported from the bucket ARN the release-branch deploy publishes to
3142
3285
  * SSM, addressed against {@link OpenHiService.releaseBranchHash}.
@@ -3163,7 +3306,7 @@ import { Duration as Duration11 } from "aws-cdk-lib";
3163
3306
  import { Effect as Effect8, PolicyStatement as PolicyStatement8 } from "aws-cdk-lib/aws-iam";
3164
3307
  import { Runtime as Runtime13 } from "aws-cdk-lib/aws-lambda";
3165
3308
  import { NodejsFunction as NodejsFunction13 } from "aws-cdk-lib/aws-lambda-nodejs";
3166
- import { Construct as Construct20 } from "constructs";
3309
+ import { Construct as Construct21 } from "constructs";
3167
3310
  function resolveHandlerEntry12(dirname, handlerName) {
3168
3311
  const sameDir = path13.join(dirname, handlerName);
3169
3312
  if (fs13.existsSync(sameDir)) {
@@ -3172,7 +3315,7 @@ function resolveHandlerEntry12(dirname, handlerName) {
3172
3315
  const libDir = path13.join(dirname, "..", "..", "..", "..", "lib", handlerName);
3173
3316
  return { entry: libDir, handler: "handler" };
3174
3317
  }
3175
- var OwningDeleteCascadeLambdas = class extends Construct20 {
3318
+ var OwningDeleteCascadeLambdas = class extends Construct21 {
3176
3319
  constructor(scope, props) {
3177
3320
  super(scope, "owning-delete-cascade-lambdas");
3178
3321
  const listResolved = resolveHandlerEntry12(
@@ -3250,8 +3393,8 @@ import {
3250
3393
  WaitTime
3251
3394
  } from "aws-cdk-lib/aws-stepfunctions";
3252
3395
  import { LambdaInvoke } from "aws-cdk-lib/aws-stepfunctions-tasks";
3253
- import { Construct as Construct21 } from "constructs";
3254
- var OwningDeleteCascadeWorkflow = class extends Construct21 {
3396
+ import { Construct as Construct22 } from "constructs";
3397
+ var OwningDeleteCascadeWorkflow = class extends Construct22 {
3255
3398
  constructor(scope, props) {
3256
3399
  super(scope, "owning-delete-cascade-workflow");
3257
3400
  this.lambdas = new OwningDeleteCascadeLambdas(this, {
@@ -3416,7 +3559,7 @@ import { Duration as Duration13 } from "aws-cdk-lib";
3416
3559
  import { Effect as Effect9, PolicyStatement as PolicyStatement9 } from "aws-cdk-lib/aws-iam";
3417
3560
  import { Runtime as Runtime14 } from "aws-cdk-lib/aws-lambda";
3418
3561
  import { NodejsFunction as NodejsFunction14 } from "aws-cdk-lib/aws-lambda-nodejs";
3419
- import { Construct as Construct22 } from "constructs";
3562
+ import { Construct as Construct23 } from "constructs";
3420
3563
  function resolveHandlerEntry13(dirname, handlerName) {
3421
3564
  const sameDir = path14.join(dirname, handlerName);
3422
3565
  if (fs14.existsSync(sameDir)) {
@@ -3425,7 +3568,7 @@ function resolveHandlerEntry13(dirname, handlerName) {
3425
3568
  const libDir = path14.join(dirname, "..", "..", "..", "..", "lib", handlerName);
3426
3569
  return { entry: libDir, handler: "handler" };
3427
3570
  }
3428
- var RenameCascadeLambdas = class extends Construct22 {
3571
+ var RenameCascadeLambdas = class extends Construct23 {
3429
3572
  constructor(scope, props) {
3430
3573
  super(scope, "rename-cascade-lambdas");
3431
3574
  const listResolved = resolveHandlerEntry13(
@@ -3499,8 +3642,8 @@ import {
3499
3642
  TaskInput as TaskInput2
3500
3643
  } from "aws-cdk-lib/aws-stepfunctions";
3501
3644
  import { LambdaInvoke as LambdaInvoke2 } from "aws-cdk-lib/aws-stepfunctions-tasks";
3502
- import { Construct as Construct23 } from "constructs";
3503
- var RenameCascadeWorkflow = class extends Construct23 {
3645
+ import { Construct as Construct24 } from "constructs";
3646
+ var RenameCascadeWorkflow = class extends Construct24 {
3504
3647
  constructor(scope, props) {
3505
3648
  super(scope, "rename-cascade-workflow");
3506
3649
  this.lambdas = new RenameCascadeLambdas(this, {
@@ -3747,6 +3890,7 @@ export {
3747
3890
  RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR,
3748
3891
  RENAME_CASCADE_SLOW_THRESHOLD_SECONDS,
3749
3892
  REST_API_BASE_URL_SSM_NAME,
3893
+ REST_API_DOMAIN_NAME_SSM_NAME,
3750
3894
  RenameCascadeLambdas,
3751
3895
  RenameCascadeWorkflow,
3752
3896
  RootGraphqlApi,
@@ -3772,6 +3916,7 @@ export {
3772
3916
  WorkflowDedupTableDuplicateError,
3773
3917
  buildFhirCurrentResourceChangeDetail,
3774
3918
  buildProvisionDefaultWorkspaceRequestedDetail,
3919
+ computeBranchHash,
3775
3920
  demoMembershipId,
3776
3921
  demoRoleAssignmentId,
3777
3922
  demoRolesForUserInTenant,