@medplum/mock 0.9.1 → 0.9.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.
package/dist/esm/index.js CHANGED
@@ -119,6 +119,11 @@ const ExampleBot = {
119
119
  id: '123',
120
120
  name: 'Test Bot',
121
121
  code: 'console.log("hello world");',
122
+ };
123
+ const ExampleClient = {
124
+ resourceType: 'ClientApplication',
125
+ id: '123',
126
+ name: 'Test Client',
122
127
  };
123
128
 
124
129
  const ExampleQuestionnaire = {
@@ -440,6 +445,7 @@ const HomerServiceRequest = {
440
445
  },
441
446
  ],
442
447
  specimen: [createReference(HomerSimpsonSpecimen)],
448
+ authoredOn: '2020-01-01T12:00:00Z',
443
449
  };
444
450
  const BartSimpson = {
445
451
  resourceType: 'Patient',
@@ -6212,6 +6218,136 @@ var StructureDefinitionList = [
6212
6218
  }
6213
6219
  ]
6214
6220
  }
6221
+ },
6222
+ {
6223
+ resourceType: "StructureDefinition",
6224
+ id: "Bot",
6225
+ name: "Bot",
6226
+ description: "Bot account for automated actions.",
6227
+ snapshot: {
6228
+ element: [
6229
+ {
6230
+ id: "Bot.id",
6231
+ path: "Bot.id",
6232
+ definition: "The logical id of the resource, as used in the URL for the resource. Once assigned, this value never changes.",
6233
+ min: 0,
6234
+ max: "1",
6235
+ type: [
6236
+ {
6237
+ code: "string"
6238
+ }
6239
+ ]
6240
+ },
6241
+ {
6242
+ id: "Bot.meta",
6243
+ path: "Bot.meta",
6244
+ definition: "The metadata about the resource. This is content that is maintained by the infrastructure. Changes to the content might not always be associated with version changes to the resource.",
6245
+ min: 0,
6246
+ max: "1",
6247
+ type: [
6248
+ {
6249
+ code: "Meta"
6250
+ }
6251
+ ]
6252
+ },
6253
+ {
6254
+ id: "Bot.implicitRules",
6255
+ path: "Bot.implicitRules",
6256
+ definition: "A reference to a set of rules that were followed when the resource was constructed, and which must be understood when processing the content. Often, this is a reference to an implementation guide that defines the special rules along with other profiles etc.",
6257
+ min: 0,
6258
+ max: "1",
6259
+ type: [
6260
+ {
6261
+ code: "uri"
6262
+ }
6263
+ ]
6264
+ },
6265
+ {
6266
+ id: "Bot.language",
6267
+ path: "Bot.language",
6268
+ definition: "The base language in which the resource is written.",
6269
+ min: 0,
6270
+ max: "1",
6271
+ type: [
6272
+ {
6273
+ code: "code"
6274
+ }
6275
+ ]
6276
+ },
6277
+ {
6278
+ id: "Bot.name",
6279
+ path: "Bot.name",
6280
+ definition: "A name associated with the Bot.",
6281
+ min: 0,
6282
+ max: "1",
6283
+ type: [
6284
+ {
6285
+ code: "string"
6286
+ }
6287
+ ]
6288
+ },
6289
+ {
6290
+ id: "Bot.description",
6291
+ path: "Bot.description",
6292
+ definition: "A summary, characterization or explanation of the Bot.",
6293
+ min: 0,
6294
+ max: "1",
6295
+ type: [
6296
+ {
6297
+ code: "string"
6298
+ }
6299
+ ]
6300
+ },
6301
+ {
6302
+ id: "Bot.runtimeVersion",
6303
+ path: "Bot.runtimeVersion",
6304
+ definition: "The identifier of the bot runtime environment (i.e., vmcontext, awslambda, etc).",
6305
+ min: 0,
6306
+ max: "1",
6307
+ type: [
6308
+ {
6309
+ code: "string"
6310
+ }
6311
+ ]
6312
+ },
6313
+ {
6314
+ id: "Bot.photo",
6315
+ path: "Bot.photo",
6316
+ definition: "Image of the bot.",
6317
+ min: 0,
6318
+ max: "1",
6319
+ type: [
6320
+ {
6321
+ code: "Attachment"
6322
+ }
6323
+ ]
6324
+ },
6325
+ {
6326
+ id: "Bot.code",
6327
+ path: "Bot.code",
6328
+ definition: "Bot logic script.",
6329
+ min: 0,
6330
+ max: "1",
6331
+ type: [
6332
+ {
6333
+ code: "string"
6334
+ }
6335
+ ]
6336
+ },
6337
+ {
6338
+ id: "Bot.runAsUser",
6339
+ path: "Bot.runAsUser",
6340
+ definition: "Optional flag to indicate that the bot should be run as the user.",
6341
+ min: 0,
6342
+ max: "1",
6343
+ type: [
6344
+ {
6345
+ code: "boolean"
6346
+ }
6347
+ ]
6348
+ }
6349
+ ]
6350
+ }
6215
6351
  }
