@openhi/constructs 0.0.128 → 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 CHANGED
@@ -1142,6 +1142,23 @@ declare class StaticContent extends Construct {
1142
1142
  * OpenHiWebsiteService for fromConstruct() lookups.
1143
1143
  */
1144
1144
  declare const STATIC_HOSTING_SERVICE_TYPE = "website";
1145
+ /**
1146
+ * Shared prefix for every per-PR preview hostname / S3 key
1147
+ * (`admin-pr-<N>.<zone>`). Consumed by both the `StaticHosting`
1148
+ * lifecycle rule (`prefixPattern`) and the per-PR deployment construct
1149
+ * (`computeSubDomain` in `OpenHiWebsiteService`) so the two sides
1150
+ * cannot drift — a unit test asserts they reference the same constant.
1151
+ */
1152
+ declare const PER_BRANCH_PREVIEW_PREFIX = "admin-pr-";
1153
+ /**
1154
+ * Default TTL applied to objects matching the `prefixPattern` lifecycle
1155
+ * rule when `enablePreviewLifecycle` is `true` and `previewExpiration`
1156
+ * is omitted. Per-PR preview content is small and short-lived; 14 days
1157
+ * is long enough that a forgotten preview can still be opened during a
1158
+ * code review and short enough that abandoned content does not
1159
+ * accumulate.
1160
+ */
1161
+ declare const DEFAULT_PREVIEW_EXPIRATION_DAYS = 14;
1145
1162
  /**
1146
1163
  * Props for the StaticHosting construct.
1147
1164
  */
@@ -1238,6 +1255,33 @@ interface StaticHostingProps {
1238
1255
  readonly maxTtl?: Duration;
1239
1256
  };
1240
1257
  };
1258
+ /**
1259
+ * S3 key prefix that the per-PR preview lifecycle rule matches. Must
1260
+ * be the same value the per-PR deployment construct writes under
1261
+ * (see `PER_BRANCH_PREVIEW_PREFIX`). Required even when
1262
+ * `enablePreviewLifecycle` is `false` so the contract between the
1263
+ * deployment side and the lifecycle side is single-sourced.
1264
+ */
1265
+ readonly prefixPattern: string;
1266
+ /**
1267
+ * When `true`, add an S3 lifecycle rule to the bucket that expires
1268
+ * objects matching `prefixPattern` after `previewExpiration`. **No
1269
+ * default** — every caller must make the stage decision explicitly
1270
+ * because adding the rule in production could silently delete real
1271
+ * content if the prefix ever overlapped with release content.
1272
+ *
1273
+ * Callers gate this against the stage (e.g.
1274
+ * `ohEnv.ohStage.stageType !== OPEN_HI_STAGE.PROD`) before passing
1275
+ * the prop.
1276
+ */
1277
+ readonly enablePreviewLifecycle: boolean;
1278
+ /**
1279
+ * TTL applied to objects under `prefixPattern` when the lifecycle
1280
+ * rule is created.
1281
+ *
1282
+ * @default Duration.days(14)
1283
+ */
1284
+ readonly previewExpiration?: Duration;
1241
1285
  }
1242
1286
  /**
1243
1287
  * Static hosting: S3 bucket (private) + CloudFront distribution with Origin
@@ -1272,7 +1316,7 @@ declare class StaticHosting extends Construct {
1272
1316
  readonly bucket: IBucket;
1273
1317
  readonly distribution: Distribution;
1274
1318
  readonly viewerRequestHandler: NodejsFunction;
1275
- constructor(scope: Construct, id: string, props?: StaticHostingProps);
1319
+ constructor(scope: Construct, id: string, props: StaticHostingProps);
1276
1320
  /**
1277
1321
  * Builds the `/api/*` and `/api/control/runtime-config` behaviors backed
1278
1322
  * by the REST API custom-domain origin. Returns `undefined` when no
@@ -1365,6 +1409,19 @@ declare class OpenHiAuthService extends OpenHiService {
1365
1409
  * Returns an IUserPoolDomain by looking up the Auth stack's User Pool Domain from SSM.
1366
1410
  */
1367
1411
  static userPoolDomainFromConstruct(scope: Construct): IUserPoolDomain;
1412
+ /**
1413
+ * Returns the full Cognito Hosted UI base URL (e.g.
1414
+ * `https://auth-abc.auth.us-east-2.amazoncognito.com`) by looking up
1415
+ * the Auth stack's User Pool Domain from SSM and composing it with the
1416
+ * calling stack's region.
1417
+ *
1418
+ * Equivalent to `UserPoolDomain.baseUrl()` on the concrete construct,
1419
+ * but works across stacks where the looked-up `IUserPoolDomain` is an
1420
+ * `Import` and does not carry the `baseUrl()` method. Assumes the
1421
+ * domain was created as a Cognito-managed prefix domain (the only
1422
+ * variant `OpenHiAuthService.createUserPoolDomain` produces).
1423
+ */
1424
+ static userPoolDomainBaseUrlFromConstruct(scope: Construct): string;
1368
1425
  /**
1369
1426
  * Returns an IKey (KMS) by looking up the Auth stack's User Pool KMS Key ARN from SSM.
1370
1427
  */
@@ -2112,6 +2169,12 @@ declare class OpenHiGraphqlService extends OpenHiService {
2112
2169
  protected createRootGraphqlApi(): RootGraphqlApi;
2113
2170
  }
2114
2171
 
2172
+ /**
2173
+ * Environment variable that supplies the PR number on non-release website
2174
+ * deploys. Sibling of `GIT_BRANCH_NAME` used by `OpenHiService`. CI sets
2175
+ * this from `github.event.pull_request.number`.
2176
+ */
2177
+ declare const OPENHI_PR_NUMBER_ENV_VAR = "OPENHI_PR_NUMBER";
2115
2178
  /**
2116
2179
  * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-website-service.md
2117
2180
  */
