@map-colonies/config 1.0.0

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.
Files changed (50) hide show
  1. package/README.md +291 -0
  2. package/dist/avi.d.ts +2 -0
  3. package/dist/avi.d.ts.map +1 -0
  4. package/dist/avi.js +16 -0
  5. package/dist/avi.js.map +1 -0
  6. package/dist/config.d.ts +14 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +102 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/constants.d.ts +5 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +14 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/env.d.ts +3 -0
  15. package/dist/env.d.ts.map +1 -0
  16. package/dist/env.js +90 -0
  17. package/dist/env.js.map +1 -0
  18. package/dist/errors.d.ts +74 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +55 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/httpClient.d.ts +4 -0
  23. package/dist/httpClient.d.ts.map +1 -0
  24. package/dist/httpClient.js +64 -0
  25. package/dist/httpClient.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +9 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/options.d.ts +4 -0
  31. package/dist/options.d.ts.map +1 -0
  32. package/dist/options.js +50 -0
  33. package/dist/options.js.map +1 -0
  34. package/dist/schemas.d.ts +296 -0
  35. package/dist/schemas.d.ts.map +1 -0
  36. package/dist/schemas.js +41 -0
  37. package/dist/schemas.js.map +1 -0
  38. package/dist/types.d.ts +105 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +23 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/utils/debug.d.ts +3 -0
  43. package/dist/utils/debug.d.ts.map +1 -0
  44. package/dist/utils/debug.js +12 -0
  45. package/dist/utils/debug.js.map +1 -0
  46. package/dist/validator.d.ts +7 -0
  47. package/dist/validator.d.ts.map +1 -0
  48. package/dist/validator.js +43 -0
  49. package/dist/validator.js.map +1 -0
  50. package/package.json +85 -0
