@openmrs/esm-config 3.4.1-pre.96 → 4.0.0-pre.1

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.
@@ -0,0 +1,57 @@
1
+ import { Config, ConfigObject, ConfigSchema } from "../types";
2
+ /**
3
+ * This defines a configuration schema for a module. The schema tells the
4
+ * configuration system how the module can be configured. It specifies
5
+ * what makes configuration valid or invalid.
6
+ *
7
+ * See [Configuration System](http://o3-dev.docs.openmrs.org/#/main/config)
8
+ * for more information about defining a config schema.
9
+ *
10
+ * @param moduleName Name of the module the schema is being defined for. Generally
11
+ * should be the one in which the `defineConfigSchema` call takes place.
12
+ * @param schema The config schema for the module
13
+ */
14
+ export declare function defineConfigSchema(moduleName: string, schema: ConfigSchema): void;
15
+ /**
16
+ * This defines a configuration schema for an extension. When a schema is defined
17
+ * for an extension, that extension will receive the configuration corresponding
18
+ * to that schema, rather than the configuration corresponding to the module
19
+ * in which it is defined.
20
+ *
21
+ * The schema tells the configuration system how the module can be configured.
22
+ * It specifies what makes configuration valid or invalid.
23
+ *
24
+ * See [Configuration System](http://o3-dev.docs.openmrs.org/#/main/config)
25
+ * for more information about defining a config schema.
26
+ *
27
+ * @param extensionName Name of the extension the schema is being defined for.
28
+ * Should match the `name` of one of the `extensions` entries being returned
29
+ * by `setupOpenMRS`.
30
+ * @param schema The config schema for the extension
31
+ */
32
+ export declare function defineExtensionConfigSchema(extensionName: string, schema: ConfigSchema): void;
33
+ export declare function provide(config: Config, sourceName?: string): void;
34
+ /**
35
+ * A promise-based way to access the config as soon as it is fully loaded.
36
+ * If it is already loaded, resolves the config in its present state.
37
+ *
38
+ * In general you should use the Unistore-based API provided by
39
+ * `getConfigStore`, which allows creating a subscription so that you always
40
+ * have the latest config. If using React, just use `useConfig`.
41
+ *
42
+ * This is a useful function if you need to get the config in the course
43
+ * of the execution of a function.
44
+ *
45
+ * @param moduleName The name of the module for which to look up the config
46
+ */
47
+ export declare function getConfig(moduleName: string): Promise<Config>;
48
+ /**
49
+ * Validate and interpolate defaults for `providedConfig` according to `schema`
50
+ *
51
+ * @param schema a configuration schema
52
+ * @param providedConfig an object of config values (without the top-level module name)
53
+ * @param keyPathContext a dot-deparated string which helps the user figure out where
54
+ * the provided config came from
55
+ * @internal
56
+ */
57
+ export declare function processConfig(schema: ConfigSchema, providedConfig: ConfigObject, keyPathContext: string, devDefaultsAreOn?: boolean): Config;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,109 @@
1
+ import { Config, ConfigObject, ConfigSchema, ExtensionSlotConfigObject, ProvidedConfig } from "../types";
2
+ /**
3
+ * Internal store
4
+ * A store of the inputs and internal state
5
+ * @internal
6
+ */
7
+ export interface ConfigInternalStore {
8
+ /** Configs added using the `provide` function */
9
+ providedConfigs: Array<ProvidedConfig>;
10
+ /** An object with module names for keys and schemas for values */
11
+ schemas: Record<string, ConfigSchema>;
12
+ /** Whether to use dev defaults or not */
13
+ devDefaultsAreOn: boolean;
14
+ }
15
+ /**
16
+ * @internal
17
+ */
18
+ export declare const configInternalStore: import("unistore").Store<ConfigInternalStore>;
19
+ /**
20
+ * Temporary config
21
+ * LocalStorage-based config used by the implementer tools
22
+ * @internal
23
+ */
24
+ export interface TemporaryConfigStore {
25
+ config: Config;
26
+ }
27
+ /** @internal */
28
+ export declare const temporaryConfigStore: import("unistore").Store<TemporaryConfigStore>;
29
+ /**
30
+ * Config-side extension store
31
+ * Just what esm-config needs to know about extension state. This
32
+ * is to avoid having esm-config depend on esm-extensions, which would
33
+ * create a circular dependency.
34
+ * @internal
35
+ */
36
+ export interface ConfigExtensionStore {
37
+ mountedExtensions: Array<ConfigExtensionStoreElement>;
38
+ }
39
+ /** @internal */
40
+ export interface ConfigExtensionStoreElement {
41
+ slotModuleName: string;
42
+ extensionModuleName: string;
43
+ slotName: string;
44
+ extensionId: string;
45
+ }
46
+ /** @internal */
47
+ export declare const configExtensionStore: import("unistore").Store<ConfigExtensionStore>;
48
+ /**
49
+ * Output configs
50
+ *
51
+ * Each module has its own stores for its config and its extension slots' configs.
52
+ * @internal
53
+ */
54
+ export interface ConfigStore {
55
+ config: ConfigObject | null;
56
+ loaded: boolean;
57
+ }
58
+ /** @internal */
59
+ export declare function getConfigStore(moduleName: string): import("unistore").Store<ConfigStore>;
60
+ /**
61
+ * Configuration for all the specific extension slots
62
+ * @internal
63
+ */
64
+ export interface ExtensionSlotsConfigStore {
65
+ slots: {
66
+ [slotName: string]: {
67
+ config: ExtensionSlotConfigObject;
68
+ loaded: boolean;
69
+ };
70
+ };
71
+ }
72
+ /** @internal */
73
+ export declare function getExtensionSlotsConfigStore(): import("unistore").Store<ExtensionSlotsConfigStore>;
74
+ /** @internal */
75
+ export declare function getExtensionSlotConfig(slotName: string): {
76
+ config: ExtensionSlotConfigObject;
77
+ loaded: boolean;
78
+ };
79
+ /** @internal */
80
+ export declare function getExtensionSlotConfigFromStore(state: ExtensionSlotsConfigStore, slotName: string): {
81
+ config: ExtensionSlotConfigObject;
82
+ loaded: boolean;
83
+ };
84
+ /** @internal */
85
+ export interface ExtensionsConfigStore {
86
+ configs: {
87
+ [slotName: string]: {
88
+ [extensionId: string]: ConfigStore;
89
+ };
90
+ };
91
+ }
92
+ /**
93
+ * One store for all the extensions
94
+ * @internal
95
+ */
96
+ export declare function getExtensionsConfigStore(): import("unistore").Store<ExtensionsConfigStore>;
97
+ /** @internal */
98
+ export declare function getExtensionConfig(slotName: string, extensionId: string): ConfigStore;
99
+ /** @internal */
100
+ export declare function getExtensionConfigFromStore(state: ExtensionsConfigStore, slotName: string, extensionId: string): ConfigStore;
101
+ /**
102
+ * A store of the implementer tools output config
103
+ * @internal
104
+ */
105
+ export interface ImplementerToolsConfigStore {
106
+ config: Config;
107
+ }
108
+ /** @internal */
109
+ export declare const implementerToolsConfigStore: import("unistore").Store<ImplementerToolsConfigStore>;
@@ -0,0 +1,34 @@
1
+ /** @module @category Navigation */
2
+ /**
3
+ * Interpolates a string with openmrsBase and openmrsSpaBase.
4
+ *
5
+ * Useful for accepting `${openmrsBase}` or `${openmrsSpaBase}` template
6
+ * parameters in configurable URLs.
7
+ *
8
+ * @param template A string to interpolate
9
+ * @param additionalParams Additional values to interpolate into the string template
10
+ */
11
+ export declare function interpolateUrl(template: string, additionalParams?: {
12
+ [key: string]: string;
13
+ }): string;
14
+ /**
15
+ * Interpolates values of `params` into the `template` string.
16
+ *
17
+ * Useful for additional template parameters in URLs.
18
+ *
19
+ * Example usage:
20
+ * ```js
21
+ * navigate({
22
+ * to: interpolateString(
23
+ * config.links.patientChart,
24
+ * { patientUuid: patient.uuid }
25
+ * )
26
+ * });
27
+ * ```
28
+ *
29
+ * @param template With optional params wrapped in `${ }`
30
+ * @param params Values to interpolate into the string template
31
+ */
32
+ export declare function interpolateString(template: string, params: {
33
+ [key: string]: string;
34
+ }): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ export declare type TemplateParams = {
2
+ [key: string]: string;
3
+ };
4
+ export interface NavigateOptions {
5
+ to: string;
6
+ templateParams?: TemplateParams;
7
+ }
8
+ /**
9
+ * Calls `location.assign` for non-SPA paths and [navigateToUrl](https://single-spa.js.org/docs/api/#navigatetourl) for SPA paths
10
+ *
11
+ * Example usage:
12
+ * ```js
13
+ * const config = useConfig();
14
+ * const submitHandler = () => {
15
+ * navigate({ to: config.links.submitSuccess });
16
+ * };
17
+ * ```
18
+ *
19
+ * @param to The target path or URL. Supports templating with 'openmrsBase', 'openmrsSpaBase',
20
+ * and any additional template parameters defined in `templateParams`.
21
+ * For example, `${openmrsSpaBase}/home` will resolve to `/openmrs/spa/home`
22
+ * for implementations using the standard OpenMRS and SPA base paths.
23
+ * If `templateParams` contains `{ foo: "bar" }`, then the URL `${openmrsBase}/${foo}`
24
+ * will become `/openmrs/bar`.
25
+ */
26
+ export declare function navigate({ to, templateParams }: NavigateOptions): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ export * from "./types";
2
+ export * from "./navigation/interpolate-string";
3
+ export * from "./navigation/navigate";
4
+ export * from "./validators/validator";
5
+ export * from "./validators/validators";
6
+ export { defineConfigSchema, defineExtensionConfigSchema, provide, getConfig, } from "./module-config/module-config";
7
+ export { getConfigStore, ConfigStore } from "./module-config/state";
@@ -0,0 +1,49 @@
1
+ export declare enum Type {
2
+ Array = "Array",
3
+ Boolean = "Boolean",
4
+ ConceptUuid = "ConceptUuid",
5
+ Number = "Number",
6
+ Object = "Object",
7
+ String = "String",
8
+ UUID = "UUID",
9
+ PersonAttributeTypeUuid = "PersonAttributeTypeUuid",
10
+ PatientIdentifierTypeUuid = "PatientIdentifierTypeUuid"
11
+ }
12
+ export interface ConfigSchema {
13
+ [key: string]: ConfigSchema | ConfigValue;
14
+ _type?: Type;
15
+ _validators?: Array<Validator>;
16
+ _elements?: ConfigSchema;
17
+ }
18
+ export interface Config extends Object {
19
+ [moduleName: string]: {
20
+ [key: string]: any;
21
+ };
22
+ }
23
+ export interface ConfigObject extends Object {
24
+ [key: string]: any;
25
+ }
26
+ export declare type ConfigValue = string | number | boolean | void | Array<any> | object;
27
+ export interface ExtensionSlotConfig {
28
+ add?: Array<string>;
29
+ remove?: Array<string>;
30
+ order?: Array<string>;
31
+ configure?: ExtensionSlotConfigureValueObject;
32
+ }
33
+ export interface ExtensionSlotConfigureValueObject {
34
+ [key: string]: object;
35
+ }
36
+ export interface ExtensionSlotConfigObject {
37
+ /** Additional extension IDs to assign to this slot, in addition to those `attach`ed in code. */
38
+ add?: Array<string>;
39
+ /** Extension IDs which were `attach`ed to the slot but which should not be assigned. */
40
+ remove?: Array<string>;
41
+ /** Overrides the default ordering of extensions. */
42
+ order?: Array<string>;
43
+ }
44
+ export declare type ProvidedConfig = {
45
+ source: string;
46
+ config: Config;
47
+ };
48
+ export declare type ValidatorFunction = (value: any) => boolean;
49
+ export declare type Validator = (value: any) => void | string;
@@ -0,0 +1,6 @@
1
+ export declare const isArray: import("..").Validator;
2
+ export declare const isBoolean: import("..").Validator;
3
+ export declare const isNumber: import("..").Validator;
4
+ export declare const isString: import("..").Validator;
5
+ export declare const isObject: import("..").Validator;
6
+ export declare const isUuid: import("..").Validator;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ /** @module @category Config Validation */
2
+ import { Validator, ValidatorFunction } from "../types";
3
+ /**
4
+ * Constructs a custom validator.
5
+ *
6
+ * ### Example
7
+ *
8
+ * ```typescript
9
+ * {
10
+ * foo: {
11
+ * _default: 0,
12
+ * _validators: [
13
+ * validator(val => val >= 0, "Must not be negative.")
14
+ * ]
15
+ * }
16
+ * }
17
+ * ```
18
+ * @param validationFunction Takes the configured value as input. Returns true
19
+ * if it is valid, false otherwise.
20
+ * @param message A string message that explains why the value is invalid. Can
21
+ * also be a function that takes the value as input and returns a string.
22
+ * @returns A validator ready for use in a config schema
23
+ */
24
+ export declare function validator(validationFunction: ValidatorFunction, message: string | ((value: any) => string)): Validator;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Verifies that the value is between the provided minimum and maximum
3
+ *
4
+ * @param min Minimum acceptable value
5
+ * @param max Maximum acceptable value
6
+ */
7
+ export declare const inRange: (min: number, max: number) => import("..").Validator;
8
+ /**
9
+ * Verifies that a string contains only the default URL template
10
+ * parameters, plus any specified in `allowedTemplateParameters`.
11
+ *
12
+ * @param allowedTemplateParameters To be added to `openmrsBase` and `openmrsSpaBase`
13
+ * @category Navigation
14
+ */
15
+ export declare const isUrlWithTemplateParameters: (allowedTemplateParameters: string[]) => import("..").Validator;
16
+ /**
17
+ * Verifies that a string contains only the default URL template parameters.
18
+ *
19
+ * @category Navigation
20
+ */
21
+ export declare const isUrl: import("..").Validator;
22
+ /**
23
+ * Verifies that the value is one of the allowed options.
24
+ * @param allowedValues The list of allowable values
25
+ */
26
+ export declare const oneOf: (allowedValues: Array<any>) => import("..").Validator;
27
+ export declare const validators: {
28
+ inRange: (min: number, max: number) => import("..").Validator;
29
+ isUrl: import("..").Validator;
30
+ isUrlWithTemplateParameters: (allowedTemplateParameters: string[]) => import("..").Validator;
31
+ oneOf: (allowedValues: Array<any>) => import("..").Validator;
32
+ };
@@ -0,0 +1 @@
1
+ export {};
package/jest.config.js CHANGED
@@ -8,4 +8,8 @@ module.exports = {
8
8
  "@openmrs/esm-globals": "<rootDir>/__mocks__/openmrs-esm-globals.mock.tsx",
9
9
  "@openmrs/esm-state": "<rootDir>/__mocks__/openmrs-esm-state.mock.tsx",
10
10
  },
