@medplum/mock 2.0.3 → 2.0.4

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.
@@ -1,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@medplum/core'), require('rfc6902')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@medplum/core', 'rfc6902'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.mock = {}), global.medplum.core, global.rfc6902));
5
- })(this, (function (exports, core, rfc6902) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@medplum/core'), require('@medplum/fhir-router')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@medplum/core', '@medplum/fhir-router'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.medplum = global.medplum || {}, global.medplum.mock = {}), global.medplum.core, global.medplum.fhirRouter));
5
+ })(this, (function (exports, core, fhirRouter) { 'use strict';
6
6
 
7
7
  const ExampleAccessPolicy = {
8
8
  resourceType: 'AccessPolicy',
@@ -785,6 +785,134 @@
785
785
  },
786
786
  };
787
787
 
788
+ const exampleValueSet = {
789
+ resourceType: 'ValueSet',
790
+ expansion: {
791
+ contains: [
792
+ {
793
+ system: 'x',
794
+ code: 'test-code',
795
+ display: 'Test Display',
796
+ },
797
+ ],
798
+ },
799
+ };
800
+
801
+ const ExampleWorkflowQuestionnaire1 = {
802
+ resourceType: 'Questionnaire',
803
+ id: 'workflow-questionnaire-1',
804
+ name: 'Patient Registration',
805
+ title: 'Patient Registration',
806
+ subjectType: ['Patient'],
807
+ item: [
808
+ {
809
+ linkId: '1',
810
+ text: 'First question',
811
+ type: 'string',
812
+ },
813
+ ],
814
+ };
815
+ const ExampleWorkflowQuestionnaire2 = {
816
+ resourceType: 'Questionnaire',
817
+ id: 'workflow-questionnaire-2',
818
+ name: 'Surgery History',
819
+ title: 'Surgery History',
820
+ subjectType: ['Patient'],
821
+ item: [
822
+ {
823
+ linkId: '1',
824
+ text: 'First question',
825
+ type: 'string',
826
+ },
827
+ ],
828
+ };
829
+ const ExampleWorkflowQuestionnaire3 = {
830
+ resourceType: 'Questionnaire',
831
+ id: 'workflow-questionnaire-3',
832
+ name: 'Family Health History',
833
+ title: 'Family Health History',
834
+ subjectType: ['Patient'],
835
+ item: [
836
+ {
837
+ linkId: '1',
838
+ text: 'First question',
839
+ type: 'string',
840
+ },
841
+ ],
842
+ };
843
+ const ExampleWorkflowPlanDefinition = {
844
+ resourceType: 'PlanDefinition',
845
+ id: 'workflow-plan-definition-1',
846
+ title: 'Example Plan Definition',
847
+ action: [
848
+ {
849
+ title: ExampleWorkflowQuestionnaire1.title,
850
+ definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire1),
851
+ },
852
+ {
853
+ title: ExampleWorkflowQuestionnaire2.title,
854
+ definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire2),
855
+ },
856
+ {
857
+ title: ExampleWorkflowQuestionnaire3.title,
858
+ definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire3),
859
+ },
860
+ ],
861
+ };
862
+ const ExampleWorkflowQuestionnaireResponse1 = {
863
+ resourceType: 'QuestionnaireResponse',
864
+ id: 'workflow-questionnaire-response-1',
865
+ questionnaire: core.getReferenceString(ExampleWorkflowQuestionnaire1),
866
+ subject: core.createReference(HomerSimpson),
867
+ source: core.createReference(HomerSimpson),
868
+ };
869
+ // Based on: http://build.fhir.org/ig/HL7/sdc/Task-example.json.html
870
+ const ExampleWorkflowTask1 = {
871
+ resourceType: 'Task',
872
+ id: 'workflow-task-1',
873
+ status: 'completed',
874
+ meta: { author: core.createReference(HomerSimpson) },
875
+ requester: core.createReference(DrAliceSmith),
876
+ input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire1) }],
877
+ output: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaireResponse1) }],
878
+ };
879
+ const ExampleWorkflowTask2 = {
880
+ resourceType: 'Task',
881
+ id: 'workflow-task-2',
882
+ status: 'requested',
883
+ meta: { author: core.createReference(DrAliceSmith) },
884
+ requester: core.createReference(DrAliceSmith),
885
+ input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire2) }],
886
+ };
887
+ const ExampleWorkflowTask3 = {
888
+ resourceType: 'Task',
889
+ id: 'workflow-task-3',
890
+ status: 'requested',
891
+ meta: { author: core.createReference(DrAliceSmith) },
892
+ requester: core.createReference(DrAliceSmith),
893
+ input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire3) }],
894
+ };
895
+ const ExampleWorkflowRequestGroup = {
896
+ resourceType: 'RequestGroup',
897
+ id: 'workflow-request-group-1',
898
+ instantiatesCanonical: [core.getReferenceString(ExampleWorkflowPlanDefinition)],
899
+ status: 'active',
900
+ action: [
901
+ {
902
+ title: ExampleWorkflowQuestionnaire1.title,
903
+ resource: core.createReference(ExampleWorkflowTask1),
904
+ },
905
+ {
906
+ title: ExampleWorkflowQuestionnaire2.title,
907
+ resource: core.createReference(ExampleWorkflowTask2),
908
+ },
909
+ {
910
+ title: ExampleWorkflowQuestionnaire3.title,
911
+ resource: core.createReference(ExampleWorkflowTask3),
912
+ },
913
+ ],
914
+ };
915
+
788
916
  var SearchParameterList = [
789
917
  {
790
918
  resourceType: "SearchParameter",
@@ -1037,6 +1165,15 @@
1037
1165
  }
1038
1166
  ];
