@pcg/dotenv-yaml 1.0.0-alpha.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/CHANGELOG.md +7 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.js +5 -0
- package/package.json +33 -0
- package/src/index.ts +49 -0
- package/tests/dotenv.test.ts +46 -0
- package/tests/envs/.env.test.yml +1 -0
- package/tests/envs/.env.yml +3 -0
- package/tsconfig.json +10 -0
- package/tsconfig.lib.json +8 -0
- package/tsdown.config.ts +11 -0
- package/vitest.config.ts +19 -0
package/CHANGELOG.md
ADDED
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
2
|
+
interface DotYamlOptions {
|
|
3
|
+
path: string;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
encoding?: BufferEncoding;
|
|
6
|
+
}
|
|
7
|
+
declare const parseDotEnvFile: (path: string, encoding: BufferEncoding) => Record<string, unknown>;
|
|
8
|
+
declare const parseDotEnvFiles: (opts: DotYamlOptions[]) => Record<string, unknown>;
|
|
9
|
+
declare const useDotEnv: (opts: DotYamlOptions[]) => Record<string, unknown>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { DotYamlOptions, parseDotEnvFile, parseDotEnvFiles, useDotEnv };
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { load } from "js-yaml";
|
|
3
|
+
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
const parseDotEnvFile = (path, encoding) => {
|
|
6
|
+
return load(readFileSync(path, { encoding })) ?? {};
|
|
7
|
+
};
|
|
8
|
+
const parseDotEnvFiles = (opts) => {
|
|
9
|
+
const mergedEnv = {};
|
|
10
|
+
for (const opt of opts) if (opt.enabled ?? true) {
|
|
11
|
+
const parsedDoc = parseDotEnvFile(opt.path, opt.encoding ?? "utf8");
|
|
12
|
+
Object.assign(mergedEnv, parsedDoc);
|
|
13
|
+
}
|
|
14
|
+
return mergedEnv;
|
|
15
|
+
};
|
|
16
|
+
const useDotEnv = (opts) => {
|
|
17
|
+
const mergedEnv = parseDotEnvFiles(opts);
|
|
18
|
+
for (const key of Object.keys(mergedEnv)) {
|
|
19
|
+
const existingValue = process.env[key];
|
|
20
|
+
const envValue = mergedEnv[key];
|
|
21
|
+
if (existingValue !== void 0) continue;
|
|
22
|
+
if (typeof envValue === "string" || typeof envValue === "number" || typeof envValue === "boolean") process.env[key] = String(envValue);
|
|
23
|
+
}
|
|
24
|
+
return mergedEnv;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { parseDotEnvFile, parseDotEnvFiles, useDotEnv };
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["loadYaml","mergedEnv: Record<string, unknown>"],"sources":["../src/index.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { load as loadYaml } from 'js-yaml';\n\nexport interface DotYamlOptions {\n path: string;\n enabled?: boolean;\n encoding?: BufferEncoding;\n}\n\nexport const parseDotEnvFile = (path: string, encoding: BufferEncoding): Record<string, unknown> => {\n const fileContent = readFileSync(path, { encoding });\n const result = loadYaml(fileContent) as Record<string, unknown> | undefined;\n\n return result ?? {};\n};\n\nexport const parseDotEnvFiles = (opts: DotYamlOptions[]): Record<string, unknown> => {\n const mergedEnv: Record<string, unknown> = {};\n\n for (const opt of opts) {\n const enabled = opt.enabled ?? true;\n\n if (enabled) {\n const parsedDoc = parseDotEnvFile(opt.path, opt.encoding ?? 'utf8');\n Object.assign(mergedEnv, parsedDoc);\n }\n }\n\n return mergedEnv;\n};\n\nexport const useDotEnv = (opts: DotYamlOptions[]): Record<string, unknown> => {\n const mergedEnv = parseDotEnvFiles(opts);\n\n for (const key of Object.keys(mergedEnv)) {\n const existingValue = process.env[key];\n const envValue = mergedEnv[key];\n\n if (existingValue !== undefined) {\n continue;\n }\n\n if (typeof envValue === 'string' || typeof envValue === 'number' || typeof envValue === 'boolean') {\n process.env[key] = String(envValue);\n }\n }\n\n return mergedEnv;\n};\n"],"mappings":";;;;AASA,MAAa,mBAAmB,MAAc,aAAsD;AAIlG,QAFeA,KADK,aAAa,MAAM,EAAE,UAAU,CAAC,CAChB,IAEnB,EAAE;;AAGrB,MAAa,oBAAoB,SAAoD;CACnF,MAAMC,YAAqC,EAAE;AAE7C,MAAK,MAAM,OAAO,KAGhB,KAFgB,IAAI,WAAW,MAElB;EACX,MAAM,YAAY,gBAAgB,IAAI,MAAM,IAAI,YAAY,OAAO;AACnE,SAAO,OAAO,WAAW,UAAU;;AAIvC,QAAO;;AAGT,MAAa,aAAa,SAAoD;CAC5E,MAAM,YAAY,iBAAiB,KAAK;AAExC,MAAK,MAAM,OAAO,OAAO,KAAK,UAAU,EAAE;EACxC,MAAM,gBAAgB,QAAQ,IAAI;EAClC,MAAM,WAAW,UAAU;AAE3B,MAAI,kBAAkB,OACpB;AAGF,MAAI,OAAO,aAAa,YAAY,OAAO,aAAa,YAAY,OAAO,aAAa,UACtF,SAAQ,IAAI,OAAO,OAAO,SAAS;;AAIvC,QAAO"}
|
package/eslint.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pcg/dotenv-yaml",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "Load environment variables from YAML files",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"email": "code@deepvision.team",
|
|
8
|
+
"name": "DeepVision Code"
|
|
9
|
+
},
|
|
10
|
+
"contributors": [
|
|
11
|
+
"Vitaliy Angolenko <v.angolenko@deepvision.software>",
|
|
12
|
+
"Sergii Sadovyi <s.sadovyi@deepvision.software>"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"js-yaml": "^4.1.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/js-yaml": "^4.0.9",
|
|
22
|
+
"@types/node": "^22.0.0",
|
|
23
|
+
"@vitest/ui": "^3.2.4",
|
|
24
|
+
"vitest": "^3.2.4"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"dev": "tsdown --watch",
|
|
28
|
+
"build": "tsdown",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest",
|
|
31
|
+
"lint": "eslint \"src/**/*.ts\" --fix"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { load as loadYaml } from 'js-yaml';
|
|
3
|
+
|
|
4
|
+
export interface DotYamlOptions {
|
|
5
|
+
path: string;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
encoding?: BufferEncoding;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const parseDotEnvFile = (path: string, encoding: BufferEncoding): Record<string, unknown> => {
|
|
11
|
+
const fileContent = readFileSync(path, { encoding });
|
|
12
|
+
const result = loadYaml(fileContent) as Record<string, unknown> | undefined;
|
|
13
|
+
|
|
14
|
+
return result ?? {};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const parseDotEnvFiles = (opts: DotYamlOptions[]): Record<string, unknown> => {
|
|
18
|
+
const mergedEnv: Record<string, unknown> = {};
|
|
19
|
+
|
|
20
|
+
for (const opt of opts) {
|
|
21
|
+
const enabled = opt.enabled ?? true;
|
|
22
|
+
|
|
23
|
+
if (enabled) {
|
|
24
|
+
const parsedDoc = parseDotEnvFile(opt.path, opt.encoding ?? 'utf8');
|
|
25
|
+
Object.assign(mergedEnv, parsedDoc);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return mergedEnv;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const useDotEnv = (opts: DotYamlOptions[]): Record<string, unknown> => {
|
|
33
|
+
const mergedEnv = parseDotEnvFiles(opts);
|
|
34
|
+
|
|
35
|
+
for (const key of Object.keys(mergedEnv)) {
|
|
36
|
+
const existingValue = process.env[key];
|
|
37
|
+
const envValue = mergedEnv[key];
|
|
38
|
+
|
|
39
|
+
if (existingValue !== undefined) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof envValue === 'string' || typeof envValue === 'number' || typeof envValue === 'boolean') {
|
|
44
|
+
process.env[key] = String(envValue);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return mergedEnv;
|
|
49
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/// <reference types="vitest/globals" />
|
|
2
|
+
import { useDotEnv } from '../src/index.js';
|
|
3
|
+
|
|
4
|
+
describe('dotenv', () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
delete process.env.NODE_ENV;
|
|
7
|
+
delete process.env.API_KEY;
|
|
8
|
+
delete process.env.API_SECRET;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe('useDotEnv', () => {
|
|
12
|
+
it('should load environment variables from many .env.yml files', () => {
|
|
13
|
+
useDotEnv([
|
|
14
|
+
{
|
|
15
|
+
path: 'tests/envs/.env.yml',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
path: 'tests/envs/.env.test.yml',
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
expect(process.env).toMatchObject({
|
|
23
|
+
NODE_ENV: 'test',
|
|
24
|
+
API_KEY: 'test_key',
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should load environment variables from many .env.yml files but ignore disabled', () => {
|
|
29
|
+
useDotEnv([
|
|
30
|
+
{
|
|
31
|
+
path: 'tests/envs/.env.yml',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
path: 'tests/envs/.env.test.yml',
|
|
35
|
+
enabled: false,
|
|
36
|
+
},
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
expect(process.env).toMatchObject({
|
|
40
|
+
NODE_ENV: 'test',
|
|
41
|
+
API_KEY: '1234567890',
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
API_KEY: 'test_key'
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "dist",
|
|
5
|
+
"typeRoots": ["./node_modules/@types", "../../node_modules/@types"],
|
|
6
|
+
"types": ["node"]
|
|
7
|
+
},
|
|
8
|
+
"include": ["src/**/*.ts", "tests/**/*.ts"],
|
|
9
|
+
"exclude": ["node_modules", "dist"]
|
|
10
|
+
}
|
package/tsdown.config.ts
ADDED
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// / <reference types="vitest" />
|
|
2
|
+
// eslint-disable-next-line node/no-unpublished-import
|
|
3
|
+
import { defineConfig } from 'vitest/config';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
test: {
|
|
7
|
+
environment: 'node',
|
|
8
|
+
include: ['tests/**/*.test.ts'],
|
|
9
|
+
globals: true,
|
|
10
|
+
typecheck: {
|
|
11
|
+
tsconfig: './tsconfig.json',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
resolve: {
|
|
15
|
+
alias: {
|
|
16
|
+
'@': new URL('./src', import.meta.url).pathname,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|