@openmrs/esm-config 4.0.0-pre.0 → 4.0.1-pre.206

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.
@@ -7,8 +7,11 @@ function trimTrailingSlash(str: string) {
7
7
  return str.replace(/\/$/, "");
8
8
  }
9
9
 
10
+ export type TemplateParams = { [key: string]: string };
11
+
10
12
  export interface NavigateOptions {
11
13
  to: string;
14
+ templateParams?: TemplateParams;
12
15
  }
13
16
 
14
17
  /**
@@ -16,19 +19,29 @@ export interface NavigateOptions {
16
19
  *
17
20
  * Example usage:
18
21
  * ```js
19
- * const config = getConfig();
22
+ * const config = useConfig();
20
23
  * const submitHandler = () => {
21
24
  * navigate({ to: config.links.submitSuccess });
22
25
  * };
23
26
  * ```
27
+ * Example return values:
28
+ * navigate({ to: "/some/path" }); => window.location.assign("/some/path")
29
+ * navigate({ to: "https://single-spa.js.org/" }); => window.location.assign("https://single-spa.js.org/")
30
+ * navigate({ to: "${openmrsBase}/some/path" }); => window.location.assign("/openmrs/some/path")
31
+ * navigate({ to: "/openmrs/spa/foo/page" }); => navigateToUrl("/openmrs/spa/foo/page")
32
+ * navigate({ to: "${openmrsSpaBase}/bar/page" }); => navigateToUrl("/openmrs/spa/bar/page")
33
+ * navigate({ to: "/${openmrsSpaBase}/baz/page" }) => navigateToUrl("/openmrs/spa/baz/page")
24
34
  *
25
- * @param to The target path or URL. Supports templating with 'openmrsBase' and 'openmrsSpaBase'.
35
+ * @param to The target path or URL. Supports templating with 'openmrsBase', 'openmrsSpaBase',
36
+ * and any additional template parameters defined in `templateParams`.
26
37
  * For example, `${openmrsSpaBase}/home` will resolve to `/openmrs/spa/home`
27
38
  * for implementations using the standard OpenMRS and SPA base paths.
39
+ * If `templateParams` contains `{ foo: "bar" }`, then the URL `${openmrsBase}/${foo}`
40
+ * will become `/openmrs/bar`.
28
41
  */
29
- export function navigate({ to }: NavigateOptions): void {
42
+ export function navigate({ to, templateParams }: NavigateOptions): void {
30
43
  const openmrsSpaBase = trimTrailingSlash(window.getOpenmrsSpaBase());
31
- const target = interpolateUrl(to);
44
+ const target = interpolateUrl(to, templateParams);
32
45
  const isSpaPath = target.startsWith(openmrsSpaBase);
33
46
 
34
47
  if (isSpaPath) {
package/src/public.ts CHANGED
@@ -9,4 +9,4 @@ export {
9
9
  provide,
10
10
  getConfig,
11
11
  } from "./module-config/module-config";
12
- export { getConfigStore, ConfigStore } from "./module-config/state";
12
+ export { type ConfigStore, getConfigStore } from "./module-config/state";
package/src/types.ts CHANGED
@@ -27,6 +27,11 @@ export interface Config extends Object {
27
27
 
28
28
  export interface ConfigObject extends Object {
29
29
  [key: string]: any;
30
+ "Display conditions"?: DisplayConditionsConfigObject;
31
+ }
32
+
33
+ export interface DisplayConditionsConfigObject {
34
+ privileges?: string[];
30
35
  }
31
36
 
32
37
  export type ConfigValue =
@@ -1,13 +1,38 @@
1
1
  /** @module @category Config Validation */
2
2
  import { Validator, ValidatorFunction } from "../types";
3
3
 
4
+ /**
5
+ * Constructs a custom validator.
6
+ *
7
+ * ### Example
8
+ *
9
+ * ```typescript
10
+ * {
11
+ * foo: {
12
+ * _default: 0,
13
+ * _validators: [
14
+ * validator(val => val >= 0, "Must not be negative.")
15
+ * ]
16
+ * }
17
+ * }
18
+ * ```
19
+ * @param validationFunction Takes the configured value as input. Returns true
20
+ * if it is valid, false otherwise.
21
+ * @param message A string message that explains why the value is invalid. Can
22
+ * also be a function that takes the value as input and returns a string.
23
+ * @returns A validator ready for use in a config schema
24
+ */
4
25
  export function validator(
5
26
  validationFunction: ValidatorFunction,
6
- message: string
27
+ message: string | ((value: any) => string)
7
28
  ): Validator {
8
29
  return (value) => {
9
30
  if (!validationFunction(value)) {
10
- return message;
31
+ if (typeof message === "function") {
32
+ return message(value);
33
+ } else {
34
+ return message;
35
+ }
11
36
  }
12
37
  };
13
38
  }
@@ -1,9 +1,16 @@
1
- import { isUrl, isUrlWithTemplateParameters } from "./validators";
1
+ import {
2
+ inRange,
3
+ isUrl,
4
+ isUrlWithTemplateParameters,
5
+ oneOf,
6
+ } from "./validators";
2
7
 
3
8
  describe("all validators", () => {
4
9
  it("fail on undefined", () => {
10
+ expect(inRange(0, 10)(undefined)).toMatch(/.*/);
5
11
  expect(isUrl(undefined)).toMatch(/.*/);
6
12
  expect(isUrlWithTemplateParameters(["foo"])(undefined)).toMatch(/.*/);
13
+ expect(oneOf(["foo", "bar"])(undefined)).toMatch(/.*/);
7
14
  });
8
15
  });
9
16
 
@@ -22,3 +29,13 @@ describe("isUrl", () => {
22
29
  );
23
30
  });
24
31
  });
32
+
33
+ describe("oneOf", () => {
34
+ it("accepts one of the valid options", () => {
35
+ expect(oneOf(["foo", "bar"])("foo")).toBeUndefined();
36
+ });
37
+
38
+ it("rejects anything else", () => {
39
+ expect(oneOf(["foo", "bar"])("baz")).toMatch(/one of.*foo.*bar/i);
40
+ });
41
+ });
@@ -45,7 +45,7 @@ export const isUrlWithTemplateParameters = (
45
45
  }
46
46
 
47
47
  return true;
48
- }, "should be a URL or path. The allowed template parameters are " + allowedParams.map((p) => "${" + p + "}").join(", "));
48
+ }, "Should be a URL or path. The allowed template parameters are " + allowedParams.map((p) => "${" + p + "}").join(", "));
49
49
  };
