@openmrs/esm-utils 6.3.1-pre.2961 → 6.3.1-pre.2986
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/.swcrc +16 -0
- package/.turbo/turbo-build.log +3 -17
- package/dist/age-helpers.d.ts +12 -0
- package/dist/age-helpers.js +86 -0
- package/dist/dates/date-util.d.ts +144 -0
- package/dist/dates/date-util.js +335 -0
- package/dist/dates/index.d.ts +1 -0
- package/dist/dates/index.js +1 -0
- package/dist/get-locale.d.ts +5 -0
- package/dist/get-locale.js +13 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/is-online.d.ts +1 -0
- package/dist/is-online.js +3 -0
- package/dist/patient-helpers.d.ts +42 -0
- package/dist/patient-helpers.js +78 -0
- package/dist/retry.d.ts +38 -0
- package/dist/retry.js +45 -0
- package/dist/shallowEqual.d.ts +12 -0
- package/dist/shallowEqual.js +36 -0
- package/dist/storage.d.ts +10 -0
- package/dist/storage.js +15 -0
- package/dist/test-helpers.d.ts +12 -0
- package/dist/test-helpers.js +27 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +21 -0
- package/package.json +34 -22
- package/src/age-helpers.test.ts +1 -0
- package/src/age-helpers.ts +1 -1
- package/src/dates/date-util.test.ts +4 -3
- package/src/dates/date-util.ts +4 -4
- package/src/patient-helpers.test.ts +2 -1
- package/src/test-helpers.ts +10 -5
- package/src/version.test.ts +4 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +3 -23
- package/vitest.config.ts +8 -0
- package/dist/openmrs-esm-utils.js +0 -3
- package/dist/openmrs-esm-utils.js.LICENSE.txt +0 -7
- package/dist/openmrs-esm-utils.js.map +0 -1
- package/jest.config.js +0 -13
- package/webpack.config.js +0 -42
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** @module @category Utility */
|
|
2
|
+
/// <reference types="fhir" />
|
|
3
|
+
import { type NameUse } from '@openmrs/esm-globals';
|
|
4
|
+
/**
|
|
5
|
+
* Gets the formatted display name for a patient.
|
|
6
|
+
*
|
|
7
|
+
* The display name will be taken from the patient's 'usual' name,
|
|
8
|
+
* or may fall back to the patient's 'official' name.
|
|
9
|
+
*
|
|
10
|
+
* @param patient The patient details in FHIR format.
|
|
11
|
+
* @returns The patient's display name or an empty string if name is not present.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getPatientName(patient: fhir.Patient): string;
|
|
14
|
+
/** @deprecated Use `getPatientName` */
|
|
15
|
+
export declare function displayName(patient: fhir.Patient): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get a formatted display string for an FHIR name.
|
|
18
|
+
* @param name The name to be formatted.
|
|
19
|
+
* @returns The formatted display name or an empty string if name is undefined.
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatPatientName(name: fhir.HumanName | undefined): string;
|
|
22
|
+
/** @deprecated Use `formatPatientName` */
|
|
23
|
+
export declare function formattedName(name: fhir.HumanName | undefined): string;
|
|
24
|
+
/**
|
|
25
|
+
* Select the preferred name from the collection of names associated with a patient.
|
|
26
|
+
*
|
|
27
|
+
* Names may be specified with a usage such as 'usual', 'official', 'nickname', 'maiden', etc.
|
|
28
|
+
* A name with no usage specified is treated as the 'usual' name.
|
|
29
|
+
*
|
|
30
|
+
* The chosen name will be selected according to the priority order of `preferredNames`,
|
|
31
|
+
* @example
|
|
32
|
+
* // normal use case; prefer usual name, fallback to official name
|
|
33
|
+
* displayNameByUsage(patient, 'usual', 'official')
|
|
34
|
+
* @example
|
|
35
|
+
* // prefer usual name over nickname, fallback to official name
|
|
36
|
+
* displayNameByUsage(patient, 'usual', 'nickname', 'official')
|
|
37
|
+
*
|
|
38
|
+
* @param patient The patient from whom a name will be selected.
|
|
39
|
+
* @param preferredNames Optional ordered sequence of preferred name usages; defaults to 'usual' if not specified.
|
|
40
|
+
* @return the preferred name for the patient, or undefined if no acceptable name could be found.
|
|
41
|
+
*/
|
|
42
|
+
export declare function selectPreferredName(patient: fhir.Patient, ...preferredNames: NameUse[]): fhir.HumanName | undefined;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** @module @category Utility */ /**
|
|
2
|
+
* Gets the formatted display name for a patient.
|
|
3
|
+
*
|
|
4
|
+
* The display name will be taken from the patient's 'usual' name,
|
|
5
|
+
* or may fall back to the patient's 'official' name.
|
|
6
|
+
*
|
|
7
|
+
* @param patient The patient details in FHIR format.
|
|
8
|
+
* @returns The patient's display name or an empty string if name is not present.
|
|
9
|
+
*/ export function getPatientName(patient) {
|
|
10
|
+
const name = selectPreferredName(patient, 'usual', 'official');
|
|
11
|
+
return formatPatientName(name);
|
|
12
|
+
}
|
|
13
|
+
/** @deprecated Use `getPatientName` */ export function displayName(patient) {
|
|
14
|
+
return getPatientName(patient);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get a formatted display string for an FHIR name.
|
|
18
|
+
* @param name The name to be formatted.
|
|
19
|
+
* @returns The formatted display name or an empty string if name is undefined.
|
|
20
|
+
*/ export function formatPatientName(name) {
|
|
21
|
+
if (name) return name.text ?? defaultFormat(name);
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
/** @deprecated Use `formatPatientName` */ export function formattedName(name) {
|
|
25
|
+
return formatPatientName(name);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Select the preferred name from the collection of names associated with a patient.
|
|
29
|
+
*
|
|
30
|
+
* Names may be specified with a usage such as 'usual', 'official', 'nickname', 'maiden', etc.
|
|
31
|
+
* A name with no usage specified is treated as the 'usual' name.
|
|
32
|
+
*
|
|
33
|
+
* The chosen name will be selected according to the priority order of `preferredNames`,
|
|
34
|
+
* @example
|
|
35
|
+
* // normal use case; prefer usual name, fallback to official name
|
|
36
|
+
* displayNameByUsage(patient, 'usual', 'official')
|
|
37
|
+
* @example
|
|
38
|
+
* // prefer usual name over nickname, fallback to official name
|
|
39
|
+
* displayNameByUsage(patient, 'usual', 'nickname', 'official')
|
|
40
|
+
*
|
|
41
|
+
* @param patient The patient from whom a name will be selected.
|
|
42
|
+
* @param preferredNames Optional ordered sequence of preferred name usages; defaults to 'usual' if not specified.
|
|
43
|
+
* @return the preferred name for the patient, or undefined if no acceptable name could be found.
|
|
44
|
+
*/ export function selectPreferredName(patient, ...preferredNames) {
|
|
45
|
+
if (preferredNames.length == 0) {
|
|
46
|
+
preferredNames = [
|
|
47
|
+
'usual'
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
for (const usage of preferredNames){
|
|
51
|
+
const name = patient.name?.find((name)=>nameUsageMatches(name, usage));
|
|
52
|
+
if (name) {
|
|
53
|
+
return name;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generate a display name by concatenating forenames and surname.
|
|
60
|
+
* @param name the person's name.
|
|
61
|
+
* @returns the person's name as a string.
|
|
62
|
+
*/ function defaultFormat(name) {
|
|
63
|
+
const forenames = name.given ?? [];
|
|
64
|
+
const names = name.family ? forenames.concat(name.family) : forenames;
|
|
65
|
+
return names.join(' ');
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Determine whether the usage of a given name matches the given NameUse.
|
|
69
|
+
*
|
|
70
|
+
* A name with no usage is treated as the 'usual' name.
|
|
71
|
+
*
|
|
72
|
+
* @param name the name to test.
|
|
73
|
+
* @param usage the NameUse to test for.
|
|
74
|
+
*/ function nameUsageMatches(name, usage) {
|
|
75
|
+
if (!name.use) // a name with no usage is treated as 'usual'
|
|
76
|
+
return usage === 'usual';
|
|
77
|
+
return name.use === usage;
|
|
78
|
+
}
|
package/dist/retry.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @module @category Utility */
|
|
2
|
+
/**
|
|
3
|
+
* Options for configuring the behavior of the {@link retry} function.
|
|
4
|
+
*/
|
|
5
|
+
export interface RetryOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Determines whether the retry function should retry executing the function after it failed
|
|
8
|
+
* with an error on the current attempt.
|
|
9
|
+
* @param attempt The current (zero-based) retry attempt. `0` indicates the initial attempt.
|
|
10
|
+
*/
|
|
11
|
+
shouldRetry?(attempt: number): any;
|
|
12
|
+
/**
|
|
13
|
+
* Calculates the next delay (in milliseconds) before a retry attempt.
|
|
14
|
+
* Returning a value for the inital attempt (`0`) delays the initial function invocation.
|
|
15
|
+
* @param attempt The current (zero-based) retry attempt. `0` indicates the initial attempt.
|
|
16
|
+
*/
|
|
17
|
+
getDelay?(attempt: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Called when invoking the function resulted in an error.
|
|
20
|
+
* Allows running side-effects on errors, e.g. logging.
|
|
21
|
+
* @param e The error thrown by the function.
|
|
22
|
+
* @param attempt The current (zero-based) retry attempt. `0` indicates the initial attempt.
|
|
23
|
+
*/
|
|
24
|
+
onError?(e: any, attempt: number): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Executes the specified function and retries executing on failure with a custom backoff strategy
|
|
28
|
+
* defined by the options.
|
|
29
|
+
*
|
|
30
|
+
* If not configured otherwise, this function uses the following default options:
|
|
31
|
+
* * Retries 5 times beyond the initial attempt.
|
|
32
|
+
* * Uses an exponential backoff starting with an initial delay of 1000ms.
|
|
33
|
+
* @param fn The function to be executed and retried on failure.
|
|
34
|
+
* @param options Additional options which configure the retry behavior.
|
|
35
|
+
* @returns The result of successfully executing `fn`.
|
|
36
|
+
* @throws Rethrows the final error of running `fn` when the function stops retrying.
|
|
37
|
+
*/
|
|
38
|
+
export declare function retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
package/dist/retry.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** @module @category Utility */ /**
|
|
2
|
+
* Options for configuring the behavior of the {@link retry} function.
|
|
3
|
+
*/ /**
|
|
4
|
+
* Executes the specified function and retries executing on failure with a custom backoff strategy
|
|
5
|
+
* defined by the options.
|
|
6
|
+
*
|
|
7
|
+
* If not configured otherwise, this function uses the following default options:
|
|
8
|
+
* * Retries 5 times beyond the initial attempt.
|
|
9
|
+
* * Uses an exponential backoff starting with an initial delay of 1000ms.
|
|
10
|
+
* @param fn The function to be executed and retried on failure.
|
|
11
|
+
* @param options Additional options which configure the retry behavior.
|
|
12
|
+
* @returns The result of successfully executing `fn`.
|
|
13
|
+
* @throws Rethrows the final error of running `fn` when the function stops retrying.
|
|
14
|
+
*/ export async function retry(fn, options = {}) {
|
|
15
|
+
let { shouldRetry, getDelay, onError } = options;
|
|
16
|
+
shouldRetry = shouldRetry ?? ((attempt)=>limitAttempts(attempt, 5));
|
|
17
|
+
getDelay = getDelay ?? ((attempt)=>getExponentialDelay(attempt, 1000));
|
|
18
|
+
let attempt = 0;
|
|
19
|
+
let lastError = undefined;
|
|
20
|
+
do {
|
|
21
|
+
try {
|
|
22
|
+
await delay(getDelay(attempt));
|
|
23
|
+
return await fn();
|
|
24
|
+
} catch (e) {
|
|
25
|
+
onError?.(e, attempt);
|
|
26
|
+
lastError = e;
|
|
27
|
+
}
|
|
28
|
+
}while (shouldRetry(attempt++))
|
|
29
|
+
// If we reach this fn errored and shouldn't retry anymore. Simply rethrow the final error as
|
|
30
|
+
// a means of ending the retry process without a result.
|
|
31
|
+
throw lastError;
|
|
32
|
+
}
|
|
33
|
+
function limitAttempts(attempt, maxAttempts) {
|
|
34
|
+
return attempt <= maxAttempts;
|
|
35
|
+
}
|
|
36
|
+
function getExponentialDelay(attempt, startingDelay, initialDelay = false) {
|
|
37
|
+
const exponent = initialDelay ? attempt + 1 : attempt;
|
|
38
|
+
return startingDelay * Math.pow(2, exponent);
|
|
39
|
+
}
|
|
40
|
+
async function delay(ms) {
|
|
41
|
+
if (ms <= 0) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
return new Promise((res)=>setTimeout(res, ms));
|
|
45
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @module @category Utility */
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether two objects are equal, using a shallow comparison, similar to React.
|
|
4
|
+
*
|
|
5
|
+
* In essence, shallowEquals ensures two objects have the same own properties and that the values
|
|
6
|
+
* of these are equal (===) to each other.
|
|
7
|
+
*
|
|
8
|
+
* @param a The first value to compare
|
|
9
|
+
* @param b The second value to compare
|
|
10
|
+
* @returns true if the objects are shallowly equal to each other
|
|
11
|
+
*/
|
|
12
|
+
export declare function shallowEqual(a: unknown, b: unknown): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** @module @category Utility */ /**
|
|
2
|
+
* Checks whether two objects are equal, using a shallow comparison, similar to React.
|
|
3
|
+
*
|
|
4
|
+
* In essence, shallowEquals ensures two objects have the same own properties and that the values
|
|
5
|
+
* of these are equal (===) to each other.
|
|
6
|
+
*
|
|
7
|
+
* @param a The first value to compare
|
|
8
|
+
* @param b The second value to compare
|
|
9
|
+
* @returns true if the objects are shallowly equal to each other
|
|
10
|
+
*/ export function shallowEqual(a, b) {
|
|
11
|
+
if (a === b || Object.is(a, b)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (Array.isArray(a)) {
|
|
15
|
+
if (!Array.isArray(b)) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (a.length !== b.length) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
for(let i = 0; i < a.length; i++){
|
|
22
|
+
if (a[i] !== b[i]) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
} else if (Array.isArray(b)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const objAKeys = Object.getOwnPropertyNames(a);
|
|
34
|
+
const objBKeys = Object.getOwnPropertyNames(b);
|
|
35
|
+
return objAKeys.length === objBKeys.length && objAKeys.every((key)=>a[key] === b[key]);
|
|
36
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** @module @category Utility */
|
|
2
|
+
/**
|
|
3
|
+
* Simple utility function to determine if an object implementing the WebStorage API
|
|
4
|
+
* is actually available. Useful for testing the availability of `localStorage` or
|
|
5
|
+
* `sessionStorage`.
|
|
6
|
+
*
|
|
7
|
+
* @param storage The WebStorage API object to check. Defaults to `localStorage`.
|
|
8
|
+
* @returns True if the WebStorage API object is able to be accessed, false otherwise
|
|
9
|
+
*/
|
|
10
|
+
export declare function canAccessStorage(storage?: Storage): boolean;
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @module @category Utility */ /**
|
|
2
|
+
* Simple utility function to determine if an object implementing the WebStorage API
|
|
3
|
+
* is actually available. Useful for testing the availability of `localStorage` or
|
|
4
|
+
* `sessionStorage`.
|
|
5
|
+
*
|
|
6
|
+
* @param storage The WebStorage API object to check. Defaults to `localStorage`.
|
|
7
|
+
* @returns True if the WebStorage API object is able to be accessed, false otherwise
|
|
8
|
+
*/ export function canAccessStorage(storage = window.localStorage) {
|
|
9
|
+
try {
|
|
10
|
+
storage.getItem('test');
|
|
11
|
+
return true;
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** @module @category Utility */
|
|
2
|
+
/**
|
|
3
|
+
* Given a config schema, this returns an object like is returned by `useConfig`
|
|
4
|
+
* with all default values.
|
|
5
|
+
*
|
|
6
|
+
* This should be used in tests and not in production code.
|
|
7
|
+
*
|
|
8
|
+
* If all you need is the default values in your tests, these are returned by
|
|
9
|
+
* default from the `useConfig`/`getConfig` mock. This function is useful if you
|
|
10
|
+
* need to override some of the default values.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getDefaultsFromConfigSchema<T = Record<string, any>>(schema: Record<string | number | symbol, unknown>): T;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** @module @category Utility */ /**
|
|
2
|
+
* Given a config schema, this returns an object like is returned by `useConfig`
|
|
3
|
+
* with all default values.
|
|
4
|
+
*
|
|
5
|
+
* This should be used in tests and not in production code.
|
|
6
|
+
*
|
|
7
|
+
* If all you need is the default values in your tests, these are returned by
|
|
8
|
+
* default from the `useConfig`/`getConfig` mock. This function is useful if you
|
|
9
|
+
* need to override some of the default values.
|
|
10
|
+
*/ export function getDefaultsFromConfigSchema(schema) {
|
|
11
|
+
let tmp = {};
|
|
12
|
+
for (let k of Object.keys(schema)){
|
|
13
|
+
if (isOrdinaryObject(schema[k]) && schema[k].hasOwnProperty('_default')) {
|
|
14
|
+
tmp[k] = schema[k]._default;
|
|
15
|
+
} else if (k.startsWith('_')) {
|
|
16
|
+
continue;
|
|
17
|
+
} else if (isOrdinaryObject(schema[k])) {
|
|
18
|
+
tmp[k] = getDefaultsFromConfigSchema(schema[k]);
|
|
19
|
+
} else {
|
|
20
|
+
tmp[k] = schema[k];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return tmp;
|
|
24
|
+
}
|
|
25
|
+
function isOrdinaryObject(x) {
|
|
26
|
+
return !!x && x.constructor === Object;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isVersionSatisfied(requiredVersion: string, installedVersion: string): boolean;
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @module @category Utility */ import * as semver from "semver";
|
|
2
|
+
function normalizeOnlyVersion(version) {
|
|
3
|
+
const [major, minor, patch] = version.split('.');
|
|
4
|
+
return `${major}.${minor}.${patch}`;
|
|
5
|
+
}
|
|
6
|
+
function normalizeFullVersion(version) {
|
|
7
|
+
const idx = version.indexOf('-');
|
|
8
|
+
const prerelease = idx >= 0;
|
|
9
|
+
if (prerelease) {
|
|
10
|
+
const ver = normalizeOnlyVersion(version.slice(0, idx));
|
|
11
|
+
const pre = version.slice(idx + 1);
|
|
12
|
+
return `${ver}-${pre}`;
|
|
13
|
+
}
|
|
14
|
+
return normalizeOnlyVersion(version);
|
|
15
|
+
}
|
|
16
|
+
export function isVersionSatisfied(requiredVersion, installedVersion) {
|
|
17
|
+
const version = normalizeFullVersion(installedVersion);
|
|
18
|
+
return semver.satisfies(version, requiredVersion, {
|
|
19
|
+
includePrerelease: true
|
|
20
|
+
});
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-utils",
|
|
3
|
-
"version": "6.3.1-pre.
|
|
3
|
+
"version": "6.3.1-pre.2986",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Helper utilities for OpenMRS",
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"type": "module",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./src/index.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
8
15
|
"source": true,
|
|
9
16
|
"sideEffects": false,
|
|
10
17
|
"scripts": {
|
|
11
|
-
"test": "cross-env TZ=UTC
|
|
12
|
-
"test:watch": "cross-env TZ=UTC
|
|
13
|
-
"build": "
|
|
14
|
-
"build:development": "
|
|
15
|
-
"
|
|
16
|
-
"typescript": "tsc",
|
|
18
|
+
"test": "cross-env TZ=UTC vitest run --passWithNoTests",
|
|
19
|
+
"test:watch": "cross-env TZ=UTC vitest watch --passWithNoTests",
|
|
20
|
+
"build": "rimraf dist && concurrently \"swc --strip-leading-paths src -d dist\" \"tsc --project tsconfig.build.json\"",
|
|
21
|
+
"build:development": "rimraf dist && concurrently \"swc --strip-leading-paths src -d dist\" \"tsc --project tsconfig.build.json\"",
|
|
22
|
+
"typescript": "tsc --project tsconfig.build.json",
|
|
17
23
|
"lint": "eslint src --ext ts,tsx"
|
|
18
24
|
},
|
|
19
25
|
"keywords": [
|
|
@@ -38,13 +44,12 @@
|
|
|
38
44
|
"publishConfig": {
|
|
39
45
|
"access": "public"
|
|
40
46
|
},
|
|
41
|
-
"
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"rxjs": "^6.5.3"
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@formatjs/intl-durationformat": "^0.7.3",
|
|
49
|
+
"@internationalized/date": "^3.8.0",
|
|
50
|
+
"any-date-parser": "^2.0.3",
|
|
51
|
+
"lodash-es": "^4.17.21",
|
|
52
|
+
"semver": "7.3.2"
|
|
48
53
|
},
|
|
49
54
|
"peerDependencies": {
|
|
50
55
|
"@openmrs/esm-globals": "6.x",
|
|
@@ -52,12 +57,19 @@
|
|
|
52
57
|
"i18next": "21.x",
|
|
53
58
|
"rxjs": "6.x"
|
|
54
59
|
},
|
|
55
|
-
"
|
|
56
|
-
"@
|
|
57
|
-
"@
|
|
58
|
-
"
|
|
59
|
-
"lodash-es": "^4.17.
|
|
60
|
-
"semver": "7.3.
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@openmrs/esm-globals": "6.3.1-pre.2986",
|
|
62
|
+
"@swc/cli": "^0.7.7",
|
|
63
|
+
"@swc/core": "^1.11.29",
|
|
64
|
+
"@types/lodash-es": "^4.17.12",
|
|
65
|
+
"@types/semver": "^7.3.4",
|
|
66
|
+
"concurrently": "^9.1.2",
|
|
67
|
+
"cross-env": "^7.0.3",
|
|
68
|
+
"dayjs": "^1.11.13",
|
|
69
|
+
"happy-dom": "^17.4.7",
|
|
70
|
+
"rimraf": "^6.0.1",
|
|
71
|
+
"rxjs": "^6.5.3",
|
|
72
|
+
"vitest": "^3.1.4"
|
|
61
73
|
},
|
|
62
74
|
"stableVersion": "6.3.0"
|
|
63
75
|
}
|
package/src/age-helpers.test.ts
CHANGED
package/src/age-helpers.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { DurationFormat } from '@formatjs/intl-durationformat';
|
|
|
3
3
|
import { type DurationFormatOptions, type DurationInput } from '@formatjs/intl-durationformat/src/types';
|
|
4
4
|
import { attempt } from 'any-date-parser';
|
|
5
5
|
import dayjs from 'dayjs';
|
|
6
|
-
import objectSupport from 'dayjs/plugin/objectSupport';
|
|
6
|
+
import objectSupport from 'dayjs/plugin/objectSupport.js';
|
|
7
7
|
import { omit } from 'lodash-es';
|
|
8
8
|
import { getLocale } from './get-locale';
|
|
9
9
|
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import timezoneMock from 'timezone-mock';
|
|
4
|
+
import type { i18n } from 'i18next';
|
|
1
5
|
import {
|
|
2
6
|
toOmrsIsoString,
|
|
3
7
|
toDateObjectStrict,
|
|
@@ -8,9 +12,6 @@ import {
|
|
|
8
12
|
registerDefaultCalendar,
|
|
9
13
|
formatPartialDate,
|
|
10
14
|
} from './date-util';
|
|
11
|
-
import dayjs from 'dayjs';
|
|
12
|
-
import timezoneMock from 'timezone-mock';
|
|
13
|
-
import type { i18n } from 'i18next';
|
|
14
15
|
|
|
15
16
|
window.i18next = { language: 'en' } as i18n;
|
|
16
17
|
|
package/src/dates/date-util.ts
CHANGED
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
createCalendar,
|
|
11
11
|
toCalendar,
|
|
12
12
|
} from '@internationalized/date';
|
|
13
|
-
import { getLocale } from '@openmrs/esm-utils';
|
|
14
13
|
import { attempt } from 'any-date-parser';
|
|
15
14
|
import dayjs from 'dayjs';
|
|
16
|
-
import isToday from 'dayjs/plugin/isToday';
|
|
17
|
-
import objectSupport from 'dayjs/plugin/objectSupport';
|
|
18
|
-
import utc from 'dayjs/plugin/utc';
|
|
15
|
+
import isToday from 'dayjs/plugin/isToday.js';
|
|
16
|
+
import objectSupport from 'dayjs/plugin/objectSupport.js';
|
|
17
|
+
import utc from 'dayjs/plugin/utc.js';
|
|
19
18
|
import { isNil, omit } from 'lodash-es';
|
|
19
|
+
import { getLocale } from '../';
|
|
20
20
|
|
|
21
21
|
dayjs.extend(isToday);
|
|
22
22
|
dayjs.extend(utc);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { type NameUse } from '@openmrs/esm-globals';
|
|
1
3
|
import { formatPatientName, getPatientName, selectPreferredName } from './patient-helpers';
|
|
2
4
|
import {
|
|
3
5
|
mockPatientWithNoName,
|
|
@@ -9,7 +11,6 @@ import {
|
|
|
9
11
|
mockPatientWithMultipleNames,
|
|
10
12
|
mockPatientWithNickAndOfficialName,
|
|
11
13
|
} from './patient-helpers.test.data';
|
|
12
|
-
import { type NameUse } from '@openmrs/esm-globals';
|
|
13
14
|
|
|
14
15
|
describe('Formatted display name', () => {
|
|
15
16
|
it.each([
|
package/src/test-helpers.ts
CHANGED
|
@@ -10,15 +10,20 @@
|
|
|
10
10
|
* default from the `useConfig`/`getConfig` mock. This function is useful if you
|
|
11
11
|
* need to override some of the default values.
|
|
12
12
|
*/
|
|
13
|
-
export function getDefaultsFromConfigSchema<T = Record<string, any>>(
|
|
13
|
+
export function getDefaultsFromConfigSchema<T = Record<string, any>>(
|
|
14
|
+
schema: Record<string | number | symbol, unknown>,
|
|
15
|
+
): T {
|
|
14
16
|
let tmp = {};
|
|
15
17
|
for (let k of Object.keys(schema)) {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
+
if (
|
|
19
|
+
isOrdinaryObject(schema[k]) &&
|
|
20
|
+
(schema[k] as Record<string | number | symbol, unknown>).hasOwnProperty('_default')
|
|
21
|
+
) {
|
|
22
|
+
tmp[k] = (schema[k] as Record<string | number | symbol, unknown>)._default;
|
|
18
23
|
} else if (k.startsWith('_')) {
|
|
19
24
|
continue;
|
|
20
25
|
} else if (isOrdinaryObject(schema[k])) {
|
|
21
|
-
tmp[k] = getDefaultsFromConfigSchema(schema[k]);
|
|
26
|
+
tmp[k] = getDefaultsFromConfigSchema(schema[k] as Record<string | number | symbol, unknown>);
|
|
22
27
|
} else {
|
|
23
28
|
tmp[k] = schema[k];
|
|
24
29
|
}
|
|
@@ -26,6 +31,6 @@ export function getDefaultsFromConfigSchema<T = Record<string, any>>(schema): T
|
|
|
26
31
|
return tmp as T;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
function isOrdinaryObject(x) {
|
|
34
|
+
function isOrdinaryObject(x: any): x is Record<string | number | symbol, unknown> {
|
|
30
35
|
return !!x && x.constructor === Object;
|
|
31
36
|
}
|
package/src/version.test.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
1
2
|
import { isVersionSatisfied } from './version';
|
|
2
3
|
|
|
3
4
|
describe('Version utilities', () => {
|
|
@@ -53,13 +54,16 @@ describe('Version utilities', () => {
|
|
|
53
54
|
|
|
54
55
|
it('Is satisfied with major version caret specifier and pre', () => {
|
|
55
56
|
const result = isVersionSatisfied('^3', '3.1.14-pre.3');
|
|
57
|
+
expect(result).toBe(true);
|
|
56
58
|
});
|
|
57
59
|
|
|
58
60
|
it('Is satisfied with major version caret specifier and pre and a build number', () => {
|
|
59
61
|
const result = isVersionSatisfied('^3', '3.1.14.7e24fb-pre.3');
|
|
62
|
+
expect(result).toBe(true);
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
it('Is satisfied with major version caret specifier and a build number', () => {
|
|
63
66
|
const result = isVersionSatisfied('^3', '3.1.14.7e24fb');
|
|
67
|
+
expect(result).toBe(true);
|
|
64
68
|
});
|
|
65
69
|
});
|
package/tsconfig.json
CHANGED
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"target": "es2015",
|
|
6
|
-
"allowSyntheticDefaultImports": true,
|
|
7
|
-
"jsx": "react",
|
|
8
|
-
"strictNullChecks": true,
|
|
9
|
-
"moduleResolution": "node",
|
|
10
|
-
"declaration": true,
|
|
11
|
-
"declarationDir": "dist",
|
|
12
|
-
"emitDeclarationOnly": true,
|
|
13
|
-
"lib": [
|
|
14
|
-
"dom",
|
|
15
|
-
"es5",
|
|
16
|
-
"scripthost",
|
|
17
|
-
"es2015",
|
|
18
|
-
"es2015.promise",
|
|
19
|
-
"es2016.array.include",
|
|
20
|
-
"es2018",
|
|
21
|
-
"esnext"
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
"include": ["src/**/*"]
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig.json",
|
|
3
|
+
"extends": "../tsconfig.json",
|
|
4
|
+
"include": ["./src/**/*.ts*"]
|
|
25
5
|
}
|