@spinajs/configuration 2.0.532 → 2.0.534
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/lib/cjs/decorators.d.ts +75 -3
- package/lib/cjs/decorators.d.ts.map +1 -1
- package/lib/cjs/decorators.js +75 -3
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/mjs/decorators.d.ts +75 -3
- package/lib/mjs/decorators.d.ts.map +1 -1
- package/lib/mjs/decorators.js +75 -3
- package/lib/mjs/decorators.js.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +6 -6
package/lib/cjs/decorators.d.ts
CHANGED
|
@@ -1,11 +1,83 @@
|
|
|
1
1
|
import { IConfigEntryOptions } from '@spinajs/configuration-common';
|
|
2
2
|
import { Class } from '@spinajs/di';
|
|
3
3
|
/**
|
|
4
|
-
* Injects configuration value
|
|
4
|
+
* Injects configuration value into a class property.
|
|
5
|
+
*
|
|
6
|
+
* The decorated property is replaced with a lazy getter. Every read resolves the
|
|
7
|
+
* {@link Configuration} service and calls `config.get(path, options.defaultValue)`,
|
|
8
|
+
* so the property always reflects the current (possibly reloaded / watched) value
|
|
9
|
+
* instead of a snapshot taken at construction time.
|
|
10
|
+
*
|
|
11
|
+
* Besides defining the getter, the decorator registers `{ path, options }` in the DI
|
|
12
|
+
* container under `__configuration_property__`. Other modules listen for these
|
|
13
|
+
* registrations - eg. `@spinajs/configuration-db-source` uses them to persist
|
|
14
|
+
* (expose) entries in the database and to watch them for changes.
|
|
15
|
+
*
|
|
16
|
+
* ### Value resolution & priority
|
|
17
|
+
*
|
|
18
|
+
* The configuration is a merge of all registered `ConfigurationSource`s (json / js
|
|
19
|
+
* files, env, db, ...) applied in their `Order`. The getter reads the merged value at
|
|
20
|
+
* `path` with lodash `_.get` semantics:
|
|
21
|
+
*
|
|
22
|
+
* - `defaultValue` is a **fallback only**. It is returned when no source provides a
|
|
23
|
+
* value at `path` (the resolved value is `undefined`).
|
|
24
|
+
* - when any source provides a value at `path`, that value is returned and
|
|
25
|
+
* `defaultValue` is ignored. The db source loads last (`Order` 999), so an exposed
|
|
26
|
+
* db row overrides the same key coming from files.
|
|
27
|
+
* - with `expose: true` the entry is inserted into the `configuration` table on first
|
|
28
|
+
* run (InsertOrIgnore) with both `Value` and `Default` columns seeded from
|
|
29
|
+
* `defaultValue`. From then on the db row is the source of truth for that key:
|
|
30
|
+
* reading it - via `@Config` or plain `Configuration.get(path)` - returns the db
|
|
31
|
+
* `Value`, and editing the row changes what the property returns (immediately with
|
|
32
|
+
* `watch: true`, otherwise after restart / `Configuration.load()`). `defaultValue`
|
|
33
|
+
* is used again only when the row cannot be loaded (no db connection, table not
|
|
34
|
+
* migrated, row deleted, `Exposed` flag cleared).
|
|
35
|
+
* - reading a key without `defaultValue` simply returns whatever the sources loaded:
|
|
36
|
+
* for an exposed entry the db `Value`, or `undefined` / `null` when it is empty.
|
|
37
|
+
*
|
|
38
|
+
* ### Options ({@link IConfigEntryOptions})
|
|
39
|
+
*
|
|
40
|
+
* - `defaultValue` - value returned when `path` is not present in the merged config.
|
|
41
|
+
* When the entry is exposed it also seeds the db row (`Value` and `Default`).
|
|
42
|
+
* - `required` - marks the entry as required. Persisted to the `Required` column of
|
|
43
|
+
* the exposed db row (informational, for admin UIs); the getter does not enforce it.
|
|
44
|
+
* - `expose` - (db source) when `true` the entry is persisted in the `configuration`
|
|
45
|
+
* table so it can be administered at runtime. Only rows with the `Exposed` flag are
|
|
46
|
+
* loaded back into the config. Requires `@spinajs/configuration-db-source` and a
|
|
47
|
+
* resolved `Orm` - without the ORM nothing is written or watched.
|
|
48
|
+
* - `exposeOptions` - (db source) metadata of the exposed row:
|
|
49
|
+
* - `type` - entry type (`string`, `number`, `float`, `boolean`, `json`, `date`,
|
|
50
|
+
* `time`, `datetime`, `*-range`, `oneOf`, `manyOf`, `range`, `file`). Drives how
|
|
51
|
+
* `Value` is serialized to and parsed from the db.
|
|
52
|
+
* - `group` - display-only grouping label for admin UIs. It is NOT part of the
|
|
53
|
+
* config path - `Slug` (the `path` argument) is the canonical path.
|
|
54
|
+
* - `label`, `description` - human readable name and help text.
|
|
55
|
+
* - `meta` - validation hints for UIs (`min`, `max`, `oneOf`, `manyOf`, `minDate`,
|
|
56
|
+
* `maxDate`), stored as JSON.
|
|
57
|
+
* - `watch` - when `true` the db row is polled (every 3 min by default, override
|
|
58
|
+
* with the `__config_watch_interval__` DI value) and changes are pushed into
|
|
59
|
+
* the live configuration without restarting the app.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* class MailService {
|
|
64
|
+
* // value from files / env, "no-reply@example.com" when the key is missing
|
|
65
|
+
* @Config('mailer.fromAddress', { defaultValue: 'no-reply@example.com' })
|
|
66
|
+
* protected From: string;
|
|
67
|
+
*
|
|
68
|
+
* // exposed to db, editable at runtime, refreshed without restart
|
|
69
|
+
* @Config('mailer.retryCount', {
|
|
70
|
+
* defaultValue: 3,
|
|
71
|
+
* expose: true,
|
|
72
|
+
* exposeOptions: { type: 'number', group: 'mailer', label: 'Retry count', watch: true },
|
|
73
|
+
* })
|
|
74
|
+
* protected Retries: number;
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
5
77
|
*
|
|
6
78
|
* @param path - path to configuration value eg. "app.dirs.stats"
|
|
7
|
-
* @param
|
|
8
|
-
* @returns
|
|
79
|
+
* @param options - entry options, see {@link IConfigEntryOptions}
|
|
80
|
+
* @returns property decorator
|
|
9
81
|
*/
|
|
10
82
|
export declare function Config(path: string, options?: IConfigEntryOptions): (target: any, key: string) => any;
|
|
11
83
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAA4B,KAAK,EAAuD,MAAM,aAAa,CAAC;AAGnH
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAA4B,KAAK,EAAuD,MAAM,aAAa,CAAC;AAGnH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,YAChD,GAAG,OAAO,MAAM,KAAG,GAAG,CAevC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,OAoDpE"}
|
package/lib/cjs/decorators.js
CHANGED
|
@@ -11,11 +11,83 @@ const configuration_common_1 = require("@spinajs/configuration-common");
|
|
|
11
11
|
const di_1 = require("@spinajs/di");
|
|
12
12
|
const internal_logger_1 = require("@spinajs/internal-logger");
|
|
13
13
|
/**
|
|
14
|
-
* Injects configuration value
|
|
14
|
+
* Injects configuration value into a class property.
|
|
15
|
+
*
|
|
16
|
+
* The decorated property is replaced with a lazy getter. Every read resolves the
|
|
17
|
+
* {@link Configuration} service and calls `config.get(path, options.defaultValue)`,
|
|
18
|
+
* so the property always reflects the current (possibly reloaded / watched) value
|
|
19
|
+
* instead of a snapshot taken at construction time.
|
|
20
|
+
*
|
|
21
|
+
* Besides defining the getter, the decorator registers `{ path, options }` in the DI
|
|
22
|
+
* container under `__configuration_property__`. Other modules listen for these
|
|
23
|
+
* registrations - eg. `@spinajs/configuration-db-source` uses them to persist
|
|
24
|
+
* (expose) entries in the database and to watch them for changes.
|
|
25
|
+
*
|
|
26
|
+
* ### Value resolution & priority
|
|
27
|
+
*
|
|
28
|
+
* The configuration is a merge of all registered `ConfigurationSource`s (json / js
|
|
29
|
+
* files, env, db, ...) applied in their `Order`. The getter reads the merged value at
|
|
30
|
+
* `path` with lodash `_.get` semantics:
|
|
31
|
+
*
|
|
32
|
+
* - `defaultValue` is a **fallback only**. It is returned when no source provides a
|
|
33
|
+
* value at `path` (the resolved value is `undefined`).
|
|
34
|
+
* - when any source provides a value at `path`, that value is returned and
|
|
35
|
+
* `defaultValue` is ignored. The db source loads last (`Order` 999), so an exposed
|
|
36
|
+
* db row overrides the same key coming from files.
|
|
37
|
+
* - with `expose: true` the entry is inserted into the `configuration` table on first
|
|
38
|
+
* run (InsertOrIgnore) with both `Value` and `Default` columns seeded from
|
|
39
|
+
* `defaultValue`. From then on the db row is the source of truth for that key:
|
|
40
|
+
* reading it - via `@Config` or plain `Configuration.get(path)` - returns the db
|
|
41
|
+
* `Value`, and editing the row changes what the property returns (immediately with
|
|
42
|
+
* `watch: true`, otherwise after restart / `Configuration.load()`). `defaultValue`
|
|
43
|
+
* is used again only when the row cannot be loaded (no db connection, table not
|
|
44
|
+
* migrated, row deleted, `Exposed` flag cleared).
|
|
45
|
+
* - reading a key without `defaultValue` simply returns whatever the sources loaded:
|
|
46
|
+
* for an exposed entry the db `Value`, or `undefined` / `null` when it is empty.
|
|
47
|
+
*
|
|
48
|
+
* ### Options ({@link IConfigEntryOptions})
|
|
49
|
+
*
|
|
50
|
+
* - `defaultValue` - value returned when `path` is not present in the merged config.
|
|
51
|
+
* When the entry is exposed it also seeds the db row (`Value` and `Default`).
|
|
52
|
+
* - `required` - marks the entry as required. Persisted to the `Required` column of
|
|
53
|
+
* the exposed db row (informational, for admin UIs); the getter does not enforce it.
|
|
54
|
+
* - `expose` - (db source) when `true` the entry is persisted in the `configuration`
|
|
55
|
+
* table so it can be administered at runtime. Only rows with the `Exposed` flag are
|
|
56
|
+
* loaded back into the config. Requires `@spinajs/configuration-db-source` and a
|
|
57
|
+
* resolved `Orm` - without the ORM nothing is written or watched.
|
|
58
|
+
* - `exposeOptions` - (db source) metadata of the exposed row:
|
|
59
|
+
* - `type` - entry type (`string`, `number`, `float`, `boolean`, `json`, `date`,
|
|
60
|
+
* `time`, `datetime`, `*-range`, `oneOf`, `manyOf`, `range`, `file`). Drives how
|
|
61
|
+
* `Value` is serialized to and parsed from the db.
|
|
62
|
+
* - `group` - display-only grouping label for admin UIs. It is NOT part of the
|
|
63
|
+
* config path - `Slug` (the `path` argument) is the canonical path.
|
|
64
|
+
* - `label`, `description` - human readable name and help text.
|
|
65
|
+
* - `meta` - validation hints for UIs (`min`, `max`, `oneOf`, `manyOf`, `minDate`,
|
|
66
|
+
* `maxDate`), stored as JSON.
|
|
67
|
+
* - `watch` - when `true` the db row is polled (every 3 min by default, override
|
|
68
|
+
* with the `__config_watch_interval__` DI value) and changes are pushed into
|
|
69
|
+
* the live configuration without restarting the app.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* class MailService {
|
|
74
|
+
* // value from files / env, "no-reply@example.com" when the key is missing
|
|
75
|
+
* @Config('mailer.fromAddress', { defaultValue: 'no-reply@example.com' })
|
|
76
|
+
* protected From: string;
|
|
77
|
+
*
|
|
78
|
+
* // exposed to db, editable at runtime, refreshed without restart
|
|
79
|
+
* @Config('mailer.retryCount', {
|
|
80
|
+
* defaultValue: 3,
|
|
81
|
+
* expose: true,
|
|
82
|
+
* exposeOptions: { type: 'number', group: 'mailer', label: 'Retry count', watch: true },
|
|
83
|
+
* })
|
|
84
|
+
* protected Retries: number;
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
15
87
|
*
|
|
16
88
|
* @param path - path to configuration value eg. "app.dirs.stats"
|
|
17
|
-
* @param
|
|
18
|
-
* @returns
|
|
89
|
+
* @param options - entry options, see {@link IConfigEntryOptions}
|
|
90
|
+
* @returns property decorator
|
|
19
91
|
*/
|
|
20
92
|
function Config(path, options) {
|
|
21
93
|
return (target, key) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":";;;;;;;AAAA,oDAAuB;AACvB,uDAAuD;AACvD,wEAAmF;AACnF,oCAAmH;AACnH,8DAA0D;AAE1D
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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"}
|
package/lib/mjs/decorators.d.ts
CHANGED
|
@@ -1,11 +1,83 @@
|
|
|
1
1
|
import { IConfigEntryOptions } from '@spinajs/configuration-common';
|
|
2
2
|
import { Class } from '@spinajs/di';
|
|
3
3
|
/**
|
|
4
|
-
* Injects configuration value
|
|
4
|
+
* Injects configuration value into a class property.
|
|
5
|
+
*
|
|
6
|
+
* The decorated property is replaced with a lazy getter. Every read resolves the
|
|
7
|
+
* {@link Configuration} service and calls `config.get(path, options.defaultValue)`,
|
|
8
|
+
* so the property always reflects the current (possibly reloaded / watched) value
|
|
9
|
+
* instead of a snapshot taken at construction time.
|
|
10
|
+
*
|
|
11
|
+
* Besides defining the getter, the decorator registers `{ path, options }` in the DI
|
|
12
|
+
* container under `__configuration_property__`. Other modules listen for these
|
|
13
|
+
* registrations - eg. `@spinajs/configuration-db-source` uses them to persist
|
|
14
|
+
* (expose) entries in the database and to watch them for changes.
|
|
15
|
+
*
|
|
16
|
+
* ### Value resolution & priority
|
|
17
|
+
*
|
|
18
|
+
* The configuration is a merge of all registered `ConfigurationSource`s (json / js
|
|
19
|
+
* files, env, db, ...) applied in their `Order`. The getter reads the merged value at
|
|
20
|
+
* `path` with lodash `_.get` semantics:
|
|
21
|
+
*
|
|
22
|
+
* - `defaultValue` is a **fallback only**. It is returned when no source provides a
|
|
23
|
+
* value at `path` (the resolved value is `undefined`).
|
|
24
|
+
* - when any source provides a value at `path`, that value is returned and
|
|
25
|
+
* `defaultValue` is ignored. The db source loads last (`Order` 999), so an exposed
|
|
26
|
+
* db row overrides the same key coming from files.
|
|
27
|
+
* - with `expose: true` the entry is inserted into the `configuration` table on first
|
|
28
|
+
* run (InsertOrIgnore) with both `Value` and `Default` columns seeded from
|
|
29
|
+
* `defaultValue`. From then on the db row is the source of truth for that key:
|
|
30
|
+
* reading it - via `@Config` or plain `Configuration.get(path)` - returns the db
|
|
31
|
+
* `Value`, and editing the row changes what the property returns (immediately with
|
|
32
|
+
* `watch: true`, otherwise after restart / `Configuration.load()`). `defaultValue`
|
|
33
|
+
* is used again only when the row cannot be loaded (no db connection, table not
|
|
34
|
+
* migrated, row deleted, `Exposed` flag cleared).
|
|
35
|
+
* - reading a key without `defaultValue` simply returns whatever the sources loaded:
|
|
36
|
+
* for an exposed entry the db `Value`, or `undefined` / `null` when it is empty.
|
|
37
|
+
*
|
|
38
|
+
* ### Options ({@link IConfigEntryOptions})
|
|
39
|
+
*
|
|
40
|
+
* - `defaultValue` - value returned when `path` is not present in the merged config.
|
|
41
|
+
* When the entry is exposed it also seeds the db row (`Value` and `Default`).
|
|
42
|
+
* - `required` - marks the entry as required. Persisted to the `Required` column of
|
|
43
|
+
* the exposed db row (informational, for admin UIs); the getter does not enforce it.
|
|
44
|
+
* - `expose` - (db source) when `true` the entry is persisted in the `configuration`
|
|
45
|
+
* table so it can be administered at runtime. Only rows with the `Exposed` flag are
|
|
46
|
+
* loaded back into the config. Requires `@spinajs/configuration-db-source` and a
|
|
47
|
+
* resolved `Orm` - without the ORM nothing is written or watched.
|
|
48
|
+
* - `exposeOptions` - (db source) metadata of the exposed row:
|
|
49
|
+
* - `type` - entry type (`string`, `number`, `float`, `boolean`, `json`, `date`,
|
|
50
|
+
* `time`, `datetime`, `*-range`, `oneOf`, `manyOf`, `range`, `file`). Drives how
|
|
51
|
+
* `Value` is serialized to and parsed from the db.
|
|
52
|
+
* - `group` - display-only grouping label for admin UIs. It is NOT part of the
|
|
53
|
+
* config path - `Slug` (the `path` argument) is the canonical path.
|
|
54
|
+
* - `label`, `description` - human readable name and help text.
|
|
55
|
+
* - `meta` - validation hints for UIs (`min`, `max`, `oneOf`, `manyOf`, `minDate`,
|
|
56
|
+
* `maxDate`), stored as JSON.
|
|
57
|
+
* - `watch` - when `true` the db row is polled (every 3 min by default, override
|
|
58
|
+
* with the `__config_watch_interval__` DI value) and changes are pushed into
|
|
59
|
+
* the live configuration without restarting the app.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* class MailService {
|
|
64
|
+
* // value from files / env, "no-reply@example.com" when the key is missing
|
|
65
|
+
* @Config('mailer.fromAddress', { defaultValue: 'no-reply@example.com' })
|
|
66
|
+
* protected From: string;
|
|
67
|
+
*
|
|
68
|
+
* // exposed to db, editable at runtime, refreshed without restart
|
|
69
|
+
* @Config('mailer.retryCount', {
|
|
70
|
+
* defaultValue: 3,
|
|
71
|
+
* expose: true,
|
|
72
|
+
* exposeOptions: { type: 'number', group: 'mailer', label: 'Retry count', watch: true },
|
|
73
|
+
* })
|
|
74
|
+
* protected Retries: number;
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
5
77
|
*
|
|
6
78
|
* @param path - path to configuration value eg. "app.dirs.stats"
|
|
7
|
-
* @param
|
|
8
|
-
* @returns
|
|
79
|
+
* @param options - entry options, see {@link IConfigEntryOptions}
|
|
80
|
+
* @returns property decorator
|
|
9
81
|
*/
|
|
10
82
|
export declare function Config(path: string, options?: IConfigEntryOptions): (target: any, key: string) => any;
|
|
11
83
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAA4B,KAAK,EAAuD,MAAM,aAAa,CAAC;AAGnH
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAA4B,KAAK,EAAuD,MAAM,aAAa,CAAC;AAGnH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,YAChD,GAAG,OAAO,MAAM,KAAG,GAAG,CAevC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,OAoDpE"}
|
package/lib/mjs/decorators.js
CHANGED
|
@@ -4,11 +4,83 @@ import { Configuration } from '@spinajs/configuration-common';
|
|
|
4
4
|
import { AddDependencyForProperty, DI } from '@spinajs/di';
|
|
5
5
|
import { InternalLogger } from '@spinajs/internal-logger';
|
|
6
6
|
/**
|
|
7
|
-
* Injects configuration value
|
|
7
|
+
* Injects configuration value into a class property.
|
|
8
|
+
*
|
|
9
|
+
* The decorated property is replaced with a lazy getter. Every read resolves the
|
|
10
|
+
* {@link Configuration} service and calls `config.get(path, options.defaultValue)`,
|
|
11
|
+
* so the property always reflects the current (possibly reloaded / watched) value
|
|
12
|
+
* instead of a snapshot taken at construction time.
|
|
13
|
+
*
|
|
14
|
+
* Besides defining the getter, the decorator registers `{ path, options }` in the DI
|
|
15
|
+
* container under `__configuration_property__`. Other modules listen for these
|
|
16
|
+
* registrations - eg. `@spinajs/configuration-db-source` uses them to persist
|
|
17
|
+
* (expose) entries in the database and to watch them for changes.
|
|
18
|
+
*
|
|
19
|
+
* ### Value resolution & priority
|
|
20
|
+
*
|
|
21
|
+
* The configuration is a merge of all registered `ConfigurationSource`s (json / js
|
|
22
|
+
* files, env, db, ...) applied in their `Order`. The getter reads the merged value at
|
|
23
|
+
* `path` with lodash `_.get` semantics:
|
|
24
|
+
*
|
|
25
|
+
* - `defaultValue` is a **fallback only**. It is returned when no source provides a
|
|
26
|
+
* value at `path` (the resolved value is `undefined`).
|
|
27
|
+
* - when any source provides a value at `path`, that value is returned and
|
|
28
|
+
* `defaultValue` is ignored. The db source loads last (`Order` 999), so an exposed
|
|
29
|
+
* db row overrides the same key coming from files.
|
|
30
|
+
* - with `expose: true` the entry is inserted into the `configuration` table on first
|
|
31
|
+
* run (InsertOrIgnore) with both `Value` and `Default` columns seeded from
|
|
32
|
+
* `defaultValue`. From then on the db row is the source of truth for that key:
|
|
33
|
+
* reading it - via `@Config` or plain `Configuration.get(path)` - returns the db
|
|
34
|
+
* `Value`, and editing the row changes what the property returns (immediately with
|
|
35
|
+
* `watch: true`, otherwise after restart / `Configuration.load()`). `defaultValue`
|
|
36
|
+
* is used again only when the row cannot be loaded (no db connection, table not
|
|
37
|
+
* migrated, row deleted, `Exposed` flag cleared).
|
|
38
|
+
* - reading a key without `defaultValue` simply returns whatever the sources loaded:
|
|
39
|
+
* for an exposed entry the db `Value`, or `undefined` / `null` when it is empty.
|
|
40
|
+
*
|
|
41
|
+
* ### Options ({@link IConfigEntryOptions})
|
|
42
|
+
*
|
|
43
|
+
* - `defaultValue` - value returned when `path` is not present in the merged config.
|
|
44
|
+
* When the entry is exposed it also seeds the db row (`Value` and `Default`).
|
|
45
|
+
* - `required` - marks the entry as required. Persisted to the `Required` column of
|
|
46
|
+
* the exposed db row (informational, for admin UIs); the getter does not enforce it.
|
|
47
|
+
* - `expose` - (db source) when `true` the entry is persisted in the `configuration`
|
|
48
|
+
* table so it can be administered at runtime. Only rows with the `Exposed` flag are
|
|
49
|
+
* loaded back into the config. Requires `@spinajs/configuration-db-source` and a
|
|
50
|
+
* resolved `Orm` - without the ORM nothing is written or watched.
|
|
51
|
+
* - `exposeOptions` - (db source) metadata of the exposed row:
|
|
52
|
+
* - `type` - entry type (`string`, `number`, `float`, `boolean`, `json`, `date`,
|
|
53
|
+
* `time`, `datetime`, `*-range`, `oneOf`, `manyOf`, `range`, `file`). Drives how
|
|
54
|
+
* `Value` is serialized to and parsed from the db.
|
|
55
|
+
* - `group` - display-only grouping label for admin UIs. It is NOT part of the
|
|
56
|
+
* config path - `Slug` (the `path` argument) is the canonical path.
|
|
57
|
+
* - `label`, `description` - human readable name and help text.
|
|
58
|
+
* - `meta` - validation hints for UIs (`min`, `max`, `oneOf`, `manyOf`, `minDate`,
|
|
59
|
+
* `maxDate`), stored as JSON.
|
|
60
|
+
* - `watch` - when `true` the db row is polled (every 3 min by default, override
|
|
61
|
+
* with the `__config_watch_interval__` DI value) and changes are pushed into
|
|
62
|
+
* the live configuration without restarting the app.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* class MailService {
|
|
67
|
+
* // value from files / env, "no-reply@example.com" when the key is missing
|
|
68
|
+
* @Config('mailer.fromAddress', { defaultValue: 'no-reply@example.com' })
|
|
69
|
+
* protected From: string;
|
|
70
|
+
*
|
|
71
|
+
* // exposed to db, editable at runtime, refreshed without restart
|
|
72
|
+
* @Config('mailer.retryCount', {
|
|
73
|
+
* defaultValue: 3,
|
|
74
|
+
* expose: true,
|
|
75
|
+
* exposeOptions: { type: 'number', group: 'mailer', label: 'Retry count', watch: true },
|
|
76
|
+
* })
|
|
77
|
+
* protected Retries: number;
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
8
80
|
*
|
|
9
81
|
* @param path - path to configuration value eg. "app.dirs.stats"
|
|
10
|
-
* @param
|
|
11
|
-
* @returns
|
|
82
|
+
* @param options - entry options, see {@link IConfigEntryOptions}
|
|
83
|
+
* @returns property decorator
|
|
12
84
|
*/
|
|
13
85
|
export function Config(path, options) {
|
|
14
86
|
return (target, key) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;AACvB,uDAAuD;AACvD,OAAO,EAAE,aAAa,EAAuB,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAE,wBAAwB,EAAS,EAAE,EAAmD,MAAM,aAAa,CAAC;AACnH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"decorators.js","sourceRoot":"","sources":["../../src/decorators.ts"],"names":[],"mappings":"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"}
|