@nsshunt/stsfhirclient 2.0.29 → 2.0.31
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/stsfhirclient.mjs
CHANGED
|
@@ -9158,325 +9158,6 @@ function splitUnderBase(pathname, basePath) {
|
|
|
9158
9158
|
return pathname.slice(basePath.length).split("/").filter(Boolean);
|
|
9159
9159
|
}
|
|
9160
9160
|
//#endregion
|
|
9161
|
-
//#region src/retryAxiosClient.ts
|
|
9162
|
-
function sleep(ms) {
|
|
9163
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9164
|
-
}
|
|
9165
|
-
function getJitteredDelay(base, jitter) {
|
|
9166
|
-
return base + Math.floor(Math.random() * jitter);
|
|
9167
|
-
}
|
|
9168
|
-
function createRetryAxiosClient(retryConfig) {
|
|
9169
|
-
const { maxRetries = 3, retryDelayMs = 300, retryJitterMs = 100, retryMethods = [
|
|
9170
|
-
"get",
|
|
9171
|
-
"head",
|
|
9172
|
-
"put",
|
|
9173
|
-
"delete",
|
|
9174
|
-
"options"
|
|
9175
|
-
], retryStatusCodes = [
|
|
9176
|
-
408,
|
|
9177
|
-
429,
|
|
9178
|
-
500,
|
|
9179
|
-
502,
|
|
9180
|
-
503,
|
|
9181
|
-
504
|
|
9182
|
-
], retryErrorCodes = [
|
|
9183
|
-
"ECONNRESET",
|
|
9184
|
-
"ETIMEDOUT",
|
|
9185
|
-
"EAI_AGAIN",
|
|
9186
|
-
"ECONNREFUSED",
|
|
9187
|
-
"ENOTFOUND",
|
|
9188
|
-
"EHOSTUNREACH",
|
|
9189
|
-
"EPIPE"
|
|
9190
|
-
], maxRetryDurationMs = 1e4, onRetryAttempt, stsAxiosConfig } = retryConfig || {};
|
|
9191
|
-
const instance = axios.create();
|
|
9192
|
-
instance.interceptors.request.use((config) => {
|
|
9193
|
-
const retryConfig = config;
|
|
9194
|
-
if (!retryConfig.metadata) retryConfig.metadata = {
|
|
9195
|
-
startTime: Date.now(),
|
|
9196
|
-
__retryCount: 0
|
|
9197
|
-
};
|
|
9198
|
-
if (stsAxiosConfig) Object.assign(config, stsAxiosConfig.config);
|
|
9199
|
-
return config;
|
|
9200
|
-
});
|
|
9201
|
-
instance.interceptors.response.use((response) => response, async (error) => {
|
|
9202
|
-
const config = error.config;
|
|
9203
|
-
if (!config || !config.method || !config.metadata) return Promise.reject(error);
|
|
9204
|
-
const elapsed = Date.now() - config.metadata.startTime;
|
|
9205
|
-
const method = config.method.toLowerCase();
|
|
9206
|
-
const status = error.response?.status;
|
|
9207
|
-
const code = error.code ?? "";
|
|
9208
|
-
const isRetryableMethod = retryMethods.includes(method);
|
|
9209
|
-
const isRetryableStatus = retryStatusCodes.includes(status ?? 0);
|
|
9210
|
-
const isRetryableCode = retryErrorCodes.includes(code);
|
|
9211
|
-
if (isRetryableMethod && (isRetryableStatus || isRetryableCode) && config.metadata.__retryCount < maxRetries && elapsed < maxRetryDurationMs) {
|
|
9212
|
-
config.metadata.__retryCount += 1;
|
|
9213
|
-
const delayMs = getJitteredDelay(retryDelayMs * Math.pow(2, config.metadata.__retryCount - 1), retryJitterMs);
|
|
9214
|
-
onRetryAttempt?.(config.metadata.__retryCount, error, delayMs);
|
|
9215
|
-
await sleep(delayMs);
|
|
9216
|
-
return instance(config);
|
|
9217
|
-
}
|
|
9218
|
-
return Promise.reject(error);
|
|
9219
|
-
});
|
|
9220
|
-
return instance;
|
|
9221
|
-
}
|
|
9222
|
-
//#endregion
|
|
9223
|
-
//#region src/cv2/fhirRESTClient.ts
|
|
9224
|
-
var FhirRESTClient = class {
|
|
9225
|
-
#options;
|
|
9226
|
-
constructor(options) {
|
|
9227
|
-
this.#options = options;
|
|
9228
|
-
}
|
|
9229
|
-
BaseUrl() {
|
|
9230
|
-
return `${this.#options.endpoint}:${this.#options.stsfhirport}${this.#options.stsfhirapiroot}`;
|
|
9231
|
-
}
|
|
9232
|
-
LogError = (method, error) => {
|
|
9233
|
-
this.#options.logger.error(`FhirRESTClient:${method}(): Error: [${error}]`);
|
|
9234
|
-
this.#options.logger.error(error);
|
|
9235
|
-
console.error(error);
|
|
9236
|
-
process.exit(0);
|
|
9237
|
-
};
|
|
9238
|
-
LogWarning = (method, message) => {
|
|
9239
|
-
this.#options.logger.warn(`FhirRESTClient:${method}(): Warn: [${message}]`);
|
|
9240
|
-
};
|
|
9241
|
-
/**
|
|
9242
|
-
*
|
|
9243
|
-
* @param url
|
|
9244
|
-
* @param httpVerb
|
|
9245
|
-
* @param versionIdETag Format "W/<versionNumber", e.g. "W/3"
|
|
9246
|
-
* @param resource
|
|
9247
|
-
* @returns
|
|
9248
|
-
*/
|
|
9249
|
-
#InvokeResourceAPI = async (url, httpVerb, versionIdETag, resource, contentType) => {
|
|
9250
|
-
const accessToken = await this.#options.GetAccessToken();
|
|
9251
|
-
let requestConfig;
|
|
9252
|
-
const headers = {
|
|
9253
|
-
Prefer: "return=representation",
|
|
9254
|
-
Accept: "application/fhir+json"
|
|
9255
|
-
};
|
|
9256
|
-
if (versionIdETag && versionIdETag !== "") headers["If-Match"] = versionIdETag;
|
|
9257
|
-
if (httpVerb === "patch") {
|
|
9258
|
-
requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationMergePatchAndJsonContentTypeHeaders();
|
|
9259
|
-
if (resource && contentType) {
|
|
9260
|
-
if (contentType.localeCompare("application/merge-patch+json") === 0) requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationMergePatchAndJsonContentTypeHeaders();
|
|
9261
|
-
else if (contentType.localeCompare("application/json-patch+json") === 0) requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationJsonPatchAndJsonContentTypeHeaders();
|
|
9262
|
-
}
|
|
9263
|
-
} else requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationFhirAndJsonContentTypeHeaders();
|
|
9264
|
-
requestConfig.withAuthHeaders(accessToken, this.#options.user).withHeaders(headers);
|
|
9265
|
-
if (resource) requestConfig.withData(resource);
|
|
9266
|
-
if (this.#options.agentManager) requestConfig.withAgentManager(this.#options.agentManager);
|
|
9267
|
-
return await createRetryAxiosClient({
|
|
9268
|
-
maxRetries: 4,
|
|
9269
|
-
retryDelayMs: 300,
|
|
9270
|
-
retryJitterMs: 150,
|
|
9271
|
-
maxRetryDurationMs: 5e3,
|
|
9272
|
-
onRetryAttempt: (attempt, error, delayMs) => {
|
|
9273
|
-
this.LogWarning("#InvokeResourceAPI", `Retry #${attempt} after ${delayMs}ms due to ${error.code || error.response?.status}`);
|
|
9274
|
-
if (this.#options.onRetryAttempt) this.#options.onRetryAttempt(attempt, error, delayMs);
|
|
9275
|
-
}
|
|
9276
|
-
})(url, requestConfig.config);
|
|
9277
|
-
};
|
|
9278
|
-
ProcessBatchOrTransactionResources = async (bundle) => {
|
|
9279
|
-
try {
|
|
9280
|
-
let url = `${this.BaseUrl()}`;
|
|
9281
|
-
const retVal = await this.#InvokeResourceAPI(url, "post", null, bundle);
|
|
9282
|
-
if (retVal) return {
|
|
9283
|
-
status: retVal.status,
|
|
9284
|
-
body: retVal.data
|
|
9285
|
-
};
|
|
9286
|
-
else throw new Error(`FhirRESTClient:ProcessBatchOrTransactionResources(): No response from #InvokeResourceAPI`);
|
|
9287
|
-
} catch (error) {
|
|
9288
|
-
this.LogError("ProcessBatchOrTransactionResources", error);
|
|
9289
|
-
throw error;
|
|
9290
|
-
}
|
|
9291
|
-
};
|
|
9292
|
-
GetResources = async (searchUrl) => {
|
|
9293
|
-
try {
|
|
9294
|
-
const retVal = await this.#InvokeResourceAPI(searchUrl.toString(), "get", null, null);
|
|
9295
|
-
if (retVal) return {
|
|
9296
|
-
status: retVal.status,
|
|
9297
|
-
body: retVal.data
|
|
9298
|
-
};
|
|
9299
|
-
else throw new Error(`FhirRESTClient:GetResources(): No response from #InvokeResourceAPI`);
|
|
9300
|
-
} catch (error) {
|
|
9301
|
-
this.LogError("GetResources", error);
|
|
9302
|
-
throw error;
|
|
9303
|
-
}
|
|
9304
|
-
};
|
|
9305
|
-
GetHistoryFhirResources = async (searchUrl) => {
|
|
9306
|
-
try {
|
|
9307
|
-
return await this.GetResources(searchUrl);
|
|
9308
|
-
} catch (error) {
|
|
9309
|
-
this.LogError("GetHistoryFhirResources", error);
|
|
9310
|
-
throw error;
|
|
9311
|
-
}
|
|
9312
|
-
};
|
|
9313
|
-
GetHistoryFhirResource = async (searchUrl) => {
|
|
9314
|
-
try {
|
|
9315
|
-
return await this.GetResources(searchUrl);
|
|
9316
|
-
} catch (error) {
|
|
9317
|
-
this.LogError("GetHistoryFhirResource", error);
|
|
9318
|
-
throw error;
|
|
9319
|
-
}
|
|
9320
|
-
};
|
|
9321
|
-
GetAllFhirResources = async (searchUrl) => {
|
|
9322
|
-
try {
|
|
9323
|
-
return await this.GetResources(searchUrl);
|
|
9324
|
-
} catch (error) {
|
|
9325
|
-
this.LogError("GetAllFhirResources", error);
|
|
9326
|
-
throw error;
|
|
9327
|
-
}
|
|
9328
|
-
};
|
|
9329
|
-
GetResource = async (resourceType, resourceId) => {
|
|
9330
|
-
try {
|
|
9331
|
-
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9332
|
-
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9333
|
-
if (retVal) return {
|
|
9334
|
-
status: retVal.status,
|
|
9335
|
-
body: retVal.data
|
|
9336
|
-
};
|
|
9337
|
-
else throw new Error(`FhirRESTClient:GetResource(): No response from #InvokeResourceAPI`);
|
|
9338
|
-
} catch (error) {
|
|
9339
|
-
if (axios.isAxiosError(error)) {
|
|
9340
|
-
const axiosError = error;
|
|
9341
|
-
return {
|
|
9342
|
-
status: axiosError.response.status,
|
|
9343
|
-
body: axiosError.response.data,
|
|
9344
|
-
headers: { ETag: axiosError.response.headers["etag"] }
|
|
9345
|
-
};
|
|
9346
|
-
} else throw error;
|
|
9347
|
-
}
|
|
9348
|
-
};
|
|
9349
|
-
PutResource = async (resourceType, domainResource, versionIdETag) => {
|
|
9350
|
-
try {
|
|
9351
|
-
let url = `${`${this.BaseUrl()}/${resourceType}`}/${domainResource.id}`;
|
|
9352
|
-
const retVal = await this.#InvokeResourceAPI(url, "put", versionIdETag, domainResource);
|
|
9353
|
-
if (retVal) return {
|
|
9354
|
-
status: retVal.status,
|
|
9355
|
-
body: retVal.data
|
|
9356
|
-
};
|
|
9357
|
-
else throw new Error(`FhirRESTClient:PutResource(): No response from #InvokeResourceAPI`);
|
|
9358
|
-
} catch (error) {
|
|
9359
|
-
this.LogError("PutResource", error);
|
|
9360
|
-
throw error;
|
|
9361
|
-
}
|
|
9362
|
-
};
|
|
9363
|
-
PatchResource = async (resourceType, resourceId, domainResource, contentType, versionIdETag) => {
|
|
9364
|
-
try {
|
|
9365
|
-
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9366
|
-
const retVal = await this.#InvokeResourceAPI(url, "patch", versionIdETag, domainResource, contentType);
|
|
9367
|
-
if (retVal) return {
|
|
9368
|
-
status: retVal.status,
|
|
9369
|
-
body: retVal.data
|
|
9370
|
-
};
|
|
9371
|
-
else throw new Error(`FhirRESTClient:PatchResource(): No response from #InvokeResourceAPI`);
|
|
9372
|
-
} catch (error) {
|
|
9373
|
-
this.LogError("PatchResource", error);
|
|
9374
|
-
throw error;
|
|
9375
|
-
}
|
|
9376
|
-
};
|
|
9377
|
-
PostResource = async (resourceType, domainResource) => {
|
|
9378
|
-
try {
|
|
9379
|
-
const url = `${this.BaseUrl()}/${resourceType}`;
|
|
9380
|
-
const retVal = await this.#InvokeResourceAPI(url, "post", null, domainResource);
|
|
9381
|
-
if (retVal) return {
|
|
9382
|
-
status: retVal.status,
|
|
9383
|
-
body: retVal.data
|
|
9384
|
-
};
|
|
9385
|
-
else throw new Error(`FhirRESTClient:PostResource(): No response from #InvokeResourceAPI`);
|
|
9386
|
-
} catch (error) {
|
|
9387
|
-
this.LogError("PostResource", error);
|
|
9388
|
-
throw error;
|
|
9389
|
-
}
|
|
9390
|
-
};
|
|
9391
|
-
GetHistoryInstanceFhirResource = async (resourceType, resourceId, versionId) => {
|
|
9392
|
-
try {
|
|
9393
|
-
const url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}/_history/${versionId.toString()}`;
|
|
9394
|
-
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9395
|
-
if (retVal) return {
|
|
9396
|
-
status: retVal.status,
|
|
9397
|
-
body: retVal.data
|
|
9398
|
-
};
|
|
9399
|
-
else throw new Error(`FhirRESTClient:GetHistoryInstanceFhirResource(): No response from #InvokeResourceAPI`);
|
|
9400
|
-
} catch (error) {
|
|
9401
|
-
if (axios.isAxiosError(error)) {
|
|
9402
|
-
const axiosError = error;
|
|
9403
|
-
return {
|
|
9404
|
-
status: axiosError.response.status,
|
|
9405
|
-
body: axiosError.response.data,
|
|
9406
|
-
headers: { ETag: axiosError.response.headers["etag"] }
|
|
9407
|
-
};
|
|
9408
|
-
} else throw error;
|
|
9409
|
-
}
|
|
9410
|
-
};
|
|
9411
|
-
ExtractNumber(str) {
|
|
9412
|
-
if (typeof str !== "string") return null;
|
|
9413
|
-
const match = str.match(/^\s*(?:W\/\s*)?"\s*([\d.]+)\s*"$/i);
|
|
9414
|
-
return match ? Number(match[1]) : null;
|
|
9415
|
-
}
|
|
9416
|
-
DeleteResource = async (resourceType, resourceId, versionIdETag) => {
|
|
9417
|
-
try {
|
|
9418
|
-
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9419
|
-
const retVal = await this.#InvokeResourceAPI(url, "delete", versionIdETag, null);
|
|
9420
|
-
if (retVal) return {
|
|
9421
|
-
status: retVal.status,
|
|
9422
|
-
body: retVal.data
|
|
9423
|
-
};
|
|
9424
|
-
else throw new Error(`FhirRESTClient:DeleteResource(): No response from #InvokeResourceAPI`);
|
|
9425
|
-
} catch (error) {
|
|
9426
|
-
if (axios.isAxiosError(error)) {
|
|
9427
|
-
const axiosError = error;
|
|
9428
|
-
const versionNumber = this.ExtractNumber(versionIdETag) + 1;
|
|
9429
|
-
return {
|
|
9430
|
-
status: axiosError.response.status,
|
|
9431
|
-
body: axiosError.response.data,
|
|
9432
|
-
headers: { ETag: `W/"${versionNumber}"` }
|
|
9433
|
-
};
|
|
9434
|
-
} else throw error;
|
|
9435
|
-
}
|
|
9436
|
-
};
|
|
9437
|
-
GetMetadata = async () => {
|
|
9438
|
-
try {
|
|
9439
|
-
const resourceUrl = `${this.BaseUrl()}/metadata`;
|
|
9440
|
-
const retVal = await this.#InvokeResourceAPI(resourceUrl, "get", null, null);
|
|
9441
|
-
if (retVal) return {
|
|
9442
|
-
status: retVal.status,
|
|
9443
|
-
body: retVal.data
|
|
9444
|
-
};
|
|
9445
|
-
else throw new Error(`FhirRESTClient:GetMetadata(): No response from #InvokeResourceAPI`);
|
|
9446
|
-
} catch (error) {
|
|
9447
|
-
this.LogError("GetMetadata", error);
|
|
9448
|
-
throw error;
|
|
9449
|
-
}
|
|
9450
|
-
};
|
|
9451
|
-
GetLatency = async (params) => {
|
|
9452
|
-
try {
|
|
9453
|
-
const url = `${this.BaseUrl()}/latency`;
|
|
9454
|
-
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9455
|
-
if (retVal) return {
|
|
9456
|
-
status: retVal.status,
|
|
9457
|
-
body: retVal.data
|
|
9458
|
-
};
|
|
9459
|
-
else throw new Error(`FhirRESTClient:GetLatency(): No response from #InvokeResourceAPI`);
|
|
9460
|
-
} catch (error) {
|
|
9461
|
-
this.LogError("GetLatency", error);
|
|
9462
|
-
throw error;
|
|
9463
|
-
}
|
|
9464
|
-
};
|
|
9465
|
-
GenericSearchTesting = async (resourceType, params) => {
|
|
9466
|
-
try {
|
|
9467
|
-
const retVal = await this.#InvokeResourceAPI(`${this.BaseUrl()}/${resourceType}/_genericSearchTesting`, "post", null, params);
|
|
9468
|
-
if (retVal) return {
|
|
9469
|
-
status: retVal.status,
|
|
9470
|
-
body: retVal.data
|
|
9471
|
-
};
|
|
9472
|
-
else throw new Error(`FhirRESTClient:GenericSearchTesting(): No response from #InvokeResourceAPI`);
|
|
9473
|
-
} catch (error) {
|
|
9474
|
-
this.LogError("GenericSearchTesting", error);
|
|
9475
|
-
throw error;
|
|
9476
|
-
}
|
|
9477
|
-
};
|
|
9478
|
-
};
|
|
9479
|
-
//#endregion
|
|
9480
9161
|
//#region node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
9481
9162
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
9482
9163
|
var wrapAnsi16 = (offset = 0) => (code) => `\u001B[${code + offset}m`;
|
|
@@ -9767,50 +9448,315 @@ var proto = Object.defineProperties(() => {}, {
|
|
|
9767
9448
|
set(level) {
|
|
9768
9449
|
this[GENERATOR].level = level;
|
|
9769
9450
|
}
|
|
9770
|
-
}
|
|
9771
|
-
});
|
|
9772
|
-
var createStyler = (open, close, parent) => {
|
|
9773
|
-
let openAll;
|
|
9774
|
-
let closeAll;
|
|
9775
|
-
if (parent === void 0) {
|
|
9776
|
-
openAll = open;
|
|
9777
|
-
closeAll = close;
|
|
9778
|
-
} else {
|
|
9779
|
-
openAll = parent.openAll + open;
|
|
9780
|
-
closeAll = close + parent.closeAll;
|
|
9781
|
-
}
|
|
9782
|
-
return {
|
|
9783
|
-
open,
|
|
9784
|
-
close,
|
|
9785
|
-
openAll,
|
|
9786
|
-
closeAll,
|
|
9787
|
-
parent
|
|
9451
|
+
}
|
|
9452
|
+
});
|
|
9453
|
+
var createStyler = (open, close, parent) => {
|
|
9454
|
+
let openAll;
|
|
9455
|
+
let closeAll;
|
|
9456
|
+
if (parent === void 0) {
|
|
9457
|
+
openAll = open;
|
|
9458
|
+
closeAll = close;
|
|
9459
|
+
} else {
|
|
9460
|
+
openAll = parent.openAll + open;
|
|
9461
|
+
closeAll = close + parent.closeAll;
|
|
9462
|
+
}
|
|
9463
|
+
return {
|
|
9464
|
+
open,
|
|
9465
|
+
close,
|
|
9466
|
+
openAll,
|
|
9467
|
+
closeAll,
|
|
9468
|
+
parent
|
|
9469
|
+
};
|
|
9470
|
+
};
|
|
9471
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
9472
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
9473
|
+
Object.setPrototypeOf(builder, proto);
|
|
9474
|
+
builder[GENERATOR] = self;
|
|
9475
|
+
builder[STYLER] = _styler;
|
|
9476
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
9477
|
+
return builder;
|
|
9478
|
+
};
|
|
9479
|
+
var applyStyle = (self, string) => {
|
|
9480
|
+
if (self.level <= 0 || !string) return self[IS_EMPTY] ? "" : string;
|
|
9481
|
+
let styler = self[STYLER];
|
|
9482
|
+
if (styler === void 0) return string;
|
|
9483
|
+
const { openAll, closeAll } = styler;
|
|
9484
|
+
if (string.includes("\x1B")) while (styler !== void 0) {
|
|
9485
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
9486
|
+
styler = styler.parent;
|
|
9487
|
+
}
|
|
9488
|
+
const lfIndex = string.indexOf("\n");
|
|
9489
|
+
if (lfIndex !== -1) string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
9490
|
+
return openAll + string + closeAll;
|
|
9491
|
+
};
|
|
9492
|
+
Object.defineProperties(createChalk.prototype, styles);
|
|
9493
|
+
var chalk = createChalk();
|
|
9494
|
+
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
9495
|
+
//#endregion
|
|
9496
|
+
//#region src/cv2/fhirRESTClient.ts
|
|
9497
|
+
var FhirRESTClient = class {
|
|
9498
|
+
#options;
|
|
9499
|
+
constructor(options) {
|
|
9500
|
+
this.#options = options;
|
|
9501
|
+
}
|
|
9502
|
+
BaseUrl() {
|
|
9503
|
+
return `${this.#options.endpoint}:${this.#options.stsfhirport}${this.#options.stsfhirapiroot}`;
|
|
9504
|
+
}
|
|
9505
|
+
HandleError = (error) => {
|
|
9506
|
+
this.#options.logger.error(chalk.red(`HandleError(): Error: [${error}]`));
|
|
9507
|
+
if (axios.isAxiosError(error)) {
|
|
9508
|
+
const axiosError = error;
|
|
9509
|
+
if (axiosError.response) {
|
|
9510
|
+
this.#options.logger.error(chalk.red(`AXIOS Error Response.Status = [${axiosError.response.status}]`));
|
|
9511
|
+
if (axiosError.response.headers) this.#options.logger.error(chalk.red(` headers: [${JSON.stringify(axiosError.response.headers)}]`));
|
|
9512
|
+
if (axiosError.response.data) this.#options.logger.error(chalk.red(` data: [${JSON.stringify(axiosError.response.data)}]`));
|
|
9513
|
+
try {
|
|
9514
|
+
if (axiosError.response.config) this.#options.logger.error(chalk.red(` config: [${JSON.stringify(axiosError.response.config)}]`));
|
|
9515
|
+
} catch (innererror) {
|
|
9516
|
+
this.#options.logger.error(chalk.red(` could not get response config, error: [${innererror}]`));
|
|
9517
|
+
}
|
|
9518
|
+
} else this.#options.logger.error(chalk.red(`AXIOS Error = [${axiosError}]`));
|
|
9519
|
+
}
|
|
9520
|
+
};
|
|
9521
|
+
LogError = (method, error) => {
|
|
9522
|
+
this.#options.logger.error(`FhirRESTClient:${method}(): Error: [${error}]`);
|
|
9523
|
+
this.#options.logger.error(error);
|
|
9524
|
+
console.error(error);
|
|
9525
|
+
this.HandleError(error);
|
|
9526
|
+
process.exit(0);
|
|
9527
|
+
};
|
|
9528
|
+
LogWarning = (method, message) => {
|
|
9529
|
+
this.#options.logger.warn(`FhirRESTClient:${method}(): Warn: [${message}]`);
|
|
9530
|
+
};
|
|
9531
|
+
/**
|
|
9532
|
+
*
|
|
9533
|
+
* @param url
|
|
9534
|
+
* @param httpVerb
|
|
9535
|
+
* @param versionIdETag Format "W/<versionNumber", e.g. "W/3"
|
|
9536
|
+
* @param resource
|
|
9537
|
+
* @returns
|
|
9538
|
+
*/
|
|
9539
|
+
#InvokeResourceAPI = async (url, httpVerb, versionIdETag, resource, contentType) => {
|
|
9540
|
+
const accessToken = await this.#options.GetAccessToken();
|
|
9541
|
+
let requestConfig;
|
|
9542
|
+
const headers = {
|
|
9543
|
+
Prefer: "return=representation",
|
|
9544
|
+
Accept: "application/fhir+json"
|
|
9545
|
+
};
|
|
9546
|
+
if (versionIdETag && versionIdETag !== "") headers["If-Match"] = versionIdETag;
|
|
9547
|
+
if (httpVerb === "patch") {
|
|
9548
|
+
requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationMergePatchAndJsonContentTypeHeaders();
|
|
9549
|
+
if (resource && contentType) {
|
|
9550
|
+
if (contentType.localeCompare("application/merge-patch+json") === 0) requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationMergePatchAndJsonContentTypeHeaders();
|
|
9551
|
+
else if (contentType.localeCompare("application/json-patch+json") === 0) requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationJsonPatchAndJsonContentTypeHeaders();
|
|
9552
|
+
}
|
|
9553
|
+
} else requestConfig = new STSAxiosConfig(url, httpVerb).withApplicationFhirAndJsonContentTypeHeaders();
|
|
9554
|
+
requestConfig.withAuthHeaders(accessToken, this.#options.user).withHeaders(headers);
|
|
9555
|
+
if (resource) requestConfig.withData(resource);
|
|
9556
|
+
if (this.#options.agentManager) requestConfig.withAgentManager(this.#options.agentManager);
|
|
9557
|
+
return await axios(requestConfig.config);
|
|
9558
|
+
};
|
|
9559
|
+
ProcessBatchOrTransactionResources = async (bundle) => {
|
|
9560
|
+
try {
|
|
9561
|
+
let url = `${this.BaseUrl()}`;
|
|
9562
|
+
const retVal = await this.#InvokeResourceAPI(url, "post", null, bundle);
|
|
9563
|
+
if (retVal) return {
|
|
9564
|
+
status: retVal.status,
|
|
9565
|
+
body: retVal.data
|
|
9566
|
+
};
|
|
9567
|
+
else throw new Error(`FhirRESTClient:ProcessBatchOrTransactionResources(): No response from #InvokeResourceAPI`);
|
|
9568
|
+
} catch (error) {
|
|
9569
|
+
this.LogError("ProcessBatchOrTransactionResources", error);
|
|
9570
|
+
throw error;
|
|
9571
|
+
}
|
|
9572
|
+
};
|
|
9573
|
+
GetResources = async (searchUrl) => {
|
|
9574
|
+
try {
|
|
9575
|
+
const retVal = await this.#InvokeResourceAPI(searchUrl.toString(), "get", null, null);
|
|
9576
|
+
if (retVal) return {
|
|
9577
|
+
status: retVal.status,
|
|
9578
|
+
body: retVal.data
|
|
9579
|
+
};
|
|
9580
|
+
else throw new Error(`FhirRESTClient:GetResources(): No response from #InvokeResourceAPI`);
|
|
9581
|
+
} catch (error) {
|
|
9582
|
+
this.LogError("GetResources", error);
|
|
9583
|
+
throw error;
|
|
9584
|
+
}
|
|
9585
|
+
};
|
|
9586
|
+
GetHistoryFhirResources = async (searchUrl) => {
|
|
9587
|
+
try {
|
|
9588
|
+
return await this.GetResources(searchUrl);
|
|
9589
|
+
} catch (error) {
|
|
9590
|
+
this.LogError("GetHistoryFhirResources", error);
|
|
9591
|
+
throw error;
|
|
9592
|
+
}
|
|
9593
|
+
};
|
|
9594
|
+
GetHistoryFhirResource = async (searchUrl) => {
|
|
9595
|
+
try {
|
|
9596
|
+
return await this.GetResources(searchUrl);
|
|
9597
|
+
} catch (error) {
|
|
9598
|
+
this.LogError("GetHistoryFhirResource", error);
|
|
9599
|
+
throw error;
|
|
9600
|
+
}
|
|
9601
|
+
};
|
|
9602
|
+
GetAllFhirResources = async (searchUrl) => {
|
|
9603
|
+
try {
|
|
9604
|
+
return await this.GetResources(searchUrl);
|
|
9605
|
+
} catch (error) {
|
|
9606
|
+
this.LogError("GetAllFhirResources", error);
|
|
9607
|
+
throw error;
|
|
9608
|
+
}
|
|
9788
9609
|
};
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9610
|
+
GetResource = async (resourceType, resourceId) => {
|
|
9611
|
+
try {
|
|
9612
|
+
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9613
|
+
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9614
|
+
if (retVal) return {
|
|
9615
|
+
status: retVal.status,
|
|
9616
|
+
body: retVal.data
|
|
9617
|
+
};
|
|
9618
|
+
else throw new Error(`FhirRESTClient:GetResource(): No response from #InvokeResourceAPI`);
|
|
9619
|
+
} catch (error) {
|
|
9620
|
+
if (axios.isAxiosError(error)) {
|
|
9621
|
+
const axiosError = error;
|
|
9622
|
+
return {
|
|
9623
|
+
status: axiosError.response.status,
|
|
9624
|
+
body: axiosError.response.data,
|
|
9625
|
+
headers: { ETag: axiosError.response.headers["etag"] }
|
|
9626
|
+
};
|
|
9627
|
+
} else throw error;
|
|
9628
|
+
}
|
|
9629
|
+
};
|
|
9630
|
+
PutResource = async (resourceType, domainResource, versionIdETag) => {
|
|
9631
|
+
try {
|
|
9632
|
+
let url = `${`${this.BaseUrl()}/${resourceType}`}/${domainResource.id}`;
|
|
9633
|
+
const retVal = await this.#InvokeResourceAPI(url, "put", versionIdETag, domainResource);
|
|
9634
|
+
if (retVal) return {
|
|
9635
|
+
status: retVal.status,
|
|
9636
|
+
body: retVal.data
|
|
9637
|
+
};
|
|
9638
|
+
else throw new Error(`FhirRESTClient:PutResource(): No response from #InvokeResourceAPI`);
|
|
9639
|
+
} catch (error) {
|
|
9640
|
+
this.LogError("PutResource", error);
|
|
9641
|
+
throw error;
|
|
9642
|
+
}
|
|
9643
|
+
};
|
|
9644
|
+
PatchResource = async (resourceType, resourceId, domainResource, contentType, versionIdETag) => {
|
|
9645
|
+
try {
|
|
9646
|
+
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9647
|
+
const retVal = await this.#InvokeResourceAPI(url, "patch", versionIdETag, domainResource, contentType);
|
|
9648
|
+
if (retVal) return {
|
|
9649
|
+
status: retVal.status,
|
|
9650
|
+
body: retVal.data
|
|
9651
|
+
};
|
|
9652
|
+
else throw new Error(`FhirRESTClient:PatchResource(): No response from #InvokeResourceAPI`);
|
|
9653
|
+
} catch (error) {
|
|
9654
|
+
this.LogError("PatchResource", error);
|
|
9655
|
+
throw error;
|
|
9656
|
+
}
|
|
9657
|
+
};
|
|
9658
|
+
PostResource = async (resourceType, domainResource) => {
|
|
9659
|
+
try {
|
|
9660
|
+
const url = `${this.BaseUrl()}/${resourceType}`;
|
|
9661
|
+
const retVal = await this.#InvokeResourceAPI(url, "post", null, domainResource);
|
|
9662
|
+
if (retVal) return {
|
|
9663
|
+
status: retVal.status,
|
|
9664
|
+
body: retVal.data
|
|
9665
|
+
};
|
|
9666
|
+
else throw new Error(`FhirRESTClient:PostResource(): No response from #InvokeResourceAPI`);
|
|
9667
|
+
} catch (error) {
|
|
9668
|
+
this.LogError("PostResource", error);
|
|
9669
|
+
throw error;
|
|
9670
|
+
}
|
|
9671
|
+
};
|
|
9672
|
+
GetHistoryInstanceFhirResource = async (resourceType, resourceId, versionId) => {
|
|
9673
|
+
try {
|
|
9674
|
+
const url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}/_history/${versionId.toString()}`;
|
|
9675
|
+
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9676
|
+
if (retVal) return {
|
|
9677
|
+
status: retVal.status,
|
|
9678
|
+
body: retVal.data
|
|
9679
|
+
};
|
|
9680
|
+
else throw new Error(`FhirRESTClient:GetHistoryInstanceFhirResource(): No response from #InvokeResourceAPI`);
|
|
9681
|
+
} catch (error) {
|
|
9682
|
+
if (axios.isAxiosError(error)) {
|
|
9683
|
+
const axiosError = error;
|
|
9684
|
+
return {
|
|
9685
|
+
status: axiosError.response.status,
|
|
9686
|
+
body: axiosError.response.data,
|
|
9687
|
+
headers: { ETag: axiosError.response.headers["etag"] }
|
|
9688
|
+
};
|
|
9689
|
+
} else throw error;
|
|
9690
|
+
}
|
|
9691
|
+
};
|
|
9692
|
+
ExtractNumber(str) {
|
|
9693
|
+
if (typeof str !== "string") return null;
|
|
9694
|
+
const match = str.match(/^\s*(?:W\/\s*)?"\s*([\d.]+)\s*"$/i);
|
|
9695
|
+
return match ? Number(match[1]) : null;
|
|
9806
9696
|
}
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9697
|
+
DeleteResource = async (resourceType, resourceId, versionIdETag) => {
|
|
9698
|
+
try {
|
|
9699
|
+
let url = `${`${this.BaseUrl()}/${resourceType}`}/${resourceId}`;
|
|
9700
|
+
const retVal = await this.#InvokeResourceAPI(url, "delete", versionIdETag, null);
|
|
9701
|
+
if (retVal) return {
|
|
9702
|
+
status: retVal.status,
|
|
9703
|
+
body: retVal.data
|
|
9704
|
+
};
|
|
9705
|
+
else throw new Error(`FhirRESTClient:DeleteResource(): No response from #InvokeResourceAPI`);
|
|
9706
|
+
} catch (error) {
|
|
9707
|
+
if (axios.isAxiosError(error)) {
|
|
9708
|
+
const axiosError = error;
|
|
9709
|
+
const versionNumber = this.ExtractNumber(versionIdETag) + 1;
|
|
9710
|
+
return {
|
|
9711
|
+
status: axiosError.response.status,
|
|
9712
|
+
body: axiosError.response.data,
|
|
9713
|
+
headers: { ETag: `W/"${versionNumber}"` }
|
|
9714
|
+
};
|
|
9715
|
+
} else throw error;
|
|
9716
|
+
}
|
|
9717
|
+
};
|
|
9718
|
+
GetMetadata = async () => {
|
|
9719
|
+
try {
|
|
9720
|
+
const resourceUrl = `${this.BaseUrl()}/metadata`;
|
|
9721
|
+
const retVal = await this.#InvokeResourceAPI(resourceUrl, "get", null, null);
|
|
9722
|
+
if (retVal) return {
|
|
9723
|
+
status: retVal.status,
|
|
9724
|
+
body: retVal.data
|
|
9725
|
+
};
|
|
9726
|
+
else throw new Error(`FhirRESTClient:GetMetadata(): No response from #InvokeResourceAPI`);
|
|
9727
|
+
} catch (error) {
|
|
9728
|
+
this.LogError("GetMetadata", error);
|
|
9729
|
+
throw error;
|
|
9730
|
+
}
|
|
9731
|
+
};
|
|
9732
|
+
GetLatency = async (params) => {
|
|
9733
|
+
try {
|
|
9734
|
+
const url = `${this.BaseUrl()}/latency`;
|
|
9735
|
+
const retVal = await this.#InvokeResourceAPI(url, "get", null, null);
|
|
9736
|
+
if (retVal) return {
|
|
9737
|
+
status: retVal.status,
|
|
9738
|
+
body: retVal.data
|
|
9739
|
+
};
|
|
9740
|
+
else throw new Error(`FhirRESTClient:GetLatency(): No response from #InvokeResourceAPI`);
|
|
9741
|
+
} catch (error) {
|
|
9742
|
+
this.LogError("GetLatency", error);
|
|
9743
|
+
throw error;
|
|
9744
|
+
}
|
|
9745
|
+
};
|
|
9746
|
+
GenericSearchTesting = async (resourceType, params) => {
|
|
9747
|
+
try {
|
|
9748
|
+
const retVal = await this.#InvokeResourceAPI(`${this.BaseUrl()}/${resourceType}/_genericSearchTesting`, "post", null, params);
|
|
9749
|
+
if (retVal) return {
|
|
9750
|
+
status: retVal.status,
|
|
9751
|
+
body: retVal.data
|
|
9752
|
+
};
|
|
9753
|
+
else throw new Error(`FhirRESTClient:GenericSearchTesting(): No response from #InvokeResourceAPI`);
|
|
9754
|
+
} catch (error) {
|
|
9755
|
+
this.LogError("GenericSearchTesting", error);
|
|
9756
|
+
throw error;
|
|
9757
|
+
}
|
|
9758
|
+
};
|
|
9810
9759
|
};
|
|
9811
|
-
Object.defineProperties(createChalk.prototype, styles);
|
|
9812
|
-
var chalk = createChalk();
|
|
9813
|
-
createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
9814
9760
|
//#endregion
|
|
9815
9761
|
//#region node_modules/@nsshunt/stssocketioutils/dist/tiny-emitter-DcZ69ZvJ.js
|
|
9816
9762
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
@@ -13743,6 +13689,68 @@ var FhirSocketClientIndividual = class extends FhirSocketClient {
|
|
|
13743
13689
|
};
|
|
13744
13690
|
};
|
|
13745
13691
|
//#endregion
|
|
13692
|
+
//#region src/retryAxiosClient.ts
|
|
13693
|
+
function sleep(ms) {
|
|
13694
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13695
|
+
}
|
|
13696
|
+
function getJitteredDelay(base, jitter) {
|
|
13697
|
+
return base + Math.floor(Math.random() * jitter);
|
|
13698
|
+
}
|
|
13699
|
+
function createRetryAxiosClient(retryConfig) {
|
|
13700
|
+
const { maxRetries = 3, retryDelayMs = 300, retryJitterMs = 100, retryMethods = [
|
|
13701
|
+
"get",
|
|
13702
|
+
"head",
|
|
13703
|
+
"put",
|
|
13704
|
+
"delete",
|
|
13705
|
+
"options"
|
|
13706
|
+
], retryStatusCodes = [
|
|
13707
|
+
408,
|
|
13708
|
+
429,
|
|
13709
|
+
500,
|
|
13710
|
+
502,
|
|
13711
|
+
503,
|
|
13712
|
+
504
|
|
13713
|
+
], retryErrorCodes = [
|
|
13714
|
+
"ECONNRESET",
|
|
13715
|
+
"ETIMEDOUT",
|
|
13716
|
+
"EAI_AGAIN",
|
|
13717
|
+
"ECONNREFUSED",
|
|
13718
|
+
"ENOTFOUND",
|
|
13719
|
+
"EHOSTUNREACH",
|
|
13720
|
+
"EPIPE"
|
|
13721
|
+
], maxRetryDurationMs = 1e4, onRetryAttempt, stsAxiosConfig } = retryConfig || {};
|
|
13722
|
+
const instance = axios.create();
|
|
13723
|
+
instance.interceptors.request.use((config) => {
|
|
13724
|
+
const retryConfig = config;
|
|
13725
|
+
if (!retryConfig.metadata) retryConfig.metadata = {
|
|
13726
|
+
startTime: Date.now(),
|
|
13727
|
+
__retryCount: 0
|
|
13728
|
+
};
|
|
13729
|
+
if (stsAxiosConfig) Object.assign(config, stsAxiosConfig.config);
|
|
13730
|
+
return config;
|
|
13731
|
+
});
|
|
13732
|
+
instance.interceptors.response.use((response) => response, async (error) => {
|
|
13733
|
+
const config = error.config;
|
|
13734
|
+
if (!config || !config.method || !config.metadata) return Promise.reject(error);
|
|
13735
|
+
const elapsed = Date.now() - config.metadata.startTime;
|
|
13736
|
+
const method = config.method.toLowerCase();
|
|
13737
|
+
const status = error.response?.status;
|
|
13738
|
+
const code = error.code ?? "";
|
|
13739
|
+
const isRetryableMethod = retryMethods.includes(method);
|
|
13740
|
+
const isRetryableStatus = retryStatusCodes.includes(status ?? 0);
|
|
13741
|
+
const isRetryableCode = retryErrorCodes.includes(code);
|
|
13742
|
+
if (isRetryableMethod && (isRetryableStatus || isRetryableCode) && config.metadata.__retryCount < maxRetries && elapsed < maxRetryDurationMs) {
|
|
13743
|
+
config.metadata.__retryCount += 1;
|
|
13744
|
+
const delayMs = getJitteredDelay(retryDelayMs * Math.pow(2, config.metadata.__retryCount - 1), retryJitterMs);
|
|
13745
|
+
onRetryAttempt?.(config.metadata.__retryCount, error, delayMs);
|
|
13746
|
+
await sleep(delayMs);
|
|
13747
|
+
return instance(config);
|
|
13748
|
+
}
|
|
13749
|
+
return Promise.reject(error);
|
|
13750
|
+
});
|
|
13751
|
+
return instance;
|
|
13752
|
+
}
|
|
13753
|
+
//#endregion
|
|
13746
13754
|
export { FhirRESTClient, FhirRouteError, FhirSocketClient, FhirSocketClientAllInOne, FhirSocketClientIndividual, GetAboveHierarchy, STSFhirValidator, createRetryAxiosClient, fhirRT, fhirSP, fhirSPRefOnly, getBaseResource, isAbsoluteUrl, normalizeUri, splitUnderBase };
|
|
13747
13755
|
|
|
13748
13756
|
//# sourceMappingURL=stsfhirclient.mjs.map
|