@meltstudio/config-loader 1.0.0 → 1.0.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.
- package/README.md +59 -34
- package/dist/index.d.ts +130 -0
- package/dist/index.js +694 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
# Config Loader
|
|
2
2
|
## Project Description
|
|
3
3
|
|
|
4
|
-
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
|
|
4
|
+
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
5
|
|
|
6
6
|
## Features
|
|
7
7
|
- Retrieve and collect variables from one or multiple files in your project.
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Compatible with TypeScript environments, making it suitable for Node.js
|
|
8
|
+
- YAML file support (support for other file types coming soon.)
|
|
9
|
+
- Data can also be retrieved from CLI or environment variables .
|
|
10
|
+
- Compatible with TypeScript/JavaScript environments, making it suitable for Node.js projects.
|
|
11
11
|
|
|
12
12
|
## Table of Contents
|
|
13
13
|
|
|
14
14
|
- [Installation](#installation)
|
|
15
15
|
- [Usage](#usage)
|
|
16
|
-
- [Contributing](#contributing)
|
|
17
16
|
- [License](#license)
|
|
18
17
|
- [Acknowledgements](#acknowledgements)
|
|
19
18
|
|
|
@@ -43,6 +42,7 @@ import Settings, { option } from "@/src";
|
|
|
43
42
|
const run = (): void => {
|
|
44
43
|
const settings = new Settings(
|
|
45
44
|
{
|
|
45
|
+
version: option.string({ required: true, cli: true }),
|
|
46
46
|
website: {
|
|
47
47
|
title: option.string({ required: true }),
|
|
48
48
|
url: option.string({
|
|
@@ -66,12 +66,10 @@ const run = (): void => {
|
|
|
66
66
|
}),
|
|
67
67
|
features: option.array({
|
|
68
68
|
required: true,
|
|
69
|
-
item:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
},
|
|
74
|
-
}),
|
|
69
|
+
item: {
|
|
70
|
+
name: option.string(),
|
|
71
|
+
enabled: option.bool(),
|
|
72
|
+
},
|
|
75
73
|
}),
|
|
76
74
|
},
|
|
77
75
|
{
|
|
@@ -86,9 +84,40 @@ const run = (): void => {
|
|
|
86
84
|
|
|
87
85
|
run();
|
|
88
86
|
```
|
|
87
|
+
|
|
88
|
+
With a config.yaml file with the following contents:
|
|
89
|
+
```yaml
|
|
90
|
+
version: 1.0.0
|
|
91
|
+
website:
|
|
92
|
+
title: My Website
|
|
93
|
+
description: A simple and elegant website
|
|
94
|
+
port: 3000
|
|
95
|
+
isProduction: false
|
|
96
|
+
|
|
97
|
+
database:
|
|
98
|
+
host: localhost
|
|
99
|
+
port: 5432
|
|
100
|
+
credentials:
|
|
101
|
+
username: admin
|
|
102
|
+
password: secret
|
|
103
|
+
|
|
104
|
+
socialMedia: [https://twitter.com/example, https://instagram.com/example]
|
|
105
|
+
|
|
106
|
+
features:
|
|
107
|
+
- name: Store
|
|
108
|
+
enabled: true
|
|
109
|
+
- name: Admin
|
|
110
|
+
enabled: false
|
|
111
|
+
|
|
112
|
+
apiKeys:
|
|
113
|
+
googleMaps: ${GOOGLE_MAPS_API_KEY}
|
|
114
|
+
sendGrid: ${SENDGRID_API_KEY}
|
|
115
|
+
```
|
|
116
|
+
|
|
89
117
|
The expected output would be:
|
|
90
118
|
```json
|
|
91
119
|
{
|
|
120
|
+
"version": "1.0.0",
|
|
92
121
|
"website": {
|
|
93
122
|
"title": "My Website",
|
|
94
123
|
"url": "www.mywebsite.dev",
|
|
@@ -126,7 +155,7 @@ You can try executing our example in your project by following these steps with
|
|
|
126
155
|
yarn example:run
|
|
127
156
|
```
|
|
128
157
|
### Usage with CLI
|
|
129
|
-
When using our package with cli, is important have the cli attribute
|
|
158
|
+
When using our package with cli, it is important to have the cli attribute set to true.
|
|
130
159
|
This will allow values to be sent when running the package from the command line.
|
|
131
160
|
```typescript
|
|
132
161
|
import path from "path";
|
|
@@ -157,14 +186,19 @@ now for use it you need to send the property name on the command line with the n
|
|
|
157
186
|
```bash
|
|
158
187
|
yarn example:run --version 2.0.0
|
|
159
188
|
```
|
|
189
|
+
Having the following config.yaml file:
|
|
190
|
+
```yaml
|
|
191
|
+
version: 1.0.0
|
|
192
|
+
```
|
|
160
193
|
The expected output would be:
|
|
161
194
|
```json
|
|
162
195
|
{
|
|
163
196
|
"version": "2.0.0",
|
|
164
197
|
}
|
|
165
198
|
```
|
|
199
|
+
You can see that the CLI variable overrode the yaml file variable
|
|
166
200
|
### Usage with Environment Variables
|
|
167
|
-
The Config Loader package allows you to
|
|
201
|
+
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**
|
|
168
202
|
```typescript
|
|
169
203
|
import path from "path";
|
|
170
204
|
|
|
@@ -197,10 +231,19 @@ const run = (): void => {
|
|
|
197
231
|
|
|
198
232
|
run();
|
|
199
233
|
```
|
|
234
|
+
With the following config.yaml file:
|
|
235
|
+
```yaml
|
|
236
|
+
database:
|
|
237
|
+
host: localhost
|
|
238
|
+
port: 5432
|
|
239
|
+
credentials:
|
|
240
|
+
username: admin
|
|
241
|
+
password: IGNORED_PASSWORD
|
|
242
|
+
```
|
|
200
243
|
```bash
|
|
201
244
|
yarn example:run
|
|
202
245
|
```
|
|
203
|
-
|
|
246
|
+
If you have the environment variable `DB_PASSWORD=ENV_USED_PASSWORD`, the expected output would be:
|
|
204
247
|
```json
|
|
205
248
|
{
|
|
206
249
|
"database": {
|
|
@@ -208,29 +251,11 @@ The expected output would be:
|
|
|
208
251
|
"port": 5432,
|
|
209
252
|
"credentials": {
|
|
210
253
|
"username": "admin",
|
|
211
|
-
"password": "
|
|
254
|
+
"password": "ENV_USED_PASSWORD"
|
|
212
255
|
}
|
|
213
256
|
}
|
|
214
257
|
}
|
|
215
258
|
```
|
|
216
|
-
|
|
217
|
-
## Contributing
|
|
218
|
-
Explain how others can contribute to the project. Include guidelines for submitting issues, pull requests, or feature requests.
|
|
219
|
-
|
|
220
|
-
1. Fork the repository
|
|
221
|
-
2. Create a new branch
|
|
222
|
-
3. Implement your changes
|
|
223
|
-
4. Open a pull request
|
|
224
|
-
|
|
259
|
+
You can notice that the environment variable overrode the value in the config.yaml file
|
|
225
260
|
## License
|
|
226
261
|
This package is licensed under the Apache License 2.0. For more information, please see the [LICENSE](./LICENSE) file.
|
|
227
|
-
|
|
228
|
-
## Acknowledgements
|
|
229
|
-
|
|
230
|
-
🙌 We would like to express our gratitude to the following individuals and resources that have contributed to this project:
|
|
231
|
-
|
|
232
|
-
- [Manuael Zapata](https://github.com/author1) 🚀: Co-creator and lead developer of the project.
|
|
233
|
-
- [Pablo Piedrahita](https://github.com/author2) 👏: Co-creator and lead developer of the project.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Thank you all for your valuable contributions and support! 🎉
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
type SourceTypes = "file" | "env" | "args" | "default";
|
|
2
|
+
declare class ConfigNode {
|
|
3
|
+
value: Value | ArrayValueContainer;
|
|
4
|
+
path: string;
|
|
5
|
+
source_type: SourceTypes;
|
|
6
|
+
file: string | null;
|
|
7
|
+
variable_name: string | null;
|
|
8
|
+
arg_name: string | null;
|
|
9
|
+
constructor(value: Value | ArrayValue, path: string, source_type: SourceTypes, file: string | null, variable_name: string | null, arg_name: string | null);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type NodeTree = {
|
|
13
|
+
[key: string]: NodeTree | ConfigNode;
|
|
14
|
+
};
|
|
15
|
+
type SettingsSources<T> = {
|
|
16
|
+
env: boolean;
|
|
17
|
+
args: boolean;
|
|
18
|
+
files?: string | string[] | false;
|
|
19
|
+
dir?: string | false;
|
|
20
|
+
defaults?: Partial<T>;
|
|
21
|
+
};
|
|
22
|
+
type OptionKind = "boolean" | "string" | "number" | "any" | "array" | "object";
|
|
23
|
+
type Path = Array<string | number>;
|
|
24
|
+
type ConfigFileStructure<T> = {
|
|
25
|
+
[key: string]: string | T | number | boolean | Array<T> | string[];
|
|
26
|
+
};
|
|
27
|
+
interface ConfigFileData extends ConfigFileStructure<ConfigFileData> {
|
|
28
|
+
}
|
|
29
|
+
type ArrayValue = Array<any>;
|
|
30
|
+
declare class InvalidValue {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare class ArrayValueContainer {
|
|
34
|
+
readonly val: ArrayValue;
|
|
35
|
+
readonly item: Node | OptionTypes;
|
|
36
|
+
constructor(item: Node | OptionTypes, val: ArrayValue);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type Value = boolean | string | number | object | InvalidValue;
|
|
40
|
+
type DefaultValue = Value | (() => string) | (() => number);
|
|
41
|
+
type RecursiveNode<T> = {
|
|
42
|
+
[key: string]: OptionBase | T;
|
|
43
|
+
};
|
|
44
|
+
interface Node extends RecursiveNode<Node> {
|
|
45
|
+
}
|
|
46
|
+
interface OptionClassParams {
|
|
47
|
+
kind: OptionKind;
|
|
48
|
+
required: boolean;
|
|
49
|
+
env: string | null;
|
|
50
|
+
cli: boolean;
|
|
51
|
+
help: string;
|
|
52
|
+
defaultValue?: DefaultValue;
|
|
53
|
+
}
|
|
54
|
+
declare class OptionBase {
|
|
55
|
+
readonly params: OptionClassParams;
|
|
56
|
+
constructor(params: OptionClassParams);
|
|
57
|
+
getValue<T>(sourceFile: string | string[], env: {
|
|
58
|
+
[key: string]: string | undefined;
|
|
59
|
+
}, args: {
|
|
60
|
+
[key: string]: string | boolean;
|
|
61
|
+
}, path: Path, defaultValues?: Partial<T>, objectFromArray?: {
|
|
62
|
+
value: ConfigFileData;
|
|
63
|
+
file: string;
|
|
64
|
+
}): ConfigNode | null;
|
|
65
|
+
protected checkNumberType(val: Value, pathStr: string, sourceOfVal: string): Value;
|
|
66
|
+
checkType(val: Value, path: Path, sourceOfVal: string): Value;
|
|
67
|
+
protected findInObject(obj: ConfigFileData, path: Path): Value | ArrayValue;
|
|
68
|
+
buildArrayOption(_val: string[] | ConfigFileData[]): ArrayValueContainer | InvalidValue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface ArrayOptionClassParams {
|
|
72
|
+
required: boolean;
|
|
73
|
+
defaultValue?: DefaultValue;
|
|
74
|
+
item: Node | OptionTypes;
|
|
75
|
+
}
|
|
76
|
+
declare class ArrayOption extends OptionBase {
|
|
77
|
+
item: Node | OptionTypes;
|
|
78
|
+
constructor(params: ArrayOptionClassParams);
|
|
79
|
+
buildArrayOption(val: string[] | ConfigFileData[]): ArrayValueContainer | InvalidValue;
|
|
80
|
+
checkType(val: Value, path: Path, sourceOfVal: string): Value;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
declare class PrimitiveOption extends OptionBase {
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
type OptionTypes = PrimitiveOption | ArrayOption;
|
|
87
|
+
|
|
88
|
+
declare class Settings<T> {
|
|
89
|
+
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;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
interface OptionPropsArgs {
|
|
112
|
+
required?: boolean;
|
|
113
|
+
env?: string | null;
|
|
114
|
+
cli?: boolean;
|
|
115
|
+
defaultValue?: DefaultValue;
|
|
116
|
+
help?: string;
|
|
117
|
+
}
|
|
118
|
+
interface ArrayOptionPropsArgs {
|
|
119
|
+
required?: boolean;
|
|
120
|
+
item: Node | OptionTypes;
|
|
121
|
+
defaultValue?: DefaultValue;
|
|
122
|
+
}
|
|
123
|
+
declare const option: {
|
|
124
|
+
string: (opts?: OptionPropsArgs) => PrimitiveOption;
|
|
125
|
+
number: (opts?: OptionPropsArgs) => PrimitiveOption;
|
|
126
|
+
bool: (opts?: OptionPropsArgs) => PrimitiveOption;
|
|
127
|
+
array: (opts: ArrayOptionPropsArgs) => ArrayOption;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export { Settings as default, option };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,694 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var __publicField = (obj, key, value) => {
|
|
31
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
32
|
+
return value;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// src/index.ts
|
|
36
|
+
var src_exports = {};
|
|
37
|
+
__export(src_exports, {
|
|
38
|
+
default: () => src_default,
|
|
39
|
+
option: () => option
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(src_exports);
|
|
42
|
+
|
|
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"));
|
|
61
|
+
|
|
62
|
+
// src/nodes/configNode.ts
|
|
63
|
+
var ConfigNode = class {
|
|
64
|
+
value;
|
|
65
|
+
path;
|
|
66
|
+
source_type;
|
|
67
|
+
file;
|
|
68
|
+
variable_name;
|
|
69
|
+
arg_name;
|
|
70
|
+
constructor(value, path, source_type, file, variable_name, arg_name) {
|
|
71
|
+
this.value = value;
|
|
72
|
+
this.path = path;
|
|
73
|
+
this.source_type = source_type;
|
|
74
|
+
this.file = file;
|
|
75
|
+
this.variable_name = variable_name;
|
|
76
|
+
this.arg_name = arg_name;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var configNode_default = ConfigNode;
|
|
80
|
+
|
|
81
|
+
// src/utils.ts
|
|
82
|
+
function valueIsInvalid(val) {
|
|
83
|
+
return val instanceof InvalidValue || val === null || val === void 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/option/errors.ts
|
|
87
|
+
var _OptionErrors = class {
|
|
88
|
+
static clearAll() {
|
|
89
|
+
_OptionErrors.errors = [];
|
|
90
|
+
_OptionErrors.warnings = [];
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
var OptionErrors = _OptionErrors;
|
|
94
|
+
__publicField(OptionErrors, "errors", []);
|
|
95
|
+
__publicField(OptionErrors, "warnings", []);
|
|
96
|
+
|
|
97
|
+
// src/option/base.ts
|
|
98
|
+
var OptionBase = class {
|
|
99
|
+
params;
|
|
100
|
+
constructor(params) {
|
|
101
|
+
this.params = params;
|
|
102
|
+
}
|
|
103
|
+
getValue(sourceFile, env, args, path, defaultValues, objectFromArray) {
|
|
104
|
+
const ident = path.join(".");
|
|
105
|
+
if (this.params.cli && args) {
|
|
106
|
+
if (ident in args) {
|
|
107
|
+
return new configNode_default(
|
|
108
|
+
this.checkType(args[ident], path, "args"),
|
|
109
|
+
ident,
|
|
110
|
+
"args",
|
|
111
|
+
null,
|
|
112
|
+
null,
|
|
113
|
+
ident
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (this.params.env && env) {
|
|
118
|
+
if (this.params.env in env) {
|
|
119
|
+
const val = env[this.params.env];
|
|
120
|
+
if (val) {
|
|
121
|
+
return new configNode_default(
|
|
122
|
+
this.checkType(val, path, "env"),
|
|
123
|
+
ident,
|
|
124
|
+
"env",
|
|
125
|
+
null,
|
|
126
|
+
this.params.env,
|
|
127
|
+
null
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (typeof sourceFile === "string") {
|
|
133
|
+
const data = import_js_yaml.default.load(
|
|
134
|
+
fs.readFileSync(sourceFile, "utf-8")
|
|
135
|
+
);
|
|
136
|
+
const val = this.findInObject(data || {}, path);
|
|
137
|
+
if (val instanceof arrayOption_default) {
|
|
138
|
+
return new configNode_default(
|
|
139
|
+
this.checkType(val, path, sourceFile),
|
|
140
|
+
ident,
|
|
141
|
+
"file",
|
|
142
|
+
sourceFile,
|
|
143
|
+
null,
|
|
144
|
+
null
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (!valueIsInvalid(val)) {
|
|
148
|
+
return new configNode_default(
|
|
149
|
+
this.checkType(val, path, sourceFile),
|
|
150
|
+
ident,
|
|
151
|
+
"file",
|
|
152
|
+
sourceFile,
|
|
153
|
+
null,
|
|
154
|
+
null
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (Array.isArray(sourceFile)) {
|
|
159
|
+
for (let index = 0; index < sourceFile.length; index += 1) {
|
|
160
|
+
const file = sourceFile[index];
|
|
161
|
+
const data = import_js_yaml.default.load(
|
|
162
|
+
fs.readFileSync(file, "utf-8")
|
|
163
|
+
);
|
|
164
|
+
const val = this.findInObject(data || {}, path);
|
|
165
|
+
if (val instanceof arrayOption_default) {
|
|
166
|
+
return new configNode_default(
|
|
167
|
+
this.checkType(val, path, file),
|
|
168
|
+
ident,
|
|
169
|
+
"file",
|
|
170
|
+
file,
|
|
171
|
+
null,
|
|
172
|
+
null
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (!valueIsInvalid(val)) {
|
|
176
|
+
return new configNode_default(
|
|
177
|
+
this.checkType(val, path, file),
|
|
178
|
+
ident,
|
|
179
|
+
"file",
|
|
180
|
+
file,
|
|
181
|
+
null,
|
|
182
|
+
null
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (objectFromArray) {
|
|
188
|
+
const val = this.findInObject(objectFromArray.value, path);
|
|
189
|
+
if (val instanceof arrayOption_default) {
|
|
190
|
+
return new configNode_default(
|
|
191
|
+
this.checkType(val, path, objectFromArray.file),
|
|
192
|
+
ident,
|
|
193
|
+
"file",
|
|
194
|
+
objectFromArray.file,
|
|
195
|
+
null,
|
|
196
|
+
null
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
if (!valueIsInvalid(val)) {
|
|
200
|
+
return new configNode_default(
|
|
201
|
+
this.checkType(val, path, objectFromArray.file),
|
|
202
|
+
ident,
|
|
203
|
+
"file",
|
|
204
|
+
objectFromArray.file,
|
|
205
|
+
null,
|
|
206
|
+
null
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (defaultValues) {
|
|
211
|
+
const val = this.findInObject(defaultValues, path);
|
|
212
|
+
if (val instanceof arrayOption_default) {
|
|
213
|
+
return new configNode_default(
|
|
214
|
+
this.checkType(val, path, "default"),
|
|
215
|
+
ident,
|
|
216
|
+
"default",
|
|
217
|
+
null,
|
|
218
|
+
null,
|
|
219
|
+
null
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
if (!valueIsInvalid(val)) {
|
|
223
|
+
return new configNode_default(
|
|
224
|
+
this.checkType(val, path, "default"),
|
|
225
|
+
ident,
|
|
226
|
+
"default",
|
|
227
|
+
null,
|
|
228
|
+
null,
|
|
229
|
+
null
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (this.params.defaultValue !== void 0) {
|
|
234
|
+
if (typeof this.params.defaultValue === "function") {
|
|
235
|
+
return new configNode_default(
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
237
|
+
this.checkType(this.params.defaultValue(), path, "default"),
|
|
238
|
+
ident,
|
|
239
|
+
"default",
|
|
240
|
+
null,
|
|
241
|
+
null,
|
|
242
|
+
null
|
|
243
|
+
);
|
|
244
|
+
}
|
|
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
|
+
}
|
|
254
|
+
if (this.params.required) {
|
|
255
|
+
OptionErrors.errors.push(`Required option '${ident}' not provided.`);
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
// eslint-disable-next-line class-methods-use-this
|
|
260
|
+
checkNumberType(val, pathStr, sourceOfVal) {
|
|
261
|
+
if (typeof val === "string") {
|
|
262
|
+
const parseVal = parseInt(val, 10);
|
|
263
|
+
if (Number.isNaN(parseVal)) {
|
|
264
|
+
OptionErrors.errors.push(
|
|
265
|
+
`Cannot convert value '${val}' for '${pathStr}' to number in ${sourceOfVal}.`
|
|
266
|
+
);
|
|
267
|
+
return new InvalidValue();
|
|
268
|
+
}
|
|
269
|
+
OptionErrors.warnings.push(
|
|
270
|
+
`The option ${pathStr} is stated as a number but is provided as a string`
|
|
271
|
+
);
|
|
272
|
+
return parseVal;
|
|
273
|
+
}
|
|
274
|
+
OptionErrors.errors.push(`Invalid state. Invalid kind in ${sourceOfVal}`);
|
|
275
|
+
return new InvalidValue();
|
|
276
|
+
}
|
|
277
|
+
checkType(val, path, sourceOfVal) {
|
|
278
|
+
const ident = path.join(".");
|
|
279
|
+
if (valueIsInvalid(val)) {
|
|
280
|
+
OptionErrors.errors.push(`Invalid state. Invalid kind in ${sourceOfVal}`);
|
|
281
|
+
return val;
|
|
282
|
+
}
|
|
283
|
+
if (typeof val === this.params.kind) {
|
|
284
|
+
return val;
|
|
285
|
+
}
|
|
286
|
+
if (this.params.kind === "string") {
|
|
287
|
+
if (typeof val === "number") {
|
|
288
|
+
OptionErrors.warnings.push(
|
|
289
|
+
`The option ${ident} is stated as a string but is provided as a number`
|
|
290
|
+
);
|
|
291
|
+
return val.toString();
|
|
292
|
+
}
|
|
293
|
+
OptionErrors.errors.push(
|
|
294
|
+
`Cannot convert value '${val.toString()}' for '${ident}' to string in ${sourceOfVal}.`
|
|
295
|
+
);
|
|
296
|
+
return new InvalidValue();
|
|
297
|
+
}
|
|
298
|
+
if (this.params.kind === "boolean") {
|
|
299
|
+
if (typeof val !== "boolean" && typeof val !== "object") {
|
|
300
|
+
if ([1, "1", "true"].includes(val)) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
if ([0, "0", "false"].includes(val)) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
OptionErrors.errors.push(
|
|
308
|
+
`Cannot convert value '${val.toString()}' for '${ident}' to boolean in ${sourceOfVal}.`
|
|
309
|
+
);
|
|
310
|
+
return new InvalidValue();
|
|
311
|
+
}
|
|
312
|
+
if (this.params.kind === "number") {
|
|
313
|
+
return this.checkNumberType(val, ident, sourceOfVal);
|
|
314
|
+
}
|
|
315
|
+
if (this.params.kind === "any") {
|
|
316
|
+
return val;
|
|
317
|
+
}
|
|
318
|
+
OptionErrors.errors.push(`Invalid state. Invalid kind in ${sourceOfVal}`);
|
|
319
|
+
throw new Error(
|
|
320
|
+
"Invalid kind. Must be 'string', 'number', 'boolean', 'array' or 'any'"
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
findInObject(obj, path) {
|
|
324
|
+
if (path.length > 1) {
|
|
325
|
+
const [child, ...rest] = path;
|
|
326
|
+
const val = obj[child];
|
|
327
|
+
if (typeof val === "string") {
|
|
328
|
+
OptionErrors.errors.push(`Cant get path from string value '${val}'`);
|
|
329
|
+
return new InvalidValue();
|
|
330
|
+
}
|
|
331
|
+
if (typeof val === "number") {
|
|
332
|
+
OptionErrors.errors.push(`Cant get path from number value '${val}'`);
|
|
333
|
+
return new InvalidValue();
|
|
334
|
+
}
|
|
335
|
+
if (typeof val === "boolean") {
|
|
336
|
+
OptionErrors.errors.push(
|
|
337
|
+
`Cant get path from boolean value '${val.toString()}'`
|
|
338
|
+
);
|
|
339
|
+
return new InvalidValue();
|
|
340
|
+
}
|
|
341
|
+
if (Array.isArray(val)) {
|
|
342
|
+
OptionErrors.errors.push(
|
|
343
|
+
`Cant get path from array value '${val.toString()}'`
|
|
344
|
+
);
|
|
345
|
+
return new InvalidValue();
|
|
346
|
+
}
|
|
347
|
+
if (val == null) {
|
|
348
|
+
return new InvalidValue();
|
|
349
|
+
}
|
|
350
|
+
return this.findInObject(val, rest);
|
|
351
|
+
}
|
|
352
|
+
if (path.length === 1) {
|
|
353
|
+
const val = obj[path[0]];
|
|
354
|
+
if (!Array.isArray(val) && typeof val === "object" && val || typeof val === "string" || typeof val === "number" || typeof val === "boolean" || typeof val === "undefined") {
|
|
355
|
+
return val;
|
|
356
|
+
}
|
|
357
|
+
if (Array.isArray(val)) {
|
|
358
|
+
return this.buildArrayOption(val);
|
|
359
|
+
}
|
|
360
|
+
OptionErrors.errors.push(
|
|
361
|
+
`Invalid path '${path.join(".")}': ${typeof val}`
|
|
362
|
+
);
|
|
363
|
+
return new InvalidValue();
|
|
364
|
+
}
|
|
365
|
+
OptionErrors.errors.push(`Invalid path '${path.join()}'`);
|
|
366
|
+
return new InvalidValue();
|
|
367
|
+
}
|
|
368
|
+
// eslint-disable-next-line class-methods-use-this
|
|
369
|
+
buildArrayOption(_val) {
|
|
370
|
+
return new InvalidValue();
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
// src/option/array.ts
|
|
375
|
+
var ArrayOption = class extends OptionBase {
|
|
376
|
+
item;
|
|
377
|
+
constructor(params) {
|
|
378
|
+
super({
|
|
379
|
+
kind: "array",
|
|
380
|
+
env: null,
|
|
381
|
+
cli: false,
|
|
382
|
+
help: "",
|
|
383
|
+
...params
|
|
384
|
+
});
|
|
385
|
+
this.item = params.item;
|
|
386
|
+
}
|
|
387
|
+
buildArrayOption(val) {
|
|
388
|
+
if (this.item === null) {
|
|
389
|
+
OptionErrors.errors.push(`Array item cannot be null`);
|
|
390
|
+
return new InvalidValue();
|
|
391
|
+
}
|
|
392
|
+
return new arrayOption_default(this.item, val);
|
|
393
|
+
}
|
|
394
|
+
// eslint-disable-next-line class-methods-use-this
|
|
395
|
+
checkType(val, path, sourceOfVal) {
|
|
396
|
+
if (val instanceof arrayOption_default) {
|
|
397
|
+
val.val.forEach((v, i) => {
|
|
398
|
+
if (this.item instanceof OptionBase) {
|
|
399
|
+
this.item.checkType(v, [...path, i], sourceOfVal);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
return val;
|
|
403
|
+
}
|
|
404
|
+
OptionErrors.errors.push(`Invalid state. Invalid kind in ${sourceOfVal}`);
|
|
405
|
+
return new InvalidValue();
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
// src/option/primitive.ts
|
|
410
|
+
var PrimitiveOption = class extends OptionBase {
|
|
411
|
+
};
|
|
412
|
+
|
|
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
|
+
// src/settings.ts
|
|
427
|
+
var Settings = class {
|
|
428
|
+
schema;
|
|
429
|
+
sources;
|
|
430
|
+
sourceFile = [];
|
|
431
|
+
argsData = {};
|
|
432
|
+
envData = {};
|
|
433
|
+
optionsTree = {};
|
|
434
|
+
defaultData = {};
|
|
435
|
+
program;
|
|
436
|
+
constructor(schema, sources) {
|
|
437
|
+
this.schema = schema;
|
|
438
|
+
this.sources = sources;
|
|
439
|
+
this.program = new import_commander.Command();
|
|
440
|
+
this.load();
|
|
441
|
+
}
|
|
442
|
+
validateFiles() {
|
|
443
|
+
const { files, dir } = this.sources;
|
|
444
|
+
if (files && dir)
|
|
445
|
+
throw new Error("Dir and files are specified, choose one");
|
|
446
|
+
if (files) {
|
|
447
|
+
if (Array.isArray(files)) {
|
|
448
|
+
files.forEach((file) => {
|
|
449
|
+
if (!fs2.existsSync(file)) {
|
|
450
|
+
throw new Error(`Invalid config file '${file}'`);
|
|
451
|
+
} else {
|
|
452
|
+
if (!Array.isArray(this.sourceFile)) {
|
|
453
|
+
this.sourceFile = [];
|
|
454
|
+
}
|
|
455
|
+
this.sourceFile.push(file);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
} else {
|
|
459
|
+
if (!fs2.existsSync(files)) {
|
|
460
|
+
throw new Error(`Invalid config file '${files}'`);
|
|
461
|
+
}
|
|
462
|
+
this.sourceFile = files;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (dir) {
|
|
466
|
+
if (!(fs2.existsSync(dir) && fs2.lstatSync(dir).isDirectory())) {
|
|
467
|
+
throw new Error(`'${dir}' not exists or is not a dir`);
|
|
468
|
+
}
|
|
469
|
+
const filesInDirectory = fs2.readdirSync(dir);
|
|
470
|
+
if (filesInDirectory.length === 0) {
|
|
471
|
+
throw new Error(`Directory '${dir}' is empty`);
|
|
472
|
+
}
|
|
473
|
+
filesInDirectory.forEach((file) => {
|
|
474
|
+
if (!Array.isArray(this.sourceFile)) {
|
|
475
|
+
this.sourceFile = [];
|
|
476
|
+
}
|
|
477
|
+
this.sourceFile.unshift(`${dir}/${file}`);
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
load() {
|
|
482
|
+
this.validateFiles();
|
|
483
|
+
if (this.sources.env) {
|
|
484
|
+
this.envData = process.env;
|
|
485
|
+
}
|
|
486
|
+
if (this.sources.args) {
|
|
487
|
+
this.traverseOptions(this.schema, [], this.addArg.bind(this));
|
|
488
|
+
this.program.parse(process.argv);
|
|
489
|
+
this.argsData = this.program.opts();
|
|
490
|
+
}
|
|
491
|
+
if (this.sources.defaults) {
|
|
492
|
+
this.defaultData = this.sources.defaults;
|
|
493
|
+
}
|
|
494
|
+
this.traverseOptions(
|
|
495
|
+
this.schema,
|
|
496
|
+
[],
|
|
497
|
+
this.buildOption.bind(this, this.optionsTree, {
|
|
498
|
+
sourceFile: this.sourceFile,
|
|
499
|
+
envData: this.envData,
|
|
500
|
+
argsData: this.argsData,
|
|
501
|
+
defaultValue: this.defaultData
|
|
502
|
+
})
|
|
503
|
+
);
|
|
504
|
+
if (OptionErrors.warnings.length > 0) {
|
|
505
|
+
for (let index = 0; index < OptionErrors.warnings.length; index += 1) {
|
|
506
|
+
console.warn(`[Warning]: ${OptionErrors.warnings[index]}`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if (OptionErrors.errors.length > 0) {
|
|
510
|
+
for (let index = 0; index < OptionErrors.errors.length; index += 1) {
|
|
511
|
+
console.error(`[Error]: ${OptionErrors.errors[index]}`);
|
|
512
|
+
}
|
|
513
|
+
process.exit(1);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
traverseOptions(node, path, callback) {
|
|
517
|
+
if (node instanceof OptionBase) {
|
|
518
|
+
callback(node, path);
|
|
519
|
+
} else {
|
|
520
|
+
Object.keys(node).forEach((key) => {
|
|
521
|
+
const val = node[key];
|
|
522
|
+
this.traverseOptions(val, [...path, key], callback);
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
buildOption(result, configData, node, path) {
|
|
527
|
+
const { sourceFile, envData, argsData, defaultValue, objectFromArray } = configData;
|
|
528
|
+
const value = node.getValue(
|
|
529
|
+
sourceFile,
|
|
530
|
+
envData,
|
|
531
|
+
argsData,
|
|
532
|
+
path,
|
|
533
|
+
defaultValue,
|
|
534
|
+
objectFromArray
|
|
535
|
+
);
|
|
536
|
+
if (value === null) {
|
|
537
|
+
} else {
|
|
538
|
+
this.setOption(result, path, value);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
getValidatedArray(item, values, file) {
|
|
542
|
+
if (item instanceof PrimitiveOption) {
|
|
543
|
+
if (item.params.kind === "string") {
|
|
544
|
+
return values.map((v) => v);
|
|
545
|
+
}
|
|
546
|
+
if (item.params.kind === "number") {
|
|
547
|
+
return values.map((v) => parseInt(v, 10));
|
|
548
|
+
}
|
|
549
|
+
if (item.params.kind === "boolean") {
|
|
550
|
+
return values.map((v) => {
|
|
551
|
+
if (v === "true")
|
|
552
|
+
return true;
|
|
553
|
+
if (v === "1")
|
|
554
|
+
return true;
|
|
555
|
+
if (v === 1)
|
|
556
|
+
return true;
|
|
557
|
+
if (v === "false")
|
|
558
|
+
return false;
|
|
559
|
+
if (v === "0")
|
|
560
|
+
return false;
|
|
561
|
+
if (v === 0)
|
|
562
|
+
return false;
|
|
563
|
+
return v;
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
const arrayValues = values.map(
|
|
568
|
+
(v) => (
|
|
569
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
570
|
+
this.processArrayWithSchema(item, v, file)
|
|
571
|
+
)
|
|
572
|
+
);
|
|
573
|
+
return new configNodeArray_default(arrayValues);
|
|
574
|
+
}
|
|
575
|
+
processArrayWithSchema(item, v, file) {
|
|
576
|
+
const result = {};
|
|
577
|
+
this.traverseOptions(
|
|
578
|
+
item,
|
|
579
|
+
[],
|
|
580
|
+
this.buildOption.bind(this, result, {
|
|
581
|
+
objectFromArray: {
|
|
582
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
583
|
+
value: v,
|
|
584
|
+
file
|
|
585
|
+
}
|
|
586
|
+
})
|
|
587
|
+
);
|
|
588
|
+
return result;
|
|
589
|
+
}
|
|
590
|
+
setOption(options, path, node) {
|
|
591
|
+
if (path.length > 1) {
|
|
592
|
+
const [child, ...rest] = path;
|
|
593
|
+
if (!options[child]) {
|
|
594
|
+
options[child] = {};
|
|
595
|
+
}
|
|
596
|
+
this.setOption(options[child], rest, node);
|
|
597
|
+
} else if (path.length === 1) {
|
|
598
|
+
const [child] = path;
|
|
599
|
+
if (node != null) {
|
|
600
|
+
if (node.value instanceof arrayOption_default) {
|
|
601
|
+
options[child] = node;
|
|
602
|
+
options[child].value = this.getValidatedArray(
|
|
603
|
+
node.value.item,
|
|
604
|
+
node.value.val,
|
|
605
|
+
node.file || node.variable_name || node.arg_name || ""
|
|
606
|
+
);
|
|
607
|
+
} else {
|
|
608
|
+
options[child] = node;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
} else {
|
|
612
|
+
throw new Error(
|
|
613
|
+
`Invalid path '${node.path}' getting from '${node.arg_name || node.file || node.variable_name || ""}' in ' ${node.source_type}`
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
addArg(node, path = []) {
|
|
618
|
+
if (node.params.cli) {
|
|
619
|
+
const ident = path.join(".");
|
|
620
|
+
this.program.option(`--${ident} <value>`, node.params.help);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
getValuesFromTree(node) {
|
|
624
|
+
if (node instanceof configNode_default) {
|
|
625
|
+
if (node.value instanceof configNodeArray_default) {
|
|
626
|
+
return node.value.arrayValues.map(this.getValuesFromTree.bind(this));
|
|
627
|
+
}
|
|
628
|
+
return node.value;
|
|
629
|
+
}
|
|
630
|
+
return Object.entries(node).reduce(
|
|
631
|
+
(acc, item) => {
|
|
632
|
+
const [key, value] = item;
|
|
633
|
+
acc[key] = this.getValuesFromTree(value);
|
|
634
|
+
return acc;
|
|
635
|
+
},
|
|
636
|
+
{}
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
get() {
|
|
640
|
+
return this.getValuesFromTree(this.optionsTree);
|
|
641
|
+
}
|
|
642
|
+
getExtended() {
|
|
643
|
+
return this.optionsTree;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
var settings_default = Settings;
|
|
647
|
+
|
|
648
|
+
// src/index.ts
|
|
649
|
+
var src_default = settings_default;
|
|
650
|
+
var DEFAULTS = {
|
|
651
|
+
required: false,
|
|
652
|
+
env: null,
|
|
653
|
+
cli: false,
|
|
654
|
+
help: ""
|
|
655
|
+
// properties: {},
|
|
656
|
+
};
|
|
657
|
+
var string = (opts) => {
|
|
658
|
+
return new PrimitiveOption({
|
|
659
|
+
kind: "string",
|
|
660
|
+
...DEFAULTS,
|
|
661
|
+
...opts
|
|
662
|
+
});
|
|
663
|
+
};
|
|
664
|
+
var number = (opts) => {
|
|
665
|
+
return new PrimitiveOption({
|
|
666
|
+
kind: "number",
|
|
667
|
+
...DEFAULTS,
|
|
668
|
+
...opts
|
|
669
|
+
});
|
|
670
|
+
};
|
|
671
|
+
var bool = (opts) => {
|
|
672
|
+
return new PrimitiveOption({
|
|
673
|
+
kind: "boolean",
|
|
674
|
+
...DEFAULTS,
|
|
675
|
+
...opts
|
|
676
|
+
});
|
|
677
|
+
};
|
|
678
|
+
var array = (opts) => {
|
|
679
|
+
return new ArrayOption({
|
|
680
|
+
...DEFAULTS,
|
|
681
|
+
...opts
|
|
682
|
+
});
|
|
683
|
+
};
|
|
684
|
+
var option = {
|
|
685
|
+
string,
|
|
686
|
+
number,
|
|
687
|
+
bool,
|
|
688
|
+
// object,
|
|
689
|
+
array
|
|
690
|
+
};
|
|
691
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
692
|
+
0 && (module.exports = {
|
|
693
|
+
option
|
|
694
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meltstudio/config-loader",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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",
|
|
7
7
|
"repository": "https://github.com/MeltStudio/config-loader",
|
|
8
8
|
"author": "MeltStudio <dev@meltstudio.co>",
|
|
9
|
-
"license": "
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"configuration",
|
|
12
12
|
"config",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
-
"build": "rimraf ./dist && tsup src/index.ts --dts --config tsconfig.build.json
|
|
23
|
+
"build": "rimraf ./dist && tsup src/index.ts --dts --config tsconfig.build.json",
|
|
24
24
|
"lint": "eslint --ext .ts --max-warnings=0 --fix .",
|
|
25
25
|
"type-check": "tsc --noEmit",
|
|
26
26
|
"test": "jest --verbose",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
27
|
+
"example:run": "ts-node -r tsconfig-paths/register ./example/index.ts",
|
|
28
|
+
"prepare": "husky install"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@types/js-yaml": "^4.0.5",
|