@openhi/constructs 0.0.0 → 0.0.1

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.
Files changed (101) hide show
  1. package/lib/chunk-LZOMFHX3.mjs +38 -0
  2. package/lib/chunk-LZOMFHX3.mjs.map +1 -0
  3. package/lib/index.d.mts +664 -0
  4. package/lib/index.d.ts +745 -3
  5. package/lib/index.js +1133 -19
  6. package/lib/index.js.map +1 -0
  7. package/lib/index.mjs +1120 -0
  8. package/lib/index.mjs.map +1 -0
  9. package/lib/rest-api-lambda.handler.d.mts +6 -0
  10. package/lib/rest-api-lambda.handler.d.ts +6 -0
  11. package/lib/rest-api-lambda.handler.js +677 -0
  12. package/lib/rest-api-lambda.handler.js.map +1 -0
  13. package/lib/rest-api-lambda.handler.mjs +646 -0
  14. package/lib/rest-api-lambda.handler.mjs.map +1 -0
  15. package/package.json +37 -28
  16. package/lib/app/index.d.ts +0 -4
  17. package/lib/app/index.js +0 -21
  18. package/lib/app/open-hi-app.d.ts +0 -85
  19. package/lib/app/open-hi-app.js +0 -127
  20. package/lib/app/open-hi-environment.d.ts +0 -59
  21. package/lib/app/open-hi-environment.js +0 -72
  22. package/lib/app/open-hi-service.d.ts +0 -169
  23. package/lib/app/open-hi-service.js +0 -195
  24. package/lib/app/open-hi-stage.d.ts +0 -71
  25. package/lib/app/open-hi-stage.js +0 -70
  26. package/lib/components/acm/root-wildcard-certificate.d.ts +0 -15
  27. package/lib/components/acm/root-wildcard-certificate.js +0 -35
  28. package/lib/components/api-gateway/core-http-api.d.ts +0 -10
  29. package/lib/components/api-gateway/core-http-api.js +0 -44
  30. package/lib/components/api-gateway/http-lambda-integration-no-permissions.d.ts +0 -18
  31. package/lib/components/api-gateway/http-lambda-integration-no-permissions.js +0 -26
  32. package/lib/components/app-sync/core-graphql-api.d.ts +0 -12
  33. package/lib/components/app-sync/core-graphql-api.js +0 -54
  34. package/lib/components/auth.d.ts +0 -75
  35. package/lib/components/auth.js +0 -100
  36. package/lib/components/cognito/core-user-pool-client.d.ts +0 -10
  37. package/lib/components/cognito/core-user-pool-client.js +0 -47
  38. package/lib/components/cognito/core-user-pool-domain.d.ts +0 -10
  39. package/lib/components/cognito/core-user-pool-domain.js +0 -41
  40. package/lib/components/cognito/core-user-pool-kms-key.d.ts +0 -10
  41. package/lib/components/cognito/core-user-pool-kms-key.js +0 -37
  42. package/lib/components/cognito/core-user-pool.d.ts +0 -10
  43. package/lib/components/cognito/core-user-pool.js +0 -54
  44. package/lib/components/core.d.ts +0 -102
  45. package/lib/components/core.js +0 -79
  46. package/lib/components/dynamodb/dynamo-db-data-store.d.ts +0 -33
  47. package/lib/components/dynamodb/dynamo-db-data-store.js +0 -107
  48. package/lib/components/event-bridge/data-event-bus.d.ts +0 -19
  49. package/lib/components/event-bridge/data-event-bus.js +0 -34
  50. package/lib/components/event-bridge/ops-event-bus.d.ts +0 -19
  51. package/lib/components/event-bridge/ops-event-bus.js +0 -34
  52. package/lib/components/global.d.ts +0 -36
  53. package/lib/components/global.js +0 -63
  54. package/lib/components/index.d.ts +0 -1
  55. package/lib/components/index.js +0 -18
  56. package/lib/components/route-53/child-hosted-zone.d.ts +0 -20
  57. package/lib/components/route-53/child-hosted-zone.js +0 -48
  58. package/lib/components/route-53/root-hosted-zone.d.ts +0 -10
  59. package/lib/components/route-53/root-hosted-zone.js +0 -20
  60. package/lib/components/ssm/discoverable-string-parameter.d.ts +0 -59
  61. package/lib/components/ssm/discoverable-string-parameter.js +0 -50
  62. package/lib/components/ssm/index.d.ts +0 -1
  63. package/lib/components/ssm/index.js +0 -18
  64. package/lib/data/dynamo/ehr/r4/Patient.d.ts +0 -180
  65. package/lib/data/dynamo/ehr/r4/Patient.js +0 -192
  66. package/lib/data/dynamo/ehr/r4/ehr-r4-data-service.d.ts +0 -162
  67. package/lib/data/dynamo/ehr/r4/ehr-r4-data-service.js +0 -37
  68. package/lib/data/hello-world.d.ts +0 -39
  69. package/lib/data/hello-world.js +0 -59
  70. package/lib/data/import-patient-with-dynalite.d.ts +0 -1
  71. package/lib/data/import-patient-with-dynalite.js +0 -87
  72. package/lib/data/import-patient.d.ts +0 -47
  73. package/lib/data/import-patient.js +0 -158
  74. package/lib/data/lambda/rest-api-lambda.d.ts +0 -13
  75. package/lib/data/lambda/rest-api-lambda.handler.d.ts +0 -1
  76. package/lib/data/lambda/rest-api-lambda.handler.js +0 -10
  77. package/lib/data/lambda/rest-api-lambda.js +0 -22
  78. package/lib/data/middleware/open-hi-context.d.ts +0 -13
  79. package/lib/data/middleware/open-hi-context.js +0 -31
  80. package/lib/data/rest-api/ehr/r4/Patient.d.ts +0 -16
  81. package/lib/data/rest-api/ehr/r4/Patient.js +0 -234
  82. package/lib/data/rest-api/rest-api-local.d.ts +0 -1
  83. package/lib/data/rest-api/rest-api-local.js +0 -8
  84. package/lib/data/rest-api/rest-api-mockdata.d.ts +0 -7
  85. package/lib/data/rest-api/rest-api-mockdata.js +0 -585
  86. package/lib/data/rest-api/rest-api.d.ts +0 -3
  87. package/lib/data/rest-api/rest-api.js +0 -26
  88. package/lib/lib/compression.d.ts +0 -27
  89. package/lib/lib/compression.js +0 -87
  90. package/lib/services/index.d.ts +0 -5
  91. package/lib/services/index.js +0 -22
  92. package/lib/services/open-hi-auth-service.d.ts +0 -31
  93. package/lib/services/open-hi-auth-service.js +0 -31
  94. package/lib/services/open-hi-core-service.d.ts +0 -15
  95. package/lib/services/open-hi-core-service.js +0 -38
  96. package/lib/services/open-hi-data-service.d.ts +0 -18
  97. package/lib/services/open-hi-data-service.js +0 -18
  98. package/lib/services/open-hi-global-service.d.ts +0 -15
  99. package/lib/services/open-hi-global-service.js +0 -44
  100. package/lib/services/open-hi-rest-api-service.d.ts +0 -17
  101. package/lib/services/open-hi-rest-api-service.js +0 -107
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/lambda/rest-api-lambda.handler.ts","../src/data/rest-api/rest-api.ts","../src/data/middleware/open-hi-context.ts","../src/data/rest-api/ehr/r4/Patient.ts","../src/lib/compression.ts","../src/data/dynamo/ehr/r4/ehr-r4-data-service.ts","../src/data/dynamo/ehr/r4/Patient.ts","../src/data/import-patient.ts"],"sourcesContent":["import serverlessExpress from \"@codegenie/serverless-express\";\nimport { app } from \"../rest-api/rest-api\";\n\nexport const handler = serverlessExpress({ app });\n","import path from \"path\";\nimport cors from \"cors\";\nimport express, { Express, Request, Response } from \"express\";\nimport { openHiContextMiddleware } from \"../middleware/open-hi-context\";\nimport { patientRouter } from \"./ehr/r4/Patient\";\n\nconst app: Express = express();\n\napp.set(\"view engine\", \"ejs\");\napp.set(\"views\", path.join(__dirname, \"views\"));\n\napp.use(cors());\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\napp.get(\"/\", (_req: Request, res: Response) => {\n return res.status(200).json({ message: \"POC App is running\" });\n});\n\n// Tenant/workspace resolved from headers/env (or JWT when implemented); attached to req for /ehr routes\napp.use(\"/ehr\", openHiContextMiddleware);\n\n// FHIR R4 EHR endpoints: path structure mirrors folder structure (ehr/r4/Patient.ts → /ehr/r4/Patient)\napp.use(\"/ehr/r4/Patient\", patientRouter);\n\nexport { app };\n","import type { Request, Response, NextFunction } from \"express\";\n\n/** Static context used until JWT claims are implemented. */\nconst STATIC_TENANT_ID = \"tenant-1\";\nconst STATIC_WORKSPACE_ID = \"ws-1\";\nconst STATIC_USER_ID = \"rest-api\";\nconst STATIC_USER_NAME = \"REST API\";\n\n/**\n * Express middleware that sets req.openhiContext for /ehr (and other domain API)\n * routes. Context includes tenantId, workspaceId, and the three standard audit\n * fields (date, userId, username) for audit records and for merging into FHIR\n * data on mutations.\n *\n * **TODO: A future task will populate context from JWT claims** (e.g. after\n * verifying the token). For now, static values are used.\n *\n * @see sites/www-docs/content/packages/@openhi/constructs/rest-api.md — Middleware\n */\nexport function openHiContextMiddleware(\n req: Request,\n _res: Response,\n next: NextFunction,\n): void {\n const now = new Date().toISOString();\n req.openhiContext = {\n tenantId: STATIC_TENANT_ID,\n workspaceId: STATIC_WORKSPACE_ID,\n date: now,\n userId: STATIC_USER_ID,\n username: STATIC_USER_NAME,\n };\n next();\n}\n","import express, { Request, Response } from \"express\";\nimport {\n compressResource,\n decompressResource,\n} from \"../../../../lib/compression\";\nimport { getEhrR4DataService } from \"../../../dynamo/ehr/r4/ehr-r4-data-service\";\nimport {\n mergeAuditIntoMeta,\n patientToPutAttrs,\n type ImportPatientOptions,\n} from \"../../../import-patient\";\n\nconst BASE_PATH = \"/ehr/r4/Patient\";\nconst router: express.Router = express.Router();\nconst SK = \"CURRENT\";\n\nconst TABLE_NAME = process.env.DYNAMO_TABLE_NAME ?? \"jesttesttable\";\n\n/**\n * GET /ehr/r4/Patient — search/list: returns a FHIR Bundle (searchset) from the data store.\n * Uses GSI4 (Resource Type Index) to list all Patients in the workspace without a table scan.\n * @see {@link https://github.com/codedrifters/openhi/blob/main/sites/www-docs/content/architecture/dynamodb-single-table-design.md | DynamoDB Single-Table Design} — GSI4, Query and Access Rules (no scans).\n */\nexport async function listPatients(\n req: Request,\n res: Response,\n): Promise<Response> {\n const { tenantId, workspaceId } = req.openhiContext!;\n const service = getEhrR4DataService(TABLE_NAME);\n\n try {\n const result = await service.entities.patient.query\n .gsi4({ tenantId, workspaceId })\n .go();\n\n const entries = (result.data ?? []).map((item) => {\n const resource = JSON.parse(decompressResource(item.resource)) as Record<\n string,\n unknown\n >;\n return {\n fullUrl: `${BASE_PATH}/${item.id}`,\n resource: { ...resource, id: item.id },\n };\n });\n const bundle = {\n resourceType: \"Bundle\",\n type: \"searchset\",\n total: entries.length,\n link: [{ relation: \"self\", url: BASE_PATH }],\n entry: entries,\n };\n return res.json(bundle);\n } catch (err: unknown) {\n console.error(\"GET /Patient list error:\", err);\n return res.status(500).json({\n resourceType: \"OperationOutcome\",\n issue: [\n {\n severity: \"error\",\n code: \"exception\",\n diagnostics: String(err),\n },\n ],\n });\n }\n}\n\nrouter.get(\"/\", listPatients);\n\nexport async function getPatientById(\n req: Request,\n res: Response,\n): Promise<Response> {\n const id = String(req.params.id);\n const { tenantId, workspaceId } = req.openhiContext!;\n const service = getEhrR4DataService(TABLE_NAME);\n\n try {\n const result = await service.entities.patient\n .get({ tenantId, workspaceId, id, sk: \"CURRENT\" })\n .go();\n\n if (!result.data) {\n return res.status(404).json({\n resourceType: \"OperationOutcome\",\n issue: [\n {\n severity: \"error\",\n code: \"not-found\",\n diagnostics: `Patient ${id} not found`,\n },\n ],\n });\n }\n\n const resource = JSON.parse(\n decompressResource(result.data.resource),\n ) as Record<string, unknown>;\n return res.json({ ...resource, id: result.data.id });\n } catch (err: unknown) {\n console.error(\"GET Patient error:\", err);\n return res.status(500).json({\n resourceType: \"OperationOutcome\",\n issue: [\n {\n severity: \"error\",\n code: \"exception\",\n diagnostics: String(err),\n },\n ],\n });\n }\n}\n\n/** GET /ehr/r4/Patient/:id — read: returns a single Patient resource from the data store or 404. */\nrouter.get(\"/:id\", getPatientById);\n\n/** POST /ehr/r4/Patient — create: accepts Patient in body, persists via data store, returns 201. */\nexport async function createPatient(\n req: Request,\n res: Response,\n): Promise<Response> {\n const ctx = req.openhiContext!;\n const { tenantId, workspaceId, date, userId, username } = ctx;\n const body = req.body as Record<string, unknown>;\n const id = (body?.id as string) ?? `patient-${Date.now()}`;\n const patient = {\n ...body,\n resourceType: \"Patient\",\n id,\n meta: {\n ...((body?.meta as object) ?? {}),\n lastUpdated: date,\n versionId: \"1\",\n },\n } as { resourceType: string; id: string; meta?: { lastUpdated?: string } };\n const options: ImportPatientOptions = {\n tenantId,\n workspaceId,\n createdDate: date,\n createdById: userId,\n createdByName: username,\n modifiedDate: date,\n modifiedById: userId,\n modifiedByName: username,\n };\n const service = getEhrR4DataService(TABLE_NAME);\n\n try {\n const attrs = patientToPutAttrs(patient, options);\n await service.entities.patient\n .put(\n attrs as unknown as Parameters<typeof service.entities.patient.put>[0],\n )\n .go();\n return res.status(201).location(`${BASE_PATH}/${id}`).json(patient);\n } catch (err: unknown) {\n console.error(\"POST Patient error:\", err);\n return res.status(500).json({\n resourceType: \"OperationOutcome\",\n issue: [\n { severity: \"error\", code: \"exception\", diagnostics: String(err) },\n ],\n });\n }\n}\n\nrouter.post(\"/\", createPatient);\n\n/** PUT /ehr/r4/Patient/:id — update: accepts Patient in body, persists via data store, returns 200. */\nexport async function updatePatient(\n req: Request,\n res: Response,\n): Promise<Response> {\n const id = String(req.params.id);\n const ctx = req.openhiContext!;\n const { tenantId, workspaceId, date, userId, username } = ctx;\n const body = req.body as Record<string, unknown>;\n const patient = {\n ...body,\n resourceType: \"Patient\",\n id,\n meta: {\n ...((body?.meta as object) ?? {}),\n lastUpdated: date,\n versionId: \"2\",\n },\n };\n const service = getEhrR4DataService(TABLE_NAME);\n\n try {\n const existing = await service.entities.patient\n .get({ tenantId, workspaceId, id, sk: SK })\n .go();\n if (!existing.data) {\n return res.status(404).json({\n resourceType: \"OperationOutcome\",\n issue: [\n {\n severity: \"error\",\n code: \"not-found\",\n diagnostics: `Patient ${id} not found`,\n },\n ],\n });\n }\n const existingMeta =\n existing.data.resource != null\n ? (\n JSON.parse(decompressResource(existing.data.resource)) as {\n meta?: Record<string, unknown>;\n }\n ).meta\n : undefined;\n const patientWithMeta = {\n ...patient,\n meta: mergeAuditIntoMeta(\n (patient.meta as Record<string, unknown> | undefined) ?? existingMeta,\n {\n modifiedDate: date,\n modifiedById: userId,\n modifiedByName: username,\n },\n ),\n };\n await service.entities.patient\n .patch({ tenantId, workspaceId, id, sk: SK })\n .set({\n resource: compressResource(JSON.stringify(patientWithMeta)),\n lastUpdated: date,\n })\n .go();\n return res.json(patientWithMeta);\n } catch (err: unknown) {\n console.error(\"PUT Patient error:\", err);\n return res.status(500).json({\n resourceType: \"OperationOutcome\",\n issue: [\n { severity: \"error\", code: \"exception\", diagnostics: String(err) },\n ],\n });\n }\n}\n\nrouter.put(\"/:id\", updatePatient);\n\n/** DELETE /ehr/r4/Patient/:id — delete: removes from data store, returns 204. */\nexport async function deletePatient(\n req: Request,\n res: Response,\n): Promise<Response> {\n const id = String(req.params.id);\n const { tenantId, workspaceId } = req.openhiContext!;\n const service = getEhrR4DataService(TABLE_NAME);\n\n try {\n await service.entities.patient\n .delete({ tenantId, workspaceId, id, sk: SK })\n .go();\n return res.status(204).send();\n } catch (err: unknown) {\n console.error(\"DELETE Patient error:\", err);\n return res.status(500).json({\n resourceType: \"OperationOutcome\",\n issue: [\n { severity: \"error\", code: \"exception\", diagnostics: String(err) },\n ],\n });\n }\n}\n\nrouter.delete(\"/:id\", deletePatient);\n\nexport { router as patientRouter };\n","import { gzipSync, gunzipSync } from \"node:zlib\";\n\n/** Envelope format version. See ADR 2026-02-15-02 (data layer compression). */\nconst ENVELOPE_VERSION = 1;\n\n/**\n * Compression algorithm identifiers supported by the envelope (string values).\n * Only algos that Node.js supports out of the box (zlib): gzip, brotli, deflate.\n * \"none\" = uncompressed payload. zstd was considered in the ADR but requires native addon/WASM.\n */\nexport const COMPRESSION_ALGOS = {\n NONE: \"none\",\n GZIP: \"gzip\",\n BROTLI: \"brotli\",\n DEFLATE: \"deflate\",\n} as const;\n\n/** Algorithm value for envelope `algo`; only gzip and none are implemented today. */\nexport type CompressionAlgo =\n (typeof COMPRESSION_ALGOS)[keyof typeof COMPRESSION_ALGOS];\n\n/** Stored value is a JSON string of this envelope. */\ninterface CompressionEnvelope {\n v: number;\n algo: string;\n payload: string;\n}\n\nfunction isEnvelope(obj: unknown): obj is CompressionEnvelope {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"v\" in obj &&\n \"algo\" in obj &&\n \"payload\" in obj &&\n typeof (obj as CompressionEnvelope).payload === \"string\"\n );\n}\n\n/**\n * Compresses a JSON string (e.g. serialized FHIR resource) for storage in DynamoDB.\n * Uses a versioned envelope: { v, algo, payload } with gzip+base64 in payload.\n * Used by the data layer on write; see REST API docs (compression in data layer).\n * Optional compression: pass `{ algo: COMPRESSION_ALGOS.NONE }` to store in envelope without compressing.\n */\nexport function compressResource(\n jsonString: string,\n options?: { algo?: CompressionAlgo },\n): string {\n const algo = options?.algo ?? COMPRESSION_ALGOS.GZIP;\n if (algo === COMPRESSION_ALGOS.NONE) {\n const envelope: CompressionEnvelope = {\n v: ENVELOPE_VERSION,\n algo: COMPRESSION_ALGOS.NONE,\n payload: jsonString,\n };\n return JSON.stringify(envelope);\n }\n const buf = Buffer.from(jsonString, \"utf-8\");\n const payload = gzipSync(buf).toString(\"base64\");\n const envelope: CompressionEnvelope = {\n v: ENVELOPE_VERSION,\n algo: COMPRESSION_ALGOS.GZIP,\n payload,\n };\n return JSON.stringify(envelope);\n}\n\n/**\n * Decompresses a stored value: versioned envelope (v, algo, payload) or legacy gzip+base64 / raw.\n * If the value is not valid envelope JSON, falls back to legacy: try gzip magic on base64, else return as-is.\n */\nexport function decompressResource(compressedOrRaw: string): string {\n try {\n const parsed = JSON.parse(compressedOrRaw) as unknown;\n if (isEnvelope(parsed)) {\n if (parsed.algo === COMPRESSION_ALGOS.GZIP) {\n const buf = Buffer.from(parsed.payload, \"base64\");\n return gunzipSync(buf).toString(\"utf-8\");\n }\n if (parsed.algo === COMPRESSION_ALGOS.NONE) {\n return parsed.payload;\n }\n // Unknown algo: return payload as-is (safe fallback per ADR)\n return parsed.payload;\n }\n } catch {\n // Not valid envelope JSON — legacy path\n }\n\n // Legacy: pre-envelope gzip+base64 or raw\n try {\n const buf = Buffer.from(compressedOrRaw, \"base64\");\n if (buf.length >= 2 && buf[0] === 0x1f && buf[1] === 0x8b) {\n return gunzipSync(buf).toString(\"utf-8\");\n }\n } catch {\n // not base64 or gunzip failed\n }\n return compressedOrRaw;\n}\n","import { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";\nimport { Service } from \"electrodb\";\nimport { Patient } from \"./Patient\";\n\n/**\n * DynamoDB table name for the data store. Set via DYNAMO_TABLE_NAME at runtime\n * (e.g. from Lambda env); defaults for local/test.\n */\nconst table = process.env.DYNAMO_TABLE_NAME ?? \"jesttesttable\";\n\n/**\n * DynamoDB client. When MOCK_DYNAMODB_ENDPOINT is set (e.g. local DynamoDB or\n * jest-dynalite), uses that endpoint with no SSL and region \"local\".\n */\nconst client = new DynamoDBClient({\n ...(process.env.MOCK_DYNAMODB_ENDPOINT && {\n endpoint: process.env.MOCK_DYNAMODB_ENDPOINT,\n sslEnabled: false,\n region: \"local\",\n }),\n});\n\nconst entities = { patient: Patient };\n\n/**\n * ElectroDB Service for the single-table data store. Provides access to Patient\n * and other entities; use with the data store table (PK, SK, GSI1, GSI2, GSI3, GSI4).\n */\nexport const EhrR4DataService = new Service(entities, { table, client });\n\n/**\n * Returns an ElectroDB Service for the data store using the given table name.\n * Use in tests with a dedicated table (e.g. \"data-store-test\" in jest-dynalite).\n */\nexport function getEhrR4DataService(\n tableName: string,\n): typeof EhrR4DataService {\n return new Service(entities, { table: tableName, client });\n}\n","import { Entity } from \"electrodb\";\n\n/**\n * Patient data-store entity based on FHIR (single-table store).\n *\n * Key structure: PK = TID#<tenantId>#WID#<workspaceId>#RT#Patient#ID#<id>, SK = CURRENT.\n * Standard attributes (FHIR source and entity purpose) are documented in the Data-Store Entity Standards (FHIR).\n *\n * @see sites/www-docs/content/reference/data-store-entities.md — Standard attributes (all FHIR domain resources)\n * @see sites/www-docs/content/architecture/dynamodb-single-table-design.md\n */\nexport const Patient = new Entity({\n model: {\n entity: \"patient\",\n service: \"fhir\",\n version: \"01\",\n },\n attributes: {\n /** Sort key. \"CURRENT\" for current version; version history in S3. */\n sk: {\n type: \"string\",\n required: true,\n default: \"CURRENT\",\n },\n tenantId: {\n type: \"string\",\n required: true,\n },\n workspaceId: {\n type: \"string\",\n required: true,\n },\n /** FHIR Resource.id; logical id in URL and PK. */\n id: {\n type: \"string\",\n required: true,\n },\n /** FHIR resource as JSON string. JSON.stringify(resource) on write; JSON.parse(item.resource) on read. */\n resource: {\n type: \"string\",\n required: true,\n },\n /** Version id (e.g. ULID). Tracks current version; S3 history key. */\n vid: {\n type: \"string\",\n required: true,\n },\n lastUpdated: {\n type: \"string\",\n required: true,\n },\n deleted: {\n type: \"boolean\",\n required: false,\n },\n bundleId: {\n type: \"string\",\n required: false,\n },\n msgId: {\n type: \"string\",\n required: false,\n },\n // Audit is in FHIR resource meta (meta.extension), not item attributes. See data-store-entities.md.\n // --- GSI2 (Identifier Lookup): optional; set when indexing this patient by identifier (e.g. MRN)\n /** Identifier system (e.g. MRN system URI). When set with identifierValue, item is written to GSI2. */\n identifierSystem: {\n type: \"string\",\n required: false,\n },\n /** Identifier value (e.g. MRN). When set with identifierSystem, item is written to GSI2. */\n identifierValue: {\n type: \"string\",\n required: false,\n },\n /** For GSI2/GSI3 projection: base table PK/SK so GetItem can be used after query. */\n resourcePk: {\n type: \"string\",\n required: false,\n },\n resourceSk: {\n type: \"string\",\n required: false,\n },\n /** For GSI2 projection: display name for roster/lookup. */\n display: {\n type: \"string\",\n required: false,\n },\n /** For GSI2 projection: resource status if applicable. */\n status: {\n type: \"string\",\n required: false,\n },\n // --- GSI3 (Facility Ops): optional; set when indexing this patient on a facility roster\n /** Facility id. When set with normalizedName, item is written to GSI3. */\n facilityId: {\n type: \"string\",\n required: false,\n },\n /** Normalized display name for roster sort. When set with facilityId, item is written to GSI3. */\n normalizedName: {\n type: \"string\",\n required: false,\n },\n },\n indexes: {\n /** Base table: PK, SK (data store key names). PK is built from tenantId, workspaceId, id; do not supply PK from outside. */\n record: {\n pk: {\n field: \"PK\",\n composite: [\"tenantId\", \"workspaceId\", \"id\"],\n template: \"TID#${tenantId}#WID#${workspaceId}#RT#Patient#ID#${id}\",\n },\n sk: {\n field: \"SK\",\n composite: [\"sk\"],\n },\n },\n\n /**\n * GSI1 — Reverse Reference: query \"what references this patient?\".\n * Patient items are never written to GSI1 (condition: false); reference index items\n * are written by other resources. This index enables querying GSI1 by REFTO#RT#Patient#ID#<id>.\n */\n gsi1: {\n index: \"GSI1\",\n condition: () => false,\n pk: {\n field: \"GSI1PK\",\n composite: [\"tenantId\", \"workspaceId\", \"id\"],\n template:\n \"TID#${tenantId}#WID#${workspaceId}#REFTO#RT#Patient#ID#${id}\",\n },\n sk: {\n field: \"GSI1SK\",\n composite: [],\n },\n },\n\n /** GSI2 — Identifier Lookup: MRN, NPI, member ID, etc. Keys built from identifier components. */\n gsi2: {\n index: \"GSI2\",\n condition: (attr) =>\n attr.identifierSystem != null && attr.identifierValue != null,\n pk: {\n field: \"GSI2PK\",\n composite: [\n \"tenantId\",\n \"workspaceId\",\n \"identifierSystem\",\n \"identifierValue\",\n ],\n template:\n \"TID#${tenantId}#WID#${workspaceId}#IDENT#${identifierSystem}#${identifierValue}\",\n },\n sk: {\n field: \"GSI2SK\",\n composite: [\"id\"],\n template: \"RT#Patient#ID#${id}\",\n },\n },\n /** GSI3 — Facility Ops: facility roster, worklists. Keys built from facility + name. */\n gsi3: {\n index: \"GSI3\",\n condition: (attr) =>\n attr.facilityId != null && attr.normalizedName != null,\n pk: {\n field: \"GSI3PK\",\n composite: [\"tenantId\", \"workspaceId\", \"facilityId\"],\n template: \"TID#${tenantId}#WID#${workspaceId}#FAC#${facilityId}\",\n },\n sk: {\n field: \"GSI3SK\",\n composite: [\"id\", \"normalizedName\"],\n template: \"TYPE#PATIENT#PAT#${id}#NAME#${normalizedName}\",\n },\n },\n /** GSI4 — Resource Type Index: list all Patients in workspace (no scan). */\n gsi4: {\n index: \"GSI4\",\n condition: () => true,\n pk: {\n field: \"GSI4PK\",\n composite: [\"tenantId\", \"workspaceId\"],\n template: \"TID#${tenantId}#WID#${workspaceId}#RT#Patient\",\n },\n sk: {\n field: \"GSI4SK\",\n composite: [\"id\"],\n template: \"ID#${id}\",\n },\n },\n },\n});\n","import { readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { compressResource } from \"../lib/compression\";\nimport { getEhrR4DataService } from \"./dynamo/ehr/r4/ehr-r4-data-service\";\n\n/** OpenHI extension URLs for audit in resource meta (per ADR 2026-01-13-06). */\nconst OPENHI_EXT = \"http://openhi.org/fhir/StructureDefinition\";\n\n/** Audit fields stored in FHIR resource meta.extension. */\nexport interface AuditFields {\n createdDate?: string;\n createdById?: string;\n createdByName?: string;\n modifiedDate?: string;\n modifiedById?: string;\n modifiedByName?: string;\n deletedDate?: string;\n deletedById?: string;\n deletedByName?: string;\n}\n\n/** Builds meta.extension entries for audit; merges with existing meta. */\nexport function mergeAuditIntoMeta(\n meta: Record<string, unknown> | undefined,\n audit: AuditFields,\n): Record<string, unknown> {\n const existing = meta ?? {};\n const ext: Array<{\n url: string;\n valueString?: string;\n valueDateTime?: string;\n }> = [\n ...(Array.isArray(existing.extension)\n ? (existing.extension as Array<{\n url: string;\n valueString?: string;\n valueDateTime?: string;\n }>)\n : []),\n ];\n const byUrl = new Map(ext.map((e) => [e.url, e]));\n function set(\n url: string,\n value: string | undefined,\n type: \"valueString\" | \"valueDateTime\",\n ) {\n if (value == null) return;\n byUrl.set(url, { url, [type]: value });\n }\n set(`${OPENHI_EXT}/created-date`, audit.createdDate, \"valueDateTime\");\n set(`${OPENHI_EXT}/created-by-id`, audit.createdById, \"valueString\");\n set(`${OPENHI_EXT}/created-by-name`, audit.createdByName, \"valueString\");\n set(`${OPENHI_EXT}/modified-date`, audit.modifiedDate, \"valueDateTime\");\n set(`${OPENHI_EXT}/modified-by-id`, audit.modifiedById, \"valueString\");\n set(`${OPENHI_EXT}/modified-by-name`, audit.modifiedByName, \"valueString\");\n set(`${OPENHI_EXT}/deleted-date`, audit.deletedDate, \"valueDateTime\");\n set(`${OPENHI_EXT}/deleted-by-id`, audit.deletedById, \"valueString\");\n set(`${OPENHI_EXT}/deleted-by-name`, audit.deletedByName, \"valueString\");\n return { ...existing, extension: Array.from(byUrl.values()) };\n}\n\n/** Minimal FHIR Patient shape needed for import (id and resourceType required). */\ninterface FhirPatientLike {\n resourceType: string;\n id: string;\n meta?: Record<string, unknown>;\n}\n\n/** FHIR Bundle entry (e.g. Synthea transaction bundle). */\ninterface BundleEntry {\n fullUrl?: string;\n resource?: {\n resourceType?: string;\n id?: string;\n meta?: { lastUpdated?: string };\n };\n}\n\n/**\n * Extracts a Patient from parsed JSON. Accepts either:\n * - A standalone Patient resource (root has resourceType \"Patient\"), or\n * - A FHIR Bundle (e.g. Synthea transaction) — uses the first entry whose resource is a Patient.\n */\nfunction extractPatient(parsed: unknown): FhirPatientLike {\n if (parsed && typeof parsed === \"object\" && \"resourceType\" in parsed) {\n const root = parsed as {\n resourceType?: string;\n id?: string;\n meta?: { lastUpdated?: string };\n };\n if (root.resourceType === \"Patient\" && root.id) {\n return root as FhirPatientLike;\n }\n if (root.resourceType === \"Bundle\" && \"entry\" in parsed) {\n const entries = (parsed as { entry?: BundleEntry[] }).entry;\n if (Array.isArray(entries)) {\n const patientEntry = entries.find(\n (e) => e?.resource?.resourceType === \"Patient\" && e.resource.id,\n );\n if (patientEntry?.resource) {\n return patientEntry.resource as FhirPatientLike;\n }\n }\n }\n }\n throw new Error(\n \"File must be a FHIR Patient resource or a Bundle containing at least one Patient entry\",\n );\n}\n\nconst SK = \"CURRENT\";\n\n/** Default audit values for create/modify when importing. */\nconst defaultAudit = {\n createdDate: new Date().toISOString(),\n createdById: \"import\",\n createdByName: \"Bulk import\",\n modifiedDate: new Date().toISOString(),\n modifiedById: \"import\",\n modifiedByName: \"Bulk import\",\n};\n\nexport interface ImportPatientOptions {\n tenantId: string;\n workspaceId: string;\n tableName?: string;\n /** Audit fields at same level as tenantId/workspaceId; merged with defaults. */\n createdDate?: string;\n createdById?: string;\n createdByName?: string;\n modifiedDate?: string;\n modifiedById?: string;\n modifiedByName?: string;\n}\n\n/**\n * Maps a FHIR Patient (from JSON) to the attributes required for Patient.put().\n * Uses placeholder GSI2/GSI3 fields so ElectroDB index conditions are satisfied.\n */\nexport function patientToPutAttrs(\n patient: FhirPatientLike,\n options: ImportPatientOptions,\n): Record<string, unknown> {\n const {\n tenantId,\n workspaceId,\n createdDate,\n createdById,\n createdByName,\n modifiedDate,\n modifiedById,\n modifiedByName,\n } = options;\n const lastUpdated =\n (patient.meta?.lastUpdated as string | undefined) ??\n modifiedDate ??\n defaultAudit.modifiedDate ??\n new Date().toISOString();\n const auditMerged: AuditFields = {\n ...defaultAudit,\n ...(createdDate != null && { createdDate }),\n ...(createdById != null && { createdById }),\n ...(createdByName != null && { createdByName }),\n ...(modifiedDate != null && { modifiedDate }),\n ...(modifiedById != null && { modifiedById }),\n ...(modifiedByName != null && { modifiedByName }),\n };\n\n const patientWithMeta = {\n ...patient,\n meta: mergeAuditIntoMeta(patient.meta, auditMerged),\n };\n if (lastUpdated && !patientWithMeta.meta.lastUpdated) {\n (patientWithMeta.meta as Record<string, unknown>).lastUpdated = lastUpdated;\n }\n\n return {\n sk: SK,\n tenantId,\n workspaceId,\n id: patient.id,\n resource: compressResource(JSON.stringify(patientWithMeta)),\n vid:\n lastUpdated.replace(/[-:T.Z]/g, \"\").slice(0, 12) ||\n Date.now().toString(36),\n lastUpdated,\n identifierSystem: \"\",\n identifierValue: \"\",\n facilityId: \"\",\n normalizedName: \"\",\n };\n}\n\n/**\n * Reads a single Patient JSON file and imports it into the FHIR store.\n * Table name: options.tableName ?? process.env.DYNAMO_TABLE_NAME ?? \"jesttesttable\".\n */\nexport async function importPatientFromFile(\n filePath: string,\n options: ImportPatientOptions,\n): Promise<{ id: string; tenantId: string; workspaceId: string }> {\n const resolved = resolve(filePath);\n const raw = readFileSync(resolved, \"utf-8\");\n const parsed: unknown = JSON.parse(raw);\n const patient = extractPatient(parsed);\n\n const tableName =\n options.tableName ?? process.env.DYNAMO_TABLE_NAME ?? \"jesttesttable\";\n const service = getEhrR4DataService(tableName);\n const attrs = patientToPutAttrs(patient, options);\n\n const result = await service.entities.patient\n .put(attrs as unknown as Parameters<typeof service.entities.patient.put>[0])\n .go();\n\n const data = (\n result as { data?: { id: string; tenantId: string; workspaceId: string } }\n ).data;\n if (!data) {\n throw new Error(`Put failed for Patient ${patient.id}`);\n }\n\n return {\n id: data.id,\n tenantId: data.tenantId,\n workspaceId: data.workspaceId,\n };\n}\n\n/** Run as script: node/ts-node import-patient.ts <path-to-patient.json> [tenantId] [workspaceId] */\nasync function main(): Promise<void> {\n const [, , fileArg, tenantId = \"tenant-1\", workspaceId = \"ws-1\"] =\n process.argv;\n\n if (!fileArg) {\n console.error(\n \"Usage: import-patient.ts <path-to-patient.json> [tenantId] [workspaceId]\",\n );\n process.exit(1);\n }\n\n try {\n const result = await importPatientFromFile(fileArg, {\n tenantId,\n workspaceId,\n });\n console.log(\n `Imported Patient ${result.id} (tenant=${result.tenantId}, workspace=${result.workspaceId})`,\n );\n } catch (err) {\n console.error(err);\n process.exit(1);\n }\n}\n\nif (require.main === module) {\n void main();\n}\n"],"mappings":"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","names":["express","envelope","SK","express"]}
package/package.json CHANGED
@@ -1,23 +1,5 @@
1
1
  {
2
2
  "name": "@openhi/constructs",
3
- "scripts": {
4
- "build": "npx projen build",
5
- "compile": "npx projen compile",
6
- "default": "npx projen default",
7
- "eslint": "npx projen eslint",
8
- "import-patient": "npx projen import-patient",
9
- "package": "npx projen package",
10
- "post-compile": "npx projen post-compile",
11
- "post-upgrade": "npx projen post-upgrade",
12
- "pre-compile": "npx projen pre-compile",
13
- "reset": "npx projen reset",
14
- "run-lambda-local": "npx projen run-lambda-local",
15
- "test": "npx projen test",
16
- "test:watch": "npx projen test:watch",
17
- "upgrade": "npx projen upgrade",
18
- "watch": "npx projen watch",
19
- "projen": "npx projen"
20
- },
21
3
  "devDependencies": {
22
4
  "@swc/core": "^1.15.11",
23
5
  "@swc/jest": "^0.2.39",
@@ -27,8 +9,9 @@
27
9
  "@types/node": "^22.19.11",
28
10
  "@typescript-eslint/eslint-plugin": "^8",
29
11
  "@typescript-eslint/parser": "^8",
30
- "aws-cdk-lib": "catalog:",
31
- "constructs": "catalog:",
12
+ "aws-cdk-lib": "2.238.0",
13
+ "commit-and-tag-version": "^12",
14
+ "constructs": "10.4.5",
32
15
  "copyfiles": "^2.4.1",
33
16
  "eslint": "^9",
34
17
  "eslint-config-prettier": "^10.1.8",
@@ -39,29 +22,55 @@
39
22
  "jest-dynalite": "^3.6.1",
40
23
  "jest-junit": "^16",
41
24
  "prettier": "^3.8.1",
25
+ "rollup": "^4.57.1",
26
+ "rollup-plugin-dts": "^6.3.0",
27
+ "tsup": "^8.5.1",
42
28
  "typescript": "^5.9.3"
43
29
  },
44
30
  "peerDependencies": {
45
- "aws-cdk-lib": "catalog:",
46
- "constructs": "catalog:"
31
+ "aws-cdk-lib": "2.238.0",
32
+ "constructs": "10.4.5"
47
33
  },
48
34
  "dependencies": {
49
35
  "@aws-sdk/client-dynamodb": "^3.990.0",
50
36
  "@codedrifters/utils": "^0.0.0",
51
37
  "@codegenie/serverless-express": "^4.17.1",
52
- "@openhi/config": "workspace:*",
53
38
  "@types/aws-lambda": "^8.10.160",
54
39
  "awscdk-appsync-utils": "^0.0.850",
55
40
  "change-case": "^4.0",
56
41
  "cors": "^2.8.6",
57
42
  "electrodb": "^3.5.3",
58
43
  "express": "^5.2.1",
59
- "type-fest": "^4"
44
+ "type-fest": "^4",
45
+ "@openhi/config": "0.0.0"
60
46
  },
61
47
  "main": "lib/index.js",
62
48
  "license": "UNLICENSED",
63
- "version": "0.0.0",
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "version": "0.0.1",
64
53
  "types": "lib/index.d.ts",
65
- "packageManager": "pnpm@10.29.3",
66
- "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
67
- }
54
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\".",
55
+ "scripts": {
56
+ "build": "npx projen build",
57
+ "bump": "npx projen bump",
58
+ "compile": "npx projen compile",
59
+ "default": "npx projen default",
60
+ "eslint": "npx projen eslint",
61
+ "import-patient": "npx projen import-patient",
62
+ "package": "npx projen package",
63
+ "post-compile": "npx projen post-compile",
64
+ "post-upgrade": "npx projen post-upgrade",
65
+ "pre-compile": "npx projen pre-compile",
66
+ "release": "npx projen release",
67
+ "reset": "npx projen reset",
68
+ "run-lambda-local": "npx projen run-lambda-local",
69
+ "test": "npx projen test",
70
+ "test:watch": "npx projen test:watch",
71
+ "unbump": "npx projen unbump",
72
+ "upgrade": "npx projen upgrade",
73
+ "watch": "npx projen watch",
74
+ "projen": "npx projen"
75
+ }
76
+ }
@@ -1,4 +0,0 @@
1
- export * from "./open-hi-app";
2
- export * from "./open-hi-environment";
3
- export * from "./open-hi-service";
4
- export * from "./open-hi-stage";
package/lib/app/index.js DELETED
@@ -1,21 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./open-hi-app"), exports);
18
- __exportStar(require("./open-hi-environment"), exports);
19
- __exportStar(require("./open-hi-service"), exports);
20
- __exportStar(require("./open-hi-stage"), exports);
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBOEI7QUFDOUIsd0RBQXNDO0FBQ3RDLG9EQUFrQztBQUNsQyxrREFBZ0MiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9vcGVuLWhpLWFwcFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3Blbi1oaS1lbnZpcm9ubWVudFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3Blbi1oaS1zZXJ2aWNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vcGVuLWhpLXN0YWdlXCI7XG4iXX0=
@@ -1,85 +0,0 @@
1
- import { OpenHiConfig } from "@openhi/config";
2
- import { App, AppProps } from "aws-cdk-lib";
3
- import { IConstruct } from "constructs";
4
- import { OpenHiEnvironment } from "./open-hi-environment";
5
- import { OpenHiStage } from "./open-hi-stage";
6
- /**
7
- * Properties for creating an OpenHiApp instance.
8
- */
9
- export interface OpenHiAppProps extends AppProps {
10
- /**
11
- * Optional name for the application.
12
- * ```
13
- */
14
- readonly appName?: string;
15
- /**
16
- * The OpenHi configuration object that defines stages, environments, and
17
- * their associated AWS account and region settings.
18
- */
19
- readonly config: OpenHiConfig;
20
- }
21
- /**
22
- * Root application construct for OpenHi CDK applications.
23
- */
24
- export declare class OpenHiApp extends App {
25
- /**
26
- * Finds the OpenHiApp instance that contains the given construct in its
27
- * construct tree.
28
- */
29
- static of(construct: IConstruct): OpenHiApp | undefined;
30
- /**
31
- * Type guard that checks if a value is an OpenHiApp instance.
32
- */
33
- static isOpenHiApp(this: void, x: any): x is OpenHiApp;
34
- /**
35
- * Name for the application.
36
- */
37
- readonly appName: string;
38
- /**
39
- * The OpenHi configuration object for this application.
40
- */
41
- readonly config: OpenHiConfig;
42
- /**
43
- * Creates a new OpenHiApp instance.
44
- */
45
- constructor(props: OpenHiAppProps);
46
- /*****************************************************************************
47
- *
48
- * Stages
49
- *
50
- ****************************************************************************/
51
- /**
52
- * Gets all OpenHiStage instances that are direct children of this app.
53
-
54
- */
55
- get stages(): Array<OpenHiStage>;
56
- /**
57
- * Gets the development stage, if it exists.
58
- */
59
- get devStage(): OpenHiStage | undefined;
60
- /**
61
- * Gets the staging stage, if it exists.
62
- */
63
- get stageStage(): OpenHiStage | undefined;
64
- /**
65
- * Gets the production stage, if it exists.
66
- */
67
- get prodStage(): OpenHiStage | undefined;
68
- /*****************************************************************************
69
- *
70
- * Environments
71
- *
72
- ****************************************************************************/
73
- /**
74
- * Gets all OpenHiEnvironment instances across all stages in this app.
75
- */
76
- get environments(): Array<OpenHiEnvironment>;
77
- /**
78
- * Gets all primary environments across all stages in this app.
79
- */
80
- get primaryEnvironments(): Array<OpenHiEnvironment>;
81
- /**
82
- * Gets all secondary environments across all stages in this app.
83
- */
84
- get secondaryEnvironments(): Array<OpenHiEnvironment>;
85
- }
@@ -1,127 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenHiApp = void 0;
4
- const config_1 = require("@openhi/config");
5
- const aws_cdk_lib_1 = require("aws-cdk-lib");
6
- const open_hi_environment_1 = require("./open-hi-environment");
7
- const open_hi_stage_1 = require("./open-hi-stage");
8
- /**
9
- * Symbol used for runtime type checking to identify OpenHiApp instances.
10
- *
11
- * @internal
12
- */
13
- const OPEN_HI_APP_SYMBOL = Symbol.for("@openhi/constructs/core.OpenHiApp");
14
- /**
15
- * Root application construct for OpenHi CDK applications.
16
- */
17
- class OpenHiApp extends aws_cdk_lib_1.App {
18
- /**
19
- * Finds the OpenHiApp instance that contains the given construct in its
20
- * construct tree.
21
- */
22
- static of(construct) {
23
- return construct.node.scopes.reverse().find(OpenHiApp.isOpenHiApp);
24
- }
25
- /**
26
- * Type guard that checks if a value is an OpenHiApp instance.
27
- */
28
- static isOpenHiApp(x) {
29
- return x !== null && typeof x === "object" && OPEN_HI_APP_SYMBOL in x;
30
- }
31
- /**
32
- * Creates a new OpenHiApp instance.
33
- */
34
- constructor(props) {
35
- super(props);
36
- // Set runtime symbol for type checking
37
- Object.defineProperty(this, OPEN_HI_APP_SYMBOL, { value: true });
38
- // Store app name, defaulting to "openhi" if not provided
39
- this.appName = props.appName ?? "openhi";
40
- // Store configuration for use by child constructs
41
- this.config = props.config;
42
- // Create stages and environments based on configuration
43
- // Iterate through all possible stage types (dev, stage, prod)
44
- Object.values(config_1.OPEN_HI_STAGE).forEach((stageType) => {
45
- // Only create a stage if it's configured in the config
46
- if (this.config.deploymentTargets?.[stageType]) {
47
- const stage = new open_hi_stage_1.OpenHiStage(this, { stageType });
48
- // Create primary deployment target if configured
49
- // Each stage can have at most one primary deployment target
50
- if (this.config.deploymentTargets?.[stageType]?.[config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY]) {
51
- const envConfig = this.config.deploymentTargets[stageType][config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY];
52
- new open_hi_environment_1.OpenHiEnvironment(stage, {
53
- deploymentTargetRole: config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY,
54
- config: envConfig,
55
- env: { account: envConfig.account, region: envConfig.region },
56
- });
57
- }
58
- // Create secondary deployment targets if configured
59
- // Each stage can have zero or more secondary deployment targets
60
- if (this.config.deploymentTargets?.[stageType]?.[config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY]) {
61
- this.config.deploymentTargets[stageType][config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY].forEach((envConfig) => {
62
- new open_hi_environment_1.OpenHiEnvironment(stage, {
63
- deploymentTargetRole: config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.SECONDARY,
64
- config: envConfig,
65
- env: { account: envConfig.account, region: envConfig.region },
66
- });
67
- });
68
- }
69
- }
70
- });
71
- }
72
- /*****************************************************************************
73
- *
74
- * Stages
75
- *
76
- ****************************************************************************/
77
- /**
78
- * Gets all OpenHiStage instances that are direct children of this app.
79
-
80
- */
81
- get stages() {
82
- return this.node.children.filter(open_hi_stage_1.OpenHiStage.isOpenHiStage);
83
- }
84
- /**
85
- * Gets the development stage, if it exists.
86
- */
87
- get devStage() {
88
- return this.stages.find((stage) => stage.stageType === config_1.OPEN_HI_STAGE.DEV);
89
- }
90
- /**
91
- * Gets the staging stage, if it exists.
92
- */
93
- get stageStage() {
94
- return this.stages.find((stage) => stage.stageType === config_1.OPEN_HI_STAGE.STAGE);
95
- }
96
- /**
97
- * Gets the production stage, if it exists.
98
- */
99
- get prodStage() {
100
- return this.stages.find((stage) => stage.stageType === config_1.OPEN_HI_STAGE.PROD);
101
- }
102
- /*****************************************************************************
103
- *
104
- * Environments
105
- *
106
- ****************************************************************************/
107
- /**
108
- * Gets all OpenHiEnvironment instances across all stages in this app.
109
- */
110
- get environments() {
111
- return this.stages.flatMap((stage) => stage.environments);
112
- }
113
- /**
114
- * Gets all primary environments across all stages in this app.
115
- */
116
- get primaryEnvironments() {
117
- return this.environments.filter((env) => env.deploymentTargetRole === "primary");
118
- }
119
- /**
120
- * Gets all secondary environments across all stages in this app.
121
- */
122
- get secondaryEnvironments() {
123
- return this.environments.filter((env) => env.deploymentTargetRole === "secondary");
124
- }
125
- }
126
- exports.OpenHiApp = OpenHiApp;
127
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi1oaS1hcHAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwL29wZW4taGktYXBwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUt3QjtBQUN4Qiw2Q0FBNEM7QUFFNUMsK0RBQTBEO0FBQzFELG1EQUE4QztBQUU5Qzs7OztHQUlHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFtQjNFOztHQUVHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsaUJBQUc7SUFDaEM7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFxQjtRQUNwQyxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFdBQVcsQ0FBYSxDQUFNO1FBQzFDLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksa0JBQWtCLElBQUksQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFZRDs7T0FFRztJQUNILFlBQVksS0FBcUI7UUFDL0IsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsdUNBQXVDO1FBQ3ZDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFakUseURBQXlEO1FBQ3pELElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSSxRQUFRLENBQUM7UUFFekMsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUUzQix3REFBd0Q7UUFDeEQsOERBQThEO1FBQzlELE1BQU0sQ0FBQyxNQUFNLENBQUMsc0JBQWEs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QUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBVyxtQkFBbUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FDN0IsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsS0FBSyxTQUFTLENBQ2hELENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFXLHFCQUFxQjtRQUM5QixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUM3QixDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLG9CQUFvQixLQUFLLFdBQVcsQ0FDbEQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXhKRCw4QkF3SkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBPUEVOX0hJX0RFUExPWU1FTlRfVEFSR0VUX1JPTEUsXG4gIE9QRU5fSElfU1RBR0UsXG4gIE9wZW5IaUNvbmZpZyxcbiAgT3BlbkhpRW52aXJvbm1lbnRDb25maWcsXG59IGZyb20gXCJAb3BlbmhpL2NvbmZpZ1wiO1xuaW1wb3J0IHsgQXBwLCBBcHBQcm9wcyB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBPcGVuSGlFbnZpcm9ubWVudCB9IGZyb20gXCIuL29wZW4taGktZW52aXJvbm1lbnRcIjtcbmltcG9ydCB7IE9wZW5IaVN0YWdlIH0gZnJvbSBcIi4vb3Blbi1oaS1zdGFnZVwiO1xuXG4vKipcbiAqIFN5bWJvbCB1c2VkIGZvciBydW50aW1lIHR5cGUgY2hlY2tpbmcgdG8gaWRlbnRpZnkgT3BlbkhpQXBwIGluc3RhbmNlcy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY29uc3QgT1BFTl9ISV9BUFBfU1lNQk9MID0gU3ltYm9sLmZvcihcIkBvcGVuaGkvY29uc3RydWN0cy9jb3JlLk9wZW5IaUFwcFwiKTtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBjcmVhdGluZyBhbiBPcGVuSGlBcHAgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkhpQXBwUHJvcHMgZXh0ZW5kcyBBcHBQcm9wcyB7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBuYW1lIGZvciB0aGUgYXBwbGljYXRpb24uXG4gICAqIGBgYFxuICAgKi9cbiAgcmVhZG9ubHkgYXBwTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIE9wZW5IaSBjb25maWd1cmF0aW9uIG9iamVjdCB0aGF0IGRlZmluZXMgc3RhZ2VzLCBlbnZpcm9ubWVudHMsIGFuZFxuICAgKiB0aGVpciBhc3NvY2lhdGVkIEFXUyBhY2NvdW50IGFuZCByZWdpb24gc2V0dGluZ3MuXG4gICAqL1xuICByZWFkb25seSBjb25maWc6IE9wZW5IaUNvbmZpZztcbn1cblxuLyoqXG4gKiBSb290IGFwcGxpY2F0aW9uIGNvbnN0cnVjdCBmb3IgT3BlbkhpIENESyBhcHBsaWNhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuSGlBcHAgZXh0ZW5kcyBBcHAge1xuICAvKipcbiAgICogRmluZHMgdGhlIE9wZW5IaUFwcCBpbnN0YW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBnaXZlbiBjb25zdHJ1Y3QgaW4gaXRzXG4gICAqIGNvbnN0cnVjdCB0cmVlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBvZihjb25zdHJ1Y3Q6IElDb25zdHJ1Y3QpOiBPcGVuSGlBcHAgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBjb25zdHJ1Y3Qubm9kZS5zY29wZXMucmV2ZXJzZSgpLmZpbmQoT3BlbkhpQXBwLmlzT3BlbkhpQXBwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUeXBlIGd1YXJkIHRoYXQgY2hlY2tzIGlmIGEgdmFsdWUgaXMgYW4gT3BlbkhpQXBwIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc09wZW5IaUFwcCh0aGlzOiB2b2lkLCB4OiBhbnkpOiB4IGlzIE9wZW5IaUFwcCB7XG4gICAgcmV0dXJuIHggIT09IG51bGwgJiYgdHlwZW9mIHggPT09IFwib2JqZWN0XCIgJiYgT1BFTl9ISV9BUFBfU1lNQk9MIGluIHg7XG4gIH1cblxuICAvKipcbiAgICogTmFtZSBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgYXBwTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgT3BlbkhpIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciB0aGlzIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnOiBPcGVuSGlDb25maWc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgT3BlbkhpQXBwIGluc3RhbmNlLlxuICAgKi9cbiAgY29uc3RydWN0b3IocHJvcHM6IE9wZW5IaUFwcFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4gICAgLy8gU2V0IHJ1bnRpbWUgc3ltYm9sIGZvciB0eXBlIGNoZWNraW5nXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIE9QRU5fSElfQVBQX1NZTUJPTCwgeyB2YWx1ZTogdHJ1ZSB9KTtcblxuICAgIC8vIFN0b3JlIGFwcCBuYW1lLCBkZWZhdWx0aW5nIHRvIFwib3BlbmhpXCIgaWYgbm90IHByb3ZpZGVkXG4gICAgdGhpcy5hcHBOYW1lID0gcHJvcHMuYXBwTmFtZSA/PyBcIm9wZW5oaVwiO1xuXG4gICAgLy8gU3RvcmUgY29uZmlndXJhdGlvbiBmb3IgdXNlIGJ5IGNoaWxkIGNvbnN0cnVjdHNcbiAgICB0aGlzLmNvbmZpZyA9IHByb3BzLmNvbmZpZztcblxuICAgIC8vIENyZWF0ZSBzdGFnZXMgYW5kIGVudmlyb25tZW50cyBiYXNlZCBvbiBjb25maWd1cmF0aW9uXG4gICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBzdGFnZSB0eXBlcyAoZGV2LCBzdGFnZSwgcHJvZClcbiAgICBPYmplY3QudmFsdWVzKE9QRU5fSElfU1RBR0UpLmZvckVhY2goKHN0YWdlVHlwZSkgPT4ge1xuICAgICAgLy8gT25seSBjcmVhdGUgYSBzdGFnZSBpZiBpdCdzIGNvbmZpZ3VyZWQgaW4gdGhlIGNvbmZpZ1xuICAgICAgaWYgKHRoaXMuY29uZmlnLmRlcGxveW1lbnRUYXJnZXRzPy5bc3RhZ2VUeXBlXSkge1xuICAgICAgICBjb25zdCBzdGFnZSA9IG5ldyBPcGVuSGlTdGFnZSh0aGlzLCB7IHN0YWdlVHlwZSB9KTtcblxuICAgICAgICAvLyBDcmVhdGUgcHJpbWFyeSBkZXBsb3ltZW50IHRhcmdldCBpZiBjb25maWd1cmVkXG4gICAgICAgIC8vIEVhY2ggc3RhZ2UgY2FuIGhhdmUgYXQgbW9zdCBvbmUgcHJpbWFyeSBkZXBsb3ltZW50IHRhcmdldFxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5jb25maWcuZGVwbG95bWVudFRhcmdldHM/LltzdGFnZVR5cGVdPy5bXG4gICAgICAgICAgICBPUEVOX0hJX0RFUExPWU1FTlRfVEFSR0VUX1JPTEUuUFJJTUFSWVxuICAgICAgICAgIF1cbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZW52Q29uZmlnID1cbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmRlcGxveW1lbnRUYXJnZXRzW3N0YWdlVHlwZV1bXG4gICAgICAgICAgICAgIE9QRU5fSElfREVQTE9ZTUVOVF9UQVJHRVRfUk9MRS5QUklNQVJZXG4gICAgICAgICAgICBdITtcbiAgICAgICAgICBuZXcgT3BlbkhpRW52aXJvbm1lbnQoc3RhZ2UsIHtcbiAgICAgICAgICAgIGRlcGxveW1lbnRUYXJnZXRSb2xlOiBPUEVOX0hJX0RFUExPWU1FTlRfVEFSR0VUX1JPTEUuUFJJTUFSWSxcbiAgICAgICAgICAgIGNvbmZpZzogZW52Q29uZmlnLFxuICAgICAgICAgICAgZW52OiB7IGFjY291bnQ6IGVudkNvbmZpZy5hY2NvdW50LCByZWdpb246IGVudkNvbmZpZy5yZWdpb24gfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBzZWNvbmRhcnkgZGVwbG95bWVudCB0YXJnZXRzIGlmIGNvbmZpZ3VyZWRcbiAgICAgICAgLy8gRWFjaCBzdGFnZSBjYW4gaGF2ZSB6ZXJvIG9yIG1vcmUgc2Vjb25kYXJ5IGRlcGxveW1lbnQgdGFyZ2V0c1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5jb25maWcuZGVwbG95bWVudFRhcmdldHM/LltzdGFnZVR5cGVdPy5bXG4gICAgICAgICAgICBPUEVOX0hJX0RFUExPWU1FTlRfVEFSR0VUX1JPTEUuU0VDT05EQVJZXG4gICAgICAgICAgXVxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLmNvbmZpZy5kZXBsb3ltZW50VGFyZ2V0c1tzdGFnZVR5cGVdW1xuICAgICAgICAgICAgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFLlNFQ09OREFSWVxuICAgICAgICAgIF0hLmZvckVhY2goKGVudkNvbmZpZzogT3BlbkhpRW52aXJvbm1lbnRDb25maWcpID0+IHtcbiAgICAgICAgICAgIG5ldyBPcGVuSGlFbnZpcm9ubWVudChzdGFnZSwge1xuICAgICAgICAgICAgICBkZXBsb3ltZW50VGFyZ2V0Um9sZTogT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFLlNFQ09OREFSWSxcbiAgICAgICAgICAgICAgY29uZmlnOiBlbnZDb25maWcsXG4gICAgICAgICAgICAgIGVudjogeyBhY2NvdW50OiBlbnZDb25maWcuYWNjb3VudCwgcmVnaW9uOiBlbnZDb25maWcucmVnaW9uIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAqXG4gICAqIFN0YWdlc1xuICAgKlxuICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAvKipcbiAgICogR2V0cyBhbGwgT3BlbkhpU3RhZ2UgaW5zdGFuY2VzIHRoYXQgYXJlIGRpcmVjdCBjaGlsZHJlbiBvZiB0aGlzIGFwcC5cblxuICAgKi9cbiAgcHVibGljIGdldCBzdGFnZXMoKTogQXJyYXk8T3BlbkhpU3RhZ2U+IHtcbiAgICByZXR1cm4gdGhpcy5ub2RlLmNoaWxkcmVuLmZpbHRlcihPcGVuSGlTdGFnZS5pc09wZW5IaVN0YWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkZXZlbG9wbWVudCBzdGFnZSwgaWYgaXQgZXhpc3RzLlxuICAgKi9cbiAgcHVibGljIGdldCBkZXZTdGFnZSgpOiBPcGVuSGlTdGFnZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhZ2VzLmZpbmQoKHN0YWdlKSA9PiBzdGFnZS5zdGFnZVR5cGUgPT09IE9QRU5fSElfU1RBR0UuREVWKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBzdGFnaW5nIHN0YWdlLCBpZiBpdCBleGlzdHMuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHN0YWdlU3RhZ2UoKTogT3BlbkhpU3RhZ2UgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0YWdlcy5maW5kKChzdGFnZSkgPT4gc3RhZ2Uuc3RhZ2VUeXBlID09PSBPUEVOX0hJX1NUQUdFLlNUQUdFKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBwcm9kdWN0aW9uIHN0YWdlLCBpZiBpdCBleGlzdHMuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHByb2RTdGFnZSgpOiBPcGVuSGlTdGFnZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhZ2VzLmZpbmQoKHN0YWdlKSA9PiBzdGFnZS5zdGFnZVR5cGUgPT09IE9QRU5fSElfU1RBR0UuUFJPRCk7XG4gIH1cblxuICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICpcbiAgICogRW52aXJvbm1lbnRzXG4gICAqXG4gICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBPcGVuSGlFbnZpcm9ubWVudCBpbnN0YW5jZXMgYWNyb3NzIGFsbCBzdGFnZXMgaW4gdGhpcyBhcHAuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGVudmlyb25tZW50cygpOiBBcnJheTxPcGVuSGlFbnZpcm9ubWVudD4ge1xuICAgIHJldHVybiB0aGlzLnN0YWdlcy5mbGF0TWFwKChzdGFnZSkgPT4gc3RhZ2UuZW52aXJvbm1lbnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBwcmltYXJ5IGVudmlyb25tZW50cyBhY3Jvc3MgYWxsIHN0YWdlcyBpbiB0aGlzIGFwcC5cbiAgICovXG4gIHB1YmxpYyBnZXQgcHJpbWFyeUVudmlyb25tZW50cygpOiBBcnJheTxPcGVuSGlFbnZpcm9ubWVudD4ge1xuICAgIHJldHVybiB0aGlzLmVudmlyb25tZW50cy5maWx0ZXIoXG4gICAgICAoZW52KSA9PiBlbnYuZGVwbG95bWVudFRhcmdldFJvbGUgPT09IFwicHJpbWFyeVwiLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBhbGwgc2Vjb25kYXJ5IGVudmlyb25tZW50cyBhY3Jvc3MgYWxsIHN0YWdlcyBpbiB0aGlzIGFwcC5cbiAgICovXG4gIHB1YmxpYyBnZXQgc2Vjb25kYXJ5RW52aXJvbm1lbnRzKCk6IEFycmF5PE9wZW5IaUVudmlyb25tZW50PiB7XG4gICAgcmV0dXJuIHRoaXMuZW52aXJvbm1lbnRzLmZpbHRlcihcbiAgICAgIChlbnYpID0+IGVudi5kZXBsb3ltZW50VGFyZ2V0Um9sZSA9PT0gXCJzZWNvbmRhcnlcIixcbiAgICApO1xuICB9XG59XG4iXX0=
@@ -1,59 +0,0 @@
1
- import { OPEN_HI_DEPLOYMENT_TARGET_ROLE, OpenHiEnvironmentConfig } from "@openhi/config";
2
- import { Stage, StageProps } from "aws-cdk-lib";
3
- import { IConstruct } from "constructs";
4
- import { OpenHiStage } from "./open-hi-stage";
5
- /**
6
- * Properties for creating an OpenHiEnvironment.
7
- */
8
- export interface OpenHiEnvironmentProps extends StageProps {
9
- /**
10
- * The deployment target role for this (account, region).
11
- */
12
- readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];
13
- /**
14
- * Configuration for this specific environment.
15
- */
16
- readonly config: OpenHiEnvironmentConfig;
17
- }
18
- /**
19
- * Represents an OpenHi environment within an AWS CDK stage.
20
- */
21
- export declare class OpenHiEnvironment extends Stage {
22
- /**
23
- * The OpenHiStage that contains this environment.
24
- */
25
- ohStage: OpenHiStage;
26
- /**
27
- * Properties for creating the environment.
28
- */
29
- props: OpenHiEnvironmentProps;
30
- /**
31
- * Finds the OpenHiEnvironment that contains the given construct.
32
- * ```
33
- */
34
- static of(construct: IConstruct): OpenHiEnvironment | undefined;
35
- /**
36
- * Type guard to check if a value is an OpenHiEnvironment instance.
37
- */
38
- static isOpenHiEnvironment(this: void, x: any): x is OpenHiEnvironment;
39
- /**
40
- * Configuration for this specific environment.
41
- */
42
- readonly config: OpenHiEnvironmentConfig;
43
- /**
44
- * The deployment target role for this (account, region).
45
- */
46
- readonly deploymentTargetRole: (typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE)[keyof typeof OPEN_HI_DEPLOYMENT_TARGET_ROLE];
47
- /**
48
- * Creates a new OpenHiEnvironment.
49
- */
50
- constructor(
51
- /**
52
- * The OpenHiStage that contains this environment.
53
- */
54
- ohStage: OpenHiStage,
55
- /**
56
- * Properties for creating the environment.
57
- */
58
- props: OpenHiEnvironmentProps);
59
- }
@@ -1,72 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenHiEnvironment = void 0;
4
- const config_1 = require("@openhi/config");
5
- const aws_cdk_lib_1 = require("aws-cdk-lib");
6
- /**
7
- * Symbol used to identify OpenHiEnvironment instances at runtime.
8
- */
9
- const OPEN_HI_ENVIRONMENT_SYMBOL = Symbol.for("@openhi/constructs/core.OpenHiEnvironment");
10
- /**
11
- * Represents an OpenHi environment within an AWS CDK stage.
12
- */
13
- class OpenHiEnvironment extends aws_cdk_lib_1.Stage {
14
- /**
15
- * Finds the OpenHiEnvironment that contains the given construct.
16
- * ```
17
- */
18
- static of(construct) {
19
- return construct.node.scopes
20
- .reverse()
21
- .find(OpenHiEnvironment.isOpenHiEnvironment);
22
- }
23
- /**
24
- * Type guard to check if a value is an OpenHiEnvironment instance.
25
- */
26
- static isOpenHiEnvironment(x) {
27
- return (x !== null && typeof x === "object" && OPEN_HI_ENVIRONMENT_SYMBOL in x);
28
- }
29
- /**
30
- * Creates a new OpenHiEnvironment.
31
- */
32
- constructor(
33
- /**
34
- * The OpenHiStage that contains this environment.
35
- */
36
- ohStage,
37
- /**
38
- * Properties for creating the environment.
39
- */
40
- props) {
41
- // Copy account and region from config into env, if provided.
42
- // This allows all resources in this environment to default to the correct
43
- // account and region without having to specify it on each stack or resource.
44
- if (props.config.account && props.config.region) {
45
- props = {
46
- ...props,
47
- env: {
48
- account: props.config.account,
49
- region: props.config.region,
50
- },
51
- };
52
- }
53
- // Determine the stage name:
54
- // - Primary environments use the environment type as the name
55
- // - Secondary deployment targets use "{deploymentTargetRole}-{index}" format
56
- const stageName = props.deploymentTargetRole === config_1.OPEN_HI_DEPLOYMENT_TARGET_ROLE.PRIMARY
57
- ? props.deploymentTargetRole
58
- : [props.deploymentTargetRole, ohStage.environments.length].join("-");
59
- super(ohStage, stageName, {
60
- env: props.env ?? ohStage.props.env,
61
- ...props,
62
- });
63
- this.ohStage = ohStage;
64
- this.props = props;
65
- // Mark this instance as an OpenHiEnvironment for runtime type checking
66
- Object.defineProperty(this, OPEN_HI_ENVIRONMENT_SYMBOL, { value: true });
67
- this.deploymentTargetRole = props.deploymentTargetRole;
68
- this.config = props.config;
69
- }
70
- }
71
- exports.OpenHiEnvironment = OpenHiEnvironment;
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi1oaS1lbnZpcm9ubWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcHAvb3Blbi1oaS1lbnZpcm9ubWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FHd0I7QUFDeEIsNkNBQWdEO0FBSWhEOztHQUVHO0FBQ0gsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUMzQywyQ0FBMkMsQ0FDNUMsQ0FBQztBQWlCRjs7R0FFRztBQUNILE1BQWEsaUJBQWtCLFNBQVEsbUJBQUs7SUFDMUM7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFxQjtRQUNwQyxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsTUFBTTthQUN6QixPQUFPLEVBQUU7YUFDVCxJQUFJLENBQUMsaUJBQWlCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsbUJBQW1CLENBRS9CLENBQU07UUFFTixPQUFPLENBQ0wsQ0FBQyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksMEJBQTBCLElBQUksQ0FBQyxDQUN2RSxDQUFDO0lBQ0osQ0FBQztJQVlEOztPQUVHO0lBQ0g7SUFDRTs7T0FFRztJQUNJLE9BQW9CO0lBQzNCOztPQUVHO0lBQ0ksS0FBNkI7UUFFcEMsNkRBQTZEO1FBQzdELDBFQUEwRTtRQUMxRSw2RUFBNkU7UUFDN0UsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hELEtBQUssR0FBRztnQkFDTixHQUFHLEtBQUs7Z0JBQ1IsR0FBRyxFQUFFO29CQUNILE9BQU8sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU87b0JBQzdCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU07aUJBQzVCO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCw0QkFBNEI7UUFDNUIsOERBQThEO1FBQzlELDZFQUE2RTtRQUM3RSxNQUFNLFNBQVMsR0FDYixLQUFLLENBQUMsb0JBQW9CLEtBQUssdUNBQThCLENBQUMsT0FBTztZQUNuRSxDQUFDLENBQUMsS0FBSyxDQUFDLG9CQUFvQjtZQUM1QixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFMUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUU7WUFDeEIsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHO1lBQ25DLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztRQTlCSSxZQUFPLEdBQVAsT0FBTyxDQUFhO1FBSXBCLFVBQUssR0FBTCxLQUFLLENBQXdCO1FBNEJwQyx1RUFBdUU7UUFDdkUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsMEJBQTBCLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUV6RSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsS0FBSyxDQUFDLG9CQUFvQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUM3QixDQUFDO0NBQ0Y7QUE5RUQsOENBOEVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFLFxuICBPcGVuSGlFbnZpcm9ubWVudENvbmZpZyxcbn0gZnJvbSBcIkBvcGVuaGkvY29uZmlnXCI7XG5pbXBvcnQgeyBTdGFnZSwgU3RhZ2VQcm9wcyB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBPcGVuSGlTdGFnZSB9IGZyb20gXCIuL29wZW4taGktc3RhZ2VcIjtcblxuLyoqXG4gKiBTeW1ib2wgdXNlZCB0byBpZGVudGlmeSBPcGVuSGlFbnZpcm9ubWVudCBpbnN0YW5jZXMgYXQgcnVudGltZS5cbiAqL1xuY29uc3QgT1BFTl9ISV9FTlZJUk9OTUVOVF9TWU1CT0wgPSBTeW1ib2wuZm9yKFxuICBcIkBvcGVuaGkvY29uc3RydWN0cy9jb3JlLk9wZW5IaUVudmlyb25tZW50XCIsXG4pO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGFuIE9wZW5IaUVudmlyb25tZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5IaUVudmlyb25tZW50UHJvcHMgZXh0ZW5kcyBTdGFnZVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBkZXBsb3ltZW50IHRhcmdldCByb2xlIGZvciB0aGlzIChhY2NvdW50LCByZWdpb24pLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudFRhcmdldFJvbGU6ICh0eXBlb2YgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFKVtrZXlvZiB0eXBlb2YgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFXTtcblxuICAvKipcbiAgICogQ29uZmlndXJhdGlvbiBmb3IgdGhpcyBzcGVjaWZpYyBlbnZpcm9ubWVudC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbmZpZzogT3BlbkhpRW52aXJvbm1lbnRDb25maWc7XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBPcGVuSGkgZW52aXJvbm1lbnQgd2l0aGluIGFuIEFXUyBDREsgc3RhZ2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuSGlFbnZpcm9ubWVudCBleHRlbmRzIFN0YWdlIHtcbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBPcGVuSGlFbnZpcm9ubWVudCB0aGF0IGNvbnRhaW5zIHRoZSBnaXZlbiBjb25zdHJ1Y3QuXG4gICAqIGBgYFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBvZihjb25zdHJ1Y3Q6IElDb25zdHJ1Y3QpOiBPcGVuSGlFbnZpcm9ubWVudCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGNvbnN0cnVjdC5ub2RlLnNjb3Blc1xuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoT3BlbkhpRW52aXJvbm1lbnQuaXNPcGVuSGlFbnZpcm9ubWVudCk7XG4gIH1cblxuICAvKipcbiAgICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHZhbHVlIGlzIGFuIE9wZW5IaUVudmlyb25tZW50IGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc09wZW5IaUVudmlyb25tZW50KFxuICAgIHRoaXM6IHZvaWQsXG4gICAgeDogYW55LFxuICApOiB4IGlzIE9wZW5IaUVudmlyb25tZW50IHtcbiAgICByZXR1cm4gKFxuICAgICAgeCAhPT0gbnVsbCAmJiB0eXBlb2YgeCA9PT0gXCJvYmplY3RcIiAmJiBPUEVOX0hJX0VOVklST05NRU5UX1NZTUJPTCBpbiB4XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciB0aGlzIHNwZWNpZmljIGVudmlyb25tZW50LlxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlnOiBPcGVuSGlFbnZpcm9ubWVudENvbmZpZztcblxuICAvKipcbiAgICogVGhlIGRlcGxveW1lbnQgdGFyZ2V0IHJvbGUgZm9yIHRoaXMgKGFjY291bnQsIHJlZ2lvbikuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGVwbG95bWVudFRhcmdldFJvbGU6ICh0eXBlb2YgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFKVtrZXlvZiB0eXBlb2YgT1BFTl9ISV9ERVBMT1lNRU5UX1RBUkdFVF9ST0xFXTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBPcGVuSGlFbnZpcm9ubWVudC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIFRoZSBPcGVuSGlTdGFnZSB0aGF0IGNvbnRhaW5zIHRoaXMgZW52aXJvbm1lbnQuXG4gICAgICovXG4gICAgcHVibGljIG9oU3RhZ2U6IE9wZW5IaVN0YWdlLFxuICAgIC8qKlxuICAgICAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIHRoZSBlbnZpcm9ubWVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgcHJvcHM6IE9wZW5IaUVudmlyb25tZW50UHJvcHMsXG4gICkge1xuICAgIC8vIENvcHkgYWNjb3VudCBhbmQgcmVnaW9uIGZyb20gY29uZmlnIGludG8gZW52LCBpZiBwcm92aWRlZC5cbiAgICAvLyBUaGlzIGFsbG93cyBhbGwgcmVzb3VyY2VzIGluIHRoaXMgZW52aXJvbm1lbnQgdG8gZGVmYXVsdCB0byB0aGUgY29ycmVjdFxuICAgIC8vIGFjY291bnQgYW5kIHJlZ2lvbiB3aXRob3V0IGhhdmluZyB0byBzcGVjaWZ5IGl0IG9uIGVhY2ggc3RhY2sgb3IgcmVzb3VyY2UuXG4gICAgaWYgKHByb3BzLmNvbmZpZy5hY2NvdW50ICYmIHByb3BzLmNvbmZpZy5yZWdpb24pIHtcbiAgICAgIHByb3BzID0ge1xuICAgICAgICAuLi5wcm9wcyxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgYWNjb3VudDogcHJvcHMuY29uZmlnLmFjY291bnQsXG4gICAgICAgICAgcmVnaW9uOiBwcm9wcy5jb25maWcucmVnaW9uLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBEZXRlcm1pbmUgdGhlIHN0YWdlIG5hbWU6XG4gICAgLy8gLSBQcmltYXJ5IGVudmlyb25tZW50cyB1c2UgdGhlIGVudmlyb25tZW50IHR5cGUgYXMgdGhlIG5hbWVcbiAgICAvLyAtIFNlY29uZGFyeSBkZXBsb3ltZW50IHRhcmdldHMgdXNlIFwie2RlcGxveW1lbnRUYXJnZXRSb2xlfS17aW5kZXh9XCIgZm9ybWF0XG4gICAgY29uc3Qgc3RhZ2VOYW1lID1cbiAgICAgIHByb3BzLmRlcGxveW1lbnRUYXJnZXRSb2xlID09PSBPUEVOX0hJX0RFUExPWU1FTlRfVEFSR0VUX1JPTEUuUFJJTUFSWVxuICAgICAgICA/IHByb3BzLmRlcGxveW1lbnRUYXJnZXRSb2xlXG4gICAgICAgIDogW3Byb3BzLmRlcGxveW1lbnRUYXJnZXRSb2xlLCBvaFN0YWdlLmVudmlyb25tZW50cy5sZW5ndGhdLmpvaW4oXCItXCIpO1xuXG4gICAgc3VwZXIob2hTdGFnZSwgc3RhZ2VOYW1lLCB7XG4gICAgICBlbnY6IHByb3BzLmVudiA/PyBvaFN0YWdlLnByb3BzLmVudixcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuXG4gICAgLy8gTWFyayB0aGlzIGluc3RhbmNlIGFzIGFuIE9wZW5IaUVudmlyb25tZW50IGZvciBydW50aW1lIHR5cGUgY2hlY2tpbmdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgT1BFTl9ISV9FTlZJUk9OTUVOVF9TWU1CT0wsIHsgdmFsdWU6IHRydWUgfSk7XG5cbiAgICB0aGlzLmRlcGxveW1lbnRUYXJnZXRSb2xlID0gcHJvcHMuZGVwbG95bWVudFRhcmdldFJvbGU7XG4gICAgdGhpcy5jb25maWcgPSBwcm9wcy5jb25maWc7XG4gIH1cbn1cbiJdfQ==