11
+ testEnvironment: "jsdom",
12
+ testEnvironmentOptions: {
13
+ url: "http://localhost/",
14
+ },
11
15
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-config",
3
- "version": "3.4.1-pre.96",
3
+ "version": "4.0.0-pre.1",
4
4
  "license": "MPL-2.0",
5
5
  "description": "A configuration library for the OpenMRS Single-Spa framework.",
6
6
  "browser": "dist/openmrs-esm-module-config.js",
@@ -39,18 +39,18 @@
39
39
  "ramda": "^0.26.1"
40
40
  },
41
41
  "peerDependencies": {
42
- "@openmrs/esm-globals": "3.x",
43
- "@openmrs/esm-state": "3.x",
42
+ "@openmrs/esm-globals": "4.x",
43
+ "@openmrs/esm-state": "4.x",
44
44
  "single-spa": "5.x",
45
45
  "systemjs": "6.x"
46
46
  },
47
47
  "devDependencies": {
48
- "@openmrs/esm-globals": "^3.4.1-pre.96",
49
- "@openmrs/esm-state": "^3.4.1-pre.96",
48
+ "@openmrs/esm-globals": "^4.0.0-pre.1",
49
+ "@openmrs/esm-state": "^4.0.0-pre.1",
50
50
  "@types/ramda": "^0.26.44",
51
51
  "@types/systemjs": "^6.1.0",
52
52
  "babel-plugin-ramda": "^2.0.0",
53
53
  "single-spa": "^5.9.2"
54
54
  },
