@efebia/env-loader 0.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/lib/client.d.ts +14 -0
- package/lib/client.js +36 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +15 -0
- package/lib/processEnv.d.ts +7 -0
- package/lib/processEnv.js +75 -0
- package/lib/utils.d.ts +16 -0
- package/lib/utils.js +9 -0
- package/package.json +23 -0
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EnvSchema, EnvValues } from './utils';
|
|
2
|
+
export type EnvironmentClientOptions = {
|
|
3
|
+
storage: object;
|
|
4
|
+
keyLoaders: (() => Record<string, unknown> | Promise<Record<string, unknown>>)[];
|
|
5
|
+
};
|
|
6
|
+
export default class EnvironmentClient {
|
|
7
|
+
storage: EnvironmentClientOptions['storage'];
|
|
8
|
+
keyLoaders: EnvironmentClientOptions['keyLoaders'];
|
|
9
|
+
constructor(opts?: Partial<EnvironmentClientOptions>);
|
|
10
|
+
loadKeys(): Promise<void>;
|
|
11
|
+
setEnv(key: string, value: unknown): void;
|
|
12
|
+
getEnv<Key extends keyof EnvSchema, Keys extends Key[] = Key[]>(...listKeys: Keys): EnvValues<Keys>;
|
|
13
|
+
getKey<Key extends keyof EnvSchema>(key: Key): any;
|
|
14
|
+
}
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("./utils");
|
|
4
|
+
class EnvironmentClient {
|
|
5
|
+
constructor(opts) {
|
|
6
|
+
const options = Object.assign({
|
|
7
|
+
storage: {},
|
|
8
|
+
keyLoaders: []
|
|
9
|
+
}, opts);
|
|
10
|
+
this.storage = options.storage;
|
|
11
|
+
this.keyLoaders = options.keyLoaders;
|
|
12
|
+
}
|
|
13
|
+
async loadKeys() {
|
|
14
|
+
const loadedKeys = await Promise.all(this.keyLoaders.map(keyLoader => keyLoader()));
|
|
15
|
+
const keysObject = loadedKeys.reduce((acc, curr) => (Object.assign(Object.assign({}, acc), curr)), {});
|
|
16
|
+
Object.entries(keysObject).forEach(([key, value]) => this.setEnv(key, value));
|
|
17
|
+
}
|
|
18
|
+
setEnv(key, value) {
|
|
19
|
+
this.storage[key] = value;
|
|
20
|
+
}
|
|
21
|
+
getEnv(...listKeys) {
|
|
22
|
+
let values = {};
|
|
23
|
+
for (const key of listKeys) {
|
|
24
|
+
const value = this.getKey(key);
|
|
25
|
+
values = Object.assign(Object.assign({}, values), { [key]: value, [(0, utils_1.convertToCamelCase)(key)]: value });
|
|
26
|
+
}
|
|
27
|
+
return values;
|
|
28
|
+
}
|
|
29
|
+
;
|
|
30
|
+
getKey(key) {
|
|
31
|
+
if (!Object.hasOwn(this.storage, key))
|
|
32
|
+
throw Error(`@efebia/env-loader: Missing environment key ${key}`);
|
|
33
|
+
return this.storage[key];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.default = EnvironmentClient;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import EnvironmentClient from "./client";
|
|
2
|
+
import ProcessEnvStorageEnvironmentClient from "./processEnv";
|
|
3
|
+
import { EnvSchema } from "./utils";
|
|
4
|
+
declare const jsonProcessEnvKeyLoader: (key: string) => () => any;
|
|
5
|
+
declare const yamlFileKeyLoader: (filePath: string) => () => unknown;
|
|
6
|
+
export { EnvironmentClient, ProcessEnvStorageEnvironmentClient, EnvSchema, jsonProcessEnvKeyLoader, yamlFileKeyLoader };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
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.yamlFileKeyLoader = exports.jsonProcessEnvKeyLoader = exports.ProcessEnvStorageEnvironmentClient = exports.EnvironmentClient = void 0;
|
|
7
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
8
|
+
const client_1 = __importDefault(require("./client"));
|
|
9
|
+
exports.EnvironmentClient = client_1.default;
|
|
10
|
+
const processEnv_1 = __importDefault(require("./processEnv"));
|
|
11
|
+
exports.ProcessEnvStorageEnvironmentClient = processEnv_1.default;
|
|
12
|
+
const jsonProcessEnvKeyLoader = (key) => () => JSON.parse(process.env[key]);
|
|
13
|
+
exports.jsonProcessEnvKeyLoader = jsonProcessEnvKeyLoader;
|
|
14
|
+
const yamlFileKeyLoader = (filePath) => () => js_yaml_1.default.load(filePath);
|
|
15
|
+
exports.yamlFileKeyLoader = yamlFileKeyLoader;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import EnvironmentClient, { EnvironmentClientOptions } from "./client";
|
|
2
|
+
import { EnvSchema } from "./utils";
|
|
3
|
+
export default class ProcessEnvStorageEnvironmentClient extends EnvironmentClient {
|
|
4
|
+
constructor(opts?: Partial<Omit<EnvironmentClientOptions, 'storage'>>);
|
|
5
|
+
setEnv(key: string, value: unknown): void;
|
|
6
|
+
getKey<Key extends keyof EnvSchema>(key: Key): any;
|
|
7
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
const client_1 = __importDefault(require("./client"));
|
|
7
|
+
const tryParseJSON = (value) => {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(value);
|
|
10
|
+
}
|
|
11
|
+
catch (_a) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const tryParseInt = (value) => {
|
|
16
|
+
if (/^\d+$/.test(value))
|
|
17
|
+
return parseInt(value);
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
const tryParseFloat = (value) => {
|
|
21
|
+
try {
|
|
22
|
+
return parseFloat(value);
|
|
23
|
+
}
|
|
24
|
+
catch (_a) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const tryParseBoolean = (value) => {
|
|
29
|
+
if (value === 'true')
|
|
30
|
+
return true;
|
|
31
|
+
if (value === 'false')
|
|
32
|
+
return false;
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
const tryParseDate = (value) => {
|
|
36
|
+
const parsed = Date.parse(value);
|
|
37
|
+
if (isNaN(parsed))
|
|
38
|
+
return null;
|
|
39
|
+
return new Date(parsed);
|
|
40
|
+
};
|
|
41
|
+
const parseValue = (value) => {
|
|
42
|
+
let parsed = tryParseJSON(value);
|
|
43
|
+
if (parsed !== null)
|
|
44
|
+
return parsed;
|
|
45
|
+
parsed = tryParseInt(value);
|
|
46
|
+
if (parsed !== null)
|
|
47
|
+
return parsed;
|
|
48
|
+
parsed = tryParseFloat(value);
|
|
49
|
+
if (parsed !== null)
|
|
50
|
+
return parsed;
|
|
51
|
+
parsed = tryParseBoolean(value);
|
|
52
|
+
if (parsed !== null)
|
|
53
|
+
return parsed;
|
|
54
|
+
parsed = tryParseDate(value);
|
|
55
|
+
if (parsed !== null)
|
|
56
|
+
return parsed;
|
|
57
|
+
return value;
|
|
58
|
+
};
|
|
59
|
+
class ProcessEnvStorageEnvironmentClient extends client_1.default {
|
|
60
|
+
constructor(opts) {
|
|
61
|
+
super(Object.assign(Object.assign({}, opts), { storage: process.env }));
|
|
62
|
+
}
|
|
63
|
+
setEnv(key, value) {
|
|
64
|
+
this.storage[key] = typeof value === 'object' ? JSON.stringify(value) : value;
|
|
65
|
+
}
|
|
66
|
+
getKey(key) {
|
|
67
|
+
const anyStorage = this.storage;
|
|
68
|
+
if (!Object.hasOwn(this.storage, key))
|
|
69
|
+
throw new Error(`@efebia/env-loader: Missing environment key ${key}`);
|
|
70
|
+
if (anyStorage[key].trim() === '')
|
|
71
|
+
throw new Error(`@efebia/env-loader: ${key} is empty`);
|
|
72
|
+
return parseValue(anyStorage[key]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.default = ProcessEnvStorageEnvironmentClient;
|
package/lib/utils.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ConvertToCamelCase<Key extends PropertyKey> = Key extends `${infer TFirst}_${infer TSecond}` ? `${TFirst}${Capitalize<ConvertToCamelCase<TSecond>>}` : Key;
|
|
2
|
+
export declare const convertToCamelCase: (key: string) => string;
|
|
3
|
+
export type EnvValues<TKeys extends [...(keyof EnvSchema)[]]> = TKeys extends [
|
|
4
|
+
infer TFirst,
|
|
5
|
+
...infer TRest
|
|
6
|
+
] ? TRest["length"] extends 0 ? TFirst extends keyof EnvSchema ? EnvSchema[TFirst] : never : {
|
|
7
|
+
[key in TRest[number] as key extends keyof EnvSchema ? key : never]: key extends keyof EnvSchema ? EnvSchema[key] : never;
|
|
8
|
+
} & {
|
|
9
|
+
[key in TRest[number] as key extends `${string}_${string}` ? ConvertToCamelCase<key> : never]: key extends keyof EnvSchema ? EnvSchema[key] : never;
|
|
10
|
+
} & {
|
|
11
|
+
[key in TFirst as key extends string ? ConvertToCamelCase<key> : never]: key extends keyof EnvSchema ? EnvSchema[key] : never;
|
|
12
|
+
} : never;
|
|
13
|
+
export interface EnvSchema {
|
|
14
|
+
test_key_1: string;
|
|
15
|
+
test_key_2: string;
|
|
16
|
+
}
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToCamelCase = void 0;
|
|
4
|
+
const convertToCamelCase = (key) => {
|
|
5
|
+
return key
|
|
6
|
+
.toLowerCase()
|
|
7
|
+
.replace(/([_][a-z])/g, (group) => group.toUpperCase().replace("_", ""));
|
|
8
|
+
};
|
|
9
|
+
exports.convertToCamelCase = convertToCamelCase;
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@efebia/env-loader",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"devDependencies": {
|
|
6
|
+
"@types/jest": "^29.2.5",
|
|
7
|
+
"@types/js-yaml": "^4.0.5",
|
|
8
|
+
"@types/node": "^18.11.18",
|
|
9
|
+
"jest": "^29.3.1",
|
|
10
|
+
"ts-jest": "^29.0.3",
|
|
11
|
+
"typescript": "^4.9.4"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"js-yaml": "^4.1.0"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"/lib"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc"
|
|
21
|
+
},
|
|
22
|
+
"main": "./lib"
|
|
23
|
+
}
|