@@ -2178,6 +2241,18 @@ interface OpenHiWebsiteServiceProps extends OpenHiServiceProps {
2178
2241
  * @default false
2179
2242
  */
2180
2243
  readonly restApi?: boolean;
2244
+ /**
2245
+ * Pull-request number used to compute the per-PR preview hostname
2246
+ * (`\<domainPrefix\>-pr-\<N\>.\<zone\>`). Falls back to the
2247
+ * `OPENHI_PR_NUMBER` env var when omitted — CI workflows set the env
2248
+ * var from `github.event.pull_request.number`.
2249
+ *
2250
+ * Required on non-release-branch deploys; ignored on release-branch
2251
+ * deploys where the hostname is `\<domainPrefix\>.\<zone\>`.
2252
+ *
2253
+ * @default - parsed from `OPENHI_PR_NUMBER` env var when set
2254
+ */
2255
+ readonly prNumber?: number;
2181
2256
  }
2182
2257
  /**
2183
2258
  * SSM parameter name suffix for the website's full domain
@@ -2185,10 +2260,13 @@ interface OpenHiWebsiteServiceProps extends OpenHiServiceProps {
2185
2260
  */
2186
2261
  declare const SSM_PARAM_NAME_FULL_DOMAIN = "WEBSITE_FULL_DOMAIN";
2187
2262
  /**
2188
- * Website service stack: composes StaticHosting (only on release-branch
2189
- * deploys) and StaticContent (always) so feature branches can ship their
2190
- * content to a per-branch sub-domain folder against the release-branch
2191
- * bucket without provisioning duplicate infrastructure.
2263
+ * Website service stack. Release-branch deploys compose `StaticHosting`
2264
+ * (bucket + CloudFront distribution with a wildcard SAN for per-PR
2265
+ * previews + Lambda@Edge + DNS) and `StaticContent` (content upload).
2266
+ * Non-release-branch deploys compose `PerBranchHostname` (a per-PR
2267
+ * Route53 alias aliased to the release distribution) and `StaticContent`
2268
+ * (per-PR upload to the shared bucket) so feature branches publish
2269
+ * previews without provisioning duplicate infrastructure.
2192
2270
  *
2193
2271
  * Resources are created in protected methods; subclasses may override to
2194
2272
  * customize.
@@ -2224,8 +2302,10 @@ declare class OpenHiWebsiteService extends OpenHiService {
2224
2302
  /** Override so this.props is typed with this service's options. */
2225
2303
  props: OpenHiWebsiteServiceProps;
2226
2304
  /**
2227
- * Full domain served by this website (e.g. www.example.com). Derived from
2228
- * `domainPrefix` and the child hosted zone name.
2305
+ * Full domain served by this website. On the release branch this is
2306
+ * `<domainPrefix>.<zone>` (e.g. `admin.dev.openhi.org`); on every
2307
+ * other branch it is the per-PR preview hostname
2308
+ * `<domainPrefix>-pr-<N>.<zone>` (e.g. `admin-pr-123.dev.openhi.org`).
2229
2309
  */
2230
2310
  readonly fullDomain: string;
2231
2311
  /**
@@ -2241,6 +2321,20 @@ declare class OpenHiWebsiteService extends OpenHiService {
2241
2321
  * shared static-hosting bucket has been written to SSM for the first time.
2242
2322
  */
2243
2323
  readonly staticContent?: StaticContent;
2324
+ /**
2325
+ * Per-PR alias record. Created on non-release-branch deploys (when
2326
+ * `createHostingInfrastructure` is left at its default) so the PR
2327
+ * hostname `<domainPrefix>-pr-<N>.<zone>` resolves to the
2328
+ * release-branch CloudFront distribution. `undefined` on release-branch
2329
+ * deploys and on bootstrap deploys that force hosting infra on.
2330
+ */
2331
+ readonly perBranchHostname?: PerBranchHostname;
2332
+ /**
2333
+ * Pull-request number resolved from props or `OPENHI_PR_NUMBER`.
2334
+ * `undefined` on release-branch deploys (where the hostname is
2335
+ * `<domainPrefix>.<zone>` and no PR number is needed).
2336
+ */
2337
+ readonly prNumber?: number;
2244
2338
  constructor(ohEnv: OpenHiEnvironment, props: OpenHiWebsiteServiceProps);
2245
2339
  /**
2246
2340
  * Validates that config required for the website stack is present.
@@ -2260,13 +2354,40 @@ declare class OpenHiWebsiteService extends OpenHiService {
2260
2354
  */
2261
2355
  protected createCertificate(): ICertificate;
2262
2356
  /**
2263
- * Computes the full website domain from `domainPrefix` and the child
2264
- * zone name.
2357
+ * Resolves the PR number from props or the `OPENHI_PR_NUMBER` env var.
2358
+ * Returns `undefined` on release-branch deploys where no PR number is
2359
+ * needed.
2360
+ */
2361
+ protected resolvePrNumber(props: OpenHiWebsiteServiceProps): number | undefined;
2362
+ /**
2363
+ * Computes the full website domain from `domainPrefix`, the PR number,
2364
+ * and the child zone name. Release-branch deploys serve at
2365
+ * `\<domainPrefix\>.\<zone\>` (e.g. `admin.dev.openhi.org`); every other
2366
+ * deploy serves a per-PR preview at `\<domainPrefix\>-pr-\<N\>.\<zone\>`
2367
+ * (e.g. `admin-pr-123.dev.openhi.org`).
2265
2368
  */
2266
2369
  protected computeFullDomain(hostedZone: IHostedZone): string;
