@openhi/constructs 0.0.104 → 0.0.106

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 (83) hide show
  1. package/README.md +14 -0
  2. package/lib/chunk-2PM2NGXI.mjs +31 -0
  3. package/lib/chunk-2PM2NGXI.mjs.map +1 -0
  4. package/lib/chunk-AGF3RAAZ.mjs +20 -0
  5. package/lib/chunk-AGF3RAAZ.mjs.map +1 -0
  6. package/lib/chunk-AO3E22CS.mjs +108 -0
  7. package/lib/chunk-AO3E22CS.mjs.map +1 -0
  8. package/lib/chunk-CHPEQRXU.mjs +45 -0
  9. package/lib/chunk-CHPEQRXU.mjs.map +1 -0
  10. package/lib/chunk-JUNL76HF.mjs +428 -0
  11. package/lib/chunk-JUNL76HF.mjs.map +1 -0
  12. package/lib/chunk-L6UAP4KP.mjs +27 -0
  13. package/lib/chunk-L6UAP4KP.mjs.map +1 -0
  14. package/lib/{chunk-3QS3WKRC.mjs → chunk-LZOMFHX3.mjs} +9 -2
  15. package/lib/chunk-QMIOLLAS.mjs +531 -0
  16. package/lib/chunk-QMIOLLAS.mjs.map +1 -0
  17. package/lib/chunk-SYBADQXI.mjs +607 -0
  18. package/lib/chunk-SYBADQXI.mjs.map +1 -0
  19. package/lib/chunk-VXX4I3EF.mjs +19 -0
  20. package/lib/chunk-VXX4I3EF.mjs.map +1 -0
  21. package/lib/{chunk-MLTYFMSE.mjs → chunk-VYDIGFIX.mjs} +74 -29
  22. package/lib/chunk-VYDIGFIX.mjs.map +1 -0
  23. package/lib/chunk-YU2HRNUP.mjs +33 -0
  24. package/lib/chunk-YU2HRNUP.mjs.map +1 -0
  25. package/lib/chunk-YZZDUJHI.mjs +37 -0
  26. package/lib/chunk-YZZDUJHI.mjs.map +1 -0
  27. package/lib/cors-options-lambda.handler.mjs +1 -1
  28. package/lib/data-store-postgres-replication.handler.mjs +1 -1
  29. package/lib/events-BfrkMoBD.d.mts +44 -0
  30. package/lib/events-BfrkMoBD.d.ts +44 -0
  31. package/lib/events-CVA3_eEB.d.mts +23 -0
  32. package/lib/events-CVA3_eEB.d.ts +23 -0
  33. package/lib/events-DGep6C7w.d.mts +207 -0
  34. package/lib/events-DGep6C7w.d.ts +207 -0
  35. package/lib/firehose-archive-transform.handler.mjs +1 -1
  36. package/lib/index.d.mts +508 -29
  37. package/lib/index.d.ts +773 -30
  38. package/lib/index.js +2536 -105
  39. package/lib/index.js.map +1 -1
  40. package/lib/index.mjs +899 -106
  41. package/lib/index.mjs.map +1 -1
  42. package/lib/openhi-context-CaBH8SFo.d.mts +39 -0
  43. package/lib/openhi-context-CaBH8SFo.d.ts +39 -0
  44. package/lib/platform-deploy-bridge.handler.d.mts +14 -0
  45. package/lib/platform-deploy-bridge.handler.d.ts +14 -0
  46. package/lib/platform-deploy-bridge.handler.js +762 -0
  47. package/lib/platform-deploy-bridge.handler.js.map +1 -0
  48. package/lib/platform-deploy-bridge.handler.mjs +134 -0
  49. package/lib/platform-deploy-bridge.handler.mjs.map +1 -0
  50. package/lib/post-authentication.handler.mjs +1 -1
  51. package/lib/post-confirmation.handler.js +50 -904
  52. package/lib/post-confirmation.handler.js.map +1 -1
  53. package/lib/post-confirmation.handler.mjs +37 -112
  54. package/lib/post-confirmation.handler.mjs.map +1 -1
  55. package/lib/pre-token-generation.handler.js +135 -55
  56. package/lib/pre-token-generation.handler.js.map +1 -1
  57. package/lib/pre-token-generation.handler.mjs +25 -32
  58. package/lib/pre-token-generation.handler.mjs.map +1 -1
  59. package/lib/provision-default-workspace.handler.d.mts +13 -0
  60. package/lib/provision-default-workspace.handler.d.ts +13 -0
  61. package/lib/provision-default-workspace.handler.js +1172 -0
  62. package/lib/provision-default-workspace.handler.js.map +1 -0
  63. package/lib/provision-default-workspace.handler.mjs +175 -0
  64. package/lib/provision-default-workspace.handler.mjs.map +1 -0
  65. package/lib/rest-api-lambda.handler.js +114 -59
  66. package/lib/rest-api-lambda.handler.js.map +1 -1
  67. package/lib/rest-api-lambda.handler.mjs +60 -587
  68. package/lib/rest-api-lambda.handler.mjs.map +1 -1
  69. package/lib/seed-demo-data.handler.d.mts +107 -0
  70. package/lib/seed-demo-data.handler.d.ts +107 -0
  71. package/lib/seed-demo-data.handler.js +2037 -0
  72. package/lib/seed-demo-data.handler.js.map +1 -0
  73. package/lib/seed-demo-data.handler.mjs +23 -0
  74. package/lib/seed-demo-data.handler.mjs.map +1 -0
  75. package/lib/seed-system-data.handler.d.mts +64 -0
  76. package/lib/seed-system-data.handler.d.ts +64 -0
  77. package/lib/seed-system-data.handler.js +1631 -0
  78. package/lib/seed-system-data.handler.js.map +1 -0
  79. package/lib/seed-system-data.handler.mjs +135 -0
  80. package/lib/seed-system-data.handler.mjs.map +1 -0
  81. package/package.json +4 -2
  82. package/lib/chunk-MLTYFMSE.mjs.map +0 -1
  83. /package/lib/{chunk-3QS3WKRC.mjs.map → chunk-LZOMFHX3.mjs.map} +0 -0
