@medplum/mock 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,6 +8,38 @@ For example:
8
8
  - `GET fhir/R4/Practitioner/123` returns Dr. Alice Smith
9
9
  - `GET fhir/R4/Organization/123` returns Test Organization
10
10
 
11
+ ## Installation
12
+
13
+ Add as a dependency:
14
+
15
+ ```bash
16
+ npm install @medplum/mock
17
+ ```
18
+
19
+ Note the following peer dependencies:
20
+ - [@medplum/core](https://www.npmjs.com/package/@medplum/core)
21
+ - [@medplum/fhirpath](https://www.npmjs.com/package/@medplum/fhirpath)
22
+
23
+ ## Usage
24
+
25
+ Create a new mock client:
26
+
27
+ ```ts
28
+ const client = new MockClient();
29
+ ```
30
+
31
+ Read a `Patient` resource:
32
+
33
+ ```ts
34
+ const patient = await client.readResource('Patient', '123');
35
+ ```
36
+
37
+ `MockClient` is API compatible with `MedplumClient` in [@medplum/core](https://www.npmjs.com/package/@medplum/core). Please refer to `MedplumClient` for full documentation on client capabilities.
38
+
39
+ ## About Medplum
40
+
41
+ Medplum is a healthcare platform that helps you quickly develop high-quality compliant applications. Medplum includes a FHIR server, React component library, and developer app.
42
+
11
43
  ## License
12
44
 
13
45
  Apache 2.0. Copyright © Medplum 2022
package/dist/cjs/index.js CHANGED
@@ -444,6 +444,7 @@
444
444
  },
445
445
  ],
446
446
  specimen: [core.createReference(HomerSimpsonSpecimen)],
447
+ authoredOn: '2020-01-01T12:00:00Z',
447
448
  };
448
449
  const BartSimpson = {
449
450
  resourceType: 'Patient',
@@ -6311,6 +6312,14 @@
6311
6312
  expression: 'ServiceRequest.subject',
6312
6313
  target: ['Group', 'Device', 'Patient', 'Location'],
6313
6314
  },
6315
+ {
6316
+ resourceType: 'SearchParameter',
6317
+ id: 'ServiceRequest-authored',
6318
+ code: 'authored',
6319
+ base: ['ServiceRequest'],
6320
+ type: 'date',
6321
+ expression: 'ServiceRequest.authoredOn',
6322
+ },
6314
6323
  {
6315
6324
  resourceType: 'SearchParameter',
6316
6325
  id: 'Observation-value-quantity',
@@ -6968,6 +6977,23 @@
6968
6977
  eval(context) {
6969
6978
  return this.impl(ensureArray(context), ...this.args);
6970
6979
  }
6980
+ }
6981
+ class IndexerAtom {
6982
+ constructor(left, expr) {
6983
+ this.left = left;
6984
+ this.expr = expr;
6985
+ }
6986
+ eval(context) {
6987
+ const index = this.expr.eval(context);
6988
+ if (typeof index !== 'number') {
6989
+ throw new Error(`Invalid indexer expression: should return integer}`);
6990
+ }
6991
+ const leftResult = this.left.eval(context);
6992
+ if (!(index in leftResult)) {
6993
+ return [];
6994
+ }
6995
+ return leftResult[index];
6996
+ }
6971
6997
  }
6972
6998
 