50
50
 
51
51
  /**
@@ -55,8 +55,20 @@ export const isUrlWithTemplateParameters = (
55
55
  */
56
56
  export const isUrl = isUrlWithTemplateParameters([]);
57
57
 
58
+ /**
59
+ * Verifies that the value is one of the allowed options.
60
+ * @param allowedValues The list of allowable values
61
+ */
62
+ export const oneOf = (allowedValues: Array<any>) => {
63
+ return validator(
64
+ (val) => allowedValues.includes(val),
65
+ `Must be one of the following: '${allowedValues.join("', '")}'.`
66
+ );
67
+ };
68
+
58
69
  export const validators = {
59
70
  inRange,
60
71
  isUrl,
61
72
  isUrlWithTemplateParameters,
73
+ oneOf,
62
74
  };
@@ -1,2 +0,0 @@
1
- @openmrs/esm-config:lint: cache hit, replaying output e059960089b05a38
2
- @openmrs/esm-config:lint: $ eslint src --ext ts,tsx
@@ -1,13 +0,0 @@
1
- @openmrs/esm-config:test: cache hit, replaying output 938f45b775e0cbf4
2
- @openmrs/esm-config:test: $ jest --config jest.config.js --passWithNoTests
3
- @openmrs/esm-config:test: PASS src/navigation/navigate.test.ts
4
- @openmrs/esm-config:test: PASS src/validators/validators.test.ts
5
- @openmrs/esm-config:test: PASS src/navigation/interpolate-string.test.ts
6
- @openmrs/esm-config:test: PASS src/validators/type-validators.test.ts
7
- @openmrs/esm-config:test: PASS src/module-config/module-config.test.ts
8
- @openmrs/esm-config:test: 
9
- @openmrs/esm-config:test: Test Suites: 5 passed, 5 total
10
- @openmrs/esm-config:test: Tests: 1 skipped, 85 passed, 86 total
11
- @openmrs/esm-config:test: Snapshots: 0 total
12
- @openmrs/esm-config:test: Time: 9.879 s
13
- @openmrs/esm-config:test: Ran all test suites.
@@ -1,2 +0,0 @@
1
- @openmrs/esm-config:typescript: cache hit, replaying output 2eb1242b6e77246a
2
- @openmrs/esm-config:typescript: $ tsc