1039
1167
 
1168
+ const ExampleSmartClientApplication = {
1169
+ resourceType: 'ClientApplication',
1170
+ id: 'smart-client-app',
1171
+ name: 'Inferno Client',
1172
+ description: 'Client application used for Inferno ONC compliance testing',
1173
+ redirectUri: 'https://inferno.healthit.gov/suites/custom/smart/redirect',
1174
+ launchUri: 'https://inferno.healthit.gov/suites/custom/smart/launch',
1175
+ };
1176
+
1040
1177
  var StructureDefinitionList = [
1041
1178
  {
1042
1179
  resourceType: "StructureDefinition",
@@ -6012,7 +6149,8 @@
6012
6149
  path: "Observation.component.referenceRange",
6013
6150
  min: 0,
6014
6151
  max: "*"
6015
- }
6152
+ },
6153
+ contentReference: "#Observation.referenceRange"
6016
6154
  }
6017
6155
  ]
6018
6156
  }
@@ -9625,7 +9763,8 @@
9625
9763
  path: "PlanDefinition.action.action",
9626
9764
  min: 0,
9627
9765
  max: "*"
9628
- }
9766
+ },
9767
+ contentReference: "#PlanDefinition.action"
9629
9768
  }
9630
9769
  ]
9631
9770
  }
@@ -11179,7 +11318,8 @@
11179
11318
  path: "Questionnaire.item.item",
11180
11319
  min: 0,
11181
11320
  max: "*"
11182
- }
11321
+ },
11322
+ contentReference: "#Questionnaire.item"
11183
11323
  }
11184
11324
  ]
11185
11325
  }
@@ -11758,7 +11898,8 @@
11758
11898
  path: "QuestionnaireResponse.item.answer.item",
11759
11899
  min: 0,
11760
11900
  max: "*"
11761
- }
11901
+ },
11902
+ contentReference: "#QuestionnaireResponse.item"
11762
11903
  },
11763
11904
  {
11764
11905
  id: "QuestionnaireResponse.item.item",
@@ -11769,7 +11910,8 @@
11769
11910
  path: "QuestionnaireResponse.item.item",
11770
11911
  min: 0,
11771
11912
  max: "*"
11772
- }
11913
+ },
11914
+ contentReference: "#QuestionnaireResponse.item"
11773
11915
  }
11774
11916
  ]
11775
11917
  }
@@ -16001,6 +16143,11 @@
16001
16143
  path: "Project.id",
16002
16144
  min: 0,
16003
16145
  max: "1",
