@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
@@ -1,11 +1,45 @@
1
+ import {
2
+ createRoleOperation
3
+ } from "./chunk-YU2HRNUP.mjs";
4
+ import {
5
+ getRoleByIdOperation
6
+ } from "./chunk-L6UAP4KP.mjs";
7
+ import {
8
+ createMembershipOperation,
9
+ createRoleAssignmentOperation,
10
+ createTenantOperation,
11
+ createWorkspaceOperation
12
+ } from "./chunk-AO3E22CS.mjs";
13
+ import {
14
+ batchGetWithRetry,
15
+ buildUpdatedResourceWithAudit,
16
+ compressResource,
17
+ createDataEntityRecord,
18
+ createUserOperation,
19
+ decompressResource,
20
+ deleteDataEntityById,
21
+ deleteUserOperation,
22
+ dispatchListMode,
23
+ getDataEntityById,
24
+ getUserByIdOperation,
25
+ listDataEntitiesByWorkspace,
26
+ listUsersOperation,
27
+ mergeAuditIntoMeta,
28
+ updateDataEntityById,
29
+ updateUserOperation
30
+ } from "./chunk-JUNL76HF.mjs";
31
+ import {
32
+ NotFoundError,
33
+ domainErrorToHttpStatus
34
+ } from "./chunk-YZZDUJHI.mjs";
1
35
  import {
2
36
  SHARD_COUNT,
3
37
  computeShard,
4
38
  defaultTableName,
5
39
  dynamoClient,
6
40
  getDynamoControlService
7
- } from "./chunk-MLTYFMSE.mjs";
8
- import "./chunk-3QS3WKRC.mjs";
41
+ } from "./chunk-VYDIGFIX.mjs";
42
+ import "./chunk-LZOMFHX3.mjs";
9
43
 
10
44
  // src/data/lambda/rest-api-lambda.handler.ts
11
45
  import serverlessExpress from "@codegenie/serverless-express";
