@ayepi/env 0.2.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/LICENSE +21 -0
- package/README.md +178 -0
- package/ayepi-env.md +303 -0
- package/dist/dotenv.cjs +45 -0
- package/dist/dotenv.d.cts +36 -0
- package/dist/dotenv.d.ts +36 -0
- package/dist/dotenv.js +40 -0
- package/dist/index.cjs +739 -0
- package/dist/index.d.cts +166 -0
- package/dist/index.d.ts +166 -0
- package/dist/index.js +722 -0
- package/dist/load.cjs +40 -0
- package/dist/load.d.cts +21 -0
- package/dist/load.d.ts +21 -0
- package/dist/load.js +37 -0
- package/package.json +76 -0
package/dist/load.cjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_dotenv = require("./dotenv.cjs");
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let node_path = require("node:path");
|
|
5
|
+
//#region src/load.ts
|
|
6
|
+
/**
|
|
7
|
+
* # File loading — `@ayepi/env/load` (the only `node:fs` entry)
|
|
8
|
+
*
|
|
9
|
+
* Read `.env` and `.json` files off disk into a config **source** — a plain record you then feed
|
|
10
|
+
* to an env with `set(...)`. Kept separate from the core so the main entry stays filesystem-free.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { env } from '@ayepi/env'
|
|
14
|
+
* import { loadEnv } from '@ayepi/env/load'
|
|
15
|
+
*
|
|
16
|
+
* const ENV = env(schema)
|
|
17
|
+
* ENV.set(loadEnv({ files: ['.env', 'config.json'] })) // files win over process.env
|
|
18
|
+
* ENV.set({ ...loadEnv({ files: ['.env'] }), ...process.env }) // …or let process.env win
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
*/
|
|
23
|
+
/** Read one `.env` or `.json` file into a config source. A `.json` file may carry already-typed values. */
|
|
24
|
+
function readEnvFile(path) {
|
|
25
|
+
const text = (0, node_fs.readFileSync)(path, "utf8");
|
|
26
|
+
return (0, node_path.extname)(path) === ".json" ? JSON.parse(text) : require_dotenv.parseDotenv(text);
|
|
27
|
+
}
|
|
28
|
+
/** Read the listed files into a single merged source (later files win). Pass the result to `set(...)`. */
|
|
29
|
+
function loadEnv(opts = {}) {
|
|
30
|
+
const out = {};
|
|
31
|
+
const req = opts.required;
|
|
32
|
+
const mustExist = (file) => req === true || Array.isArray(req) && req.includes(file);
|
|
33
|
+
for (const file of opts.files ?? []) if ((0, node_fs.existsSync)(file)) Object.assign(out, readEnvFile(file));
|
|
34
|
+
else if (mustExist(file)) throw new Error(`env file not found: ${file}`);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
exports.loadEnv = loadEnv;
|
|
39
|
+
exports.parseDotenv = require_dotenv.parseDotenv;
|
|
40
|
+
exports.readEnvFile = readEnvFile;
|
package/dist/load.d.cts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { r as EnvSource, t as parseDotenv } from "./dotenv.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/load.d.ts
|
|
4
|
+
/** Read one `.env` or `.json` file into a config source. A `.json` file may carry already-typed values. */
|
|
5
|
+
declare function readEnvFile(path: string): EnvSource;
|
|
6
|
+
/** Options for {@link loadEnv}. */
|
|
7
|
+
interface LoadOptions {
|
|
8
|
+
/** Files to read (in order, earlier is lower precedence); `.env` or `.json`. */
|
|
9
|
+
readonly files?: readonly string[];
|
|
10
|
+
/**
|
|
11
|
+
* Which missing files should **throw** instead of being skipped:
|
|
12
|
+
* - `false` / omitted — ignore every missing file (default),
|
|
13
|
+
* - `true` — throw if **any** listed file is missing,
|
|
14
|
+
* - `string[]` — throw only if one of **these specific** files is missing (others are ignored).
|
|
15
|
+
*/
|
|
16
|
+
readonly required?: boolean | readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/** Read the listed files into a single merged source (later files win). Pass the result to `set(...)`. */
|
|
19
|
+
declare function loadEnv(opts?: LoadOptions): EnvSource;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type EnvSource, LoadOptions, loadEnv, parseDotenv, readEnvFile };
|
package/dist/load.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { r as EnvSource, t as parseDotenv } from "./dotenv.js";
|
|
2
|
+
|
|
3
|
+
//#region src/load.d.ts
|
|
4
|
+
/** Read one `.env` or `.json` file into a config source. A `.json` file may carry already-typed values. */
|
|
5
|
+
declare function readEnvFile(path: string): EnvSource;
|
|
6
|
+
/** Options for {@link loadEnv}. */
|
|
7
|
+
interface LoadOptions {
|
|
8
|
+
/** Files to read (in order, earlier is lower precedence); `.env` or `.json`. */
|
|
9
|
+
readonly files?: readonly string[];
|
|
10
|
+
/**
|
|
11
|
+
* Which missing files should **throw** instead of being skipped:
|
|
12
|
+
* - `false` / omitted — ignore every missing file (default),
|
|
13
|
+
* - `true` — throw if **any** listed file is missing,
|
|
14
|
+
* - `string[]` — throw only if one of **these specific** files is missing (others are ignored).
|
|
15
|
+
*/
|
|
16
|
+
readonly required?: boolean | readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/** Read the listed files into a single merged source (later files win). Pass the result to `set(...)`. */
|
|
19
|
+
declare function loadEnv(opts?: LoadOptions): EnvSource;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type EnvSource, LoadOptions, loadEnv, parseDotenv, readEnvFile };
|
package/dist/load.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { t as parseDotenv } from "./dotenv.js";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { extname } from "node:path";
|
|
4
|
+
//#region src/load.ts
|
|
5
|
+
/**
|
|
6
|
+
* # File loading — `@ayepi/env/load` (the only `node:fs` entry)
|
|
7
|
+
*
|
|
8
|
+
* Read `.env` and `.json` files off disk into a config **source** — a plain record you then feed
|
|
9
|
+
* to an env with `set(...)`. Kept separate from the core so the main entry stays filesystem-free.
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { env } from '@ayepi/env'
|
|
13
|
+
* import { loadEnv } from '@ayepi/env/load'
|
|
14
|
+
*
|
|
15
|
+
* const ENV = env(schema)
|
|
16
|
+
* ENV.set(loadEnv({ files: ['.env', 'config.json'] })) // files win over process.env
|
|
17
|
+
* ENV.set({ ...loadEnv({ files: ['.env'] }), ...process.env }) // …or let process.env win
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
/** Read one `.env` or `.json` file into a config source. A `.json` file may carry already-typed values. */
|
|
23
|
+
function readEnvFile(path) {
|
|
24
|
+
const text = readFileSync(path, "utf8");
|
|
25
|
+
return extname(path) === ".json" ? JSON.parse(text) : parseDotenv(text);
|
|
26
|
+
}
|
|
27
|
+
/** Read the listed files into a single merged source (later files win). Pass the result to `set(...)`. */
|
|
28
|
+
function loadEnv(opts = {}) {
|
|
29
|
+
const out = {};
|
|
30
|
+
const req = opts.required;
|
|
31
|
+
const mustExist = (file) => req === true || Array.isArray(req) && req.includes(file);
|
|
32
|
+
for (const file of opts.files ?? []) if (existsSync(file)) Object.assign(out, readEnvFile(file));
|
|
33
|
+
else if (mustExist(file)) throw new Error(`env file not found: ${file}`);
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { loadEnv, parseDotenv, readEnvFile };
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ayepi/env",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Typed, lazy, reactive environment/config on zod — env({...}) reads process.env, records, .env/JSON files; coerces scalars and JSON-decodes complex types; computed fields, aliasing, and async/dynamic (live, subscribable) values",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ClickerMonkey/ayepi.git",
|
|
12
|
+
"directory": "packages/env"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/ClickerMonkey/ayepi/tree/main/packages/env#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/ClickerMonkey/ayepi/issues"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"ayepi-*.md"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"import": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"require": {
|
|
31
|
+
"types": "./dist/index.d.cts",
|
|
32
|
+
"default": "./dist/index.cjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./load": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/load.d.ts",
|
|
38
|
+
"default": "./dist/load.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/load.d.cts",
|
|
42
|
+
"default": "./dist/load.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"zod": "^4"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
55
|
+
"publint": "^0.3.0",
|
|
56
|
+
"tsdown": "^0.12.0",
|
|
57
|
+
"vitest": "^2.1.8",
|
|
58
|
+
"zod": "^4.4.3"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [
|
|
61
|
+
"ayepi",
|
|
62
|
+
"env",
|
|
63
|
+
"environment",
|
|
64
|
+
"config",
|
|
65
|
+
"dotenv",
|
|
66
|
+
"zod",
|
|
67
|
+
"configuration",
|
|
68
|
+
"12-factor"
|
|
69
|
+
],
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsdown",
|
|
72
|
+
"typecheck": "tsc --noEmit",
|
|
73
|
+
"test": "vitest run --coverage",
|
|
74
|
+
"publint": "publint"
|
|
75
|
+
}
|
|
76
|
+
}
|