16146
+ base: {
16147
+ path: "Resource.id",
16148
+ min: 0,
16149
+ max: "1"
16150
+ },
16004
16151
  type: [
16005
16152
  {
16006
16153
  code: "string"
@@ -16012,6 +16159,11 @@
16012
16159
  path: "Project.meta",
16013
16160
  min: 0,
16014
16161
  max: "1",
16162
+ base: {
16163
+ path: "Resource.meta",
16164
+ min: 0,
16165
+ max: "1"
16166
+ },
16015
16167
  type: [
16016
16168
  {
16017
16169
  code: "Meta"
@@ -16023,6 +16175,11 @@
16023
16175
  path: "Project.implicitRules",
16024
16176
  min: 0,
16025
16177
  max: "1",
16178
+ base: {
16179
+ path: "Resource.implicitRules",
16180
+ min: 0,
16181
+ max: "1"
16182
+ },
16026
16183
  type: [
16027
16184
  {
16028
16185
  code: "uri"
@@ -16034,6 +16191,11 @@
16034
16191
  path: "Project.language",
16035
16192
  min: 0,
16036
16193
  max: "1",
16194
+ base: {
16195
+ path: "Resource.language",
16196
+ min: 0,
16197
+ max: "1"
16198
+ },
16037
16199
  type: [
16038
16200
  {
16039
16201
  code: "code"
@@ -16084,6 +16246,17 @@
16084
16246
  }
16085
16247
  ]
16086
16248
  },
16249
+ {
16250
+ id: "Project.checkReferencesOnWrite",
16251
+ path: "Project.checkReferencesOnWrite",
16252
+ min: 0,
16253
+ max: "1",
16254
+ type: [
16255
+ {
16256
+ code: "boolean"
16257
+ }
16258
+ ]
16259
+ },
16087
16260
  {
16088
16261
  id: "Project.owner",
16089
16262
  path: "Project.owner",
@@ -16263,6 +16436,11 @@
16263
16436
  path: "Bot.id",
16264
16437
  min: 0,
16265
16438
  max: "1",
16439
+ base: {
16440
+ path: "Resource.id",
16441
+ min: 0,
16442
+ max: "1"
16443
+ },
16266
16444
  type: [
16267
16445
  {
16268
16446
  code: "string"
@@ -16274,6 +16452,11 @@
16274
16452
  path: "Bot.meta",
16275
16453
  min: 0,
16276
16454
  max: "1",
16455
+ base: {
16456
+ path: "Resource.meta",
16457
+ min: 0,
16458
+ max: "1"
16459
+ },
16277
16460
  type: [
16278
16461
  {
16279
16462
  code: "Meta"
@@ -16285,6 +16468,11 @@
16285
16468
  path: "Bot.implicitRules",
16286
16469
  min: 0,
16287
16470
  max: "1",
16471
+ base: {
16472
+ path: "Resource.implicitRules",
16473
+ min: 0,
16474
+ max: "1"
16475
+ },
16288
16476
  type: [
16289
16477
  {
16290
16478
  code: "uri"
@@ -16296,6 +16484,11 @@
16296
16484
  path: "Bot.language",
16297
16485
  min: 0,
16298
16486
  max: "1",
16487
+ base: {
16488
+ path: "Resource.language",
16489
+ min: 0,
16490
+ max: "1"
16491
+ },
16299
16492
  type: [
16300
16493
  {
16301
16494
  code: "code"
@@ -16373,303 +16566,22 @@
16373
16566
  }
16374
16567
  ];
16375
16568
 
16376
- const GraphQLSchemaResponse = {
16377
- data: {
16378
- StructureDefinitionList,
16379
- SearchParameterList,
16380
- },
16381
- };
16382
-
16383
- const exampleValueSet = {
16384
- resourceType: 'ValueSet',
16385
- expansion: {
16386
- contains: [
16387
- {
16388
- system: 'x',
16389
- code: 'test-code',
16390
- display: 'Test Display',
16391
- },
16392
- ],
16393
- },
16394
- };
16395
-
16396
- const ExampleWorkflowQuestionnaire1 = {
16397
- resourceType: 'Questionnaire',
16398
- id: 'workflow-questionnaire-1',
16399
- name: 'Patient Registration',
16400
- title: 'Patient Registration',
16401
- subjectType: ['Patient'],
16402
- item: [
16403
- {
16404
- linkId: '1',
16405
- text: 'First question',
16406
- type: 'string',
16407
- },
16408
- ],
16409
- };
16410
- const ExampleWorkflowQuestionnaire2 = {
16411
- resourceType: 'Questionnaire',
16412
- id: 'workflow-questionnaire-2',
16413
- name: 'Surgery History',
16414
- title: 'Surgery History',
16415
- subjectType: ['Patient'],
16416
- item: [
16417
- {
16418
- linkId: '1',
16419
- text: 'First question',
16420
- type: 'string',
16421
- },
16422
- ],
16423
- };
16424
- const ExampleWorkflowQuestionnaire3 = {
16425
- resourceType: 'Questionnaire',
16426
- id: 'workflow-questionnaire-3',
16427
- name: 'Family Health History',
16428
- title: 'Family Health History',
16429
- subjectType: ['Patient'],
16430
- item: [
16431
- {
16432
- linkId: '1',
16433
- text: 'First question',
16434
- type: 'string',
16435
- },
16436
- ],
16437
- };
16438
- const ExampleWorkflowPlanDefinition = {
16439
- resourceType: 'PlanDefinition',
16440
- id: 'workflow-plan-definition-1',
16441
- title: 'Example Plan Definition',
16442
- action: [
16443
- {
16444
- title: ExampleWorkflowQuestionnaire1.title,
16445
- definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire1),
16446
- },
16447
- {
16448
- title: ExampleWorkflowQuestionnaire2.title,
16449
- definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire2),
16450
- },
16451
- {
16452
- title: ExampleWorkflowQuestionnaire3.title,
16453
- definitionCanonical: core.getReferenceString(ExampleWorkflowQuestionnaire3),
16454
- },
16455
- ],
16456
- };
16457
- const ExampleWorkflowQuestionnaireResponse1 = {
16458
- resourceType: 'QuestionnaireResponse',
16459
- id: 'workflow-questionnaire-response-1',
16460
- questionnaire: core.getReferenceString(ExampleWorkflowQuestionnaire1),
16461
- subject: core.createReference(HomerSimpson),
16462
- source: core.createReference(HomerSimpson),
16463
- };
16464
- // Based on: http://build.fhir.org/ig/HL7/sdc/Task-example.json.html
16465
- const ExampleWorkflowTask1 = {
16466
- resourceType: 'Task',
16467
- id: 'workflow-task-1',
16468
- status: 'completed',
16469
- meta: { author: core.createReference(HomerSimpson) },
16470
- requester: core.createReference(DrAliceSmith),
16471
- input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire1) }],
16472
- output: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaireResponse1) }],
16473
- };
16474
- const ExampleWorkflowTask2 = {
16475
- resourceType: 'Task',
16476
- id: 'workflow-task-2',
16477
- status: 'requested',
16478
- meta: { author: core.createReference(DrAliceSmith) },
16479
- requester: core.createReference(DrAliceSmith),
16480
- input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire2) }],
16481
- };
16482
- const ExampleWorkflowTask3 = {
16483
- resourceType: 'Task',
16484
- id: 'workflow-task-3',
16485
- status: 'requested',
16486
- meta: { author: core.createReference(DrAliceSmith) },
16487
- requester: core.createReference(DrAliceSmith),
16488
- input: [{ valueReference: core.createReference(ExampleWorkflowQuestionnaire3) }],
16489
- };
16490
- const ExampleWorkflowRequestGroup = {
16491
- resourceType: 'RequestGroup',
16492
- id: 'workflow-request-group-1',
16493
- instantiatesCanonical: [core.getReferenceString(ExampleWorkflowPlanDefinition)],
16494
- status: 'active',
16495
- action: [
16496
- {
16497
- title: ExampleWorkflowQuestionnaire1.title,
16498
- resource: core.createReference(ExampleWorkflowTask1),
16499
- },
16500
- {
16501
- title: ExampleWorkflowQuestionnaire2.title,
16502
- resource: core.createReference(ExampleWorkflowTask2),
16503
- },
16504
- {
16505
- title: ExampleWorkflowQuestionnaire3.title,
16506
- resource: core.createReference(ExampleWorkflowTask3),
16507
- },
16508
- ],
16509
- };
16510
-
16511
- const ExampleSmartClientApplication = {
16512
- resourceType: 'ClientApplication',
16513
- id: 'smart-client-app',
16514
- name: 'Inferno Client',
16515
- description: 'Client application used for Inferno ONC compliance testing',
16516
- redirectUri: 'https://inferno.healthit.gov/suites/custom/smart/redirect',
16517
- launchUri: 'https://inferno.healthit.gov/suites/custom/smart/launch',
16518
- };
16519
-
16520
- /******************************************************************************
16521
- Copyright (c) Microsoft Corporation.
16522
-
16523
- Permission to use, copy, modify, and/or distribute this software for any
16524
- purpose with or without fee is hereby granted.
16525
-
16526
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
16527
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16528
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16529
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
16530
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16531
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16532
- PERFORMANCE OF THIS SOFTWARE.
16533
- ***************************************************************************** */
16534
-
16535
- function __classPrivateFieldGet(receiver, state, kind, f) {
16536
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
16537
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
16538
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
16539
- }
16540
-
16541
- function __classPrivateFieldSet(receiver, state, value, kind, f) {
16542
- if (kind === "m") throw new TypeError("Private method is not writable");
16543
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
16544
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
16545
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
16546
- }
16547
-
16548
- var _MemoryRepository_resources, _MemoryRepository_history;
16549
- class MemoryRepository {
16550
- constructor() {
16551
- _MemoryRepository_resources.set(this, void 0);
16552
- _MemoryRepository_history.set(this, void 0);
16553
- __classPrivateFieldSet(this, _MemoryRepository_resources, {}, "f");
16554
- __classPrivateFieldSet(this, _MemoryRepository_history, {}, "f");
16555
- }
16556
- createResource(resource) {
16557
- const result = core.deepClone(resource);
16558
- if (!result.id) {
16559
- result.id = this.generateId();
16560
- }
16561
- if (!result.meta) {
16562
- result.meta = {};
16563
- }
16564
- if (!result.meta?.versionId) {
16565
- result.meta.versionId = this.generateId();
16566
- }
16567
- if (!result.meta?.lastUpdated) {
16568
- result.meta.lastUpdated = new Date().toISOString();
16569
- }
16570
- const { resourceType, id } = result;
16571
- if (!(resourceType in __classPrivateFieldGet(this, _MemoryRepository_resources, "f"))) {
16572
- __classPrivateFieldGet(this, _MemoryRepository_resources, "f")[resourceType] = {};
16573
- }
16574
- if (!(resourceType in __classPrivateFieldGet(this, _MemoryRepository_history, "f"))) {
16575
- __classPrivateFieldGet(this, _MemoryRepository_history, "f")[resourceType] = {};
16576
- }
16577
- if (!(id in __classPrivateFieldGet(this, _MemoryRepository_history, "f")[resourceType])) {
16578
- __classPrivateFieldGet(this, _MemoryRepository_history, "f")[resourceType][id] = [];
16579
- }
16580
- __classPrivateFieldGet(this, _MemoryRepository_resources, "f")[resourceType][id] = result;
16581
- __classPrivateFieldGet(this, _MemoryRepository_history, "f")[resourceType][id].push(result);
16582
- return core.deepClone(result);
16583
- }
16584
- updateResource(resource) {
16585
- const result = JSON.parse(JSON.stringify(resource));
16586
- if (result.meta) {
16587
- if (result.meta.versionId) {
16588
- delete result.meta.versionId;
16589
- }
16590
- if (result.meta.lastUpdated) {
16591
- delete result.meta.lastUpdated;
16592
- }
16593
- }
16594
- return this.createResource(result);
16595
- }
16596
- async patchResource(resourceType, id, patch) {
16597
- const resource = this.readResource(resourceType, id);
16598
- const patchErrors = rfc6902.applyPatch(resource, patch);
16599
- for (const error of patchErrors) {
16600
- if (error) {
16601
- const message = error.message?.split('\n')?.[0] || 'JSONPatch error';
16602
- throw core.badRequest(message);
16603
- }
16604
- }
16605
- return this.updateResource(resource);
16606
- }
16607
- readResource(resourceType, id) {
16608
- const resource = __classPrivateFieldGet(this, _MemoryRepository_resources, "f")?.[resourceType]?.[id];
16609
- if (!resource) {
16610
- throw core.notFound;
16611
- }
16612
- return core.deepClone(resource);
16613
- }
16614
- readHistory(resourceType, id) {
16615
- this.readResource(resourceType, id);
16616
- return {
16617
- resourceType: 'Bundle',
16618
- type: 'history',
16619
- entry: (__classPrivateFieldGet(this, _MemoryRepository_history, "f")?.[resourceType]?.[id] ?? [])
16620
- .reverse()
16621
- .map((version) => ({ resource: core.deepClone(version) })),
16622
- };
16623
- }
16624
- readVersion(resourceType, id, versionId) {
16625
- this.readResource(resourceType, id);
16626
- const version = __classPrivateFieldGet(this, _MemoryRepository_history, "f")?.[resourceType]?.[id]?.find((v) => v.meta?.versionId === versionId);
16627
- if (!version) {
16628
- throw core.notFound;
16629
- }
16630
- return core.deepClone(version);
16631
- }
16632
- search(searchRequest) {
16633
- const { resourceType } = searchRequest;
16634
- const resources = __classPrivateFieldGet(this, _MemoryRepository_resources, "f")[resourceType] ?? {};
16635
- const result = Object.values(resources).filter((resource) => core.matchesSearchRequest(resource, searchRequest));
16636
- return {
16637
- resourceType: 'Bundle',
16638
- type: 'searchset',
16639
- entry: result.map((resource) => ({ resource: core.deepClone(resource) })),
16640
- total: result.length,
16641
- };
16642
- }
16643
- deleteResource(resourceType, id) {
16644
- if (__classPrivateFieldGet(this, _MemoryRepository_resources, "f")?.[resourceType]?.[id]) {
16645
- delete __classPrivateFieldGet(this, _MemoryRepository_resources, "f")[resourceType][id];
16646
- }
16647
- }
16648
- generateId() {
16649
- // Cross platform random UUID generator
16650
- // Note that this is not intended for production use, but rather for testing
16651
- // This should be replaced when crypto.randomUUID is fully supported
16652
- // https://stackoverflow.com/revisions/2117523/28
16653
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
16654
- const r = (Math.random() * 16) | 0;
16655
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
16656
- return v.toString(16);
16657
- });
16658
- }
16659
- }
16660
- _MemoryRepository_resources = new WeakMap(), _MemoryRepository_history = new WeakMap();
16661
-
16662
16569
  class MockClient extends core.MedplumClient {
16663
16570
  constructor(clientOptions) {
16664
- const mockFetchClient = new MockFetchClient(clientOptions?.debug);
16571
+ const router = new fhirRouter.FhirRouter();
16572
+ const repo = new fhirRouter.MemoryRepository();
16573
+ const client = new MockFetchClient(router, repo, clientOptions?.debug);
16665
16574
  super({
16666
16575
  baseUrl: 'https://example.com/',
16667
16576
  clientId: 'my-client-id',
16668
- createPdf: (docDefinition, tableLayouts, fonts) => mockFetchClient.mockCreatePdf(docDefinition, tableLayouts, fonts),
16577
+ createPdf: (docDefinition, tableLayouts, fonts) => client.mockCreatePdf(docDefinition, tableLayouts, fonts),
16669
16578
  fetch: (url, options) => {
16670
- return mockFetchClient.mockFetch(url, options);
16579
+ return client.mockFetch(url, options);
16671
16580
  },
16672
16581
  });
16582
+ this.router = router;
16583
+ this.repo = repo;
16584
+ this.client = client;
16673
16585
  this.debug = !!clientOptions?.debug;
16674
16586
  }
16675
16587
  clear() {
@@ -16727,12 +16639,20 @@
16727
16639
  }
16728
16640
  }