6973
6999
  function parseDateString(str) {
@@ -7230,7 +7256,7 @@
7230
7256
  * See: http://hl7.org/fhirpath/#selectprojection-expression-collection
7231
7257
  */
7232
7258
  function select(input, criteria) {
7233
- return ensureArray(criteria.eval(input));
7259
+ return ensureArray(input.map((e) => criteria.eval(e)).flat());
7234
7260
  }
7235
7261
  /**
7236
7262
  * A version of select that will repeat the projection and add it to the output
@@ -8685,7 +8711,7 @@
8685
8711
  prefix(tokenType, precedence, builder) {
8686
8712
  return this.registerPrefix(tokenType, {
8687
8713
  parse(parser, token) {
8688
- const right = parser.parse(precedence);
8714
+ const right = parser.consumeAndParse(precedence);
8689
8715
  return builder(token, right);
8690
8716
  },
8691
8717
  });
@@ -8693,7 +8719,7 @@
8693
8719
  infixLeft(tokenType, precedence, builder) {
8694
8720
  return this.registerInfix(tokenType, {
8695
8721
  parse(parser, left, token) {
8696
- const right = parser.parse(precedence);
8722
+ const right = parser.consumeAndParse(precedence);
8697
8723
  return builder(left, token, right);
8698
8724
  },
8699
8725
  precedence,
@@ -8722,7 +8748,7 @@
8722
8748
  __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_consume).call(this);
8723
8749
  return true;
8724
8750
  }
8725
- parse(precedence = 100 /* MaximumPrecedence */) {
8751
+ consumeAndParse(precedence = 100 /* MaximumPrecedence */) {
8726
8752
  const token = __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_consume).call(this);
8727
8753
  const prefix = __classPrivateFieldGet(this, _Parser_prefixParselets, "f")[token.id];
8728
8754
  if (!prefix) {
@@ -8757,13 +8783,23 @@
8757
8783
  };
8758
8784
  const PARENTHESES_PARSELET = {
8759
8785
  parse(parser) {
8760
- const expr = parser.parse();
8786
+ const expr = parser.consumeAndParse();
8761
8787
  if (!parser.match(')')) {
8762
8788
  throw new Error('Parse error: expected `)`');
8763
8789
  }
8764
8790
  return expr;
8765
8791
  },
8766
8792
  };
8793
+ const INDEXER_PARSELET = {
8794
+ parse(parser, left) {
8795
+ const expr = parser.consumeAndParse();
8796
+ if (!parser.match(']')) {
8797
+ throw new Error('Parse error: expected `]`');
8798
+ }
8799
+ return new IndexerAtom(left, expr);
8800
+ },
8801
+ precedence: 2 /* Indexer */,
8802
+ };
8767
8803
  const FUNCTION_CALL_PARSELET = {
8768
8804
  parse(parser, left) {
8769
8805
  if (!(left instanceof SymbolAtom)) {
@@ -8774,7 +8810,7 @@
8774
8810
  }
8775
8811
  const args = [];
8776
8812
  while (!parser.match(')')) {
8777
- args.push(parser.parse());
8813
+ args.push(parser.consumeAndParse());
8778
8814
  parser.match(',');
8779
8815
  }
8780
8816
  return new FunctionAtom(left.name, args, functions[left.name]);
@@ -8819,6 +8855,7 @@
8819
8855
  })
8820
8856
  .registerPrefix('{}', { parse: () => new EmptySetAtom() })
8821
8857
  .registerPrefix('(', PARENTHESES_PARSELET)
8858
+ .registerInfix('[', INDEXER_PARSELET)
8822
8859
  .registerInfix('(', FUNCTION_CALL_PARSELET)
8823
8860
  .prefix('+', 3 /* UnaryAdd */, (_, right) => new UnaryOperatorAtom(right, (x) => x))
8824
8861
  .prefix('-', 3 /* UnarySubtract */, (_, right) => new ArithemticOperatorAtom(right, right, (_, y) => -y))
@@ -8871,7 +8908,7 @@
8871
8908
  */
8872
8909
  function parseFhirPath(input) {
8873
8910
  try {
8874
- return new FhirPathAtom(input, parserBuilder.construct(input).parse());
8911
+ return new FhirPathAtom(input, parserBuilder.construct(input).consumeAndParse());
8875
8912
  }
8876
8913
  catch (error) {
8877
8914
  throw new Error(`FhirPathError on "${input}": ${error}`);
@@ -8999,14 +9036,10 @@
8999
9036
  if (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) {
9000
9037
  console.log('MockClient', method, path);
9001
9038
  }
9002
- const result = mockHandler(method, path, options);
9003
- if ((clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) && !result) {
9039
+ const response = mockHandler(method, path, options);
9040
+ if ((clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) && !response) {
9004
9041
  console.log('MockClient: not found', method, path);
9005
9042
  }
9006
- const response = Object.assign({ request: {
9007
- url,
9008
- options,
9009
- } }, result);
9010
9043
  if (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) {
9011
9044
  console.log('MockClient', JSON.stringify(response, null, 2));
9012
9045
  }
@@ -9095,6 +9128,11 @@
9095
9128
  if (path.startsWith('auth/resetpassword')) {
9096
9129
  return mockResetPasswordHandler(method, path, options);
9097
9130
  }
9131
+ if (path.startsWith('auth/me')) {
9132
+ return {
9133
+ profile: { reference: 'Practitioner/123' },
9134
+ };
9135
+ }
9098
9136
  return null;
9099
9137
  }
9100
9138
  function mockChangePasswordHandler(method, path, options) {