@@ -75,62 +109,6 @@ function openHiContextMiddleware(req, res, next) {
75
109
  // src/data/rest-api/routes/control/configuration/configuration.ts
76
110
  import express from "express";
77
111
 
78
- // src/lib/compression.ts
79
- import { gzipSync, gunzipSync } from "zlib";
80
- var ENVELOPE_VERSION = 1;
81
- var COMPRESSION_ALGOS = {
82
- NONE: "none",
83
- GZIP: "gzip",
84
- BROTLI: "brotli",
85
- DEFLATE: "deflate"
86
- };
87
- function isEnvelope(obj) {
88
- return typeof obj === "object" && obj !== null && "v" in obj && "algo" in obj && "payload" in obj && typeof obj.payload === "string";
89
- }
90
- function compressResource(jsonString, options) {
91
- const algo = options?.algo ?? COMPRESSION_ALGOS.GZIP;
92
- if (algo === COMPRESSION_ALGOS.NONE) {
93
- const envelope2 = {
94
- v: ENVELOPE_VERSION,
95
- algo: COMPRESSION_ALGOS.NONE,
96
- payload: jsonString
97
- };
98
- return JSON.stringify(envelope2);
99
- }
100
- const buf = Buffer.from(jsonString, "utf-8");
101
- const payload = gzipSync(buf).toString("base64");
102
- const envelope = {
103
- v: ENVELOPE_VERSION,
104
- algo: COMPRESSION_ALGOS.GZIP,
105
- payload
106
- };
107
- return JSON.stringify(envelope);
108
- }
109
- function decompressResource(compressedOrRaw) {
110
- try {
111
- const parsed = JSON.parse(compressedOrRaw);
112
- if (isEnvelope(parsed)) {
113
- if (parsed.algo === COMPRESSION_ALGOS.GZIP) {
114
- const buf = Buffer.from(parsed.payload, "base64");
115
- return gunzipSync(buf).toString("utf-8");
116
- }
117
- if (parsed.algo === COMPRESSION_ALGOS.NONE) {
118
- return parsed.payload;
119
- }
120
- return parsed.payload;
121
- }
122
- } catch {
123
- }
124
- try {
125
- const buf = Buffer.from(compressedOrRaw, "base64");
126
- if (buf.length >= 2 && buf[0] === 31 && buf[1] === 139) {
127
- return gunzipSync(buf).toString("utf-8");
128
- }
129
- } catch {
130
- }
131
- return compressedOrRaw;
132
- }
133
-
134
112
  // src/data/operations/control/configuration/configuration-create-operation.ts
135
113
  var SK = "CURRENT";
136
114
  async function createConfigurationOperation(params) {
@@ -504,38 +482,6 @@ async function deleteConfigurationRoute(req, res) {
504
482
  }
505
483
  }
506
484
 
507
- // src/data/errors/domain-errors.ts
508
- var DomainError = class extends Error {
509
- constructor(message, code, options) {
510
- super(message, options);
511
- this.name = this.constructor.name;
512
- this.code = code;
513
- this.details = options?.details;
514
- Object.setPrototypeOf(this, new.target.prototype);
515
- }
516
- };
517
- var NotFoundError = class extends DomainError {
518
- constructor(message, options) {
519
- super(message, "NOT_FOUND", options);
520
- }
521
- };
522
- var ValidationError = class extends DomainError {
523
- constructor(message, options) {
524
- super(message, "VALIDATION", options);
525
- }
526
- };
527
- var ConflictError = class extends DomainError {
528
- constructor(message, options) {
529
- super(message, "CONFLICT", options);
530
- }
531
- };
532
- function domainErrorToHttpStatus(err) {
533
- if (err instanceof NotFoundError) return 404;
534
- if (err instanceof ValidationError) return 400;
535
- if (err instanceof ConflictError) return 409;
536
- return null;
537
- }
538
-
539
485
  // src/data/operations/control/configuration/configuration-get-by-id-operation.ts
540
486
  var SK3 = "CURRENT";
541
487
  async function getConfigurationByIdOperation(params) {
@@ -599,243 +545,6 @@ async function getConfigurationByIdRoute(req, res) {
599
545
  }
600
546
  }
601
547
 
602
- // src/data/operations/data-operations-common.ts
603
- import { extractSortKey, extractSummary } from "@openhi/types";
604
-
605
- // src/data/audit-meta.ts
606
- var OPENHI_EXT = "http://openhi.org/fhir/StructureDefinition";
607
- function mergeAuditIntoMeta(meta, audit) {
608
- const existing = meta ?? {};
609
- const ext = [
610
- ...Array.isArray(existing.extension) ? existing.extension : []
611
- ];
612
- const byUrl = new Map(ext.map((e) => [e.url, e]));
613
- function set(url, value, type) {
614
- if (value == null) return;
615
- byUrl.set(url, { url, [type]: value });
616
- }
617
- set(`${OPENHI_EXT}/created-date`, audit.createdDate, "valueDateTime");
618
- set(`${OPENHI_EXT}/created-by-id`, audit.createdById, "valueString");
619
- set(`${OPENHI_EXT}/created-by-name`, audit.createdByName, "valueString");
620
- set(`${OPENHI_EXT}/modified-date`, audit.modifiedDate, "valueDateTime");
621
- set(`${OPENHI_EXT}/modified-by-id`, audit.modifiedById, "valueString");
622
- set(`${OPENHI_EXT}/modified-by-name`, audit.modifiedByName, "valueString");
623
- set(`${OPENHI_EXT}/deleted-date`, audit.deletedDate, "valueDateTime");
624
- set(`${OPENHI_EXT}/deleted-by-id`, audit.deletedById, "valueString");
625
- set(`${OPENHI_EXT}/deleted-by-name`, audit.deletedByName, "valueString");
626
- return { ...existing, extension: Array.from(byUrl.values()) };
627
- }
628
-
629
- // src/data/operations/data-operations-common.ts
630
- var DATA_ENTITY_SK = "CURRENT";
631
- async function getDataEntityById(entity, tenantId, workspaceId, id, resourceLabel) {
632
- const result = await entity.get({
633
- tenantId,
634
- workspaceId,
635
- id,
636
- sk: DATA_ENTITY_SK
637
- }).go();
638
- if (!result.data) {
639
- throw new NotFoundError(`${resourceLabel} ${id} not found`, {
640
- details: { id }
641
- });
642
- }
643
- const parsed = JSON.parse(decompressResource(result.data.resource));
644
- return {
645
- id: result.data.id,
646
- resource: { ...parsed, id: result.data.id }
647
- };
648
- }
649
- async function deleteDataEntityById(entity, tenantId, workspaceId, id) {
650
- await entity.delete({
651
- tenantId,
652
- workspaceId,
653
- id,
654
- sk: DATA_ENTITY_SK
655
- }).go();
656
- }
657
- var BATCH_GET_MAX_ATTEMPTS = 3;
658
- var BATCH_GET_BASE_BACKOFF_MS = 50;
659
- async function batchGetWithRetry(entity, keys) {
660
- if (keys.length === 0) return [];
661
- const collected = [];
662
- let pending = keys;
663
- let attempt = 0;
664
- while (pending.length > 0) {
665
- if (attempt > 0) {
666
- await new Promise(
667
- (resolve) => setTimeout(resolve, BATCH_GET_BASE_BACKOFF_MS * 2 ** (attempt - 1))
668
- );
669
- }
670
- attempt++;
671
- const result = await entity.get(pending).go();
672
- collected.push(...result.data);
673
- const unprocessed = result.unprocessed ?? [];
674
- if (unprocessed.length === 0) break;
675
- if (attempt >= BATCH_GET_MAX_ATTEMPTS) {
676
- throw new Error(
677
- `BatchGet exhausted retries: ${unprocessed.length} key(s) still unprocessed after ${BATCH_GET_MAX_ATTEMPTS} attempt(s)`
678
- );
679
- }
680
- pending = unprocessed;
681
- }
682
- return collected;
683
- }
684
- async function dispatchListMode(mode, shardResults, hooks) {
685
- if (mode === "count") {
686
- let total = 0;
687
- for (const shardResult of shardResults) {
688
- total += (shardResult.data ?? []).length;
689
- }
690
- return { entries: [], total };
691
- }
692
- if (mode === "summary") {
693
- const entries2 = [];
694
- for (const shardResult of shardResults) {
695
- for (const item of shardResult.data ?? []) {
696
- if (typeof item.summary !== "string") continue;
697
- let parsed;
698
- try {
699
- parsed = JSON.parse(item.summary);
700
- } catch {
701
- continue;
702
- }
703
- entries2.push(hooks.buildSummaryEntry(item.id, parsed));
704
- }
705
- }
706
- return { entries: entries2, total: entries2.length };
707
- }
708
- const orderedIds = [];
709
- for (const shardResult of shardResults) {
710
- for (const item of shardResult.data ?? []) {
711
- orderedIds.push(item.id);
712
- }
713
- }
714
- if (orderedIds.length === 0) return { entries: [], total: 0 };
715
- const items = await hooks.hydrate(orderedIds);
716
- const byId = new Map(items.map((item) => [hooks.getId(item), item]));
717
- const entries = [];
718
- for (const id of orderedIds) {
719
- const item = byId.get(id);
720
- if (!item) continue;
721
- entries.push(hooks.buildEntry(id, item));
722
- }
723
- return { entries, total: entries.length };
724
- }
725
- async function listDataEntitiesByWorkspace(entity, tenantId, workspaceId, mode = "full") {
726
- const shardResults = await Promise.all(
727
- Array.from(
728
- { length: SHARD_COUNT },
729
- (_, shard) => entity.query.gsi1({ tenantId, workspaceId, gsi1Shard: String(shard) }).go()
730
- )
731
- );
732
- return dispatchListMode(
733
- mode,
734
- shardResults,
735
- {
736
- hydrate: (orderedIds) => batchGetWithRetry(
737
- entity,
738
- orderedIds.map((id) => ({
739
- tenantId,
740
- workspaceId,
741
- id,
742
- sk: DATA_ENTITY_SK
743
- }))
744
- ),
745
- getId: (item) => item.id,
746
- buildEntry: (id, item) => {
747
- const parsed = JSON.parse(decompressResource(item.resource));
748
- return { id, resource: { ...parsed, id } };
749
- },
750
- buildSummaryEntry: (id, parsed) => ({
751
- id,
752
- resource: { ...parsed, id }
753
- })
754
- }
755
- );
756
- }
757
- async function createDataEntityRecord(entity, tenantId, workspaceId, id, resourceWithAudit, fallbackDate) {
758
- const lastUpdated = resourceWithAudit.meta?.lastUpdated ?? fallbackDate ?? (/* @__PURE__ */ new Date()).toISOString();
759
- const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
760
- const resourceLike = resourceWithAudit;
761
- const summary = JSON.stringify(extractSummary(resourceLike));
762
- const gsi1sk = extractSortKey(resourceLike);
763
- await entity.put({
764
- sk: DATA_ENTITY_SK,
765
- tenantId,
766
- workspaceId,
767
- id,
768
- resource: compressResource(JSON.stringify(resourceWithAudit)),
769
- summary,
770
- vid,
771
- lastUpdated,
772
- gsi1sk
773
- }).go();
774
- return {
775
- id,
776
- resource: resourceWithAudit
777
- };
778
- }
779
- function buildUpdatedResourceWithAudit(body, id, date, actorId, actorName, existingResourceStr, resourceType) {
780
- const existingMeta = JSON.parse(existingResourceStr).meta;
781
- const bodyWithMeta = body;
782
- const resourceWithVersion = {
783
- ...body,
784
- resourceType,
785
- id,
786
- meta: {
787
- ...bodyWithMeta.meta ?? {},
788
- lastUpdated: date,
789
- versionId: "2"
790
- }
791
- };
792
- const resourceWithAudit = {
793
- ...resourceWithVersion,
794
- meta: mergeAuditIntoMeta(resourceWithVersion.meta ?? existingMeta, {
795
- modifiedDate: date,
796
- modifiedById: actorId,
797
- modifiedByName: actorName
798
- })
799
- };
800
- return {
801
- resource: resourceWithAudit,
802
- lastUpdated: date
803
- };
804
- }
805
- async function updateDataEntityById(entity, tenantId, workspaceId, id, resourceLabel, context, buildPatched) {
806
- const existing = await entity.get({
807
- tenantId,
808
- workspaceId,
809
- id,
810
- sk: DATA_ENTITY_SK
811
- }).go();
812
- if (!existing.data) {
813
- throw new NotFoundError(`${resourceLabel} ${id} not found`, {
814
- details: { id }
815
- });
816
- }
817
- const existingStr = decompressResource(existing.data.resource);
818
- const { resource, lastUpdated } = buildPatched(existingStr);
819
- const resourceLike = resource;
820
- const summary = JSON.stringify(extractSummary(resourceLike));
821
- const gsi1sk = extractSortKey(resourceLike);
822
- await entity.patch({
823
- tenantId,
824
- workspaceId,
825
- id,
826
- sk: DATA_ENTITY_SK
827
- }).set({
828
- resource: compressResource(JSON.stringify(resource)),
829
- summary,
830
- lastUpdated,
831
- gsi1sk
832
- }).go();
833
- return {
834
- id,
835
- resource
836
- };
837
- }
838
-
839
548
  // src/data/operations/control/configuration/configuration-list-operation.ts
840
549
  var SK4 = "CURRENT";
841
550
  async function listConfigurationsOperation(params) {
@@ -1304,32 +1013,6 @@ router.delete("/:id", deleteConfigurationRoute);
1304
1013
  // src/data/rest-api/routes/control/membership/membership.ts
1305
1014
  import express2 from "express";
1306
1015
 
1307
- // src/data/operations/control/membership/membership-create-operation.ts
1308
- import { extractSummary as extractSummary2 } from "@openhi/types";
1309
- async function createMembershipOperation(params) {
1310
- const { context, body, tableName } = params;
1311
- const service = getDynamoControlService(tableName);
1312
- const id = body.id ?? `membership-${Date.now()}`;
1313
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
1314
- const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1315
- const vid = `1`;
1316
- const resource = { resourceType: "Membership", id, ...parsedResource };
1317
- const summary = JSON.stringify(extractSummary2(resource));
1318
- await service.entities.membership.put({
1319
- tenantId: context.tenantId,
1320
- id,
1321
- resource: JSON.stringify(resource),
1322
- summary,
1323
- vid,
1324
- lastUpdated
1325
- }).go();
1326
- return {
1327
- id,
1328
- resource,
1329
- meta: { lastUpdated, versionId: vid }
1330
- };
1331
- }
1332
-
1333
1016
  // src/data/rest-api/routes/control/membership/membership-create-route.ts
1334
1017
  async function createMembershipRoute(req, res) {
1335
1018
  const bodyResult = requireJsonBody(req, res);
@@ -1474,7 +1157,7 @@ async function listMembershipsRoute(req, res) {
1474
1157
  }
1475
1158
 
1476
1159
  // src/data/operations/control/membership/membership-update-operation.ts
1477
- import { extractSummary as extractSummary3 } from "@openhi/types";
1160
+ import { extractSummary } from "@openhi/types";
1478
1161
  async function updateMembershipOperation(params) {
1479
1162
  const { context, id, body, tableName } = params;
1480
1163
  const service = getDynamoControlService(tableName);
@@ -1486,7 +1169,7 @@ async function updateMembershipOperation(params) {
1486
1169
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1487
1170
  const vid = `${Date.now()}`;
1488
1171
  const resource = { resourceType: "Membership", id, ...parsedResource };
1489
- const summary = JSON.stringify(extractSummary3(resource));
1172
+ const summary = JSON.stringify(extractSummary(resource));
1490
1173
  await service.entities.membership.put({
1491
1174
  tenantId: context.tenantId,
1492
1175
  id,
@@ -1553,31 +1236,6 @@ router2.delete("/:id", deleteMembershipRoute);
1553
1236
  // src/data/rest-api/routes/control/role/role.ts
1554
1237
  import express3 from "express";
1555
1238
 
1556
- // src/data/operations/control/role/role-create-operation.ts
1557
- import { extractSummary as extractSummary4 } from "@openhi/types";
1558
- async function createRoleOperation(params) {
1559
- const { context, body, tableName } = params;
1560
- const service = getDynamoControlService(tableName);
1561
- const id = body.id ?? `role-${Date.now()}`;
1562
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
1563
- const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1564
- const vid = `1`;
1565
- const resource = { resourceType: "Role", id, ...parsedResource };
1566
- const summary = JSON.stringify(extractSummary4(resource));
1567
- await service.entities.role.put({
1568
- id,
1569
- resource: JSON.stringify(resource),
1570
- summary,
1571
- vid,
1572
- lastUpdated
1573
- }).go();
1574
- return {
1575
- id,
1576
- resource,
1577
- meta: { lastUpdated, versionId: vid }
1578
- };
1579
- }
1580
-
1581
1239
  // src/data/rest-api/routes/control/role/role-create-route.ts
1582
1240
  async function createRoleRoute(req, res) {
1583
1241
  const bodyResult = requireJsonBody(req, res);
@@ -1630,22 +1288,6 @@ async function deleteRoleRoute(req, res) {
1630
1288
  }
1631
1289
  }
1632
1290
 
1633
- // src/data/operations/control/role/role-get-by-id-operation.ts
1634
- async function getRoleByIdOperation(params) {
1635
- const { id, tableName } = params;
1636
- const service = getDynamoControlService(tableName);
1637
- const response = await service.entities.role.get({ id, sk: "CURRENT" }).go();
1638
- const item = response.data;
1639
- if (!item) {
1640
- throw new NotFoundError(`Role not found: ${id}`);
1641
- }
1642
- const parsedResource = JSON.parse(item.resource);
1643
- return {
1644
- id,
1645
- resource: { resourceType: "Role", id, ...parsedResource }
1646
- };
1647
- }
1648
-
1649
1291
  // src/data/rest-api/routes/control/role/role-get-by-id-route.ts
1650
1292
  async function getRoleByIdRoute(req, res) {
1651
1293
  const id = String(req.params.id);
@@ -1721,7 +1363,7 @@ async function listRolesRoute(req, res) {
1721
1363
  }
1722
1364
 
1723
1365
  // src/data/operations/control/role/role-update-operation.ts
1724
- import { extractSummary as extractSummary5 } from "@openhi/types";
1366
+ import { extractSummary as extractSummary2 } from "@openhi/types";
1725
1367
  async function updateRoleOperation(params) {
1726
1368
  const { context, id, body, tableName } = params;
1727
1369
  const service = getDynamoControlService(tableName);
@@ -1733,7 +1375,7 @@ async function updateRoleOperation(params) {
1733
1375
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1734
1376
  const vid = `${Date.now()}`;
1735
1377
  const resource = { resourceType: "Role", id, ...parsedResource };
1736
- const summary = JSON.stringify(extractSummary5(resource));
1378
+ const summary = JSON.stringify(extractSummary2(resource));
1737
1379
  await service.entities.role.put({
1738
1380
  id,
1739
1381
  resource: JSON.stringify(resource),
@@ -1799,32 +1441,6 @@ router3.delete("/:id", deleteRoleRoute);
1799
1441
  // src/data/rest-api/routes/control/roleassignment/roleassignment.ts
1800
1442
  import express4 from "express";
1801
1443
 
1802
- // src/data/operations/control/roleassignment/roleassignment-create-operation.ts
1803
- import { extractSummary as extractSummary6 } from "@openhi/types";
1804
- async function createRoleAssignmentOperation(params) {
1805
- const { context, body, tableName } = params;
1806
- const service = getDynamoControlService(tableName);
1807
- const id = body.id ?? `roleassignment-${Date.now()}`;
1808
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
1809
- const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1810
- const vid = `1`;
1811
- const resource = { resourceType: "RoleAssignment", id, ...parsedResource };
1812
- const summary = JSON.stringify(extractSummary6(resource));
1813
- await service.entities.roleAssignment.put({
1814
- tenantId: context.tenantId,
1815
- id,
1816
- resource: JSON.stringify(resource),
1817
- summary,
1818
- vid,
1819
- lastUpdated
1820
- }).go();
1821
- return {
1822
- id,
1823
- resource,
1824
- meta: { lastUpdated, versionId: vid }
1825
- };
1826
- }
1827
-
1828
1444
  // src/data/rest-api/routes/control/roleassignment/roleassignment-create-route.ts
1829
1445
  async function createRoleAssignmentRoute(req, res) {
1830
1446
  const bodyResult = requireJsonBody(req, res);
@@ -1969,7 +1585,7 @@ async function listRoleAssignmentsRoute(req, res) {
1969
1585
  }
1970
1586
 
1971
1587
  // src/data/operations/control/roleassignment/roleassignment-update-operation.ts
1972
- import { extractSummary as extractSummary7 } from "@openhi/types";
1588
+ import { extractSummary as extractSummary3 } from "@openhi/types";
1973
1589
  async function updateRoleAssignmentOperation(params) {
1974
1590
  const { context, id, body, tableName } = params;
1975
1591
  const service = getDynamoControlService(tableName);
@@ -1981,7 +1597,7 @@ async function updateRoleAssignmentOperation(params) {
1981
1597
  const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
1982
1598
  const vid = `${Date.now()}`;
1983
1599
  const resource = { resourceType: "RoleAssignment", id, ...parsedResource };
1984
- const summary = JSON.stringify(extractSummary7(resource));
1600
+ const summary = JSON.stringify(extractSummary3(resource));
1985
1601
  await service.entities.roleAssignment.put({
1986
1602
  tenantId: context.tenantId,
1987
1603
  id,
@@ -2048,28 +1664,6 @@ router4.delete("/:id", deleteRoleAssignmentRoute);
2048
1664
  // src/data/rest-api/routes/control/tenant/tenant.ts
2049
1665
  import express5 from "express";
2050
1666
 
2051
- // src/data/operations/control/tenant/tenant-create-operation.ts
2052
- import { extractSummary as extractSummary8 } from "@openhi/types";
2053
- async function createTenantOperation(params) {
2054
- const { context, body, tableName } = params;
2055
- const service = getDynamoControlService(tableName);
2056
- const id = body.id ?? `tenant-${Date.now()}`;
2057
- const lastUpdated = context.date;
2058
- const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
2059
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
2060
- const resource = { resourceType: "Tenant", id, ...parsedResource };
2061
- const summary = JSON.stringify(extractSummary8(resource));
2062
- await service.entities.tenant.put({
2063
- tenantId: id,
2064
- id,
2065
- resource: JSON.stringify(resource),
2066
- summary,
2067
- vid,
2068
- lastUpdated
2069
- }).go();
2070
- return { id, resource, meta: { lastUpdated, versionId: vid } };
2071
- }
2072
-
2073
1667
  // src/data/rest-api/routes/control/tenant/tenant-create-route.ts
2074
1668
  async function createTenantRoute(req, res) {
2075
1669
  const bodyResult = requireJsonBody(req, res);
@@ -2216,7 +1810,7 @@ async function listTenantsRoute(req, res) {
2216
1810
  }
2217
1811
 
2218
1812
  // src/data/operations/control/tenant/tenant-update-operation.ts
2219
- import { extractSummary as extractSummary9 } from "@openhi/types";
1813
+ import { extractSummary as extractSummary4 } from "@openhi/types";
2220
1814
  async function updateTenantOperation(params) {
2221
1815
  const { context, id, body, tableName } = params;
2222
1816
  const service = getDynamoControlService(tableName);
@@ -2234,7 +1828,7 @@ async function updateTenantOperation(params) {
2234
1828
  resourceType: "Tenant",
2235
1829
  id
2236
1830
  };
2237
- const summary = JSON.stringify(extractSummary9(updated));
1831
+ const summary = JSON.stringify(extractSummary4(updated));
2238
1832
  await service.entities.tenant.patch({ tenantId: id, sk: "CURRENT" }).set({ resource: JSON.stringify(updated), summary, vid, lastUpdated }).go();
2239
1833
  return { id, resource: updated, meta: { lastUpdated, versionId: vid } };
2240
1834
  }
@@ -2290,31 +1884,6 @@ router5.delete("/:id", deleteTenantRoute);
2290
1884
  // src/data/rest-api/routes/control/user/user.ts
2291
1885
  import express6 from "express";
2292
1886
 
2293
- // src/data/operations/control/user/user-create-operation.ts
2294
- import { extractSummary as extractSummary10 } from "@openhi/types";
2295
- async function createUserOperation(params) {
2296
- const { context, body, tableName } = params;
2297
- const service = getDynamoControlService(tableName);
2298
- const id = body.id ?? `user-${Date.now()}`;
2299
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
2300
- const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2301
- const vid = `1`;
2302
- const resource = { resourceType: "User", id, ...parsedResource };
2303
- const summary = JSON.stringify(extractSummary10(resource));
2304
- await service.entities.user.put({
2305
- id,
2306
- resource: JSON.stringify(resource),
2307
- summary,
2308
- vid,
2309
- lastUpdated
2310
- }).go();
2311
- return {
2312
- id,
2313
- resource,
2314
- meta: { lastUpdated, versionId: vid }
2315
- };
2316
- }
2317
-
2318
1887
  // src/data/rest-api/routes/control/user/user-create-route.ts
2319
1888
  async function createUserRoute(req, res) {
2320
1889
  const bodyResult = requireJsonBody(req, res);
@@ -2342,13 +1911,6 @@ async function createUserRoute(req, res) {
2342
1911
  }
2343
1912
  }
2344
1913
 
2345
- // src/data/operations/control/user/user-delete-operation.ts
2346
- async function deleteUserOperation(params) {
2347
- const { id, tableName } = params;
2348
- const service = getDynamoControlService(tableName);
2349
- await service.entities.user.delete({ id, sk: "CURRENT" }).go();
2350
- }
2351
-
2352
1914
  // src/data/rest-api/routes/control/user/user-delete-route.ts
2353
1915
  async function deleteUserRoute(req, res) {
2354
1916
  const id = String(req.params.id);
@@ -2367,22 +1929,6 @@ async function deleteUserRoute(req, res) {
2367
1929
  }
2368
1930
  }
2369
1931
 
2370
- // src/data/operations/control/user/user-get-by-id-operation.ts
2371
- async function getUserByIdOperation(params) {
2372
- const { id, tableName } = params;
2373
- const service = getDynamoControlService(tableName);
2374
- const response = await service.entities.user.get({ id, sk: "CURRENT" }).go();
2375
- const item = response.data;
2376
- if (!item) {
2377
- throw new NotFoundError(`User not found: ${id}`);
2378
- }
2379
- const parsedResource = JSON.parse(item.resource);
2380
- return {
2381
- id,
2382
- resource: { resourceType: "User", id, ...parsedResource }
2383
- };
2384
- }
2385
-
2386
1932
  // src/data/rest-api/routes/control/user/user-get-by-id-route.ts
2387
1933
  async function getUserByIdRoute(req, res) {
2388
1934
  const id = String(req.params.id);
@@ -2414,38 +1960,6 @@ async function getUserByIdRoute(req, res) {
2414
1960
  }
2415
1961
  }
2416
1962
 
2417
- // src/data/operations/control/user/user-list-operation.ts
2418
- var SK10 = "CURRENT";
2419
- async function listUsersOperation(params) {
2420
- const { tableName, mode = "full" } = params;
2421
- const service = getDynamoControlService(tableName);
2422
- const shardResults = await Promise.all(
2423
- Array.from(
2424
- { length: SHARD_COUNT },
2425
- (_, shard) => service.entities.user.query.gsi1({ gsi1Shard: String(shard) }).go()
2426
- )
2427
- );
2428
- return dispatchListMode(mode, shardResults, {
2429
- hydrate: (orderedIds) => batchGetWithRetry(
2430
- service.entities.user,
2431
- orderedIds.map((id) => ({ id, sk: SK10 }))
2432
- ),
2433
- getId: (item) => item.id,
2434
- buildEntry: (id, item) => ({
2435
- id,
2436
- resource: {
2437
- resourceType: "User",
2438
- id,
2439
- ...JSON.parse(item.resource)
2440
- }
2441
- }),
2442
- buildSummaryEntry: (id, parsed) => ({
2443
- id,
2444
- resource: { resourceType: "User", id, ...parsed }
2445
- })
2446
- });
2447
- }
2448
-
2449
1963
  // src/data/rest-api/routes/control/user/user-list-route.ts
2450
1964
  async function listUsersRoute(req, res) {
2451
1965
  return handleListRoute({
@@ -2457,34 +1971,6 @@ async function listUsersRoute(req, res) {
2457
1971
  });
2458
1972
  }
2459
1973
 
2460
- // src/data/operations/control/user/user-update-operation.ts
2461
- import { extractSummary as extractSummary11 } from "@openhi/types";
2462
- async function updateUserOperation(params) {
2463
- const { context, id, body, tableName } = params;
2464
- const service = getDynamoControlService(tableName);
2465
- const existing = await service.entities.user.get({ id, sk: "CURRENT" }).go();
2466
- if (!existing.data) {
2467
- throw new NotFoundError(`User not found: ${id}`);
2468
- }
2469
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
2470
- const lastUpdated = context.date ?? (/* @__PURE__ */ new Date()).toISOString();
2471
- const vid = `${Date.now()}`;
2472
- const resource = { resourceType: "User", id, ...parsedResource };
2473
- const summary = JSON.stringify(extractSummary11(resource));
2474
- await service.entities.user.put({
2475
- id,
2476
- resource: JSON.stringify(resource),
2477
- summary,
2478
- vid,
2479
- lastUpdated
2480
- }).go();
2481
- return {
2482
- id,
2483
- resource,
2484
- meta: { lastUpdated, versionId: vid }
2485
- };
2486
- }
2487
-
2488
1974
  // src/data/rest-api/routes/control/user/user-update-route.ts
2489
1975
  async function updateUserRoute(req, res) {
2490
1976
  const bodyResult = requireJsonBody(req, res);
@@ -2536,29 +2022,6 @@ router6.delete("/:id", deleteUserRoute);
2536
2022
  // src/data/rest-api/routes/control/workspace/workspace.ts
2537
2023
  import express7 from "express";
2538
2024
 
2539
- // src/data/operations/control/workspace/workspace-create-operation.ts
2540
- import { extractSummary as extractSummary12 } from "@openhi/types";
2541
- async function createWorkspaceOperation(params) {
2542
- const { context, body, tableName } = params;
2543
- const { tenantId } = context;
2544
- const service = getDynamoControlService(tableName);
2545
- const id = body.id ?? `workspace-${Date.now()}`;
2546
- const lastUpdated = context.date;
2547
- const vid = lastUpdated.replace(/[-:T.Z]/g, "").slice(0, 12) || Date.now().toString(36);
2548
- const parsedResource = typeof body.resource === "string" ? JSON.parse(body.resource) : body.resource ?? {};
2549
- const resource = { resourceType: "Workspace", id, ...parsedResource };
2550
- const summary = JSON.stringify(extractSummary12(resource));
2551
- await service.entities.workspace.put({
2552
- tenantId,
2553
- id,
2554
- resource: JSON.stringify(resource),
2555
- summary,
2556
- vid,
2557
- lastUpdated
2558
- }).go();
2559
- return { id, resource, meta: { lastUpdated, versionId: vid } };
2560
- }
2561
-
2562
2025
  // src/data/rest-api/routes/control/workspace/workspace-create-route.ts
2563
2026
  async function createWorkspaceRoute(req, res) {
2564
2027
  const bodyResult = requireJsonBody(req, res);
@@ -2660,7 +2123,7 @@ async function getWorkspaceByIdRoute(req, res) {
2660
2123
  }
2661
2124
 
2662
2125
  // src/data/operations/control/workspace/workspace-list-operation.ts
2663
- var SK11 = "CURRENT";
2126
+ var SK10 = "CURRENT";
2664
2127
  async function listWorkspacesOperation(params) {
2665
2128
  const { context, tableName, mode = "full" } = params;
2666
2129
  const { tenantId } = context;
@@ -2677,7 +2140,7 @@ async function listWorkspacesOperation(params) {
2677
2140
  {
2678
2141
  hydrate: (orderedIds) => batchGetWithRetry(
2679
2142
  service.entities.workspace,
2680
- orderedIds.map((id) => ({ tenantId, id, sk: SK11 }))
2143
+ orderedIds.map((id) => ({ tenantId, id, sk: SK10 }))
2681
2144
  ),
2682
2145
  getId: (item) => item.id,
2683
2146
  buildEntry: (id, item) => ({
@@ -2708,7 +2171,7 @@ async function listWorkspacesRoute(req, res) {
2708
2171
  }
2709
2172
 
2710
2173
  // src/data/operations/control/workspace/workspace-update-operation.ts
2711
- import { extractSummary as extractSummary13 } from "@openhi/types";
2174
+ import { extractSummary as extractSummary5 } from "@openhi/types";
2712
2175
  async function updateWorkspaceOperation(params) {
2713
2176
  const { context, id, body, tableName } = params;
2714
2177
  const { tenantId } = context;
@@ -2727,7 +2190,7 @@ async function updateWorkspaceOperation(params) {
2727
2190
  resourceType: "Workspace",
2728
2191
  id
2729
2192
  };
2730
- const summary = JSON.stringify(extractSummary13(updated));
2193
+ const summary = JSON.stringify(extractSummary5(updated));
2731
2194
  await service.entities.workspace.patch({ tenantId, id, sk: "CURRENT" }).set({ resource: JSON.stringify(updated), summary, vid, lastUpdated }).go();
2732
2195
  return { id, resource: updated, meta: { lastUpdated, versionId: vid } };
2733
2196
  }
@@ -4828,8 +4291,12 @@ var DataApiPostgresQueryRunner = class {
4828
4291
  resourceArn: this.clusterArn,
4829
4292
  secretArn: this.secretArn,
4830
4293
  database: this.database,
4831
- schema: this.schema,
4832
- sql,
4294
+ // NOTE: the Data API `schema` field is intentionally NOT set —
4295
+ // Aurora Serverless v2's Data API rejects it with
4296
+ // `ValidationException: The schema parameter isn't supported.`
4297
+ // Instead, the SQL is rewritten to schema-qualify the `resources`
4298
+ // table inline before being sent. See {@link qualifyResourcesTable}.
4299
+ sql: qualifyResourcesTable(sql, this.schema),
4833
4300
  parameters: params.map(toSqlParameter),
4834
4301
  // Results as named columns so we can map them back to JS objects.
4835
4302
  includeResultMetadata: true,
@@ -4845,6 +4312,12 @@ var DataApiPostgresQueryRunner = class {
4845
4312
  return JSON.parse(out.formattedRecords);
4846
4313
  }
4847
4314
  };
4315
+ function qualifyResourcesTable(sql, schema) {
4316
+ return sql.replace(
4317
+ /(\b(?:FROM|JOIN)\s+)resources\b/gi,
4318
+ `$1"${schema}".resources`
4319
+ );
4320
+ }
4848
4321
  function toSqlParameter(param) {
4849
4322
  if (param.value === null) {
4850
4323
  return { name: param.name, value: { isNull: true } };