fhirclient
Version:
JavaScript client for Fast Healthcare Interoperability Resources
291 lines (290 loc) • 12.7 kB
TypeScript
import { fhirclient } from "./types";
import FhirClient from "./FhirClient";
/**
* This is a FHIR client that is returned to you from the `ready()` call of the
* **SMART API**. You can also create it yourself if needed:
*
* ```js
* // BROWSER
* const client = FHIR.client("https://r4.smarthealthit.org");
*
* // SERVER
* const client = smart(req, res).client("https://r4.smarthealthit.org");
* ```
*/
export default class Client extends FhirClient {
/**
* The state of the client instance is an object with various properties.
* It contains some details about how the client has been authorized and
* determines the behavior of the client instance. This state is persisted
* in `SessionStorage` in browsers or in request session on the servers.
*/
readonly state: fhirclient.ClientState;
/**
* The adapter to use to connect to the current environment. Currently we have:
* - BrowserAdapter - for browsers
* - NodeAdapter - for Express or vanilla NodeJS servers
* - HapiAdapter - for HAPI NodeJS servers
*/
readonly environment: fhirclient.Adapter;
/**
* A SMART app is typically associated with a patient. This is a namespace
* for the patient-related functionality of the client.
*/
readonly patient: {
/**
* The ID of the current patient or `null` if there is no current patient
*/
id: string | null;
/**
* A method to fetch the current patient resource from the FHIR server.
* If there is no patient context, it will reject with an error.
* @param {fhirclient.FetchOptions} [requestOptions] Any options to pass to the `fetch` call.
* @category Request
*/
read: fhirclient.RequestFunction<fhirclient.FHIR.Patient>;
/**
* This is similar to [[request]] but it makes requests in the
* context of the current patient. For example, instead of doing
* ```js
* client.request("Observation?patient=" + client.patient.id)
* ```
* you can do
* ```js
* client.patient.request("Observation")
* ```
* The return type depends on the arguments. Typically it will be the
* response payload JSON object. Can also be a string or the `Response`
* object itself if we have received a non-json result, which allows us
* to handle even binary responses. Can also be a [[CombinedFetchResult]]
* object if the `requestOptions.includeResponse`s has been set to true.
* @category Request
*/
request: <R = fhirclient.FetchResult>(requestOptions: string | URL | fhirclient.RequestOptions, fhirOptions?: fhirclient.FhirOptions) => Promise<R>;
/**
* This is the FhirJS Patient API. It will ONLY exist if the `Client`
* instance is "connected" to FhirJS.
*/
api?: Record<string, any>;
};
/**
* The client may be associated with a specific encounter, if the scopes
* permit that and if the back-end server supports that. This is a namespace
* for encounter-related functionality.
*/
readonly encounter: {
/**
* The ID of the current encounter or `null` if there is no current
* encounter
*/
id: string | null;
/**
* A method to fetch the current encounter resource from the FHIR server.
* If there is no encounter context, it will reject with an error.
* @param [requestOptions] Any options to pass to the `fetch` call.
* @category Request
*/
read: fhirclient.RequestFunction<fhirclient.FHIR.Encounter>;
};
/**
* The client may be associated with a specific user, if the scopes
* permit that. This is a namespace for user-related functionality.
*/
readonly user: {
/**
* The ID of the current user or `null` if there is no current user
*/
id: string | null;
/**
* A method to fetch the current user resource from the FHIR server.
* If there is no user context, it will reject with an error.
* @param [requestOptions] Any options to pass to the `fetch` call.
* @category Request
*/
read: fhirclient.RequestFunction<fhirclient.FHIR.Patient | fhirclient.FHIR.Practitioner | fhirclient.FHIR.RelatedPerson>;
/**
* Returns the profile of the logged_in user (if any), or null if the
* user is not available. This is a string having the shape
* `{user type}/{user id}`. For example `Practitioner/abc` or
* `Patient/xyz`.
* @alias client.getFhirUser()
*/
fhirUser: string | null;
/**
* Returns the type of the logged-in user or null. The result can be
* `Practitioner`, `Patient` or `RelatedPerson`.
* @alias client.getUserType()
*/
resourceType: string | null;
};
/**
* The [FhirJS](https://github.com/FHIR/fhir.js/blob/master/README.md) API.
* **NOTE:** This will only be available if `fhir.js` is used. Otherwise it
* will be `undefined`.
*/
api: Record<string, any> | undefined;
/**
* Refers to the refresh task while it is being performed.
* @see [[refresh]]
*/
private _refreshTask;
/**
* Validates the parameters, creates an instance and tries to connect it to
* FhirJS, if one is available globally.
*/
constructor(environment: fhirclient.Adapter, state: fhirclient.ClientState | string);
/**
* This method is used to make the "link" between the `fhirclient` and the
* `fhir.js`, if one is available.
* **Note:** This is called by the constructor. If fhir.js is available in
* the global scope as `fhir`, it will automatically be linked to any [[Client]]
* instance. You should only use this method to connect to `fhir.js` which
* is not global.
*/
connect(fhirJs?: (options: Record<string, any>) => Record<string, any>): Client;
/**
* Returns the ID of the selected patient or null. You should have requested
* "launch/patient" scope. Otherwise this will return null.
*/
getPatientId(): string | null;
/**
* Returns the ID of the selected encounter or null. You should have
* requested "launch/encounter" scope. Otherwise this will return null.
* Note that not all servers support the "launch/encounter" scope so this
* will be null if they don't.
*/
getEncounterId(): string | null;
/**
* Returns the (decoded) id_token if any. You need to request "openid" and
* "profile" scopes if you need to receive an id_token (if you need to know
* who the logged-in user is).
*/
getIdToken(): fhirclient.IDToken | null;
/**
* Returns the profile of the logged_in user (if any). This is a string
* having the following shape `"{user type}/{user id}"`. For example:
* `"Practitioner/abc"` or `"Patient/xyz"`.
*/
getFhirUser(): string | null;
/**
* Returns the user ID or null.
*/
getUserId(): string | null;
/**
* Returns the type of the logged-in user or null. The result can be
* "Practitioner", "Patient" or "RelatedPerson".
*/
getUserType(): string | null;
/**
* Builds and returns the value of the `Authorization` header that can be
* sent to the FHIR server
*/
getAuthorizationHeader(): string | null;
/**
* Used internally to clear the state of the instance and the state in the
* associated storage.
*/
private _clearState;
/**
* @param requestOptions Can be a string URL (relative to the serviceUrl),
* or an object which will be passed to fetch()
* @param fhirOptions Additional options to control the behavior
* @param _resolvedRefs DO NOT USE! Used internally.
* @category Request
*/
request<T = any>(requestOptions: string | URL | fhirclient.RequestOptions, fhirOptions?: fhirclient.FhirOptions, _resolvedRefs?: fhirclient.JsonObject): Promise<T>;
/**
* Checks if access token and refresh token are present. If they are, and if
* the access token is expired or is about to expire in the next 10 seconds,
* calls `this.refresh()` to obtain new access token.
* @param requestOptions Any options to pass to the fetch call. Most of them
* will be overridden, bit it might still be useful for passing additional
* request options or an abort signal.
* @category Request
*/
refreshIfNeeded(requestOptions?: RequestInit): Promise<fhirclient.ClientState>;
/**
* Use the refresh token to obtain new access token. If the refresh token is
* expired (or this fails for any other reason) it will be deleted from the
* state, so that we don't enter into loops trying to re-authorize.
*
* This method is typically called internally from [[request]] if
* certain request fails with 401.
*
* @param requestOptions Any options to pass to the fetch call. Most of them
* will be overridden, bit it might still be useful for passing additional
* request options or an abort signal.
* @category Request
*/
refresh(requestOptions?: RequestInit): Promise<fhirclient.ClientState>;
/**
* Groups the observations by code. Returns a map that will look like:
* ```js
* const map = client.byCodes(observations, "code");
* // map = {
* // "55284-4": [ observation1, observation2 ],
* // "6082-2": [ observation3 ]
* // }
* ```
* @param observations Array of observations
* @param property The name of a CodeableConcept property to group by
* @todo This should be deprecated and moved elsewhere. One should not have
* to obtain an instance of [[Client]] just to use utility functions like this.
* @deprecated
* @category Utility
*/
byCode(observations: fhirclient.FHIR.Observation | fhirclient.FHIR.Observation[], property: string): fhirclient.ObservationMap;
/**
* First groups the observations by code using `byCode`. Then returns a function
* that accepts codes as arguments and will return a flat array of observations
* having that codes. Example:
* ```js
* const filter = client.byCodes(observations, "category");
* filter("laboratory") // => [ observation1, observation2 ]
* filter("vital-signs") // => [ observation3 ]
* filter("laboratory", "vital-signs") // => [ observation1, observation2, observation3 ]
* ```
* @param observations Array of observations
* @param property The name of a CodeableConcept property to group by
* @todo This should be deprecated and moved elsewhere. One should not have
* to obtain an instance of [[Client]] just to use utility functions like this.
* @deprecated
* @category Utility
*/
byCodes(observations: fhirclient.FHIR.Observation | fhirclient.FHIR.Observation[], property: string): (...codes: string[]) => any[];
/**
* @category Utility
*/
units: {
cm({ code, value }: fhirclient.CodeValue): number;
kg({ code, value }: fhirclient.CodeValue): number;
any(pq: fhirclient.CodeValue): number;
};
/**
* Walks through an object (or array) and returns the value found at the
* provided path. This function is very simple so it intentionally does not
* support any argument polymorphism, meaning that the path can only be a
* dot-separated string. If the path is invalid returns undefined.
* @param obj The object (or Array) to walk through
* @param path The path (eg. "a.b.4.c")
* @returns {*} Whatever is found in the path or undefined
* @todo This should be deprecated and moved elsewhere. One should not have
* to obtain an instance of [[Client]] just to use utility functions like this.
* @deprecated
* @category Utility
*/
getPath(obj: Record<string, any>, path?: string): any;
/**
* Returns a copy of the client state. Accepts a dot-separated path argument
* (same as for `getPath`) to allow for selecting specific properties.
* Examples:
* ```js
* client.getState(); // -> the entire state object
* client.getState("serverUrl"); // -> the URL we are connected to
* client.getState("tokenResponse.patient"); // -> The selected patient ID (if any)
* ```
* @param path The path (eg. "a.b.4.c")
* @returns {*} Whatever is found in the path or undefined
*/
getState(path?: string): any;
}