2370
+ /**
2371
+ * Returns the sub-domain label (left of the zone) for the current
2372
+ * deploy. Used both for {@link fullDomain} and for the per-branch S3
2373
+ * key prefix passed to {@link StaticContent} so the upload prefix
2374
+ * always matches the served hostname.
2375
+ *
2376
+ * Non-release deploys compose the per-PR slug from
2377
+ * {@link PER_BRANCH_PREVIEW_PREFIX} so the per-PR S3 key prefix
2378
+ * matches what `StaticHosting`'s lifecycle rule expires.
2379
+ */
2380
+ protected computeSubDomain(): string;
2267
2381
  /**
2268
2382
  * Creates the StaticHosting infrastructure (bucket + distribution +
2269
- * Lambda@Edge + 4 SSM params + DNS).
2383
+ * Lambda@Edge + 4 SSM params + DNS). The release-branch distribution
2384
+ * adds `*.\<zone\>` as a wildcard alt-name on top of the canonical
2385
+ * hostname so per-PR previews resolve via the same distribution.
2386
+ *
2387
+ * The bucket carries an S3 lifecycle rule that expires per-PR
2388
+ * preview content (keys under {@link PER_BRANCH_PREVIEW_PREFIX})
2389
+ * on non-production stages. PROD never gets the rule — see
2390
+ * `enablePreviewLifecycle`.
2270
2391
  */