16729
16641
  class MockFetchClient {
16730
- constructor(debug = false) {
16642
+ constructor(router, repo, debug = false) {
16731
16643
  this.debug = debug;
16732
- this.mockRepo = new MemoryRepository();
16733
- this.initMockRepo();
16644
+ this.initialized = false;
16645
+ this.router = router;
16646
+ this.repo = new fhirRouter.MemoryRepository();
16734
16647
  }
16735
16648
  async mockFetch(url, options) {
16649
+ if (!this.initialized) {
16650
+ if (!this.initPromise) {
16651
+ this.initPromise = this.initMockRepo();
16652
+ }
16653
+ await this.initPromise;
16654
+ this.initialized = true;
16655
+ }
16736
16656
  const method = options.method || 'GET';
16737
16657
  const path = url.replace('https://example.com/', '');
16738
16658
  if (this.debug) {
@@ -16968,176 +16888,90 @@
16968
16888
  }
16969
16889
  return null;
16970
16890
  }
16971
- initMockRepo() {
16972
- this.mockRepo.createResource(HomerSimpsonPreviousVersion);
16973
- this.mockRepo.createResource(HomerSimpson);
16974
- this.mockRepo.createResource(ExampleAccessPolicy);
16975
- this.mockRepo.createResource(ExampleStatusValueSet);
16976
- this.mockRepo.createResource(ExampleUserConfiguration);
16977
- this.mockRepo.createResource(ExampleBot);
16978
- this.mockRepo.createResource(ExampleClient);
16979
- this.mockRepo.createResource(HomerDiagnosticReport);
16980
- this.mockRepo.createResource(HomerEncounter);
16981
- this.mockRepo.createResource(HomerCommunication);
16982
- this.mockRepo.createResource(HomerMedia);
16983
- this.mockRepo.createResource(HomerObservation1);
16984
- this.mockRepo.createResource(HomerObservation2);
16985
- this.mockRepo.createResource(HomerObservation3);
16986
- this.mockRepo.createResource(HomerObservation4);
16987
- this.mockRepo.createResource(HomerObservation5);
16988
- this.mockRepo.createResource(HomerObservation6);
16989
- this.mockRepo.createResource(HomerObservation7);
16990
- this.mockRepo.createResource(HomerObservation8);
16991
- this.mockRepo.createResource(HomerSimpsonSpecimen);
16992
- this.mockRepo.createResource(TestOrganization);
16993
- this.mockRepo.createResource(DifferentOrganization);
16994
- this.mockRepo.createResource(ExampleQuestionnaire);
16995
- this.mockRepo.createResource(ExampleQuestionnaireResponse);
16996
- this.mockRepo.createResource(HomerServiceRequest);
16997
- this.mockRepo.createResource(ExampleSubscription);
16998
- this.mockRepo.createResource(BartSimpson);
16999
- this.mockRepo.createResource(DrAliceSmithPreviousVersion);
17000
- this.mockRepo.createResource(DrAliceSmith);
17001
- this.mockRepo.createResource(DrAliceSmithSchedule);
17002
- this.mockRepo.createResource(ExampleWorkflowQuestionnaire1);
17003
- this.mockRepo.createResource(ExampleWorkflowQuestionnaire2);
17004
- this.mockRepo.createResource(ExampleWorkflowQuestionnaire3);
17005
- this.mockRepo.createResource(ExampleWorkflowPlanDefinition);
17006
- this.mockRepo.createResource(ExampleWorkflowQuestionnaireResponse1);
17007
- this.mockRepo.createResource(ExampleWorkflowTask1);
17008
- this.mockRepo.createResource(ExampleWorkflowTask2);
17009
- this.mockRepo.createResource(ExampleWorkflowTask3);
17010
- this.mockRepo.createResource(ExampleWorkflowRequestGroup);
17011
- this.mockRepo.createResource(ExampleSmartClientApplication);
17012
- DrAliceSmithSlots.forEach((slot) => this.mockRepo.createResource(slot));
17013
- }
17014
- async mockFhirHandler(method, url, options) {
17015
- const path = url.includes('?') ? url.substring(0, url.indexOf('?')) : url;
17016
- const match = /fhir\/R4\/?([^/]+)?\/?([^/]+)?\/?([^/]+)?\/?([^/]+)?/.exec(path);
17017
- const resourceType = match?.[1];
17018
- const id = match?.[2];
17019
- const operation = match?.[3];
17020
- const versionId = match?.[4];
17021
- if (path.startsWith('fhir/R4/ValueSet/$expand')) {
17022
- return exampleValueSet;
16891
+ async initMockRepo() {
16892
+ const defaultResources = [
16893
+ HomerSimpsonPreviousVersion,
16894
+ HomerSimpson,
16895
+ ExampleAccessPolicy,
16896
+ ExampleStatusValueSet,
16897
+ ExampleUserConfiguration,
16898
+ ExampleBot,
16899
+ ExampleClient,
16900
+ HomerDiagnosticReport,
16901
+ HomerEncounter,
16902
+ HomerCommunication,
16903
+ HomerMedia,
16904
+ HomerObservation1,
16905
+ HomerObservation2,
16906
+ HomerObservation3,
16907
+ HomerObservation4,
16908
+ HomerObservation5,
16909
+ HomerObservation6,
16910
+ HomerObservation7,
16911
+ HomerObservation8,
16912
+ HomerSimpsonSpecimen,
16913
+ TestOrganization,
16914
+ DifferentOrganization,
16915
+ ExampleQuestionnaire,
16916
+ ExampleQuestionnaireResponse,
16917
+ HomerServiceRequest,
16918
+ ExampleSubscription,
16919
+ BartSimpson,
16920
+ DrAliceSmithPreviousVersion,
16921
+ DrAliceSmith,
16922
+ DrAliceSmithSchedule,
16923
+ ExampleWorkflowQuestionnaire1,
16924
+ ExampleWorkflowQuestionnaire2,
16925
+ ExampleWorkflowQuestionnaire3,
16926
+ ExampleWorkflowPlanDefinition,
16927
+ ExampleWorkflowQuestionnaireResponse1,
16928
+ ExampleWorkflowTask1,
16929
+ ExampleWorkflowTask2,
16930
+ ExampleWorkflowTask3,
16931
+ ExampleWorkflowRequestGroup,
16932
+ ExampleSmartClientApplication,
16933
+ ];
16934
+ for (const resource of defaultResources) {
16935
+ await this.repo.createResource(resource);
17023
16936
  }
17024
- else if (path === 'fhir/R4/$graphql') {
17025
- return this.mockFhirGraphqlHandler(method, path, options);
16937
+ for (const structureDefinition of StructureDefinitionList) {
16938
+ core.indexStructureDefinition(structureDefinition);
16939
+ await this.repo.createResource(structureDefinition);
17026
16940
  }
17027
- else if (path === 'not-found' || id === 'not-found') {
17028
- return core.notFound;
16941
+ for (const searchParameter of SearchParameterList) {
16942
+ await this.repo.createResource(searchParameter);
17029
16943
  }
17030
- else if (method === 'POST') {
17031
- if (resourceType && id && operation) {
17032
- return core.allOk;
17033
- }
17034
- else if (resourceType) {
17035
- return this.mockRepo.createResource(JSON.parse(options.body));
17036
- }
17037
- else {
17038
- return this.mockFhirBatchHandler(method, path, options);
17039
- }
17040
- }
17041
- else if (method === 'GET') {
17042
- if (resourceType && id && versionId) {
17043
- return this.mockRepo.readVersion(resourceType, id, versionId);
17044
- }
17045
- else if (resourceType && id && operation === '_history') {
17046
- return this.mockRepo.readHistory(resourceType, id);
17047
- }
17048
- else if (resourceType && id === '$csv') {
17049
- return core.allOk;
17050
- }
17051
- else if (resourceType && id) {
17052
- return this.mockRepo.readResource(resourceType, id);
17053
- }
17054
- else if (resourceType) {
17055
- return this.mockRepo.search(core.parseSearchDefinition(url));
17056
- }
17057
- }
17058
- else if (method === 'PUT') {
17059
- return this.mockRepo.updateResource(JSON.parse(options.body));
17060
- }
17061
- else if (method === 'PATCH') {
17062
- if (resourceType && id) {
17063
- return this.mockRepo.patchResource(resourceType, id, JSON.parse(options.body));
17064
- }
17065
- }
17066
- else if (method === 'DELETE') {
17067
- if (resourceType && id) {
17068
- this.mockRepo.deleteResource(resourceType, id);
17069
- return core.allOk;
17070
- }
17071
- }
17072
- throw core.notFound;
16944
+ DrAliceSmithSlots.forEach((slot) => this.repo.createResource(slot));
17073
16945
  }
17074
- mockFhirGraphqlHandler(_method, _path, options) {
17075
- const { body } = options;
17076
- if (body.includes('ResourceList: ServiceRequestList')) {
17077
- return {
17078
- data: {
17079
- ResourceList: [
17080
- {
17081
- ...HomerServiceRequest,
17082
- ObservationList: [
17083
- HomerObservation1,
17084
- HomerObservation2,
17085
- HomerObservation3,
17086
- HomerObservation4,
17087
- HomerObservation5,
17088
- HomerObservation6,
17089
- ],
17090
- },
17091
- ],
17092
- },
17093
- };
16946
+ async mockFhirHandler(method, url, options) {
16947
+ if (url.startsWith('fhir/R4/ValueSet/$expand')) {
16948
+ return exampleValueSet;
17094
16949
  }
17095
- return GraphQLSchemaResponse;
17096
- }
17097
- async mockFhirBatchHandler(_method, _path, options) {
17098
- const { body } = options;
17099
- const request = JSON.parse(body);
17100
- let entry;
17101
- if (request.entry) {
17102
- entry = [];
17103
- for (const input of request.entry) {
17104
- entry.push(await this.handleBatchEntry(input));
17105
- }
16950
+ const parsedUrl = new URL(url, 'https://example.com');
16951
+ let pathname = parsedUrl.pathname;
16952
+ if (pathname.includes('fhir/R4')) {
16953
+ pathname = pathname.substring(pathname.indexOf('fhir/R4') + 7);
17106
16954
  }
17107
- return {
17108
- resourceType: 'Bundle',
17109
- type: 'batch-response',
17110
- entry,
16955
+ let body = undefined;
16956
+ if (options.body) {
16957
+ body = JSON.parse(options.body);
16958
+ }
16959
+ const request = {
16960
+ method,
16961
+ pathname,
16962
+ body,
16963
+ params: Object.create(null),
16964
+ query: Object.fromEntries(parsedUrl.searchParams),
17111
16965
  };
17112
- }
17113
- async handleBatchEntry(input) {
17114
- try {
17115
- const url = 'fhir/R4/' + input.request?.url;
17116
- const method = input.request?.method;
17117
- const resource = await this.mockHandler(method, url, {
17118
- body: input.resource ? JSON.stringify(input.resource) : undefined,
17119
- });
17120
- if (resource?.resourceType === 'OperationOutcome') {
17121
- return {
17122
- resource,
17123
- response: { status: core.getStatus(resource).toString() },
17124
- };
17125
- }
17126
- else if (resource) {
17127
- return { resource, response: { status: '200' } };
17128
- }
17129
- else {
17130
- return { resource: core.notFound, response: { status: '404' } };
16966
+ const result = await this.router.handleRequest(request, this.repo);
16967
+ if (result.length === 1) {
16968
+ if (!core.isOk(result[0])) {
16969
+ throw result[0];
17131
16970
  }
16971
+ return result[0];
17132
16972
  }
17133
- catch (err) {
17134
- const outcome = err;
17135
- return {
17136
- response: {
17137
- status: core.getStatus(outcome).toString(),
17138
- outcome,
17139
- },
17140
- };
16973
+ else {
16974
+ return result[1];
17141
16975
  }
17142
16976
  }
17143
16977
  }
@@ -17166,7 +17000,6 @@
17166
17000
  exports.ExampleWorkflowTask1 = ExampleWorkflowTask1;
17167
17001
  exports.ExampleWorkflowTask2 = ExampleWorkflowTask2;
17168
17002
  exports.ExampleWorkflowTask3 = ExampleWorkflowTask3;
17169
- exports.GraphQLSchemaResponse = GraphQLSchemaResponse;
17170
17003
  exports.HomerBartRelatedPerson = HomerBartRelatedPerson;
17171
17004
  exports.HomerCommunication = HomerCommunication;
17172
17005
  exports.HomerDiagnosticReport = HomerDiagnosticReport;