@openhi/constructs 0.0.129 → 0.0.130
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.d.mts +132 -11
- package/lib/index.d.ts +132 -11
- package/lib/index.js +110 -9
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +107 -9
- package/lib/index.mjs.map +1 -1
- package/package.json +3 -3
package/lib/index.mjs
CHANGED
|
@@ -1526,6 +1526,8 @@ import { CloudFrontTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
|
1526
1526
|
import { Bucket as Bucket2 } from "aws-cdk-lib/aws-s3";
|
|
1527
1527
|
import { Construct as Construct8 } from "constructs";
|
|
1528
1528
|
var STATIC_HOSTING_SERVICE_TYPE = "website";
|
|
1529
|
+
var PER_BRANCH_PREVIEW_PREFIX = "admin-pr-";
|
|
1530
|
+
var DEFAULT_PREVIEW_EXPIRATION_DAYS = 14;
|
|
1529
1531
|
var _StaticHosting = class _StaticHosting extends Construct8 {
|
|
1530
1532
|
/**
|
|
1531
1533
|
* Returns true when `domainName` begins with a wildcard label (`*.`),
|
|
@@ -1535,11 +1537,19 @@ var _StaticHosting = class _StaticHosting extends Construct8 {
|
|
|
1535
1537
|
static isWildcardDomain(domainName) {
|
|
1536
1538
|
return domainName.startsWith("*.");
|
|
1537
1539
|
}
|
|
1538
|
-
constructor(scope, id, props
|
|
1540
|
+
constructor(scope, id, props) {
|
|
1539
1541
|
super(scope, id);
|
|
1540
1542
|
const stack = OpenHiService.of(scope);
|
|
1541
1543
|
const serviceType = props.serviceType ?? STATIC_HOSTING_SERVICE_TYPE;
|
|
1542
1544
|
const hostingMode = props.hostingMode ?? "spa";
|
|
1545
|
+
const previewLifecycleRules = props.enablePreviewLifecycle ? [
|
|
1546
|
+
{
|
|
1547
|
+
id: "expire-pr-previews",
|
|
1548
|
+
enabled: true,
|
|
1549
|
+
prefix: props.prefixPattern,
|
|
1550
|
+
expiration: props.previewExpiration ?? Duration5.days(DEFAULT_PREVIEW_EXPIRATION_DAYS)
|
|
1551
|
+
}
|
|
1552
|
+
] : void 0;
|
|
1543
1553
|
this.bucket = new Bucket2(this, "bucket", {
|
|
1544
1554
|
blockPublicAccess: {
|
|
1545
1555
|
blockPublicAcls: true,
|
|
@@ -1547,6 +1557,9 @@ var _StaticHosting = class _StaticHosting extends Construct8 {
|
|
|
1547
1557
|
ignorePublicAcls: true,
|
|
1548
1558
|
restrictPublicBuckets: true
|
|
1549
1559
|
},
|
|
1560
|
+
...previewLifecycleRules !== void 0 && {
|
|
1561
|
+
lifecycleRules: previewLifecycleRules
|
|
1562
|
+
},
|
|
1550
1563
|
...props.bucketProps
|
|
1551
1564
|
});
|
|
1552
1565
|
const handlerJs = path6.join(
|
|
@@ -3192,7 +3205,9 @@ _OpenHiGraphqlService.SERVICE_TYPE = "graphql-api";
|
|
|
3192
3205
|
var OpenHiGraphqlService = _OpenHiGraphqlService;
|
|
3193
3206
|
|
|
3194
3207
|
// src/services/open-hi-website-service.ts
|
|
3208
|
+
var import_config5 = __toESM(require_lib2());
|
|
3195
3209
|
import { Bucket as Bucket3 } from "aws-cdk-lib/aws-s3";
|
|
3210
|
+
var OPENHI_PR_NUMBER_ENV_VAR = "OPENHI_PR_NUMBER";
|
|
3196
3211
|
var SSM_PARAM_NAME_FULL_DOMAIN = "WEBSITE_FULL_DOMAIN";
|
|
3197
3212
|
var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
3198
3213
|
/**
|
|
@@ -3252,9 +3267,16 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
|
3252
3267
|
super(ohEnv, _OpenHiWebsiteService.SERVICE_TYPE, props);
|
|
3253
3268
|
this.props = props;
|
|
3254
3269
|
this.validateConfig(props);
|
|
3270
|
+
const isReleaseBranch = this.branchName === this.defaultReleaseBranch;
|
|
3271
|
+
this.prNumber = this.resolvePrNumber(props);
|
|
3272
|
+
if (!isReleaseBranch && this.prNumber === void 0) {
|
|
3273
|
+
throw new Error(
|
|
3274
|
+
`OpenHiWebsiteService: prNumber is required on non-release-branch deploys (branchName="${this.branchName}", defaultReleaseBranch="${this.defaultReleaseBranch}"). Pass the \`prNumber\` prop or set the ${OPENHI_PR_NUMBER_ENV_VAR} env var.`
|
|
3275
|
+
);
|
|
3276
|
+
}
|
|
3255
3277
|
const hostedZone = this.createHostedZone();
|
|
3256
3278
|
this.fullDomain = this.computeFullDomain(hostedZone);
|
|
3257
|
-
const shouldCreateHostingInfra = props.createHostingInfrastructure ??
|
|
3279
|
+
const shouldCreateHostingInfra = props.createHostingInfrastructure ?? isReleaseBranch;
|
|
3258
3280
|
if (shouldCreateHostingInfra) {
|
|
3259
3281
|
const certificate = this.createCertificate();
|
|
3260
3282
|
this.staticHosting = this.createStaticHosting({
|
|
@@ -3262,6 +3284,8 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
|
3262
3284
|
hostedZone
|
|
3263
3285
|
});
|
|
3264
3286
|
this.createFullDomainParameter();
|
|
3287
|
+
} else if (!isReleaseBranch) {
|
|
3288
|
+
this.perBranchHostname = this.createPerBranchHostname(hostedZone);
|
|
3265
3289
|
}
|
|
3266
3290
|
if (props.createStaticContent !== false) {
|
|
3267
3291
|
const bucket = this.resolveStaticHostingBucket();
|
|
@@ -3304,25 +3328,76 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
|
3304
3328
|
return OpenHiGlobalService.rootWildcardCertificateFromConstruct(this);
|
|
3305
3329
|
}
|
|
3306
3330
|
/**
|
|
3307
|
-
*
|
|
3308
|
-
*
|
|
3331
|
+
* Resolves the PR number from props or the `OPENHI_PR_NUMBER` env var.
|
|
3332
|
+
* Returns `undefined` on release-branch deploys where no PR number is
|
|
3333
|
+
* needed.
|
|
3334
|
+
*/
|
|
3335
|
+
resolvePrNumber(props) {
|
|
3336
|
+
if (props.prNumber !== void 0) {
|
|
3337
|
+
return props.prNumber;
|
|
3338
|
+
}
|
|
3339
|
+
const raw = process.env[OPENHI_PR_NUMBER_ENV_VAR]?.trim();
|
|
3340
|
+
if (!raw) {
|
|
3341
|
+
return void 0;
|
|
3342
|
+
}
|
|
3343
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3344
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
3345
|
+
throw new Error(
|
|
3346
|
+
`${OPENHI_PR_NUMBER_ENV_VAR} must be a positive integer; got "${raw}".`
|
|
3347
|
+
);
|
|
3348
|
+
}
|
|
3349
|
+
return parsed;
|
|
3350
|
+
}
|
|
3351
|
+
/**
|
|
3352
|
+
* Computes the full website domain from `domainPrefix`, the PR number,
|
|
3353
|
+
* and the child zone name. Release-branch deploys serve at
|
|
3354
|
+
* `\<domainPrefix\>.\<zone\>` (e.g. `admin.dev.openhi.org`); every other
|
|
3355
|
+
* deploy serves a per-PR preview at `\<domainPrefix\>-pr-\<N\>.\<zone\>`
|
|
3356
|
+
* (e.g. `admin-pr-123.dev.openhi.org`).
|
|
3309
3357
|
*/
|
|
3310
3358
|
computeFullDomain(hostedZone) {
|
|
3311
|
-
const
|
|
3312
|
-
return [
|
|
3359
|
+
const subDomain = this.computeSubDomain();
|
|
3360
|
+
return [subDomain, hostedZone.zoneName].join(".");
|
|
3361
|
+
}
|
|
3362
|
+
/**
|
|
3363
|
+
* Returns the sub-domain label (left of the zone) for the current
|
|
3364
|
+
* deploy. Used both for {@link fullDomain} and for the per-branch S3
|
|
3365
|
+
* key prefix passed to {@link StaticContent} so the upload prefix
|
|
3366
|
+
* always matches the served hostname.
|
|
3367
|
+
*
|
|
3368
|
+
* Non-release deploys compose the per-PR slug from
|
|
3369
|
+
* {@link PER_BRANCH_PREVIEW_PREFIX} so the per-PR S3 key prefix
|
|
3370
|
+
* matches what `StaticHosting`'s lifecycle rule expires.
|
|
3371
|
+
*/
|
|
3372
|
+
computeSubDomain() {
|
|
3373
|
+
const isReleaseBranch = this.branchName === this.defaultReleaseBranch;
|
|
3374
|
+
if (isReleaseBranch) {
|
|
3375
|
+
return this.props.domainPrefix ?? "www";
|
|
3376
|
+
}
|
|
3377
|
+
return `${PER_BRANCH_PREVIEW_PREFIX}${this.prNumber}`;
|
|
3313
3378
|
}
|
|
3314
3379
|
/**
|
|
3315
3380
|
* Creates the StaticHosting infrastructure (bucket + distribution +
|
|
3316
|
-
* Lambda@Edge + 4 SSM params + DNS).
|
|
3381
|
+
* Lambda@Edge + 4 SSM params + DNS). The release-branch distribution
|
|
3382
|
+
* adds `*.\<zone\>` as a wildcard alt-name on top of the canonical
|
|
3383
|
+
* hostname so per-PR previews resolve via the same distribution.
|
|
3384
|
+
*
|
|
3385
|
+
* The bucket carries an S3 lifecycle rule that expires per-PR
|
|
3386
|
+
* preview content (keys under {@link PER_BRANCH_PREVIEW_PREFIX})
|
|
3387
|
+
* on non-production stages. PROD never gets the rule — see
|
|
3388
|
+
* `enablePreviewLifecycle`.
|
|
3317
3389
|
*/
|
|
3318
3390
|
createStaticHosting(deps) {
|
|
3319
3391
|
const restApi = this.props.restApi === true ? this.resolveRestApi() : void 0;
|
|
3392
|
+
const wildcardSan = `*.${deps.hostedZone.zoneName}`;
|
|
3320
3393
|
return new StaticHosting(this, "static-hosting", {
|
|
3321
3394
|
serviceType: _OpenHiWebsiteService.SERVICE_TYPE,
|
|
3322
3395
|
certificate: deps.certificate,
|
|
3323
3396
|
hostedZone: deps.hostedZone,
|
|
3324
|
-
domainNames: [this.fullDomain],
|
|
3397
|
+
domainNames: [this.fullDomain, wildcardSan],
|
|
3325
3398
|
description: `OpenHI website (${this.fullDomain})`,
|
|
3399
|
+
prefixPattern: PER_BRANCH_PREVIEW_PREFIX,
|
|
3400
|
+
enablePreviewLifecycle: this.ohEnv.ohStage.stageType !== import_config5.OPEN_HI_STAGE.PROD,
|
|
3326
3401
|
...restApi !== void 0 && { restApi }
|
|
3327
3402
|
});
|
|
3328
3403
|
}
|
|
@@ -3356,6 +3431,12 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
|
3356
3431
|
* the release-branch deploy publishes to SSM, addressed against
|
|
3357
3432
|
* {@link OpenHiService.releaseBranchHash}. See
|
|
3358
3433
|
* {@link resolveStaticHostingBucket}.
|
|
3434
|
+
*
|
|
3435
|
+
* The S3 key prefix is `\<sub-domain\>.\<zone\>/\<contentDest\>` so the
|
|
3436
|
+
* upload location matches the Host-header-derived folder the Lambda@Edge
|
|
3437
|
+
* viewer-request handler prepends. Passing the zone name (rather than
|
|
3438
|
+
* `this.fullDomain`) for the `fullDomain` prop keeps the prefix flat
|
|
3439
|
+
* — `admin-pr-123.dev.openhi.org/`, not `admin-pr-123.admin.dev.openhi.org/`.
|
|
3359
3440
|
*/
|
|
3360
3441
|
createStaticContent(bucket) {
|
|
3361
3442
|
const { contentSourceDirectory, contentDestinationDirectory } = this.props;
|
|
@@ -3363,7 +3444,21 @@ var _OpenHiWebsiteService = class _OpenHiWebsiteService extends OpenHiService {
|
|
|
3363
3444
|
bucket,
|
|
3364
3445
|
contentSourceDirectory,
|
|
3365
3446
|
contentDestinationDirectory,
|
|
3366
|
-
|
|
3447
|
+
subDomain: this.computeSubDomain(),
|
|
3448
|
+
fullDomain: this.config.zoneName
|
|
3449
|
+
});
|
|
3450
|
+
}
|
|
3451
|
+
/**
|
|
3452
|
+
* Creates the per-PR `PerBranchHostname` alias record on non-release
|
|
3453
|
+
* branch deploys. The record points `\<domainPrefix\>-pr-\<N\>.\<zone\>`
|
|
3454
|
+
* at the release-branch CloudFront distribution (resolved from SSM
|
|
3455
|
+
* against {@link OpenHiService.releaseBranchHash}).
|
|
3456
|
+
*/
|
|
3457
|
+
createPerBranchHostname(hostedZone) {
|
|
3458
|
+
return new PerBranchHostname(this, "per-branch-hostname", {
|
|
3459
|
+
hostname: this.fullDomain,
|
|
3460
|
+
hostedZone,
|
|
3461
|
+
serviceType: _OpenHiWebsiteService.SERVICE_TYPE
|
|
3367
3462
|
});
|
|
3368
3463
|
}
|
|
3369
3464
|
/**
|
|
@@ -3922,6 +4017,7 @@ export {
|
|
|
3922
4017
|
DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
|
|
3923
4018
|
DATA_STORE_CHANGE_DETAIL_TYPE,
|
|
3924
4019
|
DATA_STORE_CHANGE_EVENT_SOURCE,
|
|
4020
|
+
DEFAULT_PREVIEW_EXPIRATION_DAYS,
|
|
3925
4021
|
DEMO_DATA_PLANE_FIXTURES,
|
|
3926
4022
|
DEMO_PERIOD,
|
|
3927
4023
|
DEMO_TENANT_SPECS,
|
|
@@ -3932,6 +4028,7 @@ export {
|
|
|
3932
4028
|
DataStorePostgresReplica,
|
|
3933
4029
|
DiscoverableStringParameter,
|
|
3934
4030
|
DynamoDbDataStore,
|
|
4031
|
+
OPENHI_PR_NUMBER_ENV_VAR,
|
|
3935
4032
|
OPENHI_REPO_TAG_KEY_ENV_VAR,
|
|
3936
4033
|
OPENHI_RESOURCE_URN_SYSTEM,
|
|
3937
4034
|
OPENHI_TAG_KEY_PREFIX_ENV_VAR,
|
|
@@ -3957,6 +4054,7 @@ export {
|
|
|
3957
4054
|
OpsEventBus,
|
|
3958
4055
|
OwningDeleteCascadeLambdas,
|
|
3959
4056
|
OwningDeleteCascadeWorkflow,
|
|
4057
|
+
PER_BRANCH_PREVIEW_PREFIX,
|
|
3960
4058
|
PLACEHOLDER_TENANT_ID,
|
|
3961
4059
|
PLACEHOLDER_WORKSPACE_ID,
|
|
3962
4060
|
PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM,
|