55
- "gitHead": "593214cd88408e07e9c18eab4c204be4a3722c73"
55
+ "gitHead": "9f58b801f07526083a9edc1cc5a1e58660d71eb0"
56
56
  }
@@ -15,14 +15,14 @@ describe("interpolateUrl", () => {
15
15
  describe("interpolateString", () => {
16
16
  it("interpolates template elements", () => {
17
17
  const result = interpolateString("test ${one} ${two} 3", {
18
- one: 1,
19
- two: 2,
18
+ one: "1",
19
+ two: "2",
20
20
  });
21
21
  expect(result).toBe("test 1 2 3");
22
22
  });
23
23
 
24
24
  it("tolerates extra parameters", () => {
25
- const result = interpolateString("test ok", { one: 1, two: 2 });
25
+ const result = interpolateString("test ok", { one: "1", two: "2" });
26
26
  expect(result).toBe("test ok");
27
27
  });
28
28
  });
@@ -11,12 +11,17 @@ function trimTrailingSlash(str: string) {
11
11
  * parameters in configurable URLs.
12
12
  *
13
13
  * @param template A string to interpolate
14
+ * @param additionalParams Additional values to interpolate into the string template
14
15
  */
15
- export function interpolateUrl(template: string): string {
16
+ export function interpolateUrl(
17
+ template: string,
18
+ additionalParams?: { [key: string]: string }
19
+ ): string {
16
20
  const openmrsSpaBase = trimTrailingSlash(window.getOpenmrsSpaBase());
17
21
  return interpolateString(template, {
18
22
  openmrsBase: window.openmrsBase,
19
23
  openmrsSpaBase: openmrsSpaBase,
24
+ ...additionalParams,
20
25
  }).replace(/^\/\//, "/"); // remove extra initial slash if present
21
26
  }
22
27
 
@@ -38,7 +43,10 @@ export function interpolateUrl(template: string): string {
38
43
  * @param template With optional params wrapped in `${ }`
39
44
  * @param params Values to interpolate into the string template
40
45
  */
41
- export function interpolateString(template: string, params: object): string {
46
+ export function interpolateString(
47
+ template: string,
48
+ params: { [key: string]: string }
49
+ ): string {
42
50
  const names = Object.keys(params);
43
51
  return names.reduce(
44
52
  (prev, curr) => prev.split("${" + curr + "}").join(params[curr]),
@@ -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,22 @@ 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
  * ```
24
27
  *
25
- * @param to The target path or URL. Supports templating with 'openmrsBase' and 'openmrsSpaBase'.
28
+ * @param to The target path or URL. Supports templating with 'openmrsBase', 'openmrsSpaBase',
29
+ * and any additional template parameters defined in `templateParams`.
26
30
  * For example, `${openmrsSpaBase}/home` will resolve to `/openmrs/spa/home`
27
31
  * for implementations using the standard OpenMRS and SPA base paths.
32
+ * If `templateParams` contains `{ foo: "bar" }`, then the URL `${openmrsBase}/${foo}`
33
+ * will become `/openmrs/bar`.
28
34
  */
29
- export function navigate({ to }: NavigateOptions): void {
35
+ export function navigate({ to, templateParams }: NavigateOptions): void {
30
36
  const openmrsSpaBase = trimTrailingSlash(window.getOpenmrsSpaBase());
31
- const target = interpolateUrl(to);
37
+ const target = interpolateUrl(to, templateParams);
32
38
  const isSpaPath = target.startsWith(openmrsSpaBase);
33
39
 
34
40
  if (isSpaPath) {