@openfn/language-fhir-4 0.4.0 → 0.4.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/dist/index.cjs +76 -27
- package/dist/index.js +1319 -1270
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -79,6 +79,7 @@ var import_util2 = require("@openfn/language-common/util");
|
|
|
79
79
|
|
|
80
80
|
// src/util.ts
|
|
81
81
|
var import_node_path = __toESM(require("path"), 1);
|
|
82
|
+
var import_lodash_es = __toESM(require("lodash-es"), 1);
|
|
82
83
|
var import_language_common = require("@openfn/language-common");
|
|
83
84
|
var import_util = require("@openfn/language-common/util");
|
|
84
85
|
function assertValidResourceId(id2) {
|
|
@@ -102,7 +103,7 @@ function addAuth(options) {
|
|
|
102
103
|
return {};
|
|
103
104
|
}
|
|
104
105
|
var prepareNextState = (state, response) => {
|
|
105
|
-
const { body, ...responseWithoutBody } = response;
|
|
106
|
+
const { body, validationErrors, ...responseWithoutBody } = response;
|
|
106
107
|
return {
|
|
107
108
|
...(0, import_language_common.composeNextState)(state, body),
|
|
108
109
|
response: responseWithoutBody
|
|
@@ -117,11 +118,11 @@ var logResponse = (response, query) => {
|
|
|
117
118
|
}
|
|
118
119
|
const message = `${method} ${urlWithQuery} - ${statusCode} in ${duration}ms`;
|
|
119
120
|
if (response instanceof Error) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
console.error(message);
|
|
122
|
+
console.error("response body: ");
|
|
123
|
+
console.error(response.body || "[no body]");
|
|
123
124
|
} else {
|
|
124
|
-
|
|
125
|
+
console.log(message);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
return response;
|
|
@@ -146,63 +147,102 @@ var request = (method, path, options) => {
|
|
|
146
147
|
};
|
|
147
148
|
return (0, import_util.request)(method, fullPath, opts).then(logResponse).then().catch(async (e) => {
|
|
148
149
|
if (e.headers && "content-type" in e.headers && e.headers["content-type"].match(/fhir\+json/)) {
|
|
149
|
-
logValidationErrors(e);
|
|
150
|
+
logValidationErrors(e, opts.body);
|
|
150
151
|
}
|
|
151
152
|
throw e;
|
|
152
153
|
});
|
|
153
154
|
};
|
|
154
|
-
function logValidationErrors(response,
|
|
155
|
+
function logValidationErrors(response, payload, logger = console) {
|
|
155
156
|
const error = JSON.parse(response.body);
|
|
156
157
|
if (error.issue && error.issue.length) {
|
|
157
158
|
delete response.body;
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
logger.log();
|
|
160
|
+
logger.error("FHIR server reports validation issues:");
|
|
160
161
|
const errCount = error.issue.reduce(
|
|
161
162
|
(count, e) => e.severity === "error" ? count + 1 : count,
|
|
162
163
|
0
|
|
163
164
|
);
|
|
164
165
|
if (errCount) {
|
|
165
|
-
|
|
166
|
+
logger.error(` - ${errCount} Errors`);
|
|
166
167
|
}
|
|
167
168
|
const warnCount = error.issue.reduce(
|
|
168
169
|
(count, e) => e.severity === "error" ? count + 1 : count,
|
|
169
170
|
0
|
|
170
171
|
);
|
|
171
172
|
if (warnCount) {
|
|
172
|
-
|
|
173
|
+
logger.error(` - ${warnCount} Warnings`);
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
+
logger.log();
|
|
175
176
|
const groups = {};
|
|
176
177
|
error.issue.forEach((issue) => {
|
|
177
|
-
var _a, _b;
|
|
178
|
+
var _a, _b, _c;
|
|
178
179
|
try {
|
|
179
|
-
let
|
|
180
|
-
if (
|
|
181
|
-
|
|
180
|
+
let resourceId = "unidentified resource";
|
|
181
|
+
if (issue.location) {
|
|
182
|
+
let idx = issue.location[0].match(/Bundle.entry\[(\d+)\]/);
|
|
183
|
+
if (idx && idx.length >= 2) {
|
|
184
|
+
idx = idx[1];
|
|
185
|
+
const resource = (_a = import_lodash_es.default.get(payload, `entry[${idx}]`)) == null ? void 0 : _a.resource;
|
|
186
|
+
if (resource) {
|
|
187
|
+
resourceId = `${resource.resourceType}/${resource.id}`;
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
if (payload.resourceType && payload.id) {
|
|
191
|
+
resourceId = `${payload.resourceType}/${payload.id}`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const type = `${issue.severity}s`;
|
|
196
|
+
groups[resourceId] ?? (groups[resourceId] = {});
|
|
197
|
+
let path = "*";
|
|
198
|
+
if (issue.location[0].match(/\.resource\./)) {
|
|
199
|
+
path = issue.location[0].split(/\.resource\./)[1];
|
|
200
|
+
} else if (issue.location.includes(`*${resourceId}*`)) {
|
|
201
|
+
const suffix = issue.location[0].split(/\.resource\./)[1];
|
|
202
|
+
if (suffix && suffix.length > 1) {
|
|
203
|
+
path = suffix;
|
|
204
|
+
}
|
|
182
205
|
}
|
|
183
|
-
groups[
|
|
184
|
-
(
|
|
185
|
-
groups[
|
|
206
|
+
(_b = groups[resourceId])[type] ?? (_b[type] = {});
|
|
207
|
+
(_c = groups[resourceId][type])[path] ?? (_c[path] = []);
|
|
208
|
+
groups[resourceId][type][path].push(issue.diagnostics);
|
|
186
209
|
} catch (e) {
|
|
187
|
-
|
|
210
|
+
logger.log("error parsing issue at ", issue.location);
|
|
211
|
+
console.log(e);
|
|
188
212
|
}
|
|
189
213
|
});
|
|
190
214
|
for (const resource in groups) {
|
|
191
|
-
|
|
192
|
-
["
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
215
|
+
logger.log(`${resource} issues:`);
|
|
216
|
+
["errors", "warnings"].forEach((type) => {
|
|
217
|
+
if (type in groups[resource]) {
|
|
218
|
+
logger.log(` ${type}:`.toUpperCase());
|
|
219
|
+
for (const path in groups[resource][type]) {
|
|
220
|
+
logger.log();
|
|
221
|
+
logger.log(" ", path);
|
|
222
|
+
for (const message of groups[resource][type][path]) {
|
|
223
|
+
const fn2 = type === "error" ? console.error : console.warn;
|
|
224
|
+
fn2(" -", message);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
logger.log();
|
|
196
228
|
}
|
|
197
|
-
logger2.log();
|
|
198
229
|
});
|
|
199
230
|
}
|
|
200
|
-
|
|
231
|
+
logger.log("Issues will be written to state.fhirValidationIssues");
|
|
232
|
+
response.$validationIssues = groups;
|
|
201
233
|
} else {
|
|
202
234
|
response.body = error;
|
|
203
235
|
}
|
|
204
236
|
return response;
|
|
205
237
|
}
|
|
238
|
+
function cleanResponseObject(state, response) {
|
|
239
|
+
if (response.$validationIssues) {
|
|
240
|
+
state.fhirValidationIssues ?? (state.fhirValidationIssues = {});
|
|
241
|
+
Object.assign(state.fhirValidationIssues, response.$validationIssues);
|
|
242
|
+
delete response.$validationIssues;
|
|
243
|
+
}
|
|
244
|
+
return state;
|
|
245
|
+
}
|
|
206
246
|
function collectRefs(value2) {
|
|
207
247
|
if (!value2 || typeof value2 !== "object")
|
|
208
248
|
return [];
|
|
@@ -369,6 +409,9 @@ function create(resource) {
|
|
|
369
409
|
const response = await request("POST", $resource.resourceType, {
|
|
370
410
|
configuration: state.configuration,
|
|
371
411
|
body: $resource
|
|
412
|
+
}).catch((e) => {
|
|
413
|
+
cleanResponseObject(state, e);
|
|
414
|
+
throw e;
|
|
372
415
|
});
|
|
373
416
|
console.log(`Created ${response.body.id}`);
|
|
374
417
|
return prepareNextState(state, response);
|
|
@@ -433,6 +476,9 @@ function uploadBundle(bundle = "bundle") {
|
|
|
433
476
|
const response = await request("POST", "/", {
|
|
434
477
|
configuration: state.configuration,
|
|
435
478
|
body: data
|
|
479
|
+
}).catch((e) => {
|
|
480
|
+
cleanResponseObject(state, e);
|
|
481
|
+
throw e;
|
|
436
482
|
});
|
|
437
483
|
return prepareNextState(state, response);
|
|
438
484
|
};
|
|
@@ -785,6 +831,9 @@ var composite = (object, key, value2) => {
|
|
|
785
831
|
k.push("CodeableConcept");
|
|
786
832
|
} else if (value2.reference) {
|
|
787
833
|
k.push("Reference");
|
|
834
|
+
}
|
|
835
|
+
if (value2.value && typeof value2.value === "number") {
|
|
836
|
+
k.push("Quantity");
|
|
788
837
|
} else if (value2.id && value2.meta && value2.resourceType) {
|
|
789
838
|
k.push("Reference");
|
|
790
839
|
value2 = reference(value2);
|