@pitininja/envious 3.3.4 → 4.0.0-beta.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 +60 -14
- package/dist/index.d.ts +13 -2
- package/dist/index.js +39 -25
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -10,23 +10,69 @@ npm i @pitininja/envious
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
Environment variables are automatically loaded using [Dotenv](https://github.com/motdotla/dotenv).
|
|
14
|
+
|
|
15
|
+
Refer to the [official Typebox documentation](https://github.com/sinclairzx81/typebox) for how to write a Typebox schema.
|
|
15
16
|
|
|
16
17
|
```typescript
|
|
18
|
+
import { envious } from '@pitininja/envious';
|
|
17
19
|
import { Type } from '@sinclair/typebox';
|
|
20
|
+
|
|
21
|
+
const env = envious(
|
|
22
|
+
Type.Object({
|
|
23
|
+
STRING_VAR: Type.String(),
|
|
24
|
+
NUMBER_VAR: Type.Integer(),
|
|
25
|
+
BOOLEAN_VAR_WITH_DEFAULT: Type.Boolean({ default: false }),
|
|
26
|
+
OPTIONAL_VAR: Type.Optional(Type.String())
|
|
27
|
+
})
|
|
28
|
+
);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Formats
|
|
32
|
+
|
|
33
|
+
String formats can be loaded in the `formats` property of the options parameter, as an object with the format name as key and a regex or a validation function as value.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
18
36
|
import { envious } from '@pitininja/envious';
|
|
37
|
+
import { Type } from '@sinclair/typebox';
|
|
38
|
+
import dayjs from 'dayjs';
|
|
39
|
+
|
|
40
|
+
const env = envious(
|
|
41
|
+
Type.Object({
|
|
42
|
+
EXAMPLE_URI: Type.String({ format: 'uri' }),
|
|
43
|
+
EXAMPLE_DATE: Type.String({ format: 'date' })
|
|
44
|
+
}),
|
|
45
|
+
{
|
|
46
|
+
formats: {
|
|
47
|
+
uri: /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i,
|
|
48
|
+
date: (val) => dayjs(val).isValid()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Errors
|
|
55
|
+
|
|
56
|
+
If something goes wrong, Envious will throw an error of class `EnviousError`.
|
|
57
|
+
|
|
58
|
+
An `EnviousError` error contains a message and a list of `ValueError` (an error class taken from Typebox).
|
|
59
|
+
|
|
60
|
+
Here is a simple example of how to handle Envious errors :
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { envious, EnviousError } from '@pitininja/envious';
|
|
64
|
+
import { Type } from '@sinclair/typebox';
|
|
19
65
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
66
|
+
try {
|
|
67
|
+
const env = envious(
|
|
68
|
+
Type.Object({
|
|
69
|
+
STRING_VAR: Type.String()
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
} catch (err: unknown) {
|
|
73
|
+
if (err instanceof EnviousError) {
|
|
74
|
+
console.log('Message:', err.message); // Error message
|
|
75
|
+
console.log('Errors:', err.errors); // Typebox's ValueError array
|
|
76
|
+
}
|
|
77
|
+
}
|
|
32
78
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
import 'dotenv/config';
|
|
2
|
-
import type
|
|
3
|
-
|
|
2
|
+
import { type Static, type TObject } from '@sinclair/typebox';
|
|
3
|
+
import { type ValueError } from '@sinclair/typebox/value';
|
|
4
|
+
export type EnviousFormats = {
|
|
5
|
+
[name: string]: RegExp | ((val: unknown) => boolean);
|
|
6
|
+
};
|
|
7
|
+
export type EnviousOptions = {
|
|
8
|
+
formats: EnviousFormats;
|
|
9
|
+
};
|
|
10
|
+
export declare class EnviousError extends Error {
|
|
11
|
+
errors: ValueError[];
|
|
12
|
+
constructor(message: string, errors?: ValueError[]);
|
|
13
|
+
}
|
|
14
|
+
export declare const envious: <T extends TObject>(schema: T, options?: EnviousOptions) => Static<T>;
|
package/dist/index.js
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.envious = void 0;
|
|
3
|
+
exports.envious = exports.EnviousError = void 0;
|
|
7
4
|
require("dotenv/config");
|
|
8
|
-
const
|
|
5
|
+
const typebox_1 = require("@sinclair/typebox");
|
|
9
6
|
const value_1 = require("@sinclair/typebox/value");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
7
|
+
class EnviousError extends Error {
|
|
8
|
+
errors;
|
|
9
|
+
constructor(message, errors) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.errors = errors ?? [];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.EnviousError = EnviousError;
|
|
15
|
+
const setFormats = (formats) => {
|
|
16
|
+
for (const name of Object.keys(formats)) {
|
|
17
|
+
const format = formats[name];
|
|
18
|
+
typebox_1.FormatRegistry.Set(name, format instanceof RegExp ? (val) => format.test(val) : format);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const envious = (schema, options) => {
|
|
22
|
+
const invalidEnvVarMessage = 'Invalid environment variables';
|
|
23
|
+
try {
|
|
24
|
+
if (options?.formats) {
|
|
25
|
+
setFormats(options.formats);
|
|
26
|
+
}
|
|
27
|
+
const parsed = value_1.Value.Parse(schema, process.env);
|
|
28
|
+
const errors = [...value_1.Value.Errors(schema, parsed)];
|
|
29
|
+
if (errors.length) {
|
|
30
|
+
throw new EnviousError(invalidEnvVarMessage, errors);
|
|
31
|
+
}
|
|
32
|
+
return value_1.Value.Cast({
|
|
33
|
+
...schema,
|
|
34
|
+
additionalProperties: false
|
|
35
|
+
}, parsed);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err instanceof EnviousError) {
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
if (err instanceof value_1.AssertError) {
|
|
42
|
+
throw new EnviousError(invalidEnvVarMessage, err.error ? [err.error] : []);
|
|
21
43
|
}
|
|
22
|
-
|
|
23
|
-
'Invalid environment variables',
|
|
24
|
-
...Object.entries(computedErrorMessages).map(([varName, messages]) => ` ${varName} : ${messages.join(', ')}`)
|
|
25
|
-
];
|
|
26
|
-
throw new Error(errorTextParts.join(node_os_1.default.EOL));
|
|
44
|
+
throw new EnviousError(`Unexpected error while parsing environment variables${err instanceof Error ? ` (${err.message})` : ''}`);
|
|
27
45
|
}
|
|
28
|
-
return value_1.Value.Cast({
|
|
29
|
-
...schema,
|
|
30
|
-
additionalProperties: false
|
|
31
|
-
}, parsed);
|
|
32
46
|
};
|
|
33
47
|
exports.envious = envious;
|
|
34
48
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yBAAuB;AACvB,+CAA8E;AAC9E,mDAA8E;AAU9E,MAAa,YAAa,SAAQ,KAAK;IACnC,MAAM,CAAe;IACrB,YAAY,OAAe,EAAE,MAAqB;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;IAC/B,CAAC;CACJ;AAND,oCAMC;AAED,MAAM,UAAU,GAAG,CAAC,OAAuB,EAAE,EAAE;IAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,wBAAc,CAAC,GAAG,CACd,IAAI,EACJ,MAAM,YAAY,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAChE,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAEK,MAAM,OAAO,GAAG,CACnB,MAAS,EACT,OAAwB,EACf,EAAE;IACX,MAAM,oBAAoB,GAAG,+BAA+B,CAAC;IAC7D,IAAI,CAAC;QACD,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACnB,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,MAAM,MAAM,GAAG,aAAK,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,CAAC,GAAG,aAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,aAAK,CAAC,IAAI,CACb;YACI,GAAG,MAAM;YACT,oBAAoB,EAAE,KAAK;SAC9B,EACD,MAAM,CACT,CAAC;IACN,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;YAC9B,MAAM,GAAG,CAAC;QACd,CAAC;QACD,IAAI,GAAG,YAAY,mBAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,YAAY,CAClB,oBAAoB,EACpB,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAC/B,CAAC;QACN,CAAC;QACD,MAAM,IAAI,YAAY,CAClB,uDAAuD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3G,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAnCW,QAAA,OAAO,WAmClB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pitininja/envious",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-beta.1",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"homepage": "https://github.com/pitininja/envious",
|
|
6
6
|
"repository": {
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@biomejs/biome": "^1.9.4",
|
|
26
|
-
"@tsconfig/recommended": "^1.0.
|
|
27
|
-
"@types/node": "^22.
|
|
28
|
-
"@vitest/coverage-istanbul": "^2.1.
|
|
26
|
+
"@tsconfig/recommended": "^1.0.8",
|
|
27
|
+
"@types/node": "^22.8.6",
|
|
28
|
+
"@vitest/coverage-istanbul": "^2.1.4",
|
|
29
29
|
"husky": "^9.1.6",
|
|
30
30
|
"typescript": "^5.6.3",
|
|
31
|
-
"vitest": "^2.1.
|
|
31
|
+
"vitest": "^2.1.4"
|
|
32
32
|
}
|
|
33
33
|
}
|