6216
6352
  ];
6217
6353
 
@@ -6307,6 +6443,14 @@ const PatientSearchParameters = [
6307
6443
  expression: 'ServiceRequest.subject',
6308
6444
  target: ['Group', 'Device', 'Patient', 'Location'],
6309
6445
  },
6446
+ {
6447
+ resourceType: 'SearchParameter',
6448
+ id: 'ServiceRequest-authored',
6449
+ code: 'authored',
6450
+ base: ['ServiceRequest'],
6451
+ type: 'date',
6452
+ expression: 'ServiceRequest.authoredOn',
6453
+ },
6310
6454
  {
6311
6455
  resourceType: 'SearchParameter',
6312
6456
  id: 'Observation-value-quantity',
@@ -6964,6 +7108,23 @@ class FunctionAtom {
6964
7108
  eval(context) {
6965
7109
  return this.impl(ensureArray(context), ...this.args);
6966
7110
  }
7111
+ }
7112
+ class IndexerAtom {
7113
+ constructor(left, expr) {
7114
+ this.left = left;
7115
+ this.expr = expr;
7116
+ }
7117
+ eval(context) {
7118
+ const index = this.expr.eval(context);
7119
+ if (typeof index !== 'number') {
7120
+ throw new Error(`Invalid indexer expression: should return integer}`);
7121
+ }
7122
+ const leftResult = this.left.eval(context);
7123
+ if (!(index in leftResult)) {
7124
+ return [];
7125
+ }
7126
+ return leftResult[index];
7127
+ }
6967
7128
  }
6968
7129
 
6969
7130
  function parseDateString(str) {
@@ -7226,7 +7387,7 @@ function where(input, criteria) {
7226
7387
  * See: http://hl7.org/fhirpath/#selectprojection-expression-collection
7227
7388
  */
7228
7389
  function select(input, criteria) {
7229
- return ensureArray(criteria.eval(input));
7390
+ return ensureArray(input.map((e) => criteria.eval(e)).flat());
7230
7391
  }
7231
7392
  /**
7232
7393
  * A version of select that will repeat the projection and add it to the output
@@ -8311,7 +8472,11 @@ function resolve(input) {
8311
8472
  refStr = e;
8312
8473
  }
8313
8474
  else if (typeof e === 'object') {
8314
- refStr = e.reference;
8475
+ const ref = e;
8476
+ if (ref.resource) {
8477
+ return ref.resource;
8478
+ }
8479
+ refStr = ref.reference;
8315
8480
  }
8316
8481
  if (!refStr) {
8317
8482
  return undefined;
@@ -8681,7 +8846,7 @@ class ParserBuilder {
8681
8846
  prefix(tokenType, precedence, builder) {
8682
8847
  return this.registerPrefix(tokenType, {
8683
8848
  parse(parser, token) {
8684
- const right = parser.parse(precedence);
8849
+ const right = parser.consumeAndParse(precedence);
8685
8850
  return builder(token, right);
8686
8851
  },
8687
8852
  });
@@ -8689,7 +8854,7 @@ class ParserBuilder {
8689
8854
  infixLeft(tokenType, precedence, builder) {
8690
8855
  return this.registerInfix(tokenType, {
8691
8856
  parse(parser, left, token) {
8692
- const right = parser.parse(precedence);
8857
+ const right = parser.consumeAndParse(precedence);
8693
8858
  return builder(left, token, right);
8694
8859
  },
8695
8860
  precedence,
@@ -8718,7 +8883,7 @@ class Parser {
8718
8883
  __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_consume).call(this);
8719
8884
  return true;
8720
8885
  }
8721
- parse(precedence = 100 /* MaximumPrecedence */) {
8886
+ consumeAndParse(precedence = 100 /* MaximumPrecedence */) {
8722
8887
  const token = __classPrivateFieldGet(this, _Parser_instances, "m", _Parser_consume).call(this);
8723
8888
  const prefix = __classPrivateFieldGet(this, _Parser_prefixParselets, "f")[token.id];
8724
8889
  if (!prefix) {
@@ -8753,13 +8918,23 @@ _Parser_tokens = new WeakMap(), _Parser_prefixParselets = new WeakMap(), _Parser
8753
8918
  };
8754
8919
  const PARENTHESES_PARSELET = {
8755
8920
  parse(parser) {
8756
- const expr = parser.parse();
8921
+ const expr = parser.consumeAndParse();
8757
8922
  if (!parser.match(')')) {
8758
8923
  throw new Error('Parse error: expected `)`');
8759
8924
  }
8760
8925
  return expr;
8761
8926
  },
8762
8927
  };
8928
+ const INDEXER_PARSELET = {
8929
+ parse(parser, left) {
8930
+ const expr = parser.consumeAndParse();
8931
+ if (!parser.match(']')) {
8932
+ throw new Error('Parse error: expected `]`');
8933
+ }
8934
+ return new IndexerAtom(left, expr);
8935
+ },
8936
+ precedence: 2 /* Indexer */,
8937
+ };
8763
8938
  const FUNCTION_CALL_PARSELET = {
8764
8939
  parse(parser, left) {
8765
8940
  if (!(left instanceof SymbolAtom)) {
@@ -8770,7 +8945,7 @@ const FUNCTION_CALL_PARSELET = {
8770
8945
  }
8771
8946
  const args = [];
8772
8947
  while (!parser.match(')')) {
8773
- args.push(parser.parse());
8948
+ args.push(parser.consumeAndParse());
8774
8949
  parser.match(',');
8775
8950
  }
8776
8951
  return new FunctionAtom(left.name, args, functions[left.name]);
@@ -8815,6 +8990,7 @@ const parserBuilder = new ParserBuilder()
8815
8990
  })
8816
8991
  .registerPrefix('{}', { parse: () => new EmptySetAtom() })
8817
8992
  .registerPrefix('(', PARENTHESES_PARSELET)
8993
+ .registerInfix('[', INDEXER_PARSELET)
8818
8994
  .registerInfix('(', FUNCTION_CALL_PARSELET)
8819
8995
  .prefix('+', 3 /* UnaryAdd */, (_, right) => new UnaryOperatorAtom(right, (x) => x))
8820
8996
  .prefix('-', 3 /* UnarySubtract */, (_, right) => new ArithemticOperatorAtom(right, right, (_, y) => -y))
@@ -8867,7 +9043,7 @@ const parserBuilder = new ParserBuilder()
8867
9043
  */
8868
9044
  function parseFhirPath(input) {
8869
9045
  try {
8870
- return new FhirPathAtom(input, parserBuilder.construct(input).parse());
9046
+ return new FhirPathAtom(input, parserBuilder.construct(input).consumeAndParse());
8871
9047
  }
8872
9048
  catch (error) {
8873
9049
  throw new Error(`FhirPathError on "${input}": ${error}`);
@@ -8947,6 +9123,12 @@ class MemoryRepository {
8947
9123
  total: result.length,
8948
9124
  };
8949
9125
  }
9126
+ deleteResource(resourceType, id) {
9127
+ var _a, _b;
9128
+ if ((_b = (_a = __classPrivateFieldGet$1(this, _MemoryRepository_resources, "f")) === null || _a === void 0 ? void 0 : _a[resourceType]) === null || _b === void 0 ? void 0 : _b[id]) {
9129
+ delete __classPrivateFieldGet$1(this, _MemoryRepository_resources, "f")[resourceType][id];
9130
+ }
9131
+ }
8950
9132
  generateId() {
8951
9133
  return Date.now().toString(36);
8952
9134
  }
@@ -8964,7 +9146,7 @@ function matchesSearchRequest(resource, searchRequest) {
8964
9146
  }
8965
9147
  if (searchRequest.filters) {
8966
9148
  for (const filter of searchRequest.filters) {
8967
- if (!matchesSearchFilter(resource, searchRequest, filter)) {
9149
+ if (!matchesSearchFilter(resource, filter)) {
8968
9150
  return false;
8969
9151
  }
8970
9152
  }
@@ -8977,7 +9159,7 @@ function matchesSearchRequest(resource, searchRequest) {
8977
9159
  * @param filter One of the filters of a subscription criteria.
8978
9160
  * @returns True if the resource satisfies the search filter.
8979
9161
  */
8980
- function matchesSearchFilter(resource, searchRequest, filter) {
9162
+ function matchesSearchFilter(resource, filter) {
8981
9163
  const expression = filter.code.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
8982
9164
  const values = evalFhirPath(expression, resource);
8983
9165
  const result = values.some((value) => JSON.stringify(value).toLowerCase().includes(filter.value.toLowerCase()));
@@ -8990,19 +9172,15 @@ class MockClient extends MedplumClient {
8990
9172
  baseUrl: 'https://example.com/',
8991
9173
  clientId: 'my-client-id',
8992
9174
  fetch: (url, options) => {
8993
- const method = options.method;
9175
+ const method = options.method || 'GET';
8994
9176
  const path = url.replace('https://example.com/', '');
8995
9177
  if (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) {
8996
9178
  console.log('MockClient', method, path);
8997
9179
  }
8998
- const result = mockHandler(method, path, options);
8999
- if ((clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) && !result) {
9180
+ const response = mockHandler(method, path, options);
9181
+ if ((clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) && !response) {
9000
9182
  console.log('MockClient: not found', method, path);
9001
9183
  }
9002
- const response = Object.assign({ request: {
9003
- url,
9004
- options,
9005
- } }, result);
9006
9184
  if (clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.debug) {
9007
9185
  console.log('MockClient', JSON.stringify(response, null, 2));
9008
9186
  }
@@ -9035,7 +9213,7 @@ class MockClient extends MedplumClient {
9035
9213
  }
9036
9214
  return super.getActiveLogin();
9037
9215
  }
9038
- createBinary(data, filename, contentType) {
9216
+ createBinary(_data, filename, contentType) {
9039
9217
  if (filename.endsWith('.exe')) {
9040
9218
  return Promise.reject(badRequest('Invalid file type'));
9041
9219
  }
@@ -9061,13 +9239,14 @@ function mockHandler(method, path, options) {
9061
9239
  return null;
9062
9240
  }
9063
9241
  }
9064
- function mockAdminHandler(method, path) {
9242
+ function mockAdminHandler(_method, path) {
9065
9243
  if (path.startsWith('admin/projects/123')) {
9066
9244
  return {
9067
9245
  project: { id: '123', name: 'Project 123' },
9068
9246
  members: [
9069
9247
  { id: '123', profile: { reference: 'Practitioner/123', display: 'Alice Smith' }, role: 'owner' },
9070
9248
  { id: '888', profile: { reference: 'ClientApplication/123', display: 'Test Client' }, role: 'client' },
9249
+ { id: '999', profile: { reference: 'Bot/123', display: 'Test Bot' }, role: 'bot' },
9071
9250
  ],
9072
9251
  };
9073
9252
  }
@@ -9091,9 +9270,14 @@ function mockAuthHandler(method, path, options) {
9091
9270
  if (path.startsWith('auth/resetpassword')) {
9092
9271
  return mockResetPasswordHandler(method, path, options);
9093
9272
  }
9273
+ if (path.startsWith('auth/me')) {
9274
+ return {
9275
+ profile: { reference: 'Practitioner/123' },
9276
+ };
9277
+ }
9094
9278
  return null;
9095
9279
  }
9096
- function mockChangePasswordHandler(method, path, options) {
9280
+ function mockChangePasswordHandler(_method, _path, options) {
9097
9281
  const { body } = options;
9098
9282
  const { oldPassword } = JSON.parse(body);
9099
9283
  if (oldPassword === 'orange') {
@@ -9113,7 +9297,7 @@ function mockChangePasswordHandler(method, path, options) {
9113
9297
  };
9114
9298
  }
9115
9299
  }
9116
- function mockLoginHandler(method, path, options) {
9300
+ function mockLoginHandler(_method, _path, options) {
9117
9301
  const { body } = options;
9118
9302
  const { password } = JSON.parse(body);
9119
9303
  if (password === 'password') {
@@ -9135,7 +9319,7 @@ function mockLoginHandler(method, path, options) {
9135
9319
  };
9136
9320
  }
9137
9321
  }
9138
- function mockSetPasswordHandler(method, path, options) {
9322
+ function mockSetPasswordHandler(_method, _path, options) {
9139
9323
  const { body } = options;
9140
9324
  const { password } = JSON.parse(body);
9141
9325
  if (password === 'orange') {
@@ -9155,7 +9339,7 @@ function mockSetPasswordHandler(method, path, options) {
9155
9339
  };
9156
9340
  }
9157
9341
  }
9158
- function mockRegisterHandler(method, path, options) {
9342
+ function mockRegisterHandler(_method, _path, options) {
9159
9343
  const { body } = options;
9160
9344
  const { email, password } = JSON.parse(body);
9161
9345
  if (email === 'george@example.com' && password === 'password') {
@@ -9174,7 +9358,7 @@ function mockRegisterHandler(method, path, options) {
9174
9358
  };
9175
9359
  }
9176
9360
  }
9177
- function mockResetPasswordHandler(method, path, options) {
9361
+ function mockResetPasswordHandler(_method, _path, options) {
9178
9362
  const { body } = options;
9179
9363
  const { email } = JSON.parse(body);
9180
9364
  if (email === 'admin@example.com') {
@@ -9201,6 +9385,7 @@ mockRepo.createResource(ExampleAccessPolicy);
9201
9385
  mockRepo.createResource(ExampleStatusValueSet);
9202
9386
  mockRepo.createResource(ExampleUserConfiguration);
9203
9387
  mockRepo.createResource(ExampleBot);
9388
+ mockRepo.createResource(ExampleClient);
9204
9389
  mockRepo.createResource(HomerDiagnosticReport);
9205
9390
  mockRepo.createResource(HomerEncounter);
9206
9391
  mockRepo.createResource(HomerCommunication);
@@ -9234,7 +9419,7 @@ function mockFhirHandler(method, url, options) {
9234
9419
  return exampleValueSet;
9235
9420
  }
9236
9421
  else if (path === 'fhir/R4/%24graphql') {
9237
- return GraphQLSchemaResponse;
9422
+ return mockFhirGraphqlHandler(method, path, options);
9238
9423
  }
9239
9424
  else if (path === 'not-found' || id === 'not-found') {
9240
9425
  return notFound;
@@ -9264,8 +9449,36 @@ function mockFhirHandler(method, url, options) {
9264
9449
  else if (method === 'PUT') {
9265
9450
  return mockRepo.createResource(JSON.parse(options.body));
9266
9451
  }
9452
+ else if (method === 'DELETE') {
9453
+ if (resourceType && id) {
9454
+ return mockRepo.deleteResource(resourceType, id);
9455
+ }
9456
+ else {
9457
+ return notFound;
9458
+ }
9459
+ }
9460
+ }
9461
+ function mockFhirGraphqlHandler(_method, _path, options) {
9462
+ const { body } = options;
9463
+ if (body.includes('ResourceList: ServiceRequestList')) {
9464
+ return {
9465
+ data: {
9466
+ ResourceList: [
9467
+ Object.assign(Object.assign({}, HomerServiceRequest), { ObservationList: [
9468
+ HomerObservation1,
9469
+ HomerObservation2,
9470
+ HomerObservation3,
9471
+ HomerObservation4,
9472
+ HomerObservation5,
9473
+ HomerObservation6,
9474
+ ] }),
9475
+ ],
9476
+ },
9477
+ };
9478
+ }
9479
+ return GraphQLSchemaResponse;
9267
9480
  }
9268
- function mockFhirBatchHandler(method, path, options) {
9481
+ function mockFhirBatchHandler(_method, _path, options) {
9269
9482
  var _a;
9270
9483
  const { body } = options;
9271
9484
  const request = JSON.parse(body);
@@ -9290,5 +9503,5 @@ function mockFhirBatchHandler(method, path, options) {
9290
9503
  };
9291
9504
  }
9292
9505
 
9293
- export { BartSimpson, DifferentOrganization, DrAliceSmith, DrAliceSmithPreviousVersion, DrAliceSmithSchedule, DrAliceSmithSlots, ExampleAccessPolicy, ExampleAuditEvent, ExampleBot, ExampleQuestionnaire, ExampleQuestionnaireResponse, ExampleStatusValueSet, ExampleSubscription, ExampleUserConfiguration, GraphQLSchemaResponse, HomerCommunication, HomerDiagnosticReport, HomerEncounter, HomerMedia, HomerObservation1, HomerObservation2, HomerObservation3, HomerObservation4, HomerObservation5, HomerObservation6, HomerServiceRequest, HomerSimpson, HomerSimpsonPreviousVersion, HomerSimpsonSpecimen, MockClient, PatientSearchParameters, TestOrganization, exampleValueSet };
9506
+ export { BartSimpson, DifferentOrganization, DrAliceSmith, DrAliceSmithPreviousVersion, DrAliceSmithSchedule, DrAliceSmithSlots, ExampleAccessPolicy, ExampleAuditEvent, ExampleBot, ExampleClient, ExampleQuestionnaire, ExampleQuestionnaireResponse, ExampleStatusValueSet, ExampleSubscription, ExampleUserConfiguration, GraphQLSchemaResponse, HomerCommunication, HomerDiagnosticReport, HomerEncounter, HomerMedia, HomerObservation1, HomerObservation2, HomerObservation3, HomerObservation4, HomerObservation5, HomerObservation6, HomerServiceRequest, HomerSimpson, HomerSimpsonPreviousVersion, HomerSimpsonSpecimen, MockClient, PatientSearchParameters, TestOrganization, exampleValueSet };
9294
9507
  //# sourceMappingURL=index.js.map