@openhi/constructs 0.0.84 → 0.0.86
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/{chunk-SWSN6GDD.mjs → chunk-CEOAGPYY.mjs} +1 -5
- package/lib/chunk-CEOAGPYY.mjs.map +1 -0
- package/lib/chunk-X5MHU7DA.mjs +298 -0
- package/lib/chunk-X5MHU7DA.mjs.map +1 -0
- package/lib/data-store-postgres-replication.handler.d.mts +55 -0
- package/lib/data-store-postgres-replication.handler.d.ts +55 -0
- package/lib/data-store-postgres-replication.handler.js +448 -0
- package/lib/data-store-postgres-replication.handler.js.map +1 -0
- package/lib/data-store-postgres-replication.handler.mjs +313 -0
- package/lib/data-store-postgres-replication.handler.mjs.map +1 -0
- package/lib/firehose-archive-transform.handler.js +0 -4
- package/lib/firehose-archive-transform.handler.js.map +1 -1
- package/lib/firehose-archive-transform.handler.mjs +5 -290
- package/lib/firehose-archive-transform.handler.mjs.map +1 -1
- package/lib/index.d.mts +201 -5
- package/lib/index.d.ts +202 -6
- package/lib/index.js +392 -92
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +381 -81
- package/lib/index.mjs.map +1 -1
- package/lib/rest-api-lambda.handler.js +636 -153
- package/lib/rest-api-lambda.handler.js.map +1 -1
- package/lib/rest-api-lambda.handler.mjs +639 -153
- package/lib/rest-api-lambda.handler.mjs.map +1 -1
- package/package.json +22 -13
- package/scripts/generate-operations.js +2 -2
- package/scripts/generate-routes.js +1 -1
- package/lib/chunk-SWSN6GDD.mjs.map +0 -1
- package/scripts/generate-route-tests.mjs +0 -227
package/lib/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
DATA_STORE_CHANGE_DETAIL_TYPE,
|
|
4
4
|
DATA_STORE_CHANGE_EVENT_SOURCE,
|
|
5
5
|
buildFhirCurrentResourceChangeDetail
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CEOAGPYY.mjs";
|
|
7
7
|
import {
|
|
8
8
|
__commonJS,
|
|
9
9
|
__toESM
|
|
@@ -347,6 +347,10 @@ var OpenHiService = class extends Stack {
|
|
|
347
347
|
this.environmentHash = environmentHash;
|
|
348
348
|
this.branchHash = branchHash;
|
|
349
349
|
this.stackHash = stackHash;
|
|
350
|
+
this.node.setContext(
|
|
351
|
+
`availability-zones:account=${account}:region=${region}`,
|
|
352
|
+
[`${region}a`, `${region}b`, `${region}c`]
|
|
353
|
+
);
|
|
350
354
|
Tags.of(this).add(`${appName}:repo-name`, repoName.slice(0, 255));
|
|
351
355
|
Tags.of(this).add(`${appName}:branch-name`, branchName.slice(0, 255));
|
|
352
356
|
Tags.of(this).add(`${appName}:service-type`, id.slice(0, 255));
|
|
@@ -530,6 +534,46 @@ var _RootGraphqlApi = class _RootGraphqlApi extends GraphqlApi {
|
|
|
530
534
|
_RootGraphqlApi.SSM_PARAM_NAME = "ROOT_GRAPHQL_API";
|
|
531
535
|
var RootGraphqlApi = _RootGraphqlApi;
|
|
532
536
|
|
|
537
|
+
// src/components/cognito/cognito-fixture-seeder-client.ts
|
|
538
|
+
import { Duration } from "aws-cdk-lib";
|
|
539
|
+
import {
|
|
540
|
+
UserPoolClient
|
|
541
|
+
} from "aws-cdk-lib/aws-cognito";
|
|
542
|
+
var CognitoFixtureSeederClient = class extends UserPoolClient {
|
|
543
|
+
constructor(scope, props) {
|
|
544
|
+
const { userPool, ...rest } = props;
|
|
545
|
+
super(scope, "fixture-seeder-client", {
|
|
546
|
+
userPool,
|
|
547
|
+
generateSecret: false,
|
|
548
|
+
authFlows: {
|
|
549
|
+
userPassword: true
|
|
550
|
+
},
|
|
551
|
+
// No OAuth flows — the seeder calls Cognito's `InitiateAuth`
|
|
552
|
+
// directly with USER_PASSWORD_AUTH, not through the hosted-UI
|
|
553
|
+
// OAuth grant flows the SPA client uses. `disableOAuth: true`
|
|
554
|
+
// causes CDK to omit `AllowedOAuthFlowsUserPoolClient` entirely;
|
|
555
|
+
// passing an empty `oAuth` block instead still flips that flag on
|
|
556
|
+
// and Cognito rejects the create call for missing flows/scopes.
|
|
557
|
+
disableOAuth: true,
|
|
558
|
+
// Short-lived tokens: a seeder run takes seconds, not hours.
|
|
559
|
+
// 1h access-token validity is the minimum Cognito permits and is
|
|
560
|
+
// plenty for a fixture run.
|
|
561
|
+
accessTokenValidity: Duration.hours(1),
|
|
562
|
+
idTokenValidity: Duration.hours(1),
|
|
563
|
+
refreshTokenValidity: Duration.days(1),
|
|
564
|
+
preventUserExistenceErrors: true,
|
|
565
|
+
...rest
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
/**
|
|
570
|
+
* SSM parameter name suffix used to publish this client's ID for
|
|
571
|
+
* cross-stack lookups. Built into a full parameter name via
|
|
572
|
+
* `buildParameterName` with `serviceType` AUTH (since the auth stack
|
|
573
|
+
* owns this resource).
|
|
574
|
+
*/
|
|
575
|
+
CognitoFixtureSeederClient.SSM_PARAM_NAME = "COGNITO_FIXTURE_SEEDER_CLIENT";
|
|
576
|
+
|
|
533
577
|
// src/components/cognito/cognito-user-pool.ts
|
|
534
578
|
import {
|
|
535
579
|
UserPool,
|
|
@@ -569,8 +613,8 @@ var CognitoUserPool = class extends UserPool {
|
|
|
569
613
|
CognitoUserPool.SSM_PARAM_NAME = "COGNITO_USER_POOL";
|
|
570
614
|
|
|
571
615
|
// src/components/cognito/cognito-user-pool-client.ts
|
|
572
|
-
import { UserPoolClient } from "aws-cdk-lib/aws-cognito";
|
|
573
|
-
var CognitoUserPoolClient = class extends
|
|
616
|
+
import { UserPoolClient as UserPoolClient2 } from "aws-cdk-lib/aws-cognito";
|
|
617
|
+
var CognitoUserPoolClient = class extends UserPoolClient2 {
|
|
574
618
|
constructor(scope, props) {
|
|
575
619
|
super(scope, "user-pool-client", {
|
|
576
620
|
/**
|
|
@@ -658,7 +702,7 @@ var PreTokenGenerationLambda = class extends Construct {
|
|
|
658
702
|
// src/components/dynamodb/data-store-historical-archive.ts
|
|
659
703
|
import fs2 from "fs";
|
|
660
704
|
import path2 from "path";
|
|
661
|
-
import { Duration, RemovalPolicy as RemovalPolicy2, Size } from "aws-cdk-lib";
|
|
705
|
+
import { Duration as Duration2, RemovalPolicy as RemovalPolicy2, Size } from "aws-cdk-lib";
|
|
662
706
|
import * as kinesisfirehose from "aws-cdk-lib/aws-kinesisfirehose";
|
|
663
707
|
import { Runtime as Runtime2 } from "aws-cdk-lib/aws-lambda";
|
|
664
708
|
import { NodejsFunction as NodejsFunction2 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
@@ -696,7 +740,7 @@ var DataStoreHistoricalArchive = class extends Construct2 {
|
|
|
696
740
|
entry: resolveHandlerEntry2(__dirname),
|
|
697
741
|
runtime: Runtime2.NODEJS_LATEST,
|
|
698
742
|
memorySize: 512,
|
|
699
|
-
timeout:
|
|
743
|
+
timeout: Duration2.minutes(1),
|
|
700
744
|
description: "Firehose transform: filter CURRENT resource rows, S3 keys, EventBridge PutEvents",
|
|
701
745
|
environment: props.dataEventBus && putEventsFailureDlqBucket ? {
|
|
702
746
|
DATA_EVENT_BUS_NAME: props.dataEventBus.eventBusName,
|
|
@@ -712,14 +756,14 @@ var DataStoreHistoricalArchive = class extends Construct2 {
|
|
|
712
756
|
const processor = new kinesisfirehose.LambdaFunctionProcessor(
|
|
713
757
|
this.transformFunction,
|
|
714
758
|
{
|
|
715
|
-
bufferInterval:
|
|
759
|
+
bufferInterval: Duration2.seconds(60),
|
|
716
760
|
bufferSize: Size.mebibytes(3),
|
|
717
761
|
retries: 3
|
|
718
762
|
}
|
|
719
763
|
);
|
|
720
764
|
const destination = new kinesisfirehose.S3Bucket(this.archiveBucket, {
|
|
721
765
|
compression: kinesisfirehose.Compression.GZIP,
|
|
722
|
-
bufferingInterval:
|
|
766
|
+
bufferingInterval: Duration2.seconds(300),
|
|
723
767
|
// Firehose requires SizeInMBs ≥ 64 when dynamic partitioning is enabled.
|
|
724
768
|
bufferingSize: Size.mebibytes(64),
|
|
725
769
|
processors: [processor],
|
|
@@ -789,7 +833,15 @@ var DynamoDbDataStore = class extends Table {
|
|
|
789
833
|
type: AttributeType.STRING
|
|
790
834
|
},
|
|
791
835
|
projectionType: ProjectionType.INCLUDE,
|
|
792
|
-
nonKeyAttributes: [
|
|
836
|
+
nonKeyAttributes: [
|
|
837
|
+
"summary",
|
|
838
|
+
"vid",
|
|
839
|
+
"lastUpdated",
|
|
840
|
+
"createdDate",
|
|
841
|
+
"modifiedDate",
|
|
842
|
+
"createdById",
|
|
843
|
+
"modifiedById"
|
|
844
|
+
]
|
|
793
845
|
});
|
|
794
846
|
this.addGlobalSecondaryIndex({
|
|
795
847
|
indexName: "GSI2",
|
|
@@ -802,32 +854,12 @@ var DynamoDbDataStore = class extends Table {
|
|
|
802
854
|
type: AttributeType.STRING
|
|
803
855
|
},
|
|
804
856
|
projectionType: ProjectionType.INCLUDE,
|
|
805
|
-
nonKeyAttributes: [
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
type: AttributeType.STRING
|
|
812
|
-
},
|
|
813
|
-
sortKey: {
|
|
814
|
-
name: "GSI3SK",
|
|
815
|
-
type: AttributeType.STRING
|
|
816
|
-
},
|
|
817
|
-
projectionType: ProjectionType.INCLUDE,
|
|
818
|
-
nonKeyAttributes: ["resourcePk", "resourceSk"]
|
|
819
|
-
});
|
|
820
|
-
this.addGlobalSecondaryIndex({
|
|
821
|
-
indexName: "GSI4",
|
|
822
|
-
partitionKey: {
|
|
823
|
-
name: "GSI4PK",
|
|
824
|
-
type: AttributeType.STRING
|
|
825
|
-
},
|
|
826
|
-
sortKey: {
|
|
827
|
-
name: "GSI4SK",
|
|
828
|
-
type: AttributeType.STRING
|
|
829
|
-
},
|
|
830
|
-
projectionType: ProjectionType.ALL
|
|
857
|
+
nonKeyAttributes: [
|
|
858
|
+
"id",
|
|
859
|
+
"currentTenant",
|
|
860
|
+
"currentWorkspace",
|
|
861
|
+
"displayName"
|
|
862
|
+
]
|
|
831
863
|
});
|
|
832
864
|
}
|
|
833
865
|
};
|
|
@@ -876,8 +908,172 @@ var OpsEventBus = class _OpsEventBus extends EventBus2 {
|
|
|
876
908
|
}
|
|
877
909
|
};
|
|
878
910
|
|
|
911
|
+
// src/components/postgres/data-store-postgres-replica.ts
|
|
912
|
+
import fs3 from "fs";
|
|
913
|
+
import path3 from "path";
|
|
914
|
+
import { Duration as Duration3, Stack as Stack2 } from "aws-cdk-lib";
|
|
915
|
+
import * as ec2 from "aws-cdk-lib/aws-ec2";
|
|
916
|
+
import { Runtime as Runtime3, StartingPosition } from "aws-cdk-lib/aws-lambda";
|
|
917
|
+
import { KinesisEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
|
|
918
|
+
import { NodejsFunction as NodejsFunction3 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
919
|
+
import * as rds from "aws-cdk-lib/aws-rds";
|
|
920
|
+
import { Construct as Construct3 } from "constructs";
|
|
921
|
+
var HANDLER_NAME3 = "data-store-postgres-replication.handler.js";
|
|
922
|
+
var DEFAULT_DATABASE_NAME = "openhi";
|
|
923
|
+
var SCHEMA_NAME_PATTERN = /^[a-z_][a-z0-9_]{0,62}$/;
|
|
924
|
+
var POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME = "POSTGRES_REPLICA_CLUSTER_ARN";
|
|
925
|
+
var POSTGRES_REPLICA_SECRET_ARN_SSM_NAME = "POSTGRES_REPLICA_SECRET_ARN";
|
|
926
|
+
var POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME = "POSTGRES_REPLICA_DATABASE_NAME";
|
|
927
|
+
function resolveHandlerEntry3(dirname) {
|
|
928
|
+
const sameDir = path3.join(dirname, HANDLER_NAME3);
|
|
929
|
+
if (fs3.existsSync(sameDir)) {
|
|
930
|
+
return sameDir;
|
|
931
|
+
}
|
|
932
|
+
return path3.join(dirname, "..", "..", "..", "lib", HANDLER_NAME3);
|
|
933
|
+
}
|
|
934
|
+
function getPostgresReplicaSchemaName(branchHash) {
|
|
935
|
+
const candidate = `b_${branchHash.toLowerCase()}`;
|
|
936
|
+
if (!SCHEMA_NAME_PATTERN.test(candidate)) {
|
|
937
|
+
throw new Error(
|
|
938
|
+
`Branch hash ${JSON.stringify(branchHash)} produces an invalid Postgres schema name ${JSON.stringify(candidate)}; expected /[a-z_][a-z0-9_]{0,62}/.`
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
return candidate;
|
|
942
|
+
}
|
|
943
|
+
var DataStorePostgresReplica = class extends Construct3 {
|
|
944
|
+
/**
|
|
945
|
+
* Resolve the cluster ARN published by an upstream {@link DataStorePostgresReplica}.
|
|
946
|
+
* Use from any stack that needs to grant `rds-data:ExecuteStatement` against
|
|
947
|
+
* the cluster.
|
|
948
|
+
*/
|
|
949
|
+
static clusterArnFromConstruct(scope) {
|
|
950
|
+
return DiscoverableStringParameter.valueForLookupName(scope, {
|
|
951
|
+
ssmParamName: POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME,
|
|
952
|
+
serviceType: "data"
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Resolve the credentials secret ARN published by an upstream
|
|
957
|
+
* {@link DataStorePostgresReplica}. Use from any stack that needs to grant
|
|
958
|
+
* `secretsmanager:GetSecretValue` against the secret.
|
|
959
|
+
*/
|
|
960
|
+
static secretArnFromConstruct(scope) {
|
|
961
|
+
return DiscoverableStringParameter.valueForLookupName(scope, {
|
|
962
|
+
ssmParamName: POSTGRES_REPLICA_SECRET_ARN_SSM_NAME,
|
|
963
|
+
serviceType: "data"
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Resolve the database name published by an upstream
|
|
968
|
+
* {@link DataStorePostgresReplica}.
|
|
969
|
+
*/
|
|
970
|
+
static databaseNameFromConstruct(scope) {
|
|
971
|
+
return DiscoverableStringParameter.valueForLookupName(scope, {
|
|
972
|
+
ssmParamName: POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME,
|
|
973
|
+
serviceType: "data"
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
constructor(scope, id, props) {
|
|
977
|
+
super(scope, id);
|
|
978
|
+
this.databaseName = props.databaseName ?? DEFAULT_DATABASE_NAME;
|
|
979
|
+
this.schemaName = getPostgresReplicaSchemaName(props.branchHash);
|
|
980
|
+
const region = Stack2.of(this).region;
|
|
981
|
+
this.vpc = props.vpc ?? new ec2.Vpc(this, "Vpc", {
|
|
982
|
+
availabilityZones: [`${region}a`, `${region}b`],
|
|
983
|
+
natGateways: 0,
|
|
984
|
+
subnetConfiguration: [
|
|
985
|
+
{
|
|
986
|
+
name: "isolated",
|
|
987
|
+
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
|
988
|
+
cidrMask: 24
|
|
989
|
+
}
|
|
990
|
+
]
|
|
991
|
+
});
|
|
992
|
+
this.cluster = new rds.DatabaseCluster(this, "Cluster", {
|
|
993
|
+
clusterIdentifier: `openhi-dstore-pg-${props.stackHash}`,
|
|
994
|
+
engine: rds.DatabaseClusterEngine.auroraPostgres({
|
|
995
|
+
version: rds.AuroraPostgresEngineVersion.VER_16_4
|
|
996
|
+
}),
|
|
997
|
+
vpc: this.vpc,
|
|
998
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
|
|
999
|
+
writer: rds.ClusterInstance.serverlessV2("writer"),
|
|
1000
|
+
serverlessV2MinCapacity: props.minCapacity ?? 1,
|
|
1001
|
+
serverlessV2MaxCapacity: props.maxCapacity ?? 2,
|
|
1002
|
+
defaultDatabaseName: this.databaseName,
|
|
1003
|
+
credentials: rds.Credentials.fromGeneratedSecret("openhi_admin"),
|
|
1004
|
+
storageEncrypted: true,
|
|
1005
|
+
removalPolicy: props.removalPolicy,
|
|
1006
|
+
// Phase 2 of ADR 2026-04-17-01: the REST API Lambda queries Postgres
|
|
1007
|
+
// via the RDS Data API (HTTPS) so it can stay out of the cluster's VPC.
|
|
1008
|
+
// Direct `pg` from the replication Lambda continues to work in parallel.
|
|
1009
|
+
enableDataApi: true
|
|
1010
|
+
});
|
|
1011
|
+
this.publishCoordinatesToSsm();
|
|
1012
|
+
this.replicationFunction = new NodejsFunction3(this, "ReplicationFunction", {
|
|
1013
|
+
entry: resolveHandlerEntry3(__dirname),
|
|
1014
|
+
runtime: Runtime3.NODEJS_LATEST,
|
|
1015
|
+
memorySize: 512,
|
|
1016
|
+
timeout: Duration3.minutes(1),
|
|
1017
|
+
vpc: this.vpc,
|
|
1018
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
|
|
1019
|
+
description: "Replicates DynamoDB current-resource changes into the Postgres `resources` JSONB table (ADR 2026-04-17-01).",
|
|
1020
|
+
environment: {
|
|
1021
|
+
OPENHI_PG_HOST: this.cluster.clusterEndpoint.hostname,
|
|
1022
|
+
OPENHI_PG_PORT: this.cluster.clusterEndpoint.port.toString(),
|
|
1023
|
+
OPENHI_PG_DATABASE: this.databaseName,
|
|
1024
|
+
OPENHI_PG_SCHEMA: this.schemaName,
|
|
1025
|
+
OPENHI_PG_SECRET_ARN: this.cluster.secret.secretArn,
|
|
1026
|
+
OPENHI_PG_SSL: "true"
|
|
1027
|
+
},
|
|
1028
|
+
bundling: {
|
|
1029
|
+
minify: true,
|
|
1030
|
+
sourceMap: false,
|
|
1031
|
+
// pg has conditional/optional deps (pg-native, pg-cloudflare) that
|
|
1032
|
+
// historically misbehave when bundled by esbuild; keep it as a real
|
|
1033
|
+
// node_module in the Lambda zip instead.
|
|
1034
|
+
nodeModules: ["pg"]
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
this.cluster.secret.grantRead(this.replicationFunction);
|
|
1038
|
+
this.cluster.connections.allowDefaultPortFrom(this.replicationFunction);
|
|
1039
|
+
this.replicationFunction.addEventSource(
|
|
1040
|
+
new KinesisEventSource(props.kinesisStream, {
|
|
1041
|
+
startingPosition: StartingPosition.LATEST,
|
|
1042
|
+
batchSize: 100,
|
|
1043
|
+
maxBatchingWindow: Duration3.seconds(5),
|
|
1044
|
+
retryAttempts: 10,
|
|
1045
|
+
bisectBatchOnError: true,
|
|
1046
|
+
parallelizationFactor: 2,
|
|
1047
|
+
reportBatchItemFailures: true
|
|
1048
|
+
})
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Publishes the cluster ARN, secret ARN, and database name as discoverable
|
|
1053
|
+
* SSM parameters so the REST API stack (and any future read-side consumer)
|
|
1054
|
+
* can wire RDS Data API access without a direct CDK cross-stack reference.
|
|
1055
|
+
*/
|
|
1056
|
+
publishCoordinatesToSsm() {
|
|
1057
|
+
new DiscoverableStringParameter(this, "cluster-arn-param", {
|
|
1058
|
+
ssmParamName: POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME,
|
|
1059
|
+
stringValue: this.cluster.clusterArn,
|
|
1060
|
+
description: "ARN of the Aurora Serverless v2 cluster backing the Postgres replication tier (ADR 2026-04-17-01)."
|
|
1061
|
+
});
|
|
1062
|
+
new DiscoverableStringParameter(this, "secret-arn-param", {
|
|
1063
|
+
ssmParamName: POSTGRES_REPLICA_SECRET_ARN_SSM_NAME,
|
|
1064
|
+
stringValue: this.cluster.secret.secretArn,
|
|
1065
|
+
description: "ARN of the Secrets Manager secret with credentials for the Postgres replication tier."
|
|
1066
|
+
});
|
|
1067
|
+
new DiscoverableStringParameter(this, "database-name-param", {
|
|
1068
|
+
ssmParamName: POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME,
|
|
1069
|
+
stringValue: this.databaseName,
|
|
1070
|
+
description: "Database name within the Postgres replication cluster."
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
|
|
879
1075
|
// src/components/route-53/child-hosted-zone.ts
|
|
880
|
-
import { Duration as
|
|
1076
|
+
import { Duration as Duration4 } from "aws-cdk-lib";
|
|
881
1077
|
import {
|
|
882
1078
|
HostedZone,
|
|
883
1079
|
NsRecord
|
|
@@ -889,7 +1085,7 @@ var ChildHostedZone = class extends HostedZone {
|
|
|
889
1085
|
zone: props.parentHostedZone,
|
|
890
1086
|
recordName: this.zoneName,
|
|
891
1087
|
values: this.hostedZoneNameServers || [],
|
|
892
|
-
ttl:
|
|
1088
|
+
ttl: Duration4.minutes(5)
|
|
893
1089
|
});
|
|
894
1090
|
}
|
|
895
1091
|
};
|
|
@@ -899,8 +1095,8 @@ var ChildHostedZone = class extends HostedZone {
|
|
|
899
1095
|
ChildHostedZone.SSM_PARAM_NAME = "CHILDHOSTEDZONE";
|
|
900
1096
|
|
|
901
1097
|
// src/components/route-53/root-hosted-zone.ts
|
|
902
|
-
import { Construct as
|
|
903
|
-
var RootHostedZone = class extends
|
|
1098
|
+
import { Construct as Construct4 } from "constructs";
|
|
1099
|
+
var RootHostedZone = class extends Construct4 {
|
|
904
1100
|
};
|
|
905
1101
|
|
|
906
1102
|
// src/components/static-hosting/static-hosting.ts
|
|
@@ -910,10 +1106,10 @@ import {
|
|
|
910
1106
|
} from "aws-cdk-lib/aws-cloudfront";
|
|
911
1107
|
import { S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
912
1108
|
import { Bucket as Bucket2 } from "aws-cdk-lib/aws-s3";
|
|
913
|
-
import { Duration as
|
|
914
|
-
import { Construct as
|
|
1109
|
+
import { Duration as Duration5 } from "aws-cdk-lib/core";
|
|
1110
|
+
import { Construct as Construct5 } from "constructs";
|
|
915
1111
|
var STATIC_HOSTING_SERVICE_TYPE = "website";
|
|
916
|
-
var _StaticHosting = class _StaticHosting extends
|
|
1112
|
+
var _StaticHosting = class _StaticHosting extends Construct5 {
|
|
917
1113
|
constructor(scope, id, props = {}) {
|
|
918
1114
|
super(scope, id);
|
|
919
1115
|
const stack = OpenHiService.of(scope);
|
|
@@ -931,9 +1127,9 @@ var _StaticHosting = class _StaticHosting extends Construct4 {
|
|
|
931
1127
|
const cachePolicy = new CachePolicy(this, "cache-policy", {
|
|
932
1128
|
cachePolicyName: `static-hosting-10s-${stack.branchHash}`,
|
|
933
1129
|
comment: "Low TTL (10s) for static hosting; no invalidation",
|
|
934
|
-
defaultTtl:
|
|
935
|
-
minTtl:
|
|
936
|
-
maxTtl:
|
|
1130
|
+
defaultTtl: Duration5.seconds(10),
|
|
1131
|
+
minTtl: Duration5.seconds(0),
|
|
1132
|
+
maxTtl: Duration5.seconds(10)
|
|
937
1133
|
});
|
|
938
1134
|
this.distribution = new Distribution(this, "distribution", {
|
|
939
1135
|
defaultBehavior: {
|
|
@@ -965,10 +1161,11 @@ _StaticHosting.SSM_PARAM_NAME_DISTRIBUTION_ARN = "STATIC_HOSTING_DISTRIBUTION_AR
|
|
|
965
1161
|
var StaticHosting = _StaticHosting;
|
|
966
1162
|
|
|
967
1163
|
// src/services/open-hi-auth-service.ts
|
|
1164
|
+
var import_config4 = __toESM(require_lib());
|
|
968
1165
|
import {
|
|
969
1166
|
LambdaVersion,
|
|
970
1167
|
UserPool as UserPool2,
|
|
971
|
-
UserPoolClient as
|
|
1168
|
+
UserPoolClient as UserPoolClient3,
|
|
972
1169
|
UserPoolDomain as UserPoolDomain2,
|
|
973
1170
|
UserPoolOperation
|
|
974
1171
|
} from "aws-cdk-lib/aws-cognito";
|
|
@@ -995,12 +1192,33 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
995
1192
|
serviceType: _OpenHiAuthService.SERVICE_TYPE
|
|
996
1193
|
}
|
|
997
1194
|
);
|
|
998
|
-
return
|
|
1195
|
+
return UserPoolClient3.fromUserPoolClientId(
|
|
999
1196
|
scope,
|
|
1000
1197
|
"user-pool-client",
|
|
1001
1198
|
userPoolClientId
|
|
1002
1199
|
);
|
|
1003
1200
|
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Returns the dedicated fixture-seeder IUserPoolClient by looking up
|
|
1203
|
+
* its ID from SSM. Only non-prod auth stacks publish this parameter
|
|
1204
|
+
* (per the conditional in {@link createFixtureSeederClient}); calling
|
|
1205
|
+
* this against a prod-deployed stack will fail at lookup time.
|
|
1206
|
+
*
|
|
1207
|
+
* Consumed by `OpenHiRestApiService` (in non-prod) so the authorizer
|
|
1208
|
+
* accepts tokens issued by this client, and by the seed-fixtures CLI
|
|
1209
|
+
* to drive USER_PASSWORD_AUTH against this client's ID.
|
|
1210
|
+
*/
|
|
1211
|
+
static fixtureSeederClientFromConstruct(scope) {
|
|
1212
|
+
const clientId = DiscoverableStringParameter.valueForLookupName(scope, {
|
|
1213
|
+
ssmParamName: CognitoFixtureSeederClient.SSM_PARAM_NAME,
|
|
1214
|
+
serviceType: _OpenHiAuthService.SERVICE_TYPE
|
|
1215
|
+
});
|
|
1216
|
+
return UserPoolClient3.fromUserPoolClientId(
|
|
1217
|
+
scope,
|
|
1218
|
+
"fixture-seeder-client",
|
|
1219
|
+
clientId
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1004
1222
|
/**
|
|
1005
1223
|
* Returns an IUserPoolDomain by looking up the Auth stack's User Pool Domain from SSM.
|
|
1006
1224
|
*/
|
|
@@ -1032,6 +1250,7 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1032
1250
|
this.userPool = this.createUserPool();
|
|
1033
1251
|
this.userPoolClient = this.createUserPoolClient();
|
|
1034
1252
|
this.userPoolDomain = this.createUserPoolDomain();
|
|
1253
|
+
this.fixtureSeederClient = this.createFixtureSeederClient();
|
|
1035
1254
|
}
|
|
1036
1255
|
/**
|
|
1037
1256
|
* Creates the KMS key for the Cognito User Pool and exports its ARN to SSM.
|
|
@@ -1093,6 +1312,31 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1093
1312
|
});
|
|
1094
1313
|
return client;
|
|
1095
1314
|
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Creates the dedicated USER_PASSWORD_AUTH app client for the
|
|
1317
|
+
* `@openhi/seed-fixtures` CLI, **only** in non-prod environments.
|
|
1318
|
+
* Returns `undefined` when this stack is being deployed to a prod
|
|
1319
|
+
* stage so the prod auth stack carries no fixture-seeder code path.
|
|
1320
|
+
*
|
|
1321
|
+
* Operator post-deploy: create a `fixture-seeder` Cognito user with
|
|
1322
|
+
* a service password (manually via console or scripted with
|
|
1323
|
+
* `aws cognito-idp admin-create-user`); the CLI consumes those creds
|
|
1324
|
+
* via env vars to drive `InitiateAuth`.
|
|
1325
|
+
*/
|
|
1326
|
+
createFixtureSeederClient() {
|
|
1327
|
+
if (this.ohEnv.ohStage.stageType === import_config4.OPEN_HI_STAGE.PROD) {
|
|
1328
|
+
return void 0;
|
|
1329
|
+
}
|
|
1330
|
+
const client = new CognitoFixtureSeederClient(this, {
|
|
1331
|
+
userPool: this.userPool
|
|
1332
|
+
});
|
|
1333
|
+
new DiscoverableStringParameter(this, "fixture-seeder-client-param", {
|
|
1334
|
+
ssmParamName: CognitoFixtureSeederClient.SSM_PARAM_NAME,
|
|
1335
|
+
stringValue: client.userPoolClientId,
|
|
1336
|
+
description: "Cognito User Pool Client ID for the OpenHI fixture-seeder CLI (USER_PASSWORD_AUTH; non-prod only); cross-stack reference"
|
|
1337
|
+
});
|
|
1338
|
+
return client;
|
|
1339
|
+
}
|
|
1096
1340
|
/**
|
|
1097
1341
|
* Creates the User Pool Domain (Cognito hosted UI) and exports domain name to SSM.
|
|
1098
1342
|
* Look up via {@link OpenHiAuthService.userPoolDomainFromConstruct}.
|
|
@@ -1224,6 +1468,7 @@ _OpenHiGlobalService.SERVICE_TYPE = "global";
|
|
|
1224
1468
|
var OpenHiGlobalService = _OpenHiGlobalService;
|
|
1225
1469
|
|
|
1226
1470
|
// src/services/open-hi-rest-api-service.ts
|
|
1471
|
+
var import_config5 = __toESM(require_lib());
|
|
1227
1472
|
import {
|
|
1228
1473
|
CorsHttpMethod,
|
|
1229
1474
|
DomainName,
|
|
@@ -1242,7 +1487,7 @@ import {
|
|
|
1242
1487
|
RecordTarget
|
|
1243
1488
|
} from "aws-cdk-lib/aws-route53";
|
|
1244
1489
|
import { ApiGatewayv2DomainProperties } from "aws-cdk-lib/aws-route53-targets";
|
|
1245
|
-
import { Duration as
|
|
1490
|
+
import { Duration as Duration6 } from "aws-cdk-lib/core";
|
|
1246
1491
|
|
|
1247
1492
|
// src/services/open-hi-data-service.ts
|
|
1248
1493
|
import { StreamViewType, Table as Table2 } from "aws-cdk-lib/aws-dynamodb";
|
|
@@ -1288,7 +1533,11 @@ var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
|
|
|
1288
1533
|
"data-store-change-stream",
|
|
1289
1534
|
{
|
|
1290
1535
|
streamName: `openhi-dstore-cdc-${this.branchHash}`,
|
|
1291
|
-
streamMode: kinesis.StreamMode.ON_DEMAND
|
|
1536
|
+
streamMode: kinesis.StreamMode.ON_DEMAND,
|
|
1537
|
+
// CDK default for kinesis.Stream is RETAIN, which strands the stream
|
|
1538
|
+
// when a non-prod stack is destroyed. Use the service's policy so
|
|
1539
|
+
// non-prod tears down cleanly while prod retains.
|
|
1540
|
+
removalPolicy: this.removalPolicy
|
|
1292
1541
|
}
|
|
1293
1542
|
);
|
|
1294
1543
|
this.dataStore = this.createDataStore();
|
|
@@ -1302,6 +1551,16 @@ var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
|
|
|
1302
1551
|
dataEventBus: this.dataEventBus
|
|
1303
1552
|
}
|
|
1304
1553
|
);
|
|
1554
|
+
this.dataStorePostgresReplica = new DataStorePostgresReplica(
|
|
1555
|
+
this,
|
|
1556
|
+
"data-store-postgres-replica",
|
|
1557
|
+
{
|
|
1558
|
+
kinesisStream: this.dataStoreChangeStream,
|
|
1559
|
+
removalPolicy: this.removalPolicy,
|
|
1560
|
+
stackHash: this.stackHash,
|
|
1561
|
+
branchHash: this.branchHash
|
|
1562
|
+
}
|
|
1563
|
+
);
|
|
1305
1564
|
}
|
|
1306
1565
|
/**
|
|
1307
1566
|
* Creates the data event bus.
|
|
@@ -1332,57 +1591,61 @@ _OpenHiDataService.SERVICE_TYPE = "data";
|
|
|
1332
1591
|
var OpenHiDataService = _OpenHiDataService;
|
|
1333
1592
|
|
|
1334
1593
|
// src/data/lambda/cors-options-lambda.ts
|
|
1335
|
-
import
|
|
1336
|
-
import
|
|
1337
|
-
import { Runtime as
|
|
1338
|
-
import { NodejsFunction as
|
|
1339
|
-
import { Construct as
|
|
1340
|
-
var
|
|
1341
|
-
function
|
|
1342
|
-
const sameDir =
|
|
1343
|
-
if (
|
|
1594
|
+
import fs4 from "fs";
|
|
1595
|
+
import path4 from "path";
|
|
1596
|
+
import { Runtime as Runtime4 } from "aws-cdk-lib/aws-lambda";
|
|
1597
|
+
import { NodejsFunction as NodejsFunction4 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1598
|
+
import { Construct as Construct6 } from "constructs";
|
|
1599
|
+
var HANDLER_NAME4 = "cors-options-lambda.handler.js";
|
|
1600
|
+
function resolveHandlerEntry4(dirname) {
|
|
1601
|
+
const sameDir = path4.join(dirname, HANDLER_NAME4);
|
|
1602
|
+
if (fs4.existsSync(sameDir)) {
|
|
1344
1603
|
return sameDir;
|
|
1345
1604
|
}
|
|
1346
|
-
const fromLib =
|
|
1605
|
+
const fromLib = path4.join(dirname, "..", "..", "..", "lib", HANDLER_NAME4);
|
|
1347
1606
|
return fromLib;
|
|
1348
1607
|
}
|
|
1349
|
-
var CorsOptionsLambda = class extends
|
|
1608
|
+
var CorsOptionsLambda = class extends Construct6 {
|
|
1350
1609
|
constructor(scope, id = "cors-options-lambda") {
|
|
1351
1610
|
super(scope, id);
|
|
1352
|
-
this.lambda = new
|
|
1353
|
-
entry:
|
|
1354
|
-
runtime:
|
|
1611
|
+
this.lambda = new NodejsFunction4(this, "handler", {
|
|
1612
|
+
entry: resolveHandlerEntry4(__dirname),
|
|
1613
|
+
runtime: Runtime4.NODEJS_LATEST,
|
|
1355
1614
|
memorySize: 128
|
|
1356
1615
|
});
|
|
1357
1616
|
}
|
|
1358
1617
|
};
|
|
1359
1618
|
|
|
1360
1619
|
// src/data/lambda/rest-api-lambda.ts
|
|
1361
|
-
import
|
|
1362
|
-
import
|
|
1363
|
-
import { Runtime as
|
|
1364
|
-
import { NodejsFunction as
|
|
1365
|
-
import { Construct as
|
|
1366
|
-
var
|
|
1367
|
-
function
|
|
1368
|
-
const sameDir =
|
|
1369
|
-
if (
|
|
1620
|
+
import fs5 from "fs";
|
|
1621
|
+
import path5 from "path";
|
|
1622
|
+
import { Runtime as Runtime5 } from "aws-cdk-lib/aws-lambda";
|
|
1623
|
+
import { NodejsFunction as NodejsFunction5 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1624
|
+
import { Construct as Construct7 } from "constructs";
|
|
1625
|
+
var HANDLER_NAME5 = "rest-api-lambda.handler.js";
|
|
1626
|
+
function resolveHandlerEntry5(dirname) {
|
|
1627
|
+
const sameDir = path5.join(dirname, HANDLER_NAME5);
|
|
1628
|
+
if (fs5.existsSync(sameDir)) {
|
|
1370
1629
|
return sameDir;
|
|
1371
1630
|
}
|
|
1372
|
-
const fromLib =
|
|
1631
|
+
const fromLib = path5.join(dirname, "..", "..", "..", "lib", HANDLER_NAME5);
|
|
1373
1632
|
return fromLib;
|
|
1374
1633
|
}
|
|
1375
|
-
var RestApiLambda = class extends
|
|
1634
|
+
var RestApiLambda = class extends Construct7 {
|
|
1376
1635
|
constructor(scope, props) {
|
|
1377
1636
|
super(scope, "rest-api-lambda");
|
|
1378
|
-
this.lambda = new
|
|
1379
|
-
entry:
|
|
1380
|
-
runtime:
|
|
1637
|
+
this.lambda = new NodejsFunction5(this, "handler", {
|
|
1638
|
+
entry: resolveHandlerEntry5(__dirname),
|
|
1639
|
+
runtime: Runtime5.NODEJS_LATEST,
|
|
1381
1640
|
memorySize: 1024,
|
|
1382
1641
|
environment: {
|
|
1383
1642
|
DYNAMO_TABLE_NAME: props.dynamoTableName,
|
|
1384
1643
|
BRANCH_TAG_VALUE: props.branchTagValue,
|
|
1385
|
-
HTTP_API_TAG_VALUE: props.httpApiTagValue
|
|
1644
|
+
HTTP_API_TAG_VALUE: props.httpApiTagValue,
|
|
1645
|
+
OPENHI_PG_CLUSTER_ARN: props.postgresClusterArn,
|
|
1646
|
+
OPENHI_PG_SECRET_ARN: props.postgresSecretArn,
|
|
1647
|
+
OPENHI_PG_DATABASE: props.postgresDatabase,
|
|
1648
|
+
OPENHI_PG_SCHEMA: props.postgresSchema
|
|
1386
1649
|
},
|
|
1387
1650
|
bundling: {
|
|
1388
1651
|
minify: true,
|
|
@@ -1501,11 +1764,36 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
1501
1764
|
*/
|
|
1502
1765
|
createRestApiLambdaAndRoutes(hostedZone, domainName) {
|
|
1503
1766
|
const dataStoreTable = OpenHiDataService.dynamoDbDataStoreFromConstruct(this);
|
|
1767
|
+
const postgresClusterArn = DataStorePostgresReplica.clusterArnFromConstruct(this);
|
|
1768
|
+
const postgresSecretArn = DataStorePostgresReplica.secretArnFromConstruct(this);
|
|
1769
|
+
const postgresDatabase = DataStorePostgresReplica.databaseNameFromConstruct(this);
|
|
1770
|
+
const postgresSchema = getPostgresReplicaSchemaName(this.branchHash);
|
|
1504
1771
|
const { lambda } = new RestApiLambda(this, {
|
|
1505
1772
|
dynamoTableName: dataStoreTable.tableName,
|
|
1506
1773
|
branchTagValue: this.branchName,
|
|
1507
|
-
httpApiTagValue: RootHttpApi.SSM_PARAM_NAME
|
|
1774
|
+
httpApiTagValue: RootHttpApi.SSM_PARAM_NAME,
|
|
1775
|
+
postgresClusterArn,
|
|
1776
|
+
postgresSecretArn,
|
|
1777
|
+
postgresDatabase,
|
|
1778
|
+
postgresSchema
|
|
1508
1779
|
});
|
|
1780
|
+
lambda.addToRolePolicy(
|
|
1781
|
+
new PolicyStatement({
|
|
1782
|
+
effect: Effect.ALLOW,
|
|
1783
|
+
actions: [
|
|
1784
|
+
"rds-data:ExecuteStatement",
|
|
1785
|
+
"rds-data:BatchExecuteStatement"
|
|
1786
|
+
],
|
|
1787
|
+
resources: [postgresClusterArn]
|
|
1788
|
+
})
|
|
1789
|
+
);
|
|
1790
|
+
lambda.addToRolePolicy(
|
|
1791
|
+
new PolicyStatement({
|
|
1792
|
+
effect: Effect.ALLOW,
|
|
1793
|
+
actions: ["secretsmanager:GetSecretValue"],
|
|
1794
|
+
resources: [postgresSecretArn]
|
|
1795
|
+
})
|
|
1796
|
+
);
|
|
1509
1797
|
const dynamoActions = [
|
|
1510
1798
|
"dynamodb:GetItem",
|
|
1511
1799
|
"dynamodb:Query",
|
|
@@ -1585,10 +1873,16 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
1585
1873
|
createRootHttpApi(domainName) {
|
|
1586
1874
|
const userPool = OpenHiAuthService.userPoolFromConstruct(this);
|
|
1587
1875
|
const userPoolClient = OpenHiAuthService.userPoolClientFromConstruct(this);
|
|
1876
|
+
const userPoolClients = [userPoolClient];
|
|
1877
|
+
if (this.ohEnv.ohStage.stageType !== import_config5.OPEN_HI_STAGE.PROD) {
|
|
1878
|
+
userPoolClients.push(
|
|
1879
|
+
OpenHiAuthService.fixtureSeederClientFromConstruct(this)
|
|
1880
|
+
);
|
|
1881
|
+
}
|
|
1588
1882
|
const cognitoAuthorizer = new HttpUserPoolAuthorizer(
|
|
1589
1883
|
"cognito-authorizer",
|
|
1590
1884
|
userPool,
|
|
1591
|
-
{ userPoolClients
|
|
1885
|
+
{ userPoolClients }
|
|
1592
1886
|
);
|
|
1593
1887
|
const { corsPreflight: cors, ...restRootHttpApiProps } = this.props.rootHttpApiProps ?? {};
|
|
1594
1888
|
const corsPreflight = cors !== void 0 ? {
|
|
@@ -1607,7 +1901,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
1607
1901
|
"Authorization"
|
|
1608
1902
|
],
|
|
1609
1903
|
allowCredentials: cors.allowCredentials ?? true,
|
|
1610
|
-
maxAge: cors.maxAge ??
|
|
1904
|
+
maxAge: cors.maxAge ?? Duration6.days(1),
|
|
1611
1905
|
...cors.exposeHeaders !== void 0 && {
|
|
1612
1906
|
exposeHeaders: cors.exposeHeaders
|
|
1613
1907
|
}
|
|
@@ -1673,6 +1967,7 @@ _OpenHiGraphqlService.SERVICE_TYPE = "graphql-api";
|
|
|
1673
1967
|
var OpenHiGraphqlService = _OpenHiGraphqlService;
|
|
1674
1968
|
export {
|
|
1675
1969
|
ChildHostedZone,
|
|
1970
|
+
CognitoFixtureSeederClient,
|
|
1676
1971
|
CognitoUserPool,
|
|
1677
1972
|
CognitoUserPoolClient,
|
|
1678
1973
|
CognitoUserPoolDomain,
|
|
@@ -1682,6 +1977,7 @@ export {
|
|
|
1682
1977
|
DATA_STORE_CHANGE_EVENT_SOURCE,
|
|
1683
1978
|
DataEventBus,
|
|
1684
1979
|
DataStoreHistoricalArchive,
|
|
1980
|
+
DataStorePostgresReplica,
|
|
1685
1981
|
DiscoverableStringParameter,
|
|
1686
1982
|
DynamoDbDataStore,
|
|
1687
1983
|
OpenHiApp,
|
|
@@ -1694,6 +1990,9 @@ export {
|
|
|
1694
1990
|
OpenHiService,
|
|
1695
1991
|
OpenHiStage,
|
|
1696
1992
|
OpsEventBus,
|
|
1993
|
+
POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME,
|
|
1994
|
+
POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME,
|
|
1995
|
+
POSTGRES_REPLICA_SECRET_ARN_SSM_NAME,
|
|
1697
1996
|
PreTokenGenerationLambda,
|
|
1698
1997
|
REST_API_BASE_URL_SSM_NAME,
|
|
1699
1998
|
RootGraphqlApi,
|
|
@@ -1703,6 +2002,7 @@ export {
|
|
|
1703
2002
|
STATIC_HOSTING_SERVICE_TYPE,
|
|
1704
2003
|
StaticHosting,
|
|
1705
2004
|
buildFhirCurrentResourceChangeDetail,
|
|
1706
|
-
getDynamoDbDataStoreTableName
|
|
2005
|
+
getDynamoDbDataStoreTableName,
|
|
2006
|
+
getPostgresReplicaSchemaName
|
|
1707
2007
|
};
|
|
1708
2008
|
//# sourceMappingURL=index.mjs.map
|