@@ -24,6 +24,9 @@ __export(pre_token_generation_handler_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(pre_token_generation_handler_exports);
26
26
 
27
+ // src/data/operations/control/user/user-create-operation.ts
28
+ var import_types2 = require("@openhi/types");
29
+
27
30
  // src/data/dynamo/dynamo-control-service.ts
28
31
  var import_electrodb8 = require("electrodb");
29
32
 
@@ -41,6 +44,9 @@ var dynamoClient = new import_client_dynamodb.DynamoDBClient({
41
44
  // src/data/dynamo/entities/control/configuration-entity.ts
42
45
  var import_electrodb = require("electrodb");
43
46
 
47
+ // src/data/dynamo/entities/control/control-entity-common.ts
48
+ var import_types = require("@openhi/types");
49
+
44
50
  // src/data/dynamo/shard.ts
45
51
  var SHARD_COUNT = 4;
46
52
  function computeShard(id) {
@@ -63,6 +69,29 @@ var gsi1ShardAttribute = {
63
69
  return String(computeShard(item.id));
64
70
  }
65
71
  };
72
+ var gsi1skAttribute = {
73
+ type: "string",
74
+ watch: ["resource", "lastUpdated", "id"],
75
+ set: (_val, item) => {
76
+ const id = typeof item?.id === "string" ? item.id : "";
77
+ const lastUpdated = typeof item?.lastUpdated === "string" ? item.lastUpdated : "";
78
+ const fallback = `${lastUpdated}#${id}`;
79
+ if (typeof item?.resource !== "string" || item.resource.length === 0) {
80
+ return fallback;
81
+ }
82
+ let parsed;
83
+ try {
84
+ parsed = JSON.parse(item.resource);
85
+ } catch {
86
+ return fallback;
87
+ }
88
+ if (!parsed || typeof parsed !== "object") return fallback;
89
+ const resourceType = parsed.resourceType;
90
+ if (typeof resourceType !== "string") return fallback;
91
+ const label = (0, import_types.extractLabel)(parsed);
92
+ return label !== void 0 ? `${label}#${id}` : fallback;
93
+ }
94
+ };
66
95
 
67
96
  // src/data/dynamo/entities/control/configuration-entity.ts
68
97
  var ConfigurationEntity = new import_electrodb.Entity({
@@ -168,8 +197,9 @@ var ConfigurationEntity = new import_electrodb.Entity({
168
197
  * (workspaceId = "-") or "list configs scoped to this workspace". Does not support
169
198
  * hierarchical resolution in one query; use base table GetItem in fallback order
170
199
  * (user → workspace → tenant → baseline) for that.
171
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
172
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
200
+ * SK is `<key>#<id>` Configuration's `key` is a required entity attribute (the
201
+ * config category: endpoints, branding, display, …) and the natural sort/lookup
202
+ * dimension. `casing: "none"` preserves the literal key value.
173
203
  */
174
204
  gsi1: {
175
205
  index: "GSI1",
@@ -181,8 +211,8 @@ var ConfigurationEntity = new import_electrodb.Entity({
181
211
  sk: {
182
212
  field: "GSI1SK",
183
213
  casing: "none",
184
- composite: ["lastUpdated", "id"],
185
- template: "${lastUpdated}#${id}"
214
+ composite: ["key", "id"],
215
+ template: "${key}#${id}"
186
216
  }
187
217
  }
188
218
  }
@@ -236,6 +266,8 @@ var MembershipEntity = new import_electrodb2.Entity({
236
266
  required: true
237
267
  },
238
268
  gsi1Shard: gsi1ShardAttribute,
269
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
270
+ gsi1sk: gsi1skAttribute,
239
271
  deleted: {
240
272
  type: "boolean",
241
273
  required: false
@@ -266,8 +298,9 @@ var MembershipEntity = new import_electrodb2.Entity({
266
298
  /**
267
299
  * GSI1 — Unified Sharded List per ADR-011: list all Memberships for a tenant across the
268
300
  * four shards. Membership is tenant-scoped only, so `WID#-` is a sentinel.
269
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
270
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
301
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
302
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
303
+ * normalized label and ISO-8601 `T`/`Z`.
271
304
  */
272
305
  gsi1: {
273
306
  index: "GSI1",
@@ -279,8 +312,8 @@ var MembershipEntity = new import_electrodb2.Entity({
279
312
  sk: {
280
313
  field: "GSI1SK",
281
314
  casing: "none",
282
- composite: ["lastUpdated", "id"],
283
- template: "${lastUpdated}#${id}"
315
+ composite: ["gsi1sk"],
316
+ template: "${gsi1sk}"
284
317
  }
285
318
  }
286
319
  }
@@ -329,6 +362,8 @@ var RoleEntity = new import_electrodb3.Entity({
329
362
  required: true
330
363
  },
331
364
  gsi1Shard: gsi1ShardAttribute,
365
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
366
+ gsi1sk: gsi1skAttribute,
332
367
  deleted: {
333
368
  type: "boolean",
334
369
  required: false
@@ -359,8 +394,9 @@ var RoleEntity = new import_electrodb3.Entity({
359
394
  /**
360
395
  * GSI1 — Unified Sharded List per ADR-011: list all Roles across the four shards.
361
396
  * Non-tenant-isolated, so `TID#-#WID#-` sentinels precede `RT#Role#SHARD#<n>`.
362
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
363
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
397
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
398
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
399
+ * normalized label and ISO-8601 `T`/`Z`.
364
400
  */
365
401
  gsi1: {
366
402
  index: "GSI1",
@@ -372,8 +408,8 @@ var RoleEntity = new import_electrodb3.Entity({
372
408
  sk: {
373
409
  field: "GSI1SK",
374
410
  casing: "none",
375
- composite: ["lastUpdated", "id"],
376
- template: "${lastUpdated}#${id}"
411
+ composite: ["gsi1sk"],
412
+ template: "${gsi1sk}"
377
413
  }
378
414
  }
379
415
  }
@@ -427,6 +463,8 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
427
463
  required: true
428
464
  },
429
465
  gsi1Shard: gsi1ShardAttribute,
466
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
467
+ gsi1sk: gsi1skAttribute,
430
468
  deleted: {
431
469
  type: "boolean",
432
470
  required: false
@@ -457,8 +495,9 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
457
495
  /**
458
496
  * GSI1 — Unified Sharded List per ADR-011: list all RoleAssignments for a tenant across the
459
497
  * four shards. Tenant-scoped only, so `WID#-` is a sentinel.
460
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
461
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
498
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
499
+ * extractable, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves the
500
+ * normalized label and ISO-8601 `T`/`Z`.
462
501
  */
463
502
  gsi1: {
464
503
  index: "GSI1",
@@ -470,8 +509,8 @@ var RoleAssignmentEntity = new import_electrodb4.Entity({
470
509
  sk: {
471
510
  field: "GSI1SK",
472
511
  casing: "none",
473
- composite: ["lastUpdated", "id"],
474
- template: "${lastUpdated}#${id}"
512
+ composite: ["gsi1sk"],
513
+ template: "${gsi1sk}"
475
514
  }
476
515
  }
477
516
  }
@@ -525,6 +564,8 @@ var TenantEntity = new import_electrodb5.Entity({
525
564
  required: true
526
565
  },
527
566
  gsi1Shard: gsi1ShardAttribute,
567
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
568
+ gsi1sk: gsi1skAttribute,
528
569
  deleted: {
529
570
  type: "boolean",
530
571
  required: false
@@ -555,8 +596,9 @@ var TenantEntity = new import_electrodb5.Entity({
555
596
  /**
556
597
  * GSI1 — Unified Sharded List per ADR-011: list all Tenants across the four shards.
557
598
  * Tenant lives at the platform tier (no parent tenant or workspace), so `TID#-#WID#-`
558
- * sentinels precede `RT#Tenant#SHARD#<n>`. SK is `<ISO-8601 lastUpdated>#<id>` (control-plane
559
- * unlabeled per DR-004). `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
599
+ * sentinels precede `RT#Tenant#SHARD#<n>`. SK is derived via `gsi1skAttribute` —
600
+ * `<normalizedName>#<id>` when the resource carries a `name`, else `<lastUpdated>#<id>`
601
+ * (DR-004). `casing: "none"` preserves the normalized label and ISO-8601 `T`/`Z`.
560
602
  */
561
603
  gsi1: {
562
604
  index: "GSI1",
@@ -568,8 +610,8 @@ var TenantEntity = new import_electrodb5.Entity({
568
610
  sk: {
569
611
  field: "GSI1SK",
570
612
  casing: "none",
571
- composite: ["lastUpdated", "id"],
572
- template: "${lastUpdated}#${id}"
613
+ composite: ["gsi1sk"],
614
+ template: "${gsi1sk}"
573
615
  }
574
616
  }
575
617
  }
@@ -626,6 +668,8 @@ var UserEntity = new import_electrodb6.Entity({
626
668
  required: true
627
669
  },
628
670
  gsi1Shard: gsi1ShardAttribute,
671
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
672
+ gsi1sk: gsi1skAttribute,
629
673
  deleted: {
630
674
  type: "boolean",
631
675
  required: false
@@ -656,8 +700,9 @@ var UserEntity = new import_electrodb6.Entity({
656
700
  /**
657
701
  * GSI1 — Unified Sharded List per ADR-011: list all Users across the four shards.
658
702
  * Non-tenant-isolated, so `TID#-#WID#-` sentinels precede `RT#User#SHARD#<n>`.
659
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
660
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z` characters.
703
+ * SK is derived via `gsi1skAttribute` uses the resource's natural label when
704
+ * extractable (string `name`/`title` via introspection), else `<lastUpdated>#<id>`
705
+ * (DR-004). `casing: "none"` preserves the normalized label and ISO-8601 `T`/`Z`.
661
706
  */
662
707
  gsi1: {
663
708
  index: "GSI1",
@@ -669,8 +714,8 @@ var UserEntity = new import_electrodb6.Entity({
669
714
  sk: {
670
715
  field: "GSI1SK",
671
716
  casing: "none",
672
- composite: ["lastUpdated", "id"],
673
- template: "${lastUpdated}#${id}"
717
+ composite: ["gsi1sk"],
718
+ template: "${gsi1sk}"
674
719
  }
675
720
  },
676
721
  /**
@@ -745,6 +790,8 @@ var WorkspaceEntity = new import_electrodb7.Entity({
745
790
  required: true
746
791
  },
747
792
  gsi1Shard: gsi1ShardAttribute,
793
+ /** Derived GSI1 sort key — name-based when extractable; else `<lastUpdated>#<id>`. */
794
+ gsi1sk: gsi1skAttribute,
748
795
  deleted: {
749
796
  type: "boolean",
750
797
  required: false
@@ -775,8 +822,9 @@ var WorkspaceEntity = new import_electrodb7.Entity({
775
822
  /**
776
823
  * GSI1 — Unified Sharded List per ADR-011: list all Workspaces for a tenant across the
777
824
  * four shards. Workspace is itself the workspace identity, so `WID#-` is a sentinel.
778
- * SK is `<ISO-8601 lastUpdated>#<id>` (control-plane unlabeled per DR-004).
779
- * `casing: "none"` on the SK preserves ISO-8601 `T`/`Z`.
825
+ * SK is derived via `gsi1skAttribute` — `<normalizedName>#<id>` when the resource
826
+ * carries a `name`, else `<lastUpdated>#<id>` (DR-004). `casing: "none"` preserves
827
+ * the normalized label and ISO-8601 `T`/`Z`.
780
828
  */
781
829
  gsi1: {
782
830
  index: "GSI1",
@@ -788,8 +836,8 @@ var WorkspaceEntity = new import_electrodb7.Entity({
788
836
  sk: {
789
837
  field: "GSI1SK",
790
838
  casing: "none",
791
- composite: ["lastUpdated", "id"],
792
- template: "${lastUpdated}#${id}"
839
+ composite: ["gsi1sk"],
840
+ template: "${gsi1sk}"
793
841
  }
794
842
  }
795
843
  }
@@ -823,31 +871,15 @@ function getDynamoControlService(tableName) {
823
871
  };
824
872
  }
825
873
 
826
- // src/components/cognito/pre-token-generation.handler.ts
827
- var REFERENCE_TYPES = {
828
- Tenant: "Tenant/",
829
- Workspace: "Workspace/"
830
- };
831
- function idFromReference(reference, prefix) {
832
- if (!reference || !reference.startsWith(prefix)) return void 0;
833
- const id = reference.slice(prefix.length);
834
- return id.length > 0 ? id : void 0;
835
- }
836
- function displayNameFor(user) {
837
- const first = user.name?.[0];
838
- return first?.text ?? first?.family ?? user.displayName ?? void 0;
839
- }
840
- function safeParseUser(json) {
841
- try {
842
- return JSON.parse(json);
843
- } catch {
844
- return void 0;
845
- }
846
- }
847
- async function findUserBySub(service, cognitoSub) {
874
+ // src/data/operations/control/user/user-find-by-sub-operation.ts
875
+ async function findUserBySubOperation(params) {
876
+ const { cognitoSub, tableName } = params;
877
+ const service = getDynamoControlService(tableName);
848
878
  const result = await service.entities.user.query.gsi2({ cognitoSub }).go({ limit: 1 });
849
879
  const item = result.data?.[0];
850
- if (!item) return void 0;
880
+ if (!item) {
881
+ return void 0;
882
+ }
851
883
  return {
852
884
  id: item.id,
853
885
  cognitoSub: item.cognitoSub,
@@ -855,16 +887,64 @@ async function findUserBySub(service, cognitoSub) {
855
887
  vid: item.vid
856
888
  };
857
889
  }
890
+
891
+ // src/data/operations/data-operations-common.ts
892
+ var import_types3 = require("@openhi/types");
893
+
894
+ // src/lib/compression.ts
895
+ var import_node_zlib = require("zlib");
896
+
897
+ // src/data/operations/control/user/user-update-operation.ts
898
+ var import_types4 = require("@openhi/types");
899
+
900
+ // src/data/operations/control/user/user-resource-helpers.ts
901
+ function parseUserResource(resource) {
902
+ try {
903
+ return JSON.parse(resource);
904
+ } catch {
905
+ return void 0;
906
+ }
907
+ }
908
+
909
+ // src/data/operations/fhir-reference.ts
910
+ function idFromReference(reference, prefix) {
911
+ if (!reference || !reference.startsWith(prefix)) {
912
+ return void 0;
913
+ }
914
+ const id = reference.slice(prefix.length);
915
+ return id.length > 0 ? id : void 0;
916
+ }
917
+
918
+ // src/components/cognito/pre-token-generation.handler.ts
919
+ var REFERENCE_TYPES = {
920
+ Tenant: "Tenant/",
921
+ Workspace: "Workspace/"
922
+ };
923
+ function displayNameFor(user) {
924
+ const names = user.name;
925
+ const first = names?.[0];
926
+ return first?.text ?? first?.family ?? void 0;
927
+ }
928
+ var lookupContext = {
929
+ tenantId: "",
930
+ workspaceId: "",
931
+ date: "",
932
+ actorId: "",
933
+ actorName: "",
934
+ actorType: "internal-system"
935
+ };
858
936
  async function resolveClaims(cognitoSub) {
859
- const service = getDynamoControlService();
860
- const user = await findUserBySub(service, cognitoSub);
937
+ const user = await findUserBySubOperation({
938
+ context: lookupContext,
939
+ cognitoSub
940
+ });
861
941
  if (!user) {
862
942
  console.warn(
863
943
  `PreTokenGeneration: no User found for cognitoSub; emitting token without OpenHI claims (sub=${cognitoSub})`
864
944
  );
865
945
  return void 0;
866
946
  }
867
- const parsed = safeParseUser(user.resource);
947
+ const parsed = parseUserResource(user.resource);
868
948
  if (!parsed) {
869
949
  console.warn(
870
950
  `PreTokenGeneration: User resource JSON could not be parsed (sub=${cognitoSub}, id=${user.id})`
@@ -882,7 +962,7 @@ async function resolveClaims(cognitoSub) {
882
962
  const displayName = displayNameFor(parsed);
883
963
  if (!tenantId || !workspaceId || !displayName) {
884
964
  console.warn(
885
- `PreTokenGeneration: resolved User missing currentTenant/currentWorkspace/displayName; emitting token without OpenHI claims (sub=${cognitoSub}, id=${user.id})`
965
+ `PreTokenGeneration: resolved User missing currentTenant/currentWorkspace/name; emitting token without OpenHI claims (sub=${cognitoSub}, id=${user.id})`
886
966
  );
887
967
  return void 0;
888
968
  }