@medplum/core 0.9.8 → 0.9.11
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/cody-pdf-test.js +1 -1
- package/dist/cjs/index.js +226 -307
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.min.js +1 -1
- package/dist/cjs/index.min.js.map +1 -1
- package/dist/esm/index.js +226 -307
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +1 -1
- package/dist/esm/index.min.js.map +1 -1
- package/dist/types/client.d.ts +59 -15
- package/package.json +2 -2
- package/test9-2.pdf +0 -0
- package/test9-3.pdf +0 -0
- package/test9-4.pdf +0 -0
- package/test9.pdf +0 -0
- package/dist/types/pdf.d.ts +0 -5
package/cody-pdf-test.js
CHANGED
|
@@ -10,7 +10,7 @@ async function main() {
|
|
|
10
10
|
|
|
11
11
|
console.log('set access token...');
|
|
12
12
|
medplum.setAccessToken(
|
|
13
|
-
'eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk5MjI2MjNmLTVmMjctNDFiYi04NTQ1LTZkY2IwZmVkODk4MSIsInR5cCI6IkpXVCJ9.
|
|
13
|
+
'eyJhbGciOiJSUzI1NiIsImtpZCI6Ijk5MjI2MjNmLTVmMjctNDFiYi04NTQ1LTZkY2IwZmVkODk4MSIsInR5cCI6IkpXVCJ9.eyJsb2dpbl9pZCI6ImVkNmNiY2Q2LTVjZjQtNDljMS05ODQzLWU1OWIyZmRlN2Q5NCIsInN1YiI6ImJiNjJmNmQzLTNiYjAtNDRjYS1iN2UzLTBmZDAwYmRmYTYyNCIsInVzZXJuYW1lIjoiYmI2MmY2ZDMtM2JiMC00NGNhLWI3ZTMtMGZkMDBiZGZhNjI0Iiwic2NvcGUiOiJvcGVuaWQiLCJwcm9maWxlIjoiUHJhY3RpdGlvbmVyL2ZkNWFiZjYyLWE5NmEtNDdkYi04MDczLTQ4ZDgxOWI0NWU4NCIsImlhdCI6MTY1NDgwOTgzOSwiaXNzIjoiaHR0cHM6Ly9hcGkubWVkcGx1bS5jb20vIiwiZXhwIjoxNjU0ODEzNDM5fQ.acK1yXI8v4_a2UWikBwOaa6JItXhh4fma92pQeIuRTsfvnduWC8eOCGOOemxwpCvtrnECCilG1FNVDHTtGKFSVzStAi9TAnO-pHf69OVRJVH1xMqJvlEi-LRiu3uCflOhiqKcnGRDfpecZ0sTcLhIpSg-Kn2-nj8pGz_DG27JfjKpPIqU2X53S3SumZU-2bRPxoSu7lPXINn_1qMTxUOpV1qY54gqX4GVhim2OTdbARx-QtO9Q7A3JR64CvS9_WLbBzsDUqfKfJJ-X6KOHnM8Dz-dieV5rjQ54Sv3yvl-B5gozMvO2ZYm4P3fQ_IBEosim8CHQEa_23UTFGEo36Axg'
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
console.log('createpdf...');
|
package/dist/cjs/index.js
CHANGED
|
@@ -810,91 +810,6 @@
|
|
|
810
810
|
}
|
|
811
811
|
}
|
|
812
812
|
|
|
813
|
-
/*
|
|
814
|
-
* This file attempts a unified "generatePdf" function that works both client-side and server-side.
|
|
815
|
-
* On client-side, it checks for a global "pdfMake" variable.
|
|
816
|
-
* On server-side, it dynamically loads "pdfmake" from the node_modules.
|
|
817
|
-
*/
|
|
818
|
-
function generatePdf(docDefinition, tableLayouts, fonts) {
|
|
819
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
820
|
-
// Setup sane defaults
|
|
821
|
-
// See: https://pdfmake.github.io/docs/0.1/document-definition-object/styling/
|
|
822
|
-
docDefinition.pageSize = docDefinition.pageSize || 'LETTER';
|
|
823
|
-
docDefinition.pageMargins = docDefinition.pageMargins || [60, 60, 60, 60];
|
|
824
|
-
docDefinition.pageOrientation = docDefinition.pageOrientation || 'portrait';
|
|
825
|
-
docDefinition.defaultStyle = docDefinition.defaultStyle || {};
|
|
826
|
-
docDefinition.defaultStyle.font = docDefinition.defaultStyle.font || 'Helvetica';
|
|
827
|
-
docDefinition.defaultStyle.fontSize = docDefinition.defaultStyle.fontSize || 11;
|
|
828
|
-
docDefinition.defaultStyle.lineHeight = docDefinition.defaultStyle.lineHeight || 2.0;
|
|
829
|
-
if (typeof pdfMake === 'undefined') {
|
|
830
|
-
return generatePdfServerSide(docDefinition, tableLayouts, fonts);
|
|
831
|
-
}
|
|
832
|
-
else {
|
|
833
|
-
return generatePdfClientSide(docDefinition, tableLayouts, fonts);
|
|
834
|
-
}
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
function generatePdfServerSide(docDefinition, tableLayouts, fonts) {
|
|
838
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
839
|
-
if (!fonts) {
|
|
840
|
-
fonts = {
|
|
841
|
-
Helvetica: {
|
|
842
|
-
normal: 'Helvetica',
|
|
843
|
-
bold: 'Helvetica-Bold',
|
|
844
|
-
italics: 'Helvetica-Oblique',
|
|
845
|
-
bolditalics: 'Helvetica-BoldOblique',
|
|
846
|
-
},
|
|
847
|
-
Roboto: {
|
|
848
|
-
normal: 'https://static.medplum.com/fonts/Roboto-Regular.ttf',
|
|
849
|
-
bold: 'https://static.medplum.com/fonts/Roboto-Medium.ttf',
|
|
850
|
-
italics: 'https://static.medplum.com/fonts/Roboto-Italic.ttf',
|
|
851
|
-
bolditalics: 'https://static.medplum.com/fonts/Roboto-MediumItalic.ttf',
|
|
852
|
-
},
|
|
853
|
-
Avenir: {
|
|
854
|
-
normal: 'https://static.medplum.com/fonts/avenir.ttf',
|
|
855
|
-
},
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
return new Promise((resolve, reject) => {
|
|
859
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
860
|
-
const PdfPrinter = require('pdfmake');
|
|
861
|
-
const printer = new PdfPrinter(fonts);
|
|
862
|
-
const pdfDoc = printer.createPdfKitDocument(docDefinition, { tableLayouts });
|
|
863
|
-
const chunks = [];
|
|
864
|
-
pdfDoc.on('data', (chunk) => chunks.push(chunk));
|
|
865
|
-
pdfDoc.on('end', () => resolve(Buffer.concat(chunks)));
|
|
866
|
-
pdfDoc.on('error', reject);
|
|
867
|
-
pdfDoc.end();
|
|
868
|
-
});
|
|
869
|
-
});
|
|
870
|
-
}
|
|
871
|
-
function generatePdfClientSide(docDefinition, tableLayouts, fonts) {
|
|
872
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
873
|
-
if (!fonts) {
|
|
874
|
-
fonts = {
|
|
875
|
-
Helvetica: {
|
|
876
|
-
normal: 'https://static.medplum.com/fonts/Helvetica.ttf',
|
|
877
|
-
bold: 'https://static.medplum.com/fonts/Helvetica-bold.ttf',
|
|
878
|
-
italics: 'https://static.medplum.com/fonts/Helvetica-italic.ttf',
|
|
879
|
-
bolditalics: 'https://static.medplum.com/fonts/Helvetica-bold-italic.ttf',
|
|
880
|
-
},
|
|
881
|
-
Roboto: {
|
|
882
|
-
normal: 'https://static.medplum.com/fonts/Roboto-Regular.ttf',
|
|
883
|
-
bold: 'https://static.medplum.com/fonts/Roboto-Medium.ttf',
|
|
884
|
-
italics: 'https://static.medplum.com/fonts/Roboto-Italic.ttf',
|
|
885
|
-
bolditalics: 'https://static.medplum.com/fonts/Roboto-MediumItalic.ttf',
|
|
886
|
-
},
|
|
887
|
-
Avenir: {
|
|
888
|
-
normal: 'https://static.medplum.com/fonts/avenir.ttf',
|
|
889
|
-
},
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
return new Promise((resolve) => {
|
|
893
|
-
pdfMake.createPdf(docDefinition, tableLayouts, fonts).getBlob(resolve);
|
|
894
|
-
});
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
|
|
898
813
|
var _ReadablePromise_suspender, _ReadablePromise_status, _ReadablePromise_response, _ReadablePromise_error, _a;
|
|
899
814
|
/**
|
|
900
815
|
* The ReadablePromise class wraps a request promise suitable for React Suspense.
|
|
@@ -971,206 +886,6 @@
|
|
|
971
886
|
}
|
|
972
887
|
_ReadablePromise_suspender = new WeakMap(), _ReadablePromise_status = new WeakMap(), _ReadablePromise_response = new WeakMap(), _ReadablePromise_error = new WeakMap(), _a = Symbol.toStringTag;
|
|
973
888
|
|
|
974
|
-
const DEFAULT_SEARCH_COUNT = 20;
|
|
975
|
-
/**
|
|
976
|
-
* Search operators.
|
|
977
|
-
* These operators represent "modifiers" and "prefixes" in FHIR search.
|
|
978
|
-
* See: https://www.hl7.org/fhir/search.html
|
|
979
|
-
*/
|
|
980
|
-
exports.Operator = void 0;
|
|
981
|
-
(function (Operator) {
|
|
982
|
-
Operator["EQUALS"] = "eq";
|
|
983
|
-
Operator["NOT_EQUALS"] = "ne";
|
|
984
|
-
// Numbers
|
|
985
|
-
Operator["GREATER_THAN"] = "gt";
|
|
986
|
-
Operator["LESS_THAN"] = "lt";
|
|
987
|
-
Operator["GREATER_THAN_OR_EQUALS"] = "ge";
|
|
988
|
-
Operator["LESS_THAN_OR_EQUALS"] = "le";
|
|
989
|
-
// Dates
|
|
990
|
-
Operator["STARTS_AFTER"] = "sa";
|
|
991
|
-
Operator["ENDS_BEFORE"] = "eb";
|
|
992
|
-
Operator["APPROXIMATELY"] = "ap";
|
|
993
|
-
// String
|
|
994
|
-
Operator["CONTAINS"] = "contains";
|
|
995
|
-
Operator["EXACT"] = "exact";
|
|
996
|
-
// Token
|
|
997
|
-
Operator["TEXT"] = "text";
|
|
998
|
-
Operator["ABOVE"] = "above";
|
|
999
|
-
Operator["BELOW"] = "below";
|
|
1000
|
-
Operator["IN"] = "in";
|
|
1001
|
-
Operator["NOT_IN"] = "not-in";
|
|
1002
|
-
Operator["OF_TYPE"] = "of-type";
|
|
1003
|
-
})(exports.Operator || (exports.Operator = {}));
|
|
1004
|
-
const MODIFIER_OPERATORS = [
|
|
1005
|
-
exports.Operator.CONTAINS,
|
|
1006
|
-
exports.Operator.EXACT,
|
|
1007
|
-
exports.Operator.TEXT,
|
|
1008
|
-
exports.Operator.ABOVE,
|
|
1009
|
-
exports.Operator.BELOW,
|
|
1010
|
-
exports.Operator.IN,
|
|
1011
|
-
exports.Operator.NOT_IN,
|
|
1012
|
-
exports.Operator.OF_TYPE,
|
|
1013
|
-
];
|
|
1014
|
-
const PREFIX_OPERATORS = [
|
|
1015
|
-
exports.Operator.NOT_EQUALS,
|
|
1016
|
-
exports.Operator.GREATER_THAN,
|
|
1017
|
-
exports.Operator.LESS_THAN,
|
|
1018
|
-
exports.Operator.GREATER_THAN_OR_EQUALS,
|
|
1019
|
-
exports.Operator.LESS_THAN_OR_EQUALS,
|
|
1020
|
-
exports.Operator.STARTS_AFTER,
|
|
1021
|
-
exports.Operator.ENDS_BEFORE,
|
|
1022
|
-
exports.Operator.APPROXIMATELY,
|
|
1023
|
-
];
|
|
1024
|
-
/**
|
|
1025
|
-
* Parses a URL into a SearchRequest.
|
|
1026
|
-
*
|
|
1027
|
-
* See the FHIR search spec: http://hl7.org/fhir/r4/search.html
|
|
1028
|
-
*
|
|
1029
|
-
* @param url The URL to parse.
|
|
1030
|
-
* @returns Parsed search definition.
|
|
1031
|
-
*/
|
|
1032
|
-
function parseSearchDefinition(url) {
|
|
1033
|
-
const location = new URL(url, 'https://example.com/');
|
|
1034
|
-
const resourceType = location.pathname
|
|
1035
|
-
.replace(/(^\/)|(\/$)/g, '') // Remove leading and trailing slashes
|
|
1036
|
-
.split('/')
|
|
1037
|
-
.pop();
|
|
1038
|
-
const params = new URLSearchParams(location.search);
|
|
1039
|
-
let filters = undefined;
|
|
1040
|
-
let sortRules = undefined;
|
|
1041
|
-
let fields = undefined;
|
|
1042
|
-
let offset = undefined;
|
|
1043
|
-
let count = undefined;
|
|
1044
|
-
let total = undefined;
|
|
1045
|
-
params.forEach((value, key) => {
|
|
1046
|
-
if (key === '_fields') {
|
|
1047
|
-
fields = value.split(',');
|
|
1048
|
-
}
|
|
1049
|
-
else if (key === '_offset') {
|
|
1050
|
-
offset = parseInt(value);
|
|
1051
|
-
}
|
|
1052
|
-
else if (key === '_count') {
|
|
1053
|
-
count = parseInt(value);
|
|
1054
|
-
}
|
|
1055
|
-
else if (key === '_total') {
|
|
1056
|
-
total = value;
|
|
1057
|
-
}
|
|
1058
|
-
else if (key === '_sort') {
|
|
1059
|
-
sortRules = sortRules || [];
|
|
1060
|
-
sortRules.push(parseSortRule(value));
|
|
1061
|
-
}
|
|
1062
|
-
else {
|
|
1063
|
-
filters = filters || [];
|
|
1064
|
-
filters.push(parseSearchFilter(key, value));
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
return {
|
|
1068
|
-
resourceType,
|
|
1069
|
-
filters,
|
|
1070
|
-
fields,
|
|
1071
|
-
offset,
|
|
1072
|
-
count,
|
|
1073
|
-
total,
|
|
1074
|
-
sortRules,
|
|
1075
|
-
};
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Parses a URL query parameter into a sort rule.
|
|
1079
|
-
*
|
|
1080
|
-
* By default, the sort rule is the field name.
|
|
1081
|
-
*
|
|
1082
|
-
* Sort rules can be reversed into descending order by prefixing the field name with a minus sign.
|
|
1083
|
-
*
|
|
1084
|
-
* See sorting: http://hl7.org/fhir/r4/search.html#_sort
|
|
1085
|
-
*
|
|
1086
|
-
* @param value The URL parameter value.
|
|
1087
|
-
* @returns The parsed sort rule.
|
|
1088
|
-
*/
|
|
1089
|
-
function parseSortRule(value) {
|
|
1090
|
-
if (value.startsWith('-')) {
|
|
1091
|
-
return { code: value.substring(1), descending: true };
|
|
1092
|
-
}
|
|
1093
|
-
else {
|
|
1094
|
-
return { code: value };
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Parses a URL query parameter into a search filter.
|
|
1099
|
-
*
|
|
1100
|
-
* FHIR search filters can be specified as modifiers or prefixes.
|
|
1101
|
-
*
|
|
1102
|
-
* For string properties, modifiers are appended to the key, e.g. "name:contains=eve".
|
|
1103
|
-
*
|
|
1104
|
-
* For date and numeric properties, prefixes are prepended to the value, e.g. "birthdate=gt2000".
|
|
1105
|
-
*
|
|
1106
|
-
* See the FHIR search spec: http://hl7.org/fhir/r4/search.html
|
|
1107
|
-
*
|
|
1108
|
-
* @param key The URL parameter key.
|
|
1109
|
-
* @param value The URL parameter value.
|
|
1110
|
-
* @returns The parsed search filter.
|
|
1111
|
-
*/
|
|
1112
|
-
function parseSearchFilter(key, value) {
|
|
1113
|
-
let code = key;
|
|
1114
|
-
let operator = exports.Operator.EQUALS;
|
|
1115
|
-
for (const modifier of MODIFIER_OPERATORS) {
|
|
1116
|
-
const modifierIndex = code.indexOf(':' + modifier);
|
|
1117
|
-
if (modifierIndex !== -1) {
|
|
1118
|
-
operator = modifier;
|
|
1119
|
-
code = code.substring(0, modifierIndex);
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
for (const prefix of PREFIX_OPERATORS) {
|
|
1123
|
-
if (value.match(new RegExp('^' + prefix + '\\d'))) {
|
|
1124
|
-
operator = prefix;
|
|
1125
|
-
value = value.substring(prefix.length);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
return { code, operator, value };
|
|
1129
|
-
}
|
|
1130
|
-
/**
|
|
1131
|
-
* Formats a search definition object into a query string.
|
|
1132
|
-
* Note: The return value does not include the resource type.
|
|
1133
|
-
* @param {!SearchRequest} definition The search definition.
|
|
1134
|
-
* @returns Formatted URL.
|
|
1135
|
-
*/
|
|
1136
|
-
function formatSearchQuery(definition) {
|
|
1137
|
-
const params = [];
|
|
1138
|
-
if (definition.fields) {
|
|
1139
|
-
params.push('_fields=' + definition.fields.join(','));
|
|
1140
|
-
}
|
|
1141
|
-
if (definition.filters) {
|
|
1142
|
-
definition.filters.forEach((filter) => params.push(formatFilter(filter)));
|
|
1143
|
-
}
|
|
1144
|
-
if (definition.sortRules && definition.sortRules.length > 0) {
|
|
1145
|
-
params.push(formatSortRules(definition.sortRules));
|
|
1146
|
-
}
|
|
1147
|
-
if (definition.offset !== undefined) {
|
|
1148
|
-
params.push('_offset=' + definition.offset);
|
|
1149
|
-
}
|
|
1150
|
-
if (definition.count !== undefined) {
|
|
1151
|
-
params.push('_count=' + definition.count);
|
|
1152
|
-
}
|
|
1153
|
-
if (definition.total !== undefined) {
|
|
1154
|
-
params.push('_total=' + definition.total);
|
|
1155
|
-
}
|
|
1156
|
-
if (params.length === 0) {
|
|
1157
|
-
return '';
|
|
1158
|
-
}
|
|
1159
|
-
params.sort();
|
|
1160
|
-
return '?' + params.join('&');
|
|
1161
|
-
}
|
|
1162
|
-
function formatFilter(filter) {
|
|
1163
|
-
const modifier = MODIFIER_OPERATORS.includes(filter.operator) ? ':' + filter.operator : '';
|
|
1164
|
-
const prefix = PREFIX_OPERATORS.includes(filter.operator) ? filter.operator : '';
|
|
1165
|
-
return `${filter.code}${modifier}=${prefix}${encodeURIComponent(filter.value)}`;
|
|
1166
|
-
}
|
|
1167
|
-
function formatSortRules(sortRules) {
|
|
1168
|
-
if (!sortRules || sortRules.length === 0) {
|
|
1169
|
-
return '';
|
|
1170
|
-
}
|
|
1171
|
-
return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
889
|
var _ClientStorage_storage, _MemoryStorage_data;
|
|
1175
890
|
/**
|
|
1176
891
|
* The ClientStorage class is a utility class for storing strings and objects.
|
|
@@ -1459,7 +1174,7 @@
|
|
|
1459
1174
|
|
|
1460
1175
|
// PKCE auth ased on:
|
|
1461
1176
|
// https://aws.amazon.com/blogs/security/how-to-add-authentication-single-page-web-application-with-amazon-cognito-oauth2-implementation/
|
|
1462
|
-
var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_storage, _MedplumClient_schema, _MedplumClient_requestCache, _MedplumClient_baseUrl, _MedplumClient_clientId, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_onUnauthenticated, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_request, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_startPkce, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
|
|
1177
|
+
var _MedplumClient_instances, _MedplumClient_fetch, _MedplumClient_createPdf, _MedplumClient_storage, _MedplumClient_schema, _MedplumClient_requestCache, _MedplumClient_baseUrl, _MedplumClient_clientId, _MedplumClient_authorizeUrl, _MedplumClient_tokenUrl, _MedplumClient_logoutUrl, _MedplumClient_onUnauthenticated, _MedplumClient_accessToken, _MedplumClient_refreshToken, _MedplumClient_refreshPromise, _MedplumClient_profilePromise, _MedplumClient_profile, _MedplumClient_config, _MedplumClient_addLogin, _MedplumClient_refreshProfile, _MedplumClient_request, _MedplumClient_addFetchOptionsDefaults, _MedplumClient_setRequestContentType, _MedplumClient_setRequestBody, _MedplumClient_handleUnauthenticated, _MedplumClient_startPkce, _MedplumClient_requestAuthorization, _MedplumClient_refresh, _MedplumClient_fetchTokens, _MedplumClient_verifyTokens, _MedplumClient_setupStorageListener;
|
|
1463
1178
|
const DEFAULT_BASE_URL = 'https://api.medplum.com/';
|
|
1464
1179
|
const DEFAULT_SCOPE = 'launch/patient openid fhirUser offline_access user/*.*';
|
|
1465
1180
|
const DEFAULT_RESOURCE_CACHE_SIZE = 1000;
|
|
@@ -1519,6 +1234,7 @@
|
|
|
1519
1234
|
super();
|
|
1520
1235
|
_MedplumClient_instances.add(this);
|
|
1521
1236
|
_MedplumClient_fetch.set(this, void 0);
|
|
1237
|
+
_MedplumClient_createPdf.set(this, void 0);
|
|
1522
1238
|
_MedplumClient_storage.set(this, void 0);
|
|
1523
1239
|
_MedplumClient_schema.set(this, void 0);
|
|
1524
1240
|
_MedplumClient_requestCache.set(this, void 0);
|
|
@@ -1543,6 +1259,7 @@
|
|
|
1543
1259
|
}
|
|
1544
1260
|
}
|
|
1545
1261
|
__classPrivateFieldSet(this, _MedplumClient_fetch, (options === null || options === void 0 ? void 0 : options.fetch) || window.fetch.bind(window), "f");
|
|
1262
|
+
__classPrivateFieldSet(this, _MedplumClient_createPdf, options === null || options === void 0 ? void 0 : options.createPdf, "f");
|
|
1546
1263
|
__classPrivateFieldSet(this, _MedplumClient_storage, new ClientStorage(), "f");
|
|
1547
1264
|
__classPrivateFieldSet(this, _MedplumClient_schema, createSchema(), "f");
|
|
1548
1265
|
__classPrivateFieldSet(this, _MedplumClient_requestCache, new LRUCache((_a = options === null || options === void 0 ? void 0 : options.resourceCacheSize) !== null && _a !== void 0 ? _a : DEFAULT_RESOURCE_CACHE_SIZE), "f");
|
|
@@ -1787,12 +1504,9 @@
|
|
|
1787
1504
|
* @param query The FHIR search query or structured query object.
|
|
1788
1505
|
* @returns The well-formed FHIR URL.
|
|
1789
1506
|
*/
|
|
1790
|
-
fhirSearchUrl(query) {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
}
|
|
1794
|
-
const url = this.fhirUrl(query.resourceType);
|
|
1795
|
-
url.search = formatSearchQuery(query);
|
|
1507
|
+
fhirSearchUrl(resourceType, query) {
|
|
1508
|
+
const url = this.fhirUrl(resourceType);
|
|
1509
|
+
url.search = query.toString();
|
|
1796
1510
|
return url;
|
|
1797
1511
|
}
|
|
1798
1512
|
/**
|
|
@@ -1849,8 +1563,8 @@
|
|
|
1849
1563
|
* @param query The search query as either a string or a structured search object.
|
|
1850
1564
|
* @returns Promise to the search result bundle.
|
|
1851
1565
|
*/
|
|
1852
|
-
search(query, options = {}) {
|
|
1853
|
-
return this.get(this.fhirSearchUrl(query), options);
|
|
1566
|
+
search(resourceType, query, options = {}) {
|
|
1567
|
+
return this.get(this.fhirSearchUrl(resourceType, query), options);
|
|
1854
1568
|
}
|
|
1855
1569
|
/**
|
|
1856
1570
|
* Sends a FHIR search request for a single resource.
|
|
@@ -1871,17 +1585,18 @@
|
|
|
1871
1585
|
* @param query The search query as either a string or a structured search object.
|
|
1872
1586
|
* @returns Promise to the search result bundle.
|
|
1873
1587
|
*/
|
|
1874
|
-
searchOne(query, options = {}) {
|
|
1875
|
-
const
|
|
1876
|
-
|
|
1877
|
-
|
|
1588
|
+
searchOne(resourceType, query, options = {}) {
|
|
1589
|
+
const url = this.fhirSearchUrl(resourceType, query);
|
|
1590
|
+
url.searchParams.set('_count', '1');
|
|
1591
|
+
url.searchParams.sort();
|
|
1592
|
+
const cacheKey = url.toString() + '-searchOne';
|
|
1878
1593
|
if (!(options === null || options === void 0 ? void 0 : options.cache)) {
|
|
1879
1594
|
const cached = __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").get(cacheKey);
|
|
1880
1595
|
if (cached) {
|
|
1881
1596
|
return cached;
|
|
1882
1597
|
}
|
|
1883
1598
|
}
|
|
1884
|
-
const promise = new ReadablePromise(this.search(
|
|
1599
|
+
const promise = new ReadablePromise(this.search(resourceType, url.searchParams, options).then((b) => { var _a, _b; return (_b = (_a = b.entry) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.resource; }));
|
|
1885
1600
|
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(cacheKey, promise);
|
|
1886
1601
|
return promise;
|
|
1887
1602
|
}
|
|
@@ -1904,15 +1619,16 @@
|
|
|
1904
1619
|
* @param query The search query as either a string or a structured search object.
|
|
1905
1620
|
* @returns Promise to the search result bundle.
|
|
1906
1621
|
*/
|
|
1907
|
-
searchResources(query, options = {}) {
|
|
1908
|
-
const
|
|
1622
|
+
searchResources(resourceType, query, options = {}) {
|
|
1623
|
+
const url = this.fhirSearchUrl(resourceType, query);
|
|
1624
|
+
const cacheKey = url.toString() + '-searchResources';
|
|
1909
1625
|
if (!(options === null || options === void 0 ? void 0 : options.cache)) {
|
|
1910
1626
|
const cached = __classPrivateFieldGet(this, _MedplumClient_requestCache, "f").get(cacheKey);
|
|
1911
1627
|
if (cached) {
|
|
1912
1628
|
return cached;
|
|
1913
1629
|
}
|
|
1914
1630
|
}
|
|
1915
|
-
const promise = new ReadablePromise(this.search(query, options).then((b) => { var _a, _b; return (_b = (_a = b.entry) === null || _a === void 0 ? void 0 : _a.map((e) => e.resource)) !== null && _b !== void 0 ? _b : []; }));
|
|
1631
|
+
const promise = new ReadablePromise(this.search(resourceType, query, options).then((b) => { var _a, _b; return (_b = (_a = b.entry) === null || _a === void 0 ? void 0 : _a.map((e) => e.resource)) !== null && _b !== void 0 ? _b : []; }));
|
|
1916
1632
|
__classPrivateFieldGet(this, _MedplumClient_requestCache, "f").set(cacheKey, promise);
|
|
1917
1633
|
return promise;
|
|
1918
1634
|
}
|
|
@@ -2169,7 +1885,7 @@
|
|
|
2169
1885
|
createResourceIfNoneExist(resource, query) {
|
|
2170
1886
|
var _a;
|
|
2171
1887
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2172
|
-
return (_a = (yield this.searchOne(
|
|
1888
|
+
return ((_a = (yield this.searchOne(resource.resourceType, query))) !== null && _a !== void 0 ? _a : this.createResource(resource));
|
|
2173
1889
|
});
|
|
2174
1890
|
}
|
|
2175
1891
|
/**
|
|
@@ -2225,7 +1941,10 @@
|
|
|
2225
1941
|
*/
|
|
2226
1942
|
createPdf(docDefinition, filename, tableLayouts, fonts) {
|
|
2227
1943
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2228
|
-
|
|
1944
|
+
if (!__classPrivateFieldGet(this, _MedplumClient_createPdf, "f")) {
|
|
1945
|
+
throw new Error('PDF creation not enabled');
|
|
1946
|
+
}
|
|
1947
|
+
const blob = yield __classPrivateFieldGet(this, _MedplumClient_createPdf, "f").call(this, docDefinition, tableLayouts, fonts);
|
|
2229
1948
|
return this.createBinary(blob, filename, 'application/pdf');
|
|
2230
1949
|
});
|
|
2231
1950
|
}
|
|
@@ -2488,7 +2207,7 @@
|
|
|
2488
2207
|
});
|
|
2489
2208
|
}
|
|
2490
2209
|
}
|
|
2491
|
-
_MedplumClient_fetch = new WeakMap(), _MedplumClient_storage = new WeakMap(), _MedplumClient_schema = new WeakMap(), _MedplumClient_requestCache = new WeakMap(), _MedplumClient_baseUrl = new WeakMap(), _MedplumClient_clientId = new WeakMap(), _MedplumClient_authorizeUrl = new WeakMap(), _MedplumClient_tokenUrl = new WeakMap(), _MedplumClient_logoutUrl = new WeakMap(), _MedplumClient_onUnauthenticated = new WeakMap(), _MedplumClient_accessToken = new WeakMap(), _MedplumClient_refreshToken = new WeakMap(), _MedplumClient_refreshPromise = new WeakMap(), _MedplumClient_profilePromise = new WeakMap(), _MedplumClient_profile = new WeakMap(), _MedplumClient_config = new WeakMap(), _MedplumClient_instances = new WeakSet(), _MedplumClient_addLogin = function _MedplumClient_addLogin(newLogin) {
|
|
2210
|
+
_MedplumClient_fetch = new WeakMap(), _MedplumClient_createPdf = new WeakMap(), _MedplumClient_storage = new WeakMap(), _MedplumClient_schema = new WeakMap(), _MedplumClient_requestCache = new WeakMap(), _MedplumClient_baseUrl = new WeakMap(), _MedplumClient_clientId = new WeakMap(), _MedplumClient_authorizeUrl = new WeakMap(), _MedplumClient_tokenUrl = new WeakMap(), _MedplumClient_logoutUrl = new WeakMap(), _MedplumClient_onUnauthenticated = new WeakMap(), _MedplumClient_accessToken = new WeakMap(), _MedplumClient_refreshToken = new WeakMap(), _MedplumClient_refreshPromise = new WeakMap(), _MedplumClient_profilePromise = new WeakMap(), _MedplumClient_profile = new WeakMap(), _MedplumClient_config = new WeakMap(), _MedplumClient_instances = new WeakSet(), _MedplumClient_addLogin = function _MedplumClient_addLogin(newLogin) {
|
|
2492
2211
|
const logins = this.getLogins().filter((login) => { var _a, _b; return ((_a = login.profile) === null || _a === void 0 ? void 0 : _a.reference) !== ((_b = newLogin.profile) === null || _b === void 0 ? void 0 : _b.reference); });
|
|
2493
2212
|
logins.push(newLogin);
|
|
2494
2213
|
__classPrivateFieldGet(this, _MedplumClient_storage, "f").setObject('logins', logins);
|
|
@@ -2558,8 +2277,8 @@
|
|
|
2558
2277
|
}, _MedplumClient_setRequestBody = function _MedplumClient_setRequestBody(options, data) {
|
|
2559
2278
|
if (typeof data === 'string' ||
|
|
2560
2279
|
(typeof Blob !== 'undefined' && data instanceof Blob) ||
|
|
2561
|
-
(typeof
|
|
2562
|
-
(typeof
|
|
2280
|
+
(typeof File !== 'undefined' && data instanceof File) ||
|
|
2281
|
+
(typeof Uint8Array !== 'undefined' && data instanceof Uint8Array)) {
|
|
2563
2282
|
options.body = data;
|
|
2564
2283
|
}
|
|
2565
2284
|
else if (data) {
|
|
@@ -5317,6 +5036,206 @@
|
|
|
5317
5036
|
}
|
|
5318
5037
|
}
|
|
5319
5038
|
|
|
5039
|
+
const DEFAULT_SEARCH_COUNT = 20;
|
|
5040
|
+
/**
|
|
5041
|
+
* Search operators.
|
|
5042
|
+
* These operators represent "modifiers" and "prefixes" in FHIR search.
|
|
5043
|
+
* See: https://www.hl7.org/fhir/search.html
|
|
5044
|
+
*/
|
|
5045
|
+
exports.Operator = void 0;
|
|
5046
|
+
(function (Operator) {
|
|
5047
|
+
Operator["EQUALS"] = "eq";
|
|
5048
|
+
Operator["NOT_EQUALS"] = "ne";
|
|
5049
|
+
// Numbers
|
|
5050
|
+
Operator["GREATER_THAN"] = "gt";
|
|
5051
|
+
Operator["LESS_THAN"] = "lt";
|
|
5052
|
+
Operator["GREATER_THAN_OR_EQUALS"] = "ge";
|
|
5053
|
+
Operator["LESS_THAN_OR_EQUALS"] = "le";
|
|
5054
|
+
// Dates
|
|
5055
|
+
Operator["STARTS_AFTER"] = "sa";
|
|
5056
|
+
Operator["ENDS_BEFORE"] = "eb";
|
|
5057
|
+
Operator["APPROXIMATELY"] = "ap";
|
|
5058
|
+
// String
|
|
5059
|
+
Operator["CONTAINS"] = "contains";
|
|
5060
|
+
Operator["EXACT"] = "exact";
|
|
5061
|
+
// Token
|
|
5062
|
+
Operator["TEXT"] = "text";
|
|
5063
|
+
Operator["ABOVE"] = "above";
|
|
5064
|
+
Operator["BELOW"] = "below";
|
|
5065
|
+
Operator["IN"] = "in";
|
|
5066
|
+
Operator["NOT_IN"] = "not-in";
|
|
5067
|
+
Operator["OF_TYPE"] = "of-type";
|
|
5068
|
+
})(exports.Operator || (exports.Operator = {}));
|
|
5069
|
+
const MODIFIER_OPERATORS = [
|
|
5070
|
+
exports.Operator.CONTAINS,
|
|
5071
|
+
exports.Operator.EXACT,
|
|
5072
|
+
exports.Operator.TEXT,
|
|
5073
|
+
exports.Operator.ABOVE,
|
|
5074
|
+
exports.Operator.BELOW,
|
|
5075
|
+
exports.Operator.IN,
|
|
5076
|
+
exports.Operator.NOT_IN,
|
|
5077
|
+
exports.Operator.OF_TYPE,
|
|
5078
|
+
];
|
|
5079
|
+
const PREFIX_OPERATORS = [
|
|
5080
|
+
exports.Operator.NOT_EQUALS,
|
|
5081
|
+
exports.Operator.GREATER_THAN,
|
|
5082
|
+
exports.Operator.LESS_THAN,
|
|
5083
|
+
exports.Operator.GREATER_THAN_OR_EQUALS,
|
|
5084
|
+
exports.Operator.LESS_THAN_OR_EQUALS,
|
|
5085
|
+
exports.Operator.STARTS_AFTER,
|
|
5086
|
+
exports.Operator.ENDS_BEFORE,
|
|
5087
|
+
exports.Operator.APPROXIMATELY,
|
|
5088
|
+
];
|
|
5089
|
+
/**
|
|
5090
|
+
* Parses a URL into a SearchRequest.
|
|
5091
|
+
*
|
|
5092
|
+
* See the FHIR search spec: http://hl7.org/fhir/r4/search.html
|
|
5093
|
+
*
|
|
5094
|
+
* @param url The URL to parse.
|
|
5095
|
+
* @returns Parsed search definition.
|
|
5096
|
+
*/
|
|
5097
|
+
function parseSearchDefinition(url) {
|
|
5098
|
+
const location = new URL(url, 'https://example.com/');
|
|
5099
|
+
const resourceType = location.pathname
|
|
5100
|
+
.replace(/(^\/)|(\/$)/g, '') // Remove leading and trailing slashes
|
|
5101
|
+
.split('/')
|
|
5102
|
+
.pop();
|
|
5103
|
+
const params = new URLSearchParams(location.search);
|
|
5104
|
+
let filters = undefined;
|
|
5105
|
+
let sortRules = undefined;
|
|
5106
|
+
let fields = undefined;
|
|
5107
|
+
let offset = undefined;
|
|
5108
|
+
let count = undefined;
|
|
5109
|
+
let total = undefined;
|
|
5110
|
+
params.forEach((value, key) => {
|
|
5111
|
+
if (key === '_fields') {
|
|
5112
|
+
fields = value.split(',');
|
|
5113
|
+
}
|
|
5114
|
+
else if (key === '_offset') {
|
|
5115
|
+
offset = parseInt(value);
|
|
5116
|
+
}
|
|
5117
|
+
else if (key === '_count') {
|
|
5118
|
+
count = parseInt(value);
|
|
5119
|
+
}
|
|
5120
|
+
else if (key === '_total') {
|
|
5121
|
+
total = value;
|
|
5122
|
+
}
|
|
5123
|
+
else if (key === '_sort') {
|
|
5124
|
+
sortRules = sortRules || [];
|
|
5125
|
+
sortRules.push(parseSortRule(value));
|
|
5126
|
+
}
|
|
5127
|
+
else {
|
|
5128
|
+
filters = filters || [];
|
|
5129
|
+
filters.push(parseSearchFilter(key, value));
|
|
5130
|
+
}
|
|
5131
|
+
});
|
|
5132
|
+
return {
|
|
5133
|
+
resourceType,
|
|
5134
|
+
filters,
|
|
5135
|
+
fields,
|
|
5136
|
+
offset,
|
|
5137
|
+
count,
|
|
5138
|
+
total,
|
|
5139
|
+
sortRules,
|
|
5140
|
+
};
|
|
5141
|
+
}
|
|
5142
|
+
/**
|
|
5143
|
+
* Parses a URL query parameter into a sort rule.
|
|
5144
|
+
*
|
|
5145
|
+
* By default, the sort rule is the field name.
|
|
5146
|
+
*
|
|
5147
|
+
* Sort rules can be reversed into descending order by prefixing the field name with a minus sign.
|
|
5148
|
+
*
|
|
5149
|
+
* See sorting: http://hl7.org/fhir/r4/search.html#_sort
|
|
5150
|
+
*
|
|
5151
|
+
* @param value The URL parameter value.
|
|
5152
|
+
* @returns The parsed sort rule.
|
|
5153
|
+
*/
|
|
5154
|
+
function parseSortRule(value) {
|
|
5155
|
+
if (value.startsWith('-')) {
|
|
5156
|
+
return { code: value.substring(1), descending: true };
|
|
5157
|
+
}
|
|
5158
|
+
else {
|
|
5159
|
+
return { code: value };
|
|
5160
|
+
}
|
|
5161
|
+
}
|
|
5162
|
+
/**
|
|
5163
|
+
* Parses a URL query parameter into a search filter.
|
|
5164
|
+
*
|
|
5165
|
+
* FHIR search filters can be specified as modifiers or prefixes.
|
|
5166
|
+
*
|
|
5167
|
+
* For string properties, modifiers are appended to the key, e.g. "name:contains=eve".
|
|
5168
|
+
*
|
|
5169
|
+
* For date and numeric properties, prefixes are prepended to the value, e.g. "birthdate=gt2000".
|
|
5170
|
+
*
|
|
5171
|
+
* See the FHIR search spec: http://hl7.org/fhir/r4/search.html
|
|
5172
|
+
*
|
|
5173
|
+
* @param key The URL parameter key.
|
|
5174
|
+
* @param value The URL parameter value.
|
|
5175
|
+
* @returns The parsed search filter.
|
|
5176
|
+
*/
|
|
5177
|
+
function parseSearchFilter(key, value) {
|
|
5178
|
+
let code = key;
|
|
5179
|
+
let operator = exports.Operator.EQUALS;
|
|
5180
|
+
for (const modifier of MODIFIER_OPERATORS) {
|
|
5181
|
+
const modifierIndex = code.indexOf(':' + modifier);
|
|
5182
|
+
if (modifierIndex !== -1) {
|
|
5183
|
+
operator = modifier;
|
|
5184
|
+
code = code.substring(0, modifierIndex);
|
|
5185
|
+
}
|
|
5186
|
+
}
|
|
5187
|
+
for (const prefix of PREFIX_OPERATORS) {
|
|
5188
|
+
if (value.match(new RegExp('^' + prefix + '\\d'))) {
|
|
5189
|
+
operator = prefix;
|
|
5190
|
+
value = value.substring(prefix.length);
|
|
5191
|
+
}
|
|
5192
|
+
}
|
|
5193
|
+
return { code, operator, value };
|
|
5194
|
+
}
|
|
5195
|
+
/**
|
|
5196
|
+
* Formats a search definition object into a query string.
|
|
5197
|
+
* Note: The return value does not include the resource type.
|
|
5198
|
+
* @param {!SearchRequest} definition The search definition.
|
|
5199
|
+
* @returns Formatted URL.
|
|
5200
|
+
*/
|
|
5201
|
+
function formatSearchQuery(definition) {
|
|
5202
|
+
const params = [];
|
|
5203
|
+
if (definition.fields) {
|
|
5204
|
+
params.push('_fields=' + definition.fields.join(','));
|
|
5205
|
+
}
|
|
5206
|
+
if (definition.filters) {
|
|
5207
|
+
definition.filters.forEach((filter) => params.push(formatFilter(filter)));
|
|
5208
|
+
}
|
|
5209
|
+
if (definition.sortRules && definition.sortRules.length > 0) {
|
|
5210
|
+
params.push(formatSortRules(definition.sortRules));
|
|
5211
|
+
}
|
|
5212
|
+
if (definition.offset !== undefined) {
|
|
5213
|
+
params.push('_offset=' + definition.offset);
|
|
5214
|
+
}
|
|
5215
|
+
if (definition.count !== undefined) {
|
|
5216
|
+
params.push('_count=' + definition.count);
|
|
5217
|
+
}
|
|
5218
|
+
if (definition.total !== undefined) {
|
|
5219
|
+
params.push('_total=' + definition.total);
|
|
5220
|
+
}
|
|
5221
|
+
if (params.length === 0) {
|
|
5222
|
+
return '';
|
|
5223
|
+
}
|
|
5224
|
+
params.sort();
|
|
5225
|
+
return '?' + params.join('&');
|
|
5226
|
+
}
|
|
5227
|
+
function formatFilter(filter) {
|
|
5228
|
+
const modifier = MODIFIER_OPERATORS.includes(filter.operator) ? ':' + filter.operator : '';
|
|
5229
|
+
const prefix = PREFIX_OPERATORS.includes(filter.operator) ? filter.operator : '';
|
|
5230
|
+
return `${filter.code}${modifier}=${prefix}${encodeURIComponent(filter.value)}`;
|
|
5231
|
+
}
|
|
5232
|
+
function formatSortRules(sortRules) {
|
|
5233
|
+
if (!sortRules || sortRules.length === 0) {
|
|
5234
|
+
return '';
|
|
5235
|
+
}
|
|
5236
|
+
return '_sort=' + sortRules.map((sr) => (sr.descending ? '-' + sr.code : sr.code)).join(',');
|
|
5237
|
+
}
|
|
5238
|
+
|
|
5320
5239
|
exports.SearchParameterType = void 0;
|
|
5321
5240
|
(function (SearchParameterType) {
|
|
5322
5241
|
SearchParameterType["BOOLEAN"] = "BOOLEAN";
|