2271
2392
  protected createStaticHosting(deps: {
2272
2393
  certificate: ICertificate;
@@ -2293,8 +2414,21 @@ declare class OpenHiWebsiteService extends OpenHiService {
2293
2414
  * the release-branch deploy publishes to SSM, addressed against
2294
2415
  * {@link OpenHiService.releaseBranchHash}. See
2295
2416
  * {@link resolveStaticHostingBucket}.
2417
+ *
2418
+ * The S3 key prefix is `\<sub-domain\>.\<zone\>/\<contentDest\>` so the
2419
+ * upload location matches the Host-header-derived folder the Lambda@Edge
2420
+ * viewer-request handler prepends. Passing the zone name (rather than
2421
+ * `this.fullDomain`) for the `fullDomain` prop keeps the prefix flat
2422
+ * — `admin-pr-123.dev.openhi.org/`, not `admin-pr-123.admin.dev.openhi.org/`.
2296
2423
  */
2297
2424
  protected createStaticContent(bucket: IBucket): StaticContent;
2425
+ /**
2426
+ * Creates the per-PR `PerBranchHostname` alias record on non-release
2427
+ * branch deploys. The record points `\<domainPrefix\>-pr-\<N\>.\<zone\>`
2428
+ * at the release-branch CloudFront distribution (resolved from SSM
2429
+ * against {@link OpenHiService.releaseBranchHash}).
2430
+ */
2431
+ protected createPerBranchHostname(hostedZone: IHostedZone): PerBranchHostname;
2298
2432
  /**
2299
2433
  * Returns an {@link IBucket} pointing at the static-hosting bucket the
2300
2434
  * uploaders write to. On the release-branch deploy this is the bucket
@@ -2489,4 +2623,4 @@ declare class RenameCascadeWorkflow extends Construct {
2489
2623
  constructor(scope: Construct, props: RenameCascadeWorkflowProps);
2490
2624
  }
2491
2625
 
2492
- export { type BuildParameterNameProps, ChildHostedZone, type ChildHostedZoneProps, CognitoUserPool, CognitoUserPoolClient, CognitoUserPoolDomain, CognitoUserPoolKmsKey, type ComputeBranchHashOptions, ControlEventBus, DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES, DATA_STORE_CHANGE_DETAIL_TYPE, DATA_STORE_CHANGE_EVENT_SOURCE, DEMO_DATA_PLANE_FIXTURES, DataEventBus, type DataEventBusOptions, DataStoreHistoricalArchive, type DataStoreHistoricalArchiveProps, DataStorePostgresReplica, type DataStorePostgresReplicaProps, type DemoWorkspaceDataPlaneFixtures, DiscoverableStringParameter, type DiscoverableStringParameterProps, DynamoDbDataStore, type DynamoDbDataStoreProps, type FhirCurrentResourceChangeDetail, type GrantConsumerOptions, HostingMode, OPENHI_TAG_SUFFIX_BRANCH_NAME, OPENHI_TAG_SUFFIX_REPO_NAME, OPENHI_TAG_SUFFIX_SERVICE_TYPE, OPENHI_TAG_SUFFIX_STAGE_TYPE, OpenHiApp, type OpenHiAppProps, OpenHiAuthService, type OpenHiAuthServiceProps, OpenHiDataService, type OpenHiDataServiceProps, OpenHiEnvironment, type OpenHiEnvironmentProps, OpenHiGlobalService, type OpenHiGlobalServiceProps, OpenHiGraphqlService, type OpenHiGraphqlServiceProps, type OpenHiRestApiRuntimeConfig, OpenHiRestApiService, type OpenHiRestApiServiceProps, OpenHiService, type OpenHiServiceProps, type OpenHiServiceType, OpenHiStage, type OpenHiStageProps, OpenHiWebsiteService, type OpenHiWebsiteServiceProps, OpsEventBus, OwningDeleteCascadeLambdas, type OwningDeleteCascadeLambdasProps, OwningDeleteCascadeWorkflow, type OwningDeleteCascadeWorkflowProps, POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME, POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME, POSTGRES_REPLICA_SECRET_ARN_SSM_NAME, PerBranchHostname, type PerBranchHostnameProps, PlatformDeployBridge, PlatformDeployBridgeLambda, type PlatformDeployBridgeLambdaProps, type PlatformDeployBridgeProps, PostAuthenticationLambda, PostConfirmationLambda, type PostConfirmationLambdaProps, PreTokenGenerationLambda, type PreTokenGenerationLambdaProps, ProvisionDefaultWorkspaceLambda, type ProvisionDefaultWorkspaceLambdaProps, REST_API_BASE_URL_SSM_NAME, REST_API_DOMAIN_NAME_SSM_NAME, RenameCascadeLambdas, type RenameCascadeLambdasProps, RenameCascadeWorkflow, type RenameCascadeWorkflowProps, RootGraphqlApi, type RootGraphqlApiProps, RootHostedZone, RootHttpApi, type RootHttpApiProps, RootWildcardCertificate, SEED_SYSTEM_DATA_ACTOR_SYSTEM, SEED_SYSTEM_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR, SSM_PARAM_NAME_FULL_DOMAIN, STATIC_HOSTING_SERVICE_TYPE, SeedDemoDataLambda, type SeedDemoDataLambdaProps, SeedDemoDataWorkflow, type SeedDemoDataWorkflowProps, SeedSystemDataLambda, type SeedSystemDataLambdaProps, SeedSystemDataWorkflow, type SeedSystemDataWorkflowProps, StaticContent, type StaticContentProps, StaticHosting, type StaticHostingProps, UserOnboardingWorkflow, type UserOnboardingWorkflowProps, WorkflowDedupConsumerNameInvalidError, WorkflowDedupTable, WorkflowDedupTableDuplicateError, type WorkflowDedupTableProps, buildFhirCurrentResourceChangeDetail, computeBranchHash, getDynamoDbDataStoreTableName, getPostgresReplicaSchemaName, getWorkflowDedupTableName, openHiTagKey };
2626
+ export { type BuildParameterNameProps, ChildHostedZone, type ChildHostedZoneProps, CognitoUserPool, CognitoUserPoolClient, CognitoUserPoolDomain, CognitoUserPoolKmsKey, type ComputeBranchHashOptions, ControlEventBus, DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES, DATA_STORE_CHANGE_DETAIL_TYPE, DATA_STORE_CHANGE_EVENT_SOURCE, DEFAULT_PREVIEW_EXPIRATION_DAYS, DEMO_DATA_PLANE_FIXTURES, DataEventBus, type DataEventBusOptions, DataStoreHistoricalArchive, type DataStoreHistoricalArchiveProps, DataStorePostgresReplica, type DataStorePostgresReplicaProps, type DemoWorkspaceDataPlaneFixtures, DiscoverableStringParameter, type DiscoverableStringParameterProps, DynamoDbDataStore, type DynamoDbDataStoreProps, type FhirCurrentResourceChangeDetail, type GrantConsumerOptions, HostingMode, OPENHI_PR_NUMBER_ENV_VAR, OPENHI_TAG_SUFFIX_BRANCH_NAME, OPENHI_TAG_SUFFIX_REPO_NAME, OPENHI_TAG_SUFFIX_SERVICE_TYPE, OPENHI_TAG_SUFFIX_STAGE_TYPE, OpenHiApp, type OpenHiAppProps, OpenHiAuthService, type OpenHiAuthServiceProps, OpenHiDataService, type OpenHiDataServiceProps, OpenHiEnvironment, type OpenHiEnvironmentProps, OpenHiGlobalService, type OpenHiGlobalServiceProps, OpenHiGraphqlService, type OpenHiGraphqlServiceProps, type OpenHiRestApiRuntimeConfig, OpenHiRestApiService, type OpenHiRestApiServiceProps, OpenHiService, type OpenHiServiceProps, type OpenHiServiceType, OpenHiStage, type OpenHiStageProps, OpenHiWebsiteService, type OpenHiWebsiteServiceProps, OpsEventBus, OwningDeleteCascadeLambdas, type OwningDeleteCascadeLambdasProps, OwningDeleteCascadeWorkflow, type OwningDeleteCascadeWorkflowProps, PER_BRANCH_PREVIEW_PREFIX, POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME, POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME, POSTGRES_REPLICA_SECRET_ARN_SSM_NAME, PerBranchHostname, type PerBranchHostnameProps, PlatformDeployBridge, PlatformDeployBridgeLambda, type PlatformDeployBridgeLambdaProps, type PlatformDeployBridgeProps, PostAuthenticationLambda, PostConfirmationLambda, type PostConfirmationLambdaProps, PreTokenGenerationLambda, type PreTokenGenerationLambdaProps, ProvisionDefaultWorkspaceLambda, type ProvisionDefaultWorkspaceLambdaProps, REST_API_BASE_URL_SSM_NAME, REST_API_DOMAIN_NAME_SSM_NAME, RenameCascadeLambdas, type RenameCascadeLambdasProps, RenameCascadeWorkflow, type RenameCascadeWorkflowProps, RootGraphqlApi, type RootGraphqlApiProps, RootHostedZone, RootHttpApi, type RootHttpApiProps, RootWildcardCertificate, SEED_SYSTEM_DATA_ACTOR_SYSTEM, SEED_SYSTEM_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR, SSM_PARAM_NAME_FULL_DOMAIN, STATIC_HOSTING_SERVICE_TYPE, SeedDemoDataLambda, type SeedDemoDataLambdaProps, SeedDemoDataWorkflow, type SeedDemoDataWorkflowProps, SeedSystemDataLambda, type SeedSystemDataLambdaProps, SeedSystemDataWorkflow, type SeedSystemDataWorkflowProps, StaticContent, type StaticContentProps, StaticHosting, type StaticHostingProps, UserOnboardingWorkflow, type UserOnboardingWorkflowProps, WorkflowDedupConsumerNameInvalidError, WorkflowDedupTable, WorkflowDedupTableDuplicateError, type WorkflowDedupTableProps, buildFhirCurrentResourceChangeDetail, computeBranchHash, getDynamoDbDataStoreTableName, getPostgresReplicaSchemaName, getWorkflowDedupTableName, openHiTagKey };
package/lib/index.d.ts CHANGED
@@ -1779,6 +1779,23 @@ declare class StaticContent extends Construct {
1779
1779
  * OpenHiWebsiteService for fromConstruct() lookups.
1780
1780
  */
1781
1781
  declare const STATIC_HOSTING_SERVICE_TYPE = "website";
1782
+ /**
1783
+ * Shared prefix for every per-PR preview hostname / S3 key
1784
+ * (`admin-pr-<N>.<zone>`). Consumed by both the `StaticHosting`
1785
+ * lifecycle rule (`prefixPattern`) and the per-PR deployment construct
1786
+ * (`computeSubDomain` in `OpenHiWebsiteService`) so the two sides
1787
+ * cannot drift — a unit test asserts they reference the same constant.
1788
+ */
1789
+ declare const PER_BRANCH_PREVIEW_PREFIX = "admin-pr-";
1790
+ /**
1791
+ * Default TTL applied to objects matching the `prefixPattern` lifecycle
1792
+ * rule when `enablePreviewLifecycle` is `true` and `previewExpiration`
1793
+ * is omitted. Per-PR preview content is small and short-lived; 14 days
1794
+ * is long enough that a forgotten preview can still be opened during a
1795
+ * code review and short enough that abandoned content does not
1796
+ * accumulate.
1797
+ */
1798
+ declare const DEFAULT_PREVIEW_EXPIRATION_DAYS = 14;
1782
1799
  /**
1783
1800
  * Props for the StaticHosting construct.
1784
1801
  */
@@ -1875,6 +1892,33 @@ interface StaticHostingProps {
1875
1892
  readonly maxTtl?: Duration;
1876
1893
  };
1877
1894
  };
1895
+ /**
1896
+ * S3 key prefix that the per-PR preview lifecycle rule matches. Must
1897
+ * be the same value the per-PR deployment construct writes under
1898
+ * (see `PER_BRANCH_PREVIEW_PREFIX`). Required even when
1899
+ * `enablePreviewLifecycle` is `false` so the contract between the
1900
+ * deployment side and the lifecycle side is single-sourced.
1901
+ */
1902
+ readonly prefixPattern: string;
1903
+ /**
1904
+ * When `true`, add an S3 lifecycle rule to the bucket that expires
1905
+ * objects matching `prefixPattern` after `previewExpiration`. **No
1906
+ * default** — every caller must make the stage decision explicitly
1907
+ * because adding the rule in production could silently delete real
1908
+ * content if the prefix ever overlapped with release content.
1909
+ *
1910
+ * Callers gate this against the stage (e.g.
1911
+ * `ohEnv.ohStage.stageType !== OPEN_HI_STAGE.PROD`) before passing
1912
+ * the prop.
1913
+ */
1914
+ readonly enablePreviewLifecycle: boolean;
1915
+ /**
1916
+ * TTL applied to objects under `prefixPattern` when the lifecycle
1917
+ * rule is created.
1918
+ *
1919
+ * @default Duration.days(14)
1920
+ */
1921
+ readonly previewExpiration?: Duration;
1878
1922
  }
1879
1923
  /**
1880
1924
  * Static hosting: S3 bucket (private) + CloudFront distribution with Origin
@@ -1909,7 +1953,7 @@ declare class StaticHosting extends Construct {
1909
1953
  readonly bucket: IBucket;
1910
1954
  readonly distribution: Distribution;
1911
1955
  readonly viewerRequestHandler: NodejsFunction;
1912
- constructor(scope: Construct, id: string, props?: StaticHostingProps);
1956
+ constructor(scope: Construct, id: string, props: StaticHostingProps);
1913
1957
  /**
1914
1958
  * Builds the `/api/*` and `/api/control/runtime-config` behaviors backed
1915
1959
  * by the REST API custom-domain origin. Returns `undefined` when no
@@ -2002,6 +2046,19 @@ declare class OpenHiAuthService extends OpenHiService {
2002
2046
  * Returns an IUserPoolDomain by looking up the Auth stack's User Pool Domain from SSM.
2003
2047
  */
2004
2048
  static userPoolDomainFromConstruct(scope: Construct): IUserPoolDomain;
2049
+ /**
2050
+ * Returns the full Cognito Hosted UI base URL (e.g.
2051
+ * `https://auth-abc.auth.us-east-2.amazoncognito.com`) by looking up
2052
+ * the Auth stack's User Pool Domain from SSM and composing it with the
2053
+ * calling stack's region.
2054
+ *
2055
+ * Equivalent to `UserPoolDomain.baseUrl()` on the concrete construct,
2056
+ * but works across stacks where the looked-up `IUserPoolDomain` is an
2057
+ * `Import` and does not carry the `baseUrl()` method. Assumes the
2058
+ * domain was created as a Cognito-managed prefix domain (the only
2059
+ * variant `OpenHiAuthService.createUserPoolDomain` produces).
2060
+ */
2061
+ static userPoolDomainBaseUrlFromConstruct(scope: Construct): string;
2005
2062
  /**
2006
2063
  * Returns an IKey (KMS) by looking up the Auth stack's User Pool KMS Key ARN from SSM.
2007
2064
  */
@@ -2749,6 +2806,12 @@ declare class OpenHiGraphqlService extends OpenHiService {
2749
2806
  protected createRootGraphqlApi(): RootGraphqlApi;
2750
2807
  }
2751
2808
 
2809
+ /**
2810
+ * Environment variable that supplies the PR number on non-release website
2811
+ * deploys. Sibling of `GIT_BRANCH_NAME` used by `OpenHiService`. CI sets
2812
+ * this from `github.event.pull_request.number`.
2813
+ */
2814
+ declare const OPENHI_PR_NUMBER_ENV_VAR = "OPENHI_PR_NUMBER";
2752
2815
  /**
2753
2816
  * @see sites/www-docs/content/packages/@openhi/constructs/services/open-hi-website-service.md
2754
2817
  */
@@ -2815,6 +2878,18 @@ interface OpenHiWebsiteServiceProps extends OpenHiServiceProps {
2815
2878
  * @default false
2816
2879
  */
2817
2880
  readonly restApi?: boolean;
2881
+ /**
2882
+ * Pull-request number used to compute the per-PR preview hostname
2883
+ * (`\<domainPrefix\>-pr-\<N\>.\<zone\>`). Falls back to the
2884
+ * `OPENHI_PR_NUMBER` env var when omitted — CI workflows set the env
2885
+ * var from `github.event.pull_request.number`.
2886
+ *
2887
+ * Required on non-release-branch deploys; ignored on release-branch
2888
+ * deploys where the hostname is `\<domainPrefix\>.\<zone\>`.
2889
+ *
2890
+ * @default - parsed from `OPENHI_PR_NUMBER` env var when set
2891
+ */
2892
+ readonly prNumber?: number;
2818
2893
  }
2819
2894
  /**
2820
2895
  * SSM parameter name suffix for the website's full domain
@@ -2822,10 +2897,13 @@ interface OpenHiWebsiteServiceProps extends OpenHiServiceProps {
2822
2897
  */
2823
2898
  declare const SSM_PARAM_NAME_FULL_DOMAIN = "WEBSITE_FULL_DOMAIN";
2824
2899
  /**
2825
- * Website service stack: composes StaticHosting (only on release-branch
2826
- * deploys) and StaticContent (always) so feature branches can ship their
2827
- * content to a per-branch sub-domain folder against the release-branch
2828
- * bucket without provisioning duplicate infrastructure.
2900
+ * Website service stack. Release-branch deploys compose `StaticHosting`
2901
+ * (bucket + CloudFront distribution with a wildcard SAN for per-PR
2902
+ * previews + Lambda@Edge + DNS) and `StaticContent` (content upload).
2903
+ * Non-release-branch deploys compose `PerBranchHostname` (a per-PR
2904
+ * Route53 alias aliased to the release distribution) and `StaticContent`
2905
+ * (per-PR upload to the shared bucket) so feature branches publish
2906
+ * previews without provisioning duplicate infrastructure.
2829
2907
  *
2830
2908
  * Resources are created in protected methods; subclasses may override to
2831
2909
  * customize.
@@ -2861,8 +2939,10 @@ declare class OpenHiWebsiteService extends OpenHiService {
2861
2939
  /** Override so this.props is typed with this service's options. */
2862
2940
  props: OpenHiWebsiteServiceProps;
2863
2941
  /**
2864
- * Full domain served by this website (e.g. www.example.com). Derived from
2865
- * `domainPrefix` and the child hosted zone name.
2942
+ * Full domain served by this website. On the release branch this is
2943
+ * `<domainPrefix>.<zone>` (e.g. `admin.dev.openhi.org`); on every
2944
+ * other branch it is the per-PR preview hostname
2945
+ * `<domainPrefix>-pr-<N>.<zone>` (e.g. `admin-pr-123.dev.openhi.org`).
2866
2946
  */
2867
2947
  readonly fullDomain: string;
2868
2948
  /**
@@ -2878,6 +2958,20 @@ declare class OpenHiWebsiteService extends OpenHiService {
2878
2958
  * shared static-hosting bucket has been written to SSM for the first time.
2879
2959
  */
2880
2960
  readonly staticContent?: StaticContent;
2961
+ /**
2962
+ * Per-PR alias record. Created on non-release-branch deploys (when
2963
+ * `createHostingInfrastructure` is left at its default) so the PR
2964
+ * hostname `<domainPrefix>-pr-<N>.<zone>` resolves to the
2965
+ * release-branch CloudFront distribution. `undefined` on release-branch
2966
+ * deploys and on bootstrap deploys that force hosting infra on.
2967
+ */
2968
+ readonly perBranchHostname?: PerBranchHostname;
2969
+ /**
2970
+ * Pull-request number resolved from props or `OPENHI_PR_NUMBER`.
2971
+ * `undefined` on release-branch deploys (where the hostname is
2972
+ * `<domainPrefix>.<zone>` and no PR number is needed).
2973
+ */
2974
+ readonly prNumber?: number;
2881
2975
  constructor(ohEnv: OpenHiEnvironment, props: OpenHiWebsiteServiceProps);
2882
2976
  /**
2883
2977
  * Validates that config required for the website stack is present.
@@ -2897,13 +2991,40 @@ declare class OpenHiWebsiteService extends OpenHiService {
2897
2991
  */
2898
2992
  protected createCertificate(): ICertificate;
2899
2993
  /**
2900
- * Computes the full website domain from `domainPrefix` and the child
2901
- * zone name.
2994
+ * Resolves the PR number from props or the `OPENHI_PR_NUMBER` env var.
2995
+ * Returns `undefined` on release-branch deploys where no PR number is
2996
+ * needed.
2997
+ */
2998
+ protected resolvePrNumber(props: OpenHiWebsiteServiceProps): number | undefined;
2999
+ /**
3000
+ * Computes the full website domain from `domainPrefix`, the PR number,
3001
+ * and the child zone name. Release-branch deploys serve at
3002
+ * `\<domainPrefix\>.\<zone\>` (e.g. `admin.dev.openhi.org`); every other
3003
+ * deploy serves a per-PR preview at `\<domainPrefix\>-pr-\<N\>.\<zone\>`
3004
+ * (e.g. `admin-pr-123.dev.openhi.org`).
2902
3005
  */
2903
3006
  protected computeFullDomain(hostedZone: IHostedZone): string;
3007
+ /**
3008
+ * Returns the sub-domain label (left of the zone) for the current
3009
+ * deploy. Used both for {@link fullDomain} and for the per-branch S3
3010
+ * key prefix passed to {@link StaticContent} so the upload prefix
3011
+ * always matches the served hostname.
3012
+ *
3013
+ * Non-release deploys compose the per-PR slug from
3014
+ * {@link PER_BRANCH_PREVIEW_PREFIX} so the per-PR S3 key prefix
3015
+ * matches what `StaticHosting`'s lifecycle rule expires.
3016
+ */
3017
+ protected computeSubDomain(): string;
2904
3018
  /**
2905
3019
  * Creates the StaticHosting infrastructure (bucket + distribution +
2906
- * Lambda@Edge + 4 SSM params + DNS).
3020
+ * Lambda@Edge + 4 SSM params + DNS). The release-branch distribution
3021
+ * adds `*.\<zone\>` as a wildcard alt-name on top of the canonical
3022
+ * hostname so per-PR previews resolve via the same distribution.
3023
+ *
3024
+ * The bucket carries an S3 lifecycle rule that expires per-PR
3025
+ * preview content (keys under {@link PER_BRANCH_PREVIEW_PREFIX})
3026
+ * on non-production stages. PROD never gets the rule — see
3027
+ * `enablePreviewLifecycle`.
2907
3028
  */
2908
3029
  protected createStaticHosting(deps: {
2909
3030
  certificate: ICertificate;
@@ -2930,8 +3051,21 @@ declare class OpenHiWebsiteService extends OpenHiService {
2930
3051
  * the release-branch deploy publishes to SSM, addressed against
2931
3052
  * {@link OpenHiService.releaseBranchHash}. See
2932
3053
  * {@link resolveStaticHostingBucket}.
3054
+ *
3055
+ * The S3 key prefix is `\<sub-domain\>.\<zone\>/\<contentDest\>` so the
3056
+ * upload location matches the Host-header-derived folder the Lambda@Edge
3057
+ * viewer-request handler prepends. Passing the zone name (rather than
3058
+ * `this.fullDomain`) for the `fullDomain` prop keeps the prefix flat
3059
+ * — `admin-pr-123.dev.openhi.org/`, not `admin-pr-123.admin.dev.openhi.org/`.
2933
3060
  */
2934
3061
  protected createStaticContent(bucket: IBucket): StaticContent;
3062
+ /**
3063
+ * Creates the per-PR `PerBranchHostname` alias record on non-release
3064
+ * branch deploys. The record points `\<domainPrefix\>-pr-\<N\>.\<zone\>`
3065
+ * at the release-branch CloudFront distribution (resolved from SSM
3066
+ * against {@link OpenHiService.releaseBranchHash}).
3067
+ */
3068
+ protected createPerBranchHostname(hostedZone: IHostedZone): PerBranchHostname;
2935
3069
  /**
2936
3070
  * Returns an {@link IBucket} pointing at the static-hosting bucket the
2937
3071
  * uploaders write to. On the release-branch deploy this is the bucket
@@ -3126,5 +3260,5 @@ declare class RenameCascadeWorkflow extends Construct {
3126
3260
  constructor(scope: Construct, props: RenameCascadeWorkflowProps);
3127
3261
  }
3128
3262
 
3129
- export { BRIDGED_STATUSES, CLOUDFORMATION_EVENT_SOURCE, CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE, CONTROL_EVENT_BUS_NAME_ENV_VAR, ChildHostedZone, CognitoUserPool, CognitoUserPoolClient, CognitoUserPoolDomain, CognitoUserPoolKmsKey, ControlEventBus, DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES, DATA_STORE_CHANGE_DETAIL_TYPE, DATA_STORE_CHANGE_EVENT_SOURCE, DEMO_DATA_PLANE_FIXTURES, DEMO_PERIOD, DEMO_TENANT_SPECS, DEMO_URN_SYSTEM, DEV_USERS, DataEventBus, DataStoreHistoricalArchive, DataStorePostgresReplica, DiscoverableStringParameter, DynamoDbDataStore, OPENHI_REPO_TAG_KEY_ENV_VAR, OPENHI_RESOURCE_URN_SYSTEM, OPENHI_TAG_KEY_PREFIX_ENV_VAR, OPENHI_TAG_SUFFIX_BRANCH_NAME, OPENHI_TAG_SUFFIX_REPO_NAME, OPENHI_TAG_SUFFIX_SERVICE_TYPE, OPENHI_TAG_SUFFIX_STAGE_TYPE, OWNING_DELETE_CASCADE_CONSUMER_NAME, OWNING_DELETE_CASCADE_DEFAULT_CONCURRENCY, OWNING_DELETE_CASCADE_STUCK_THRESHOLD_MINUTES, OWNING_DELETE_OPS_EVENT_BUS_ENV_VAR, OpenHiApp, OpenHiAuthService, OpenHiDataService, OpenHiEnvironment, OpenHiGlobalService, OpenHiGraphqlService, OpenHiRestApiService, OpenHiService, OpenHiStage, OpenHiWebsiteService, OpsEventBus, OwningDeleteCascadeLambdas, OwningDeleteCascadeWorkflow, PLACEHOLDER_TENANT_ID, PLACEHOLDER_WORKSPACE_ID, PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM, PLATFORM_SCOPE_TENANT_ID, POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME, POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME, POSTGRES_REPLICA_SECRET_ARN_SSM_NAME, PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE, PerBranchHostname, PlatformDeployBridge, PlatformDeployBridgeLambda, PostAuthenticationLambda, PostConfirmationLambda, PreTokenGenerationLambda, ProvisionDefaultWorkspaceLambda, RENAME_CASCADE_CONSUMER_NAME, RENAME_CASCADE_DEFAULT_CONCURRENCY, RENAME_CASCADE_FAILED_THRESHOLD, RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR, RENAME_CASCADE_SLOW_THRESHOLD_SECONDS, REST_API_BASE_URL_SSM_NAME, REST_API_DOMAIN_NAME_SSM_NAME, RenameCascadeLambdas, RenameCascadeWorkflow, RootGraphqlApi, RootHostedZone, RootHttpApi, RootWildcardCertificate, SEED_DEMO_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_ACTOR_SYSTEM, SEED_SYSTEM_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR, SSM_PARAM_NAME_FULL_DOMAIN, STATIC_HOSTING_SERVICE_TYPE, SeedDemoDataLambda, SeedDemoDataWorkflow, SeedSystemDataLambda, SeedSystemDataWorkflow, StaticContent, StaticHosting, USER_ONBOARDING_EVENT_SOURCE, UserOnboardingWorkflow, WorkflowDedupConsumerNameInvalidError, WorkflowDedupTable, WorkflowDedupTableDuplicateError, buildFhirCurrentResourceChangeDetail, buildProvisionDefaultWorkspaceRequestedDetail, computeBranchHash, demoMembershipId, demoRoleAssignmentId, demoRolesForUserInTenant, demoScenarioIdentifier, getDynamoDbDataStoreTableName, getPostgresReplicaSchemaName, getWorkflowDedupTableName, openHiTagKey, openhiResourceIdentifier };
3263
+ export { BRIDGED_STATUSES, CLOUDFORMATION_EVENT_SOURCE, CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE, CONTROL_EVENT_BUS_NAME_ENV_VAR, ChildHostedZone, CognitoUserPool, CognitoUserPoolClient, CognitoUserPoolDomain, CognitoUserPoolKmsKey, ControlEventBus, DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES, DATA_STORE_CHANGE_DETAIL_TYPE, DATA_STORE_CHANGE_EVENT_SOURCE, DEFAULT_PREVIEW_EXPIRATION_DAYS, DEMO_DATA_PLANE_FIXTURES, DEMO_PERIOD, DEMO_TENANT_SPECS, DEMO_URN_SYSTEM, DEV_USERS, DataEventBus, DataStoreHistoricalArchive, DataStorePostgresReplica, DiscoverableStringParameter, DynamoDbDataStore, OPENHI_PR_NUMBER_ENV_VAR, OPENHI_REPO_TAG_KEY_ENV_VAR, OPENHI_RESOURCE_URN_SYSTEM, OPENHI_TAG_KEY_PREFIX_ENV_VAR, OPENHI_TAG_SUFFIX_BRANCH_NAME, OPENHI_TAG_SUFFIX_REPO_NAME, OPENHI_TAG_SUFFIX_SERVICE_TYPE, OPENHI_TAG_SUFFIX_STAGE_TYPE, OWNING_DELETE_CASCADE_CONSUMER_NAME, OWNING_DELETE_CASCADE_DEFAULT_CONCURRENCY, OWNING_DELETE_CASCADE_STUCK_THRESHOLD_MINUTES, OWNING_DELETE_OPS_EVENT_BUS_ENV_VAR, OpenHiApp, OpenHiAuthService, OpenHiDataService, OpenHiEnvironment, OpenHiGlobalService, OpenHiGraphqlService, OpenHiRestApiService, OpenHiService, OpenHiStage, OpenHiWebsiteService, OpsEventBus, OwningDeleteCascadeLambdas, OwningDeleteCascadeWorkflow, PER_BRANCH_PREVIEW_PREFIX, PLACEHOLDER_TENANT_ID, PLACEHOLDER_WORKSPACE_ID, PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM, PLATFORM_SCOPE_TENANT_ID, POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME, POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME, POSTGRES_REPLICA_SECRET_ARN_SSM_NAME, PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE, PerBranchHostname, PlatformDeployBridge, PlatformDeployBridgeLambda, PostAuthenticationLambda, PostConfirmationLambda, PreTokenGenerationLambda, ProvisionDefaultWorkspaceLambda, RENAME_CASCADE_CONSUMER_NAME, RENAME_CASCADE_DEFAULT_CONCURRENCY, RENAME_CASCADE_FAILED_THRESHOLD, RENAME_CASCADE_OPS_EVENT_BUS_ENV_VAR, RENAME_CASCADE_SLOW_THRESHOLD_SECONDS, REST_API_BASE_URL_SSM_NAME, REST_API_DOMAIN_NAME_SSM_NAME, RenameCascadeLambdas, RenameCascadeWorkflow, RootGraphqlApi, RootHostedZone, RootHttpApi, RootWildcardCertificate, SEED_DEMO_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_ACTOR_SYSTEM, SEED_SYSTEM_DATA_CONSUMER_NAME, SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR, SSM_PARAM_NAME_FULL_DOMAIN, STATIC_HOSTING_SERVICE_TYPE, SeedDemoDataLambda, SeedDemoDataWorkflow, SeedSystemDataLambda, SeedSystemDataWorkflow, StaticContent, StaticHosting, USER_ONBOARDING_EVENT_SOURCE, UserOnboardingWorkflow, WorkflowDedupConsumerNameInvalidError, WorkflowDedupTable, WorkflowDedupTableDuplicateError, buildFhirCurrentResourceChangeDetail, buildProvisionDefaultWorkspaceRequestedDetail, computeBranchHash, demoMembershipId, demoRoleAssignmentId, demoRolesForUserInTenant, demoScenarioIdentifier, getDynamoDbDataStoreTableName, getPostgresReplicaSchemaName, getWorkflowDedupTableName, openHiTagKey, openhiResourceIdentifier };
3130
3264
  export type { BridgedStatus, BuildParameterNameProps, CascadeChunkInput, CascadeFinalizeInput, CascadeFinalizeOutput, CascadeListInput, CascadeListOutput, ChildHostedZoneProps, CloudFormationStackStatusChangeDetail, ComputeBranchHashOptions, DataEventBusOptions, DataStoreHistoricalArchiveProps, DataStorePostgresReplicaProps, DemoDevUser, DemoTenantSpec, DemoWorkspaceDataPlaneFixtures, DemoWorkspaceSpec, DiscoverableStringParameterProps, DynamoDbDataStoreProps, FhirCurrentResourceChangeDetail, GrantConsumerOptions, HostingMode, OpenHiAppProps, OpenHiAuthServiceProps, OpenHiDataServiceProps, OpenHiEnvironmentProps, OpenHiGlobalServiceProps, OpenHiGraphqlServiceProps, OpenHiRestApiRuntimeConfig, OpenHiRestApiServiceProps, OpenHiServiceProps, OpenHiServiceType, OpenHiStageProps, OpenHiWebsiteServiceProps, OwningDeleteCascadeLambdasProps, OwningDeleteCascadeWorkflowProps, PerBranchHostnameProps, PlatformDeployBridgeLambdaProps, PlatformDeployBridgeProps, PostConfirmationLambdaProps, PreTokenGenerationLambdaProps, ProvisionDefaultWorkspaceLambdaProps, ProvisionDefaultWorkspaceRequestedDetail, RenameCascadeChunkInput, RenameCascadeFinalizeInput, RenameCascadeFinalizeOutput, RenameCascadeLambdasProps, RenameCascadeListInput, RenameCascadeListOutput, RenameCascadeWorkflowProps, RootGraphqlApiProps, RootHttpApiProps, SeedDemoDataLambdaProps, SeedDemoDataWorkflowProps, SeedSystemDataLambdaProps, SeedSystemDataWorkflowProps, StaticContentProps, StaticHostingProps, UserOnboardingWorkflowProps, WorkflowDedupTableProps };