package/README.md ADDED
@@ -0,0 +1,291 @@
1
+ # Config
2
+ This package provide a solution for handling the configuration for NodeJs applications.
3
+ The package supports both working as a standalone solution and online using [config-server](https://github.com/MapColonies/config-server).
4
+
5
+ The configs are defined in the [schemas](https://github.com/MapColonies/schemas) package. It is used for validation, defining environment variable override, and for generating typescript types.
6
+
7
+ # Installation
8
+ In order to use the package you need to install both the package itself, and the schemas package that handles all the config schemas.
9
+ ```sh
10
+ npm install @map-colonies/schemas @map-colonies/config
11
+ ```
12
+
13
+ # Usage
14
+ ```typescript
15
+ import { config } from '@map-colonies/config';
16
+ import { commonBoilerplateV4 } from '@map-colonies/schemas';
17
+
18
+ const configInstance = await config({
19
+ configName: 'boiler-config',
20
+ configServerUrl: 'http://localhost:8080',
21
+ schema: commonBoilerplateV4,
22
+ version: 'latest',
23
+ offlineMode: false
24
+ });
25
+
26
+ const port = configInstance.get('server.port');
27
+ ```
28
+
29
+ ## API Documentation
30
+
31
+ This section describes the API provided by the package for interacting with the configuration.
32
+
33
+ ### `ConfigInstance<T>`
34
+
35
+ The `ConfigInstance` interface represents the your way to interact with the configuration. It provides methods to retrieve configuration values and parts.
36
+ `T` is the typescript type associated with the chosen schema. it can be imported from the `@map-colonies/schemas` package.
37
+
38
+ #### Methods
39
+
40
+ ##### `get<TPath extends string>(path: TPath): _.GetFieldType<T, TPath>`
41
+
42
+ - **Description**: Retrieves the value at the specified path from the configuration object. Note that the type of returned object is based on the path in the schema.
43
+ - **Parameters**:
44
+ - `path` (`TPath`): The path to the desired value.
45
+ - **Returns**: The value at the specified path.
46
+
47
+ ##### `getAll(): T`
48
+
49
+ - **Description**: Retrieves the entire configuration object.
50
+ - **Returns**: The entire configuration object.
51
+
52
+ ##### `getConfigParts(): { localConfig: object; config: object; envConfig: object }`
53
+
54
+ - **Description**: Retrieves different parts of the configuration object before being merged and validated. Useful for debugging.
55
+ - **Returns**: An object containing the `localConfig`, `config`, and `envConfig` parts of the configuration.
56
+ - `localConfig`: The local configuration object.
57
+ - `config`: The remote configuration object.
58
+ - `envConfig`: The environment configuration object.
59
+
60
+ ##### `getResolvedOptions(): BaseOptions`
61
+
62
+ - **Description**: Retrieves the resolved options from the configuration object. Useful for debugging.
63
+ - **Returns**: The resolved options, which are an instance of `BaseOptions`.
64
+
65
+
66
+ # Configuration Options
67
+
68
+ This package allows you to configure various options for loading and managing configurations. Below are the available options and their descriptions.
69
+
70
+ ## Options
71
+
72
+ ### `schema`
73
+ - **Type**: `T extends SchemaWithType`
74
+ - **Description**: The schema of the configuration object.
75
+
76
+ ### `configName`
77
+ - **Type**: `string`
78
+ - **Description**: The name of the remote configuration.
79
+ - **Environment Variable**: `CONFIG_NAME`
80
+
81
+ ### `version`
82
+ - **Type**: `'latest' | number`
83
+ - **Description**: The version of the remote configuration. It can be either `'latest'` or a number.
84
+ - **Environment Variable**: `CONFIG_VERSION`
85
+
86
+ ### `configServerUrl`
87
+ - **Type**: `string`
88
+ - **Description**: The URL of the configuration server.
89
+ - **Environment Variable**: `CONFIG_SERVER_URL`
90
+
91
+ ### `offlineMode`
92
+ - **Type**: `boolean`
93
+ - **Optional**: `true`
94
+ - **Description**: Indicates whether the configuration should be loaded in offline mode.
95
+ - **Environment Variable**: `CONFIG_OFFLINE_MODE`
96
+
97
+ ### `ignoreServerIsOlderVersionError`
98
+ - **Type**: `boolean`
99
+ - **Optional**: `true`
100
+ - **Description**: Indicates whether to ignore the error when the server version is older than the requested version.
101
+ - **Environment Variable**: `CONFIG_IGNORE_SERVER_IS_OLDER_VERSION_ERROR`
102
+
103
+ ### `localConfigPath`
104
+ - **Type**: `string`
105
+ - **Default**: `./config`
106
+ - **Description**: The path to the local configuration folder.
107
+
108
+ ## JSON Schema
109
+
110
+ The options are validated against the following JSON schema:
111
+
112
+ ```json
113
+ {
114
+   "required": ["configName", "configServerUrl", "version"],
115
+   "additionalProperties": false,
116
+   "type": "object",
117
+   "properties": {
118
+     "configName": { "type": "string" },
119
+     "version": {
120
+       "oneOf": [
121
+         { "type": "string", "const": "latest" },
122
+         { "type": "integer", "minimum": 1 }
123
+       ]
124
+     },
125
+     "configServerUrl": { "type": "string" },
126
+     "offlineMode": { "type": "boolean", "nullable": true },
127
+     "ignoreServerIsOlderVersionError": { "type": "boolean", "nullable": true },
128
+     "localConfigPath": { "type": "string", "default": "./config" }
129
+   }
130
+ }
131
+ ```
132
+
133
+ ## Environment Variable Configuration
134
+
135
+ The following environment variables can be used to configure the options:
136
+
137
+ - `CONFIG_NAME`: Sets the `configName` option.
138
+ - `CONFIG_VERSION`: Sets the `version` option.
139
+ - `CONFIG_SERVER_URL`: Sets the `configServerUrl` option.
140
+ - `CONFIG_OFFLINE_MODE`: Sets the `offlineMode` option.
141
+ - `CONFIG_IGNORE_SERVER_IS_OLDER_VERSION_ERROR`: Sets the `ignoreServerIsOlderVersionError` option.
142
+
143
+ ## Configuration Merging and Validation
144
+
145
+ The package supports merging configurations from multiple sources (local, remote, and environment variables) and then validates the merged configuration against the schema.
146
+
147
+ ### Local Configuration
148
+
149
+ 1. The local configuration is loaded from the path specified by the `localConfigPath` option. The default path is `./config`.
150
+
151
+ ### Remote Configuration
152
+
153
+ 1. The remote configuration is fetched from the server specified by the `configServerUrl` option.
154
+ 2. If the `version` is set to `'latest'`, the latest version of the configuration is fetched. Otherwise, the specified version is fetched.
155
+
156
+ ### Environment Variables
157
+
158
+ Configuration options can be overridden by setting the corresponding environment variables as described in schema using the `x-env-value` key.
159
+
160
+ ### Merging Configurations
161
+
162
+ 1. The configurations are merged in the following order of precedence:
163
+ - Environment variables
164
+ - Remote configuration
165
+ - Local configuration
166
+
167
+ 2. If a configuration option is specified in multiple sources, the value from the source with higher precedence (as listed above) is used.
168
+
169
+ ### Validation
170
+
171
+ 1. After merging, the final configuration is validated against the defined schema using ajv.
172
+ 2. The validation ensures that all required properties are present, and the types and values of properties conform to the schema.
173
+ 3. Any default value according to the schema is added to the final object.
174
+ 4. If the validation fails, an error is thrown, indicating the invalid properties and their issues.
175
+
176
+
177
+ # Error handling
178
+
179
+ This section describes the possible errors that can occur when using the package, along with their codes and payload structures.
180
+
181
+ ## Identifying errors
182
+ The package exposes a helper function called `isConfigError` to assert what is the error that was thrown and handle it as needed.
183
+ ```typescript
184
+ import { config, isConfigError } from '@map-colonies/config';
185
+
186
+ try {
187
+ const configInstance = await config({
188
+ configName: 'boiler-config',
189
+ configServerUrl: 'http://localhost:8080',
190
+ schema: commonBoilerplateV4,
191
+ version: 'latest',
192
+ offlineMode: false
193
+ });
194
+
195
+ } catch (error) {
196
+ if (isConfigError(error, 'configValidationError')) {
197
+ console.error('Config validation error:', error.payload);
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## Errors
203
+ ### `optionValidationError`
204
+ - **Code**: `1`
205
+ - **Payload**: `ValidationError[]`
206
+ - **Description**: This error occurs when there is a validation error with one of the configuration options.
207
+
208
+ ### `configValidationError`
209
+ - **Code**: `2`
210
+ - **Payload**: `ValidationError[]`
211
+ - **Description**: This error occurs when the configuration as a whole fails validation.
212
+
213
+ ### `httpResponseError`
214
+ - **Code**: `3`
215
+ - **Payload**:
216
+ ```typescript
217
+ {
218
+ headers: Record<string, string>;
219
+ statusCode: number;
220
+ body: string;
221
+ }
222
+ ```
223
+ - **Description**: This error occurs when an HTTP request results in an error response. The payload includes the response headers, status code and body.
224
+
225
+ ### `httpGeneralError`
226
+ - **Code**: `4`
227
+ - **Payload**: `Error`
228
+ - **Description**: This error occurs when there is a general HTTP error. The payload contains the error object.
229
+
230
+ ### `schemaNotFoundError`
231
+ - **Code**: `5`
232
+ - **Payload**:
233
+ ```typescript
234
+ {
235
+ schemaPath: string;
236
+ }
237
+ ```
238
+ - **Description**: This error occurs when the specified schema cannot be found. The payload includes the path of the missing schema.
239
+
240
+ ### `schemasPackageVersionMismatchError`
241
+ - **Code**: `6`
242
+ - **Payload**:
243
+ ```typescript
244
+ {
245
+ remotePackageVersion: string;
246
+ localPackageVersion: string;
247
+ }
248
+ ```
249
+ - **Description**: This error occurs when there is a version mismatch between the remote and local schema packages. The payload includes the versions of both the remote and local packages.
250
+
251
+ ### `schemaVersionMismatchError`
252
+ - **Code**: `7`
253
+ - **Payload**:
254
+ ```typescript
255
+ {
256
+ remoteSchemaVersion: string;
257
+ localSchemaVersion: string;
258
+ }
259
+ ```
260
+ - **Description**: This error occurs when there is a version mismatch between the remote and local schemas. The payload includes the versions of both the remote and local schemas.
261
+
262
+ # Debugging
263
+ If for some reason you want to debug the package you can either use the `getConfigParts` or the `getResolvedOptions` functions described in the API or use the more powerful debug logger.
264
+
265
+ The package debug logger is implemented using the [`debug`](https://www.npmjs.com/package/debug) npm package and is configured using the `DEBUG` Environment variable.
266
+
267
+ The following are the values you can configure to use the debug option.
268
+
269
+ ### `DEBUG=*`
270
+ Enables all the logs. Note that setting this option might enable debug logging of other packages.
271
+
272
+ ### `DEBUG=@map-colonies/config*`
273
+ Enables all the logs available in this package.
274
+
275
+ ### `DEBUG=@map-colonies/config:config`
276
+ Enables only the logs related to the main logic of the package.
277
+
278
+ ### `DEBUG=@map-colonies/config:env`
279
+ Enables only the logs related to parsing environment variables from schemas, and retrieving them for use in the configuration.
280
+
281
+ ### `DEBUG=@map-colonies/config:http`
282
+ Enables only the logs related to http requests to the `config-server`.
283
+
284
+ ### `DEBUG=@map-colonies/config:options`
285
+ Enables only the logs related to parsing and validation of the package initialization options.
286
+
287
+ ### `DEBUG=@map-colonies/config:schemas`
288
+ Enables only the logs related to the retrieving of schemas.
289
+
290
+ ### `DEBUG=@map-colonies/config:validator`
291
+ Enables only the logs related to the validation of configurations.
package/dist/avi.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=avi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avi.d.ts","sourceRoot":"","sources":["../src/avi.ts"],"names":[],"mappings":""}
package/dist/avi.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schemas_1 = require("@map-colonies/schemas");
4
+ const config_1 = require("./config");
5
+ (async () => {
6
+ const c = await (0, config_1.config)({
7
+ schema: schemas_1.threeDFileSyncerV1,
8
+ configName: 'threeDFileSyncerV1',
9
+ configServerUrl: 'http://localhost:3000',
10
+ version: 1,
11
+ offlineMode: true,
12
+ });
13
+ const a = c.get('telemetry.logger');
14
+ console.log(a);
15
+ })().catch(console.error);
16
+ //# sourceMappingURL=avi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avi.js","sourceRoot":"","sources":["../src/avi.ts"],"names":[],"mappings":";;AAAA,mDAA2D;AAC3D,qCAAkC;AAElC,CAAC,KAAK,IAAI,EAAE;IACV,MAAM,CAAC,GAAG,MAAM,IAAA,eAAM,EAAC;QACrB,MAAM,EAAE,4BAAkB;QAC1B,UAAU,EAAE,oBAAoB;QAChC,eAAe,EAAE,uBAAuB;QACxC,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { typeSymbol } from '@map-colonies/schemas/build/schemas/symbol';
2
+ import { ConfigOptions, ConfigInstance } from './types';
3
+ /**
4
+ * Retrieves the configuration based on the provided options.
5
+ *
6
+ * @template T - The type of the configuration schema.
7
+ * @param {ConfigOptions<T>} options - The options for retrieving the configuration.
8
+ * @returns {Promise<ConfigInstance<T>>} - A promise that resolves to the configuration object.
9
+ */
10
+ export declare function config<T extends {
11
+ [typeSymbol]: unknown;
12
+ $id: string;
13
+ }>(options: ConfigOptions<T>): Promise<ConfigInstance<T[typeof typeSymbol]>>;
14
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4CAA4C,CAAC;AAKxE,OAAO,EAAe,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAcrE;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,CAAC,SAAS;IAAE,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAC3E,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAmG/C"}
package/dist/config.js ADDED
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.config = void 0;
7
+ const deepmerge_1 = __importDefault(require("deepmerge"));
8
+ const symbol_1 = require("@map-colonies/schemas/build/schemas/symbol");
9
+ const config_1 = __importDefault(require("config"));
10
+ const semver_1 = __importDefault(require("semver"));
11
+ const lodash_1 = __importDefault(require("lodash"));
12
+ const env_1 = require("./env");
13
+ const schemas_1 = require("./schemas");
14
+ const options_1 = require("./options");
15
+ const httpClient_1 = require("./httpClient");
16
+ const validator_1 = require("./validator");
17
+ const debug_1 = require("./utils/debug");
18
+ const constants_1 = require("./constants");
19
+ const errors_1 = require("./errors");
20
+ const debug = (0, debug_1.createDebug)('config');
21
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
22
+ const arrayMerge = (destinationArray, sourceArray) => sourceArray;
23
+ /**
24
+ * Retrieves the configuration based on the provided options.
25
+ *
26
+ * @template T - The type of the configuration schema.
27
+ * @param {ConfigOptions<T>} options - The options for retrieving the configuration.
28
+ * @returns {Promise<ConfigInstance<T>>} - A promise that resolves to the configuration object.
29
+ */
30
+ async function config(options) {
31
+ // handle package options
32
+ debug('config called with options: %j', { ...options, schema: options.schema.$id });
33
+ const { schema: baseSchema, ...unvalidatedOptions } = options;
34
+ const { configName, offlineMode, version, ignoreServerIsOlderVersionError } = (0, options_1.initializeOptions)(unvalidatedOptions);
35
+ let remoteConfig = {};
36
+ // handle remote config
37
+ if (offlineMode !== true) {
38
+ debug('handling fetching remote data');
39
+ // check if the server is using an older version of the schemas package
40
+ const capabilitiesResponse = await (0, httpClient_1.getServerCapabilities)();
41
+ if (ignoreServerIsOlderVersionError !== true && semver_1.default.gt(constants_1.LOCAL_SCHEMAS_PACKAGE_VERSION, capabilitiesResponse.schemasPackageVersion)) {
42
+ debug('server is using an older version of the schemas package. local: %s, remote: %s', constants_1.LOCAL_SCHEMAS_PACKAGE_VERSION, capabilitiesResponse.schemasPackageVersion);
43
+ throw (0, errors_1.createConfigError)('schemasPackageVersionMismatchError', 'The server is using an older version of the schemas package. Please update the server to the latest version or ignore this error by setting the CONFIG_IGNORE_SERVER_IS_OLDER_VERSION_ERROR environment variable.', {
44
+ localPackageVersion: constants_1.LOCAL_SCHEMAS_PACKAGE_VERSION,
45
+ remotePackageVersion: capabilitiesResponse.schemasPackageVersion,
46
+ });
47
+ }
48
+ // get the remote config
49
+ const serverConfigResponse = await (0, httpClient_1.getRemoteConfig)(configName, version);
50
+ if (serverConfigResponse.schemaId !== baseSchema.$id) {
51
+ debug('schema version mismatch. local: %s, remote: %s', baseSchema.$id, serverConfigResponse.schemaId);
52
+ throw (0, errors_1.createConfigError)('schemaVersionMismatchError', 'The schema version of the remote config does not match the schema version of the local config', {
53
+ localSchemaVersion: baseSchema.$id,
54
+ remoteSchemaVersion: serverConfigResponse.schemaId,
55
+ });
56
+ }
57
+ remoteConfig = serverConfigResponse.config;
58
+ }
59
+ debug('remote config: %j', remoteConfig);
60
+ const dereferencedSchema = await (0, schemas_1.loadSchema)(baseSchema);
61
+ const localConfig = config_1.default.util.loadFileConfigs(options.localConfigPath);
62
+ debug('local config: %j', localConfig);
63
+ const envConfig = (0, env_1.getEnvValues)(dereferencedSchema);
64
+ debug('env config: %j', envConfig);
65
+ // merge all the configs into one object with the following priority: localConfig < remoteConfig < envConfig
66
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
67
+ const mergedConfig = deepmerge_1.default.all([localConfig, remoteConfig, envConfig], { arrayMerge });
68
+ debug('merged config: %j', mergedConfig);
69
+ // validate the merged config
70
+ const [errors, validatedConfig] = (0, validator_1.validate)(validator_1.ajvConfigValidator, dereferencedSchema, mergedConfig);
71
+ if (errors) {
72
+ debug('config validation error: %j', errors);
73
+ throw (0, errors_1.createConfigError)('configValidationError', 'Config validation error', errors);
74
+ }
75
+ debug('freezing validated config');
76
+ // freeze the merged config so it can't be modified by the package user
77
+ Object.freeze(validatedConfig);
78
+ function get(path) {
79
+ debug('get called with path: %s', path);
80
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
81
+ return lodash_1.default.get(validatedConfig, path);
82
+ }
83
+ function getAll() {
84
+ debug('getAll called');
85
+ return validatedConfig;
86
+ }
87
+ function getConfigParts() {
88
+ debug('getConfigParts called');
89
+ return {
90
+ localConfig,
91
+ config: remoteConfig,
92
+ envConfig,
93
+ };
94
+ }
95
+ function getResolvedOptions() {
96
+ debug('getResolvedOptions called');
97
+ return (0, options_1.getOptions)();
98
+ }
99
+ return { get, getAll, getConfigParts, getResolvedOptions };
100
+ }
101
+ exports.config = config;
102
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const LOCAL_SCHEMAS_PACKAGE_VERSION: string;
2
+ export declare const SCHEMA_DOMAIN = "https://mapcolonies.com/";
3
+ export declare const SCHEMAS_PACKAGE_RESOLVED_PATH: string;
4
+ export declare const SCHEMA_BASE_PATH: string;
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,6BAA6B,QAAgG,CAAC;AAE3I,eAAO,MAAM,aAAa,6BAA6B,CAAC;AAExD,eAAO,MAAM,6BAA6B,QAA2C,CAAC;AACtF,eAAO,MAAM,gBAAgB,QAA6F,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SCHEMA_BASE_PATH = exports.SCHEMAS_PACKAGE_RESOLVED_PATH = exports.SCHEMA_DOMAIN = exports.LOCAL_SCHEMAS_PACKAGE_VERSION = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const read_pkg_1 = require("@map-colonies/read-pkg");
9
+ const schemasPackagePathBuildPath = require.resolve('@map-colonies/schemas').substring(0, require.resolve('@map-colonies/schemas').indexOf('build'));
10
+ exports.LOCAL_SCHEMAS_PACKAGE_VERSION = (0, read_pkg_1.readPackageJsonSync)(node_path_1.default.join(schemasPackagePathBuildPath, 'package.json')).version;
11
+ exports.SCHEMA_DOMAIN = 'https://mapcolonies.com/';
12
+ exports.SCHEMAS_PACKAGE_RESOLVED_PATH = require.resolve('@map-colonies/schemas');
13
+ exports.SCHEMA_BASE_PATH = exports.SCHEMAS_PACKAGE_RESOLVED_PATH.substring(0, exports.SCHEMAS_PACKAGE_RESOLVED_PATH.lastIndexOf('/'));
14
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,qDAA6D;AAE7D,MAAM,2BAA2B,GAAG,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AACxI,QAAA,6BAA6B,GAAG,IAAA,8BAAmB,EAAC,mBAAI,CAAC,IAAI,CAAC,2BAA2B,EAAE,cAAc,CAAC,CAAC,CAAC,OAAiB,CAAC;AAE9H,QAAA,aAAa,GAAG,0BAA0B,CAAC;AAE3C,QAAA,6BAA6B,GAAG,OAAO,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;AACzE,QAAA,gBAAgB,GAAG,qCAA6B,CAAC,SAAS,CAAC,CAAC,EAAE,qCAA6B,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { JSONSchema } from '@apidevtools/json-schema-ref-parser';
2
+ export declare function getEnvValues(schema: JSONSchema): object;
3
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAkEjE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAgCvD"}
package/dist/env.js ADDED
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getEnvValues = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const debug_1 = require("./utils/debug");
9
+ const debug = (0, debug_1.createDebug)('env');
10
+ const schemaCompositionKeys = ['oneOf', 'anyOf', 'allOf'];
11
+ function parseSchemaEnv(schema) {
12
+ debug('parsing schema for env values');
13
+ const fromEnv = {};
14
+ function handlePrimitive(schema, type, path) {
15
+ debug('handling primitive %s at path %s', type, path);
16
+ // eslint-disable-next-line @typescript-eslint/naming-convention
17
+ const xFrom = schema['x-env-value'];
18
+ debug('value of xFrom: %s as path %s', xFrom, path);
19
+ if (xFrom !== undefined) {
20
+ fromEnv[xFrom] = {
21
+ type,
22
+ path,
23
+ };
24
+ }
25
+ }
26
+ function iterateOverSchemaObject(schema, path) {
27
+ debug('iterating over schema object at path %s', path);
28
+ const type = schema.type;
29
+ if (type === 'number' || type === 'string' || type === 'boolean' || type === 'integer' || type === 'null') {
30
+ return handlePrimitive(schema, type, path);
31
+ }
32
+ if (type === 'array' || type === 'any') {
33
+ debug('array or any type at path %s', path);
34
+ return;
35
+ }
36
+ schemaCompositionKeys.forEach((key) => {
37
+ const compositionObj = schema[key];
38
+ if (compositionObj !== undefined) {
39
+ debug('going over composition object %s at path %s', key, path);
40
+ for (const subSchema of compositionObj) {
41
+ if (typeof subSchema !== 'boolean') {
42
+ iterateOverSchemaObject(subSchema, path);
43
+ }
44
+ }
45
+ }
46
+ });
47
+ if (type === 'object') {
48
+ for (const key in schema.properties) {
49
+ debug('going over object properties at path %s', key, path);
50
+ const subSchema = schema.properties[key];
51
+ if (typeof subSchema !== 'boolean') {
52
+ iterateOverSchemaObject(subSchema, path === '' ? key : `${path}.${key}`);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ iterateOverSchemaObject(schema, '');
58
+ return fromEnv;
59
+ }
60
+ function getEnvValues(schema) {
61
+ const res = {};
62
+ const envMap = parseSchemaEnv(schema);
63
+ for (const [key, details] of Object.entries(envMap)) {
64
+ const unparsedValue = process.env[key];
65
+ if (unparsedValue !== undefined) {
66
+ debug('found env value for key %s with type %s', key, details.type);
67
+ let value;
68
+ switch (details.type) {
69
+ case 'boolean':
70
+ value = unparsedValue.toLowerCase() === 'true';
71
+ break;
72
+ case 'integer':
73
+ value = parseInt(unparsedValue);
74
+ break;
75
+ case 'number':
76
+ value = parseFloat(unparsedValue);
77
+ break;
78
+ case 'null':
79
+ value = null;
80
+ break;
81
+ default:
82
+ value = unparsedValue;
83
+ }
84
+ lodash_1.default.set(res, details.path, value);
85
+ }
86
+ }
87
+ return res;
88
+ }
89
+ exports.getEnvValues = getEnvValues;
90
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { ValidationError } from '@apideck/better-ajv-errors';
2
+ import { Dispatcher } from 'undici';
3
+ declare const configErrors: {
4
+ readonly optionValidationError: {
5
+ readonly code: 1;
6
+ readonly payload: ValidationError[];
7
+ };
8
+ readonly configValidationError: {
9
+ readonly code: 2;
10
+ readonly payload: ValidationError[];
11
+ };
12
+ readonly httpResponseError: {
13
+ readonly code: 3;
14
+ readonly payload: Pick<Dispatcher.ResponseData, "headers" | "statusCode"> & {
15
+ body: string;
16
+ };
17
+ };
18
+ readonly httpGeneralError: {
19
+ readonly code: 4;
20
+ readonly payload: Error;
21
+ };
22
+ readonly schemaNotFoundError: {
23
+ readonly code: 5;
24
+ readonly payload: {
25
+ schemaPath: string;
26
+ };
27
+ };
28
+ readonly schemasPackageVersionMismatchError: {
29
+ readonly code: 6;
30
+ readonly payload: {
31
+ remotePackageVersion: string;
32
+ localPackageVersion: string;
33
+ };
34
+ };
35
+ readonly schemaVersionMismatchError: {
36
+ readonly code: 7;
37
+ readonly payload: {
38
+ remoteSchemaVersion: string;
39
+ localSchemaVersion: string;
40
+ };
41
+ };
42
+ };
43
+ /**
44
+ * Represents the configuration errors.
45
+ */
46
+ export type ConfigErrors = typeof configErrors;
47
+ /**
48
+ * Represents an error specific to the configuration module.
49
+ *
50
+ * @template ErrorName - The name of the error.
51
+ * @template Payload - The payload type associated with the error.
52
+ */
53
+ export declare class ConfigError<ErrorName extends keyof ConfigErrors, Payload = ConfigErrors[ErrorName]['payload']> extends Error {
54
+ readonly payload: Payload | undefined;
55
+ readonly code: ConfigErrors[ErrorName]['code'];
56
+ /**
57
+ * Creates a new instance of the ConfigError class.
58
+ *
59
+ * @param name - The name of the error.
60
+ * @param message - The error message.
61
+ * @param payload - The payload associated with the error.
62
+ */
63
+ constructor(name: ErrorName, message: string, payload: Payload | undefined);
64
+ }
65
+ export declare function createConfigError<ErrorName extends keyof ConfigErrors, Payload extends ConfigErrors[ErrorName]['payload']>(name: ErrorName, message: string, payload: Payload): ConfigError<ErrorName, Payload>;
66
+ /**
67
+ * Checks if the given error is an instance of `ConfigError` with the specified error type.
68
+ * @param error - The error to check.
69
+ * @param errorName - The name of the error to check against.
70
+ * @returns `true` if the error is an instance of `ConfigError` with the specified error name, `false` otherwise.
71
+ */
72
+ export declare function isConfigError<ErrorName extends keyof ConfigErrors>(error: unknown, errorName: ErrorName): error is ConfigError<ErrorName>;
73
+ export {};
74
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,QAAA,MAAM,YAAY;;;;;;;;;;;;kBAG+F,MAAM;;;;;;;;;;wBAExD,MAAM;;;;;;kCACmB,MAAM;iCAAuB,MAAM;;;;;;iCAC5C,MAAM;gCAAsB,MAAM;;;CAE9C,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,qBAAa,WAAW,CAAC,SAAS,SAAS,MAAM,YAAY,EAAE,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAE,SAAQ,KAAK;aAUnD,OAAO,EAAE,OAAO,GAAG,SAAS;IATjG,SAAgB,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;IAEtD;;;;;;OAMG;gBACgB,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAkB,OAAO,EAAE,OAAO,GAAG,SAAS;CAKlG;AAED,wBAAgB,iBAAiB,CAAC,SAAS,SAAS,MAAM,YAAY,EAAE,OAAO,SAAS,YAAY,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,EACxH,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,GACf,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,IAAI,WAAW,CAAC,SAAS,CAAC,CAMzI"}