@meltstudio/config-loader 1.0.3 → 1.1.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.
package/README.md CHANGED
@@ -1,9 +1,13 @@
1
- # Config Loader
1
+ # @meltstudio/config-loader
2
+
3
+ > ⚠️ **WARNING**: This project is in beta, so some features may change in the future. Use at your own discretion
4
+
2
5
  ## Project Description
3
6
 
4
7
  The Config Loader package is a powerful and user-friendly tool that simplifies the process of retrieving and collecting variables from one or multiple files for your project. It provides an efficient way to extract specific information from files and access those variables in your code. The result is a JSON object, making it easy to work with in various applications.
5
8
 
6
9
  ## Features
10
+
7
11
  - Retrieve and collect variables from one or multiple files in your project.
8
12
  - YAML file support (support for other file types coming soon.)
9
13
  - Data can also be retrieved from CLI or environment variables .
@@ -23,9 +27,11 @@ To install the project, you can use the following steps:
23
27
  1. Ensure that you have [Node.js](https://nodejs.org/) installed on your machine.
24
28
  2. Open a terminal or command prompt.
25
29
  3. Run the following command to install the project and its dependencies via npm:
30
+
26
31
  ```bash
27
32
  $ npm install @meltstudio/config-loader
28
33
  ```
34
+
29
35
  ```bash
30
36
  $ yarn add @meltstudio/config-loader
31
37
  ```
@@ -37,48 +43,45 @@ Here's an example of how to use the `@meltstudio/config-loader` package in a Typ
37
43
  ```typescript
38
44
  import path from "path";
39
45
 
40
- import Settings, { option } from "@/src";
46
+ import c from "@meltstudio/config-loader";
41
47
 
42
48
  const run = (): void => {
43
- const settings = new Settings(
44
- {
45
- version: option.string({ required: true, cli: true }),
46
- website: {
47
- title: option.string({ required: true }),
48
- url: option.string({
49
- required: false,
50
- defaultValue: "www.mywebsite.dev",
51
- }),
52
- description: option.string({ required: true }),
53
- isProduction: option.bool({ required: true }),
54
- },
55
- database: {
56
- host: option.string({ required: true }),
57
- port: option.number({ required: true }),
58
- credentials: {
59
- username: option.string(),
60
- password: option.string(),
61
- },
62
- },
63
- socialMedia: option.array({
64
- required: true,
65
- item: option.string({ required: true }),
66
- }),
67
- features: option.array({
68
- required: true,
69
- item: {
70
- name: option.string(),
71
- enabled: option.bool(),
72
- },
49
+ const settings = c.schema({
50
+ version: c.string({ required: true, cli: true }),
51
+ website: {
52
+ title: c.string({ required: true }),
53
+ url: c.string({
54
+ required: false,
55
+ defaultValue: "www.mywebsite.dev",
73
56
  }),
57
+ description: c.string({ required: true }),
58
+ isProduction: c.bool({ required: true }),
74
59
  },
75
- {
76
- env: false,
77
- args: true,
78
- files: path.join(__dirname, "./config.yaml"),
79
- }
80
- );
81
- const config = settings.get();
60
+ database: {
61
+ host: c.string({ required: true }),
62
+ port: c.number({ required: true }),
63
+ credentials: {
64
+ username: c.string(),
65
+ password: c.string(),
66
+ },
67
+ },
68
+ socialMedia: c.array({
69
+ required: true,
70
+ item: c.string({ required: true }),
71
+ }),
72
+ features: c.array({
73
+ required: true,
74
+ item: {
75
+ name: c.string(),
76
+ enabled: c.bool(),
77
+ },
78
+ }),
79
+ });
80
+ const config = settings.load({
81
+ env: false,
82
+ args: true,
83
+ files: path.join(__dirname, "./config.yaml"),
84
+ });
82
85
  console.log(JSON.stringify(config, null, 2));
83
86
  };
84
87
 
@@ -86,6 +89,7 @@ run();
86
89
  ```
87
90
 
88
91
  With a config.yaml file with the following contents:
92
+
89
93
  ```yaml
90
94
  version: 1.0.0
91
95
  website:
@@ -115,6 +119,7 @@ apiKeys:
115
119
  ```
116
120
 
117
121
  The expected output would be:
122
+
118
123
  ```json
119
124
  {
120
125
  "version": "1.0.0",
@@ -154,84 +159,93 @@ You can try executing our example in your project by following these steps with
154
159
  ```bash
155
160
  yarn example:run
156
161
  ```
162
+
157
163
  ### Usage with CLI
164
+
158
165
  When using our package with cli, it is important to have the cli attribute set to true.
159
166
  This will allow values to be sent when running the package from the command line.
167
+
160
168
  ```typescript
161
169
  import path from "path";
162
170
 
163
- import Settings, { option } from "@/src";
171
+ import c from "@meltstudio/config-loader";
164
172
 
165
173
  const run = (): void => {
166
- const settings = new Settings(
167
- {
168
- version: option.string({
169
- required: true,
170
- cli: true, 👈
171
- }),
172
- },
173
- {
174
- env: false,
175
- args: true,
176
- files: path.join(__dirname, "./config.yaml"),
177
- }
178
- );
179
- const config = settings.get();
174
+ const settings = c.schema({
175
+ version: c.string({
176
+ required: true,
177
+ cli: true, 👈
178
+ }),
179
+ });
180
+ const config = settings.load({
181
+ env: false,
182
+ args: true,
183
+ files: path.join(__dirname, "./config.yaml"),
184
+ });
180
185
  console.log(JSON.stringify(config, null, 2));
181
186
  };
182
187
 
183
188
  run();
184
189
  ```
185
- now for use it you need to send the property name on the command line with the new value
190
+
191
+ To use it you need to send the property name on the command line with the new value
192
+
186
193
  ```bash
187
194
  yarn example:run --version 2.0.0
188
195
  ```
196
+
189
197
  Having the following config.yaml file:
198
+
190
199
  ```yaml
191
200
  version: 1.0.0
192
201
  ```
202
+
193
203
  The expected output would be:
204
+
194
205
  ```json
195
206
  {
196
- "version": "2.0.0",
207
+ "version": "2.0.0"
197
208
  }
198
209
  ```
210
+
199
211
  You can see that the CLI variable overrode the yaml file variable
212
+
200
213
  ### Usage with Environment Variables
214
+
201
215
  The Config Loader package allows you to use environment variables in your system configuration. You can specify variable names in your configuration and get them. To use this feature you need to set **env: true**
216
+
202
217
  ```typescript
203
218
  import path from "path";
204
219
 
205
- import Settings, { option } from "@/src";
220
+ import c from "@meltstudio/config-loader";
206
221
 
207
222
  const run = (): void => {
208
- const settings = new Settings(
209
- {
210
- database: {
211
- host: option.string({ required: true }),
212
- port: option.number({ required: true }),
213
- credentials: {
214
- username: option.string(),
215
- password: option.string({
216
- env: "DB_PASSWORD",
217
- cli: true,
218
- }),
219
- },
223
+ const settings = c.schema({
224
+ database: {
225
+ host: c.string({ required: true }),
226
+ port: c.number({ required: true }),
227
+ credentials: {
228
+ username: c.string(),
229
+ password: c.string({
230
+ env: "DB_PASSWORD",
231
+ cli: true,
232
+ }),
220
233
  },
221
234
  },
222
- {
223
- env: true, 👈
224
- args: true,
225
- files: path.join(__dirname, "./config.yaml"),
226
- }
227
- );
228
- const config = settings.get();
235
+ });
236
+ const config = settings.load({
237
+ env: true, 👈
238
+ args: true,
239
+ files: path.join(__dirname, "./config.yaml"),
240
+ });
229
241
  console.log(JSON.stringify(config, null, 2));
230
242
  };
231
243
 
232
244
  run();
233
245
  ```
246
+
234
247
  With the following config.yaml file:
248
+
235
249
  ```yaml
236
250
  database:
237
251
  host: localhost
@@ -240,10 +254,13 @@ database:
240
254
  username: admin
241
255
  password: IGNORED_PASSWORD
242
256
  ```
257
+
243
258
  ```bash
244
259
  yarn example:run
245
260
  ```
261
+
246
262
  If you have the environment variable `DB_PASSWORD=ENV_USED_PASSWORD`, the expected output would be:
263
+
247
264
  ```json
248
265
  {
249
266
  "database": {
@@ -256,6 +273,9 @@ If you have the environment variable `DB_PASSWORD=ENV_USED_PASSWORD`, the expect
256
273
  }
257
274
  }
258
275
  ```
276
+
259
277
  You can notice that the environment variable overrode the value in the config.yaml file
278
+
260
279
  ## License
280
+
261
281
  This package is licensed under the Apache License 2.0. For more information, please see the [LICENSE](./LICENSE) file.
package/dist/index.d.ts CHANGED
@@ -9,9 +9,6 @@ declare class ConfigNode {
9
9
  constructor(value: Value | ArrayValue, path: string, source_type: SourceTypes, file: string | null, variable_name: string | null, arg_name: string | null);
10
10
  }
11
11
 
12
- type NodeTree = {
13
- [key: string]: NodeTree | ConfigNode;
14
- };
15
12
  type SettingsSources<T> = {
16
13
  env: boolean;
17
14
  args: boolean;
@@ -37,7 +34,7 @@ declare class ArrayValueContainer {
37
34
  }
38
35
 
39
36
  type Value = boolean | string | number | object | InvalidValue;
40
- type DefaultValue = Value | (() => string) | (() => number);
37
+ type DefaultValue = Value | (() => string) | (() => number) | (() => boolean);
41
38
  type RecursiveNode<T> = {
42
39
  [key: string]: OptionBase | T;
43
40
  };
@@ -85,27 +82,10 @@ declare class PrimitiveOption extends OptionBase {
85
82
 
86
83
  type OptionTypes = PrimitiveOption | ArrayOption;
87
84
 
88
- declare class Settings<T> {
85
+ declare class SettingsBuilder {
89
86
  private readonly schema;
90
- private readonly sources;
91
- private sourceFile;
92
- private argsData;
93
- private envData;
94
- private optionsTree;
95
- private defaultData;
96
- private program;
97
- constructor(schema: Node, sources: SettingsSources<T>);
98
- private validateFiles;
99
- private load;
100
- private traverseOptions;
101
- private buildOption;
102
- private getValidatedArray;
103
- private processArrayWithSchema;
104
- private setOption;
105
- private addArg;
106
- private getValuesFromTree;
107
- get(): T;
108
- getExtended(): NodeTree;
87
+ constructor(schema: Node);
88
+ load<T>(sources: SettingsSources<T>): T;
109
89
  }
110
90
 
111
91
  interface OptionPropsArgs {
@@ -125,6 +105,7 @@ declare const option: {
125
105
  number: (opts?: OptionPropsArgs) => PrimitiveOption;
126
106
  bool: (opts?: OptionPropsArgs) => PrimitiveOption;
127
107
  array: (opts: ArrayOptionPropsArgs) => ArrayOption;
108
+ schema: (theSchema: Node) => SettingsBuilder;
128
109
  };
129
110
 
130
- export { Settings as default, option };
111
+ export { option as default };
package/dist/index.js CHANGED
@@ -35,29 +35,13 @@ var __publicField = (obj, key, value) => {
35
35
  // src/index.ts
36
36
  var src_exports = {};
37
37
  __export(src_exports, {
38
- default: () => src_default,
39
- option: () => option
38
+ default: () => src_default
40
39
  });
41
40
  module.exports = __toCommonJS(src_exports);
42
41
 
43
- // src/types.ts
44
- var InvalidValue = class {
45
- };
46
-
47
- // src/option/arrayOption.ts
48
- var ArrayValueContainer = class {
49
- val;
50
- item;
51
- constructor(item, val) {
52
- this.val = val;
53
- this.item = item;
54
- }
55
- };
56
- var arrayOption_default = ArrayValueContainer;
57
-
58
- // src/option/base.ts
59
- var fs = __toESM(require("fs"));
60
- var import_js_yaml = __toESM(require("js-yaml"));
42
+ // src/settings.ts
43
+ var import_commander = require("commander");
44
+ var fs2 = __toESM(require("fs"));
61
45
 
62
46
  // src/nodes/configNode.ts
63
47
  var ConfigNode = class {
@@ -78,6 +62,34 @@ var ConfigNode = class {
78
62
  };
79
63
  var configNode_default = ConfigNode;
80
64
 
65
+ // src/nodes/configNodeArray.ts
66
+ var ConfigNodeArray = class {
67
+ arrayValues;
68
+ constructor(arrayValues) {
69
+ this.arrayValues = arrayValues;
70
+ }
71
+ };
72
+ var configNodeArray_default = ConfigNodeArray;
73
+
74
+ // src/types.ts
75
+ var InvalidValue = class {
76
+ };
77
+
78
+ // src/option/arrayOption.ts
79
+ var ArrayValueContainer = class {
80
+ val;
81
+ item;
82
+ constructor(item, val) {
83
+ this.val = val;
84
+ this.item = item;
85
+ }
86
+ };
87
+ var arrayOption_default = ArrayValueContainer;
88
+
89
+ // src/option/base.ts
90
+ var fs = __toESM(require("fs"));
91
+ var import_js_yaml = __toESM(require("js-yaml"));
92
+
81
93
  // src/utils.ts
82
94
  function valueIsInvalid(val) {
83
95
  return val instanceof InvalidValue || val === null || val === void 0;
@@ -231,10 +243,18 @@ var OptionBase = class {
231
243
  }
232
244
  }
233
245
  if (this.params.defaultValue !== void 0) {
246
+ let defaultValue;
234
247
  if (typeof this.params.defaultValue === "function") {
248
+ defaultValue = this.params.defaultValue();
249
+ } else {
250
+ defaultValue = this.params.defaultValue;
251
+ }
252
+ if (this.params.kind === "array" && Array.isArray(defaultValue)) {
253
+ defaultValue = this.buildArrayOption(defaultValue);
254
+ }
255
+ if (!valueIsInvalid(defaultValue)) {
235
256
  return new configNode_default(
236
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
237
- this.checkType(this.params.defaultValue(), path, "default"),
257
+ this.checkType(defaultValue, path, "default"),
238
258
  ident,
239
259
  "default",
240
260
  null,
@@ -242,14 +262,6 @@ var OptionBase = class {
242
262
  null
243
263
  );
244
264
  }
245
- return new configNode_default(
246
- this.checkType(this.params.defaultValue, path, "default"),
247
- ident,
248
- "default",
249
- null,
250
- null,
251
- null
252
- );
253
265
  }
254
266
  if (this.params.required) {
255
267
  OptionErrors.errors.push(`Required option '${ident}' not provided.`);
@@ -410,19 +422,6 @@ var ArrayOption = class extends OptionBase {
410
422
  var PrimitiveOption = class extends OptionBase {
411
423
  };
412
424
 
413
- // src/settings.ts
414
- var import_commander = require("commander");
415
- var fs2 = __toESM(require("fs"));
416
-
417
- // src/nodes/configNodeArray.ts
418
- var ConfigNodeArray = class {
419
- arrayValues;
420
- constructor(arrayValues) {
421
- this.arrayValues = arrayValues;
422
- }
423
- };
424
- var configNodeArray_default = ConfigNodeArray;
425
-
426
425
  // src/settings.ts
427
426
  var Settings = class {
428
427
  schema;
@@ -433,8 +432,8 @@ var Settings = class {
433
432
  optionsTree = {};
434
433
  defaultData = {};
435
434
  program;
436
- constructor(schema, sources) {
437
- this.schema = schema;
435
+ constructor(schema2, sources) {
436
+ this.schema = schema2;
438
437
  this.sources = sources;
439
438
  this.program = new import_commander.Command().allowUnknownOption(true).allowExcessArguments(true);
440
439
  this.load();
@@ -645,8 +644,19 @@ var Settings = class {
645
644
  };
646
645
  var settings_default = Settings;
647
646
 
647
+ // src/builder/settings.ts
648
+ var SettingsBuilder = class {
649
+ schema;
650
+ constructor(schema2) {
651
+ this.schema = schema2;
652
+ }
653
+ load(sources) {
654
+ const settings = new settings_default(this.schema, sources);
655
+ return settings.get();
656
+ }
657
+ };
658
+
648
659
  // src/index.ts
649
- var src_default = settings_default;
650
660
  var DEFAULTS = {
651
661
  required: false,
652
662
  env: null,
@@ -681,14 +691,15 @@ var array = (opts) => {
681
691
  ...opts
682
692
  });
683
693
  };
694
+ var schema = (theSchema) => {
695
+ return new SettingsBuilder(theSchema);
696
+ };
684
697
  var option = {
685
698
  string,
686
699
  number,
687
700
  bool,
688
701
  // object,
689
- array
702
+ array,
703
+ schema
690
704
  };
691
- // Annotate the CommonJS export names for ESM import in node:
692
- 0 && (module.exports = {
693
- option
694
- });
705
+ var src_default = option;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltstudio/config-loader",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Melt Studio's tool for loading configurations into a Node.js application.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -25,7 +25,10 @@
25
25
  "type-check": "tsc --noEmit",
26
26
  "test": "jest --verbose",
27
27
  "example:run": "ts-node -r tsconfig-paths/register ./example/index.ts",
28
- "prepare": "husky install"
28
+ "prepare": "husky install",
29
+ "docs:install": "python -m venv ./mkdocs-py-env && ./mkdocs-py-env/Scripts/pip install -r ./mkdocs-requirements.txt",
30
+ "docs:build": "./mkdocs-py-env/Scripts/mkdocs build",
31
+ "docs:serve": "./mkdocs-py-env/Scripts/mkdocs serve"
29
32
  },
30
33
  "dependencies": {
31
34
  "@types/js-yaml": "^4.0.5",