@puristic/env 1.0.0 → 1.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.
Files changed (2) hide show
  1. package/README.md +85 -0
  2. package/package.json +21 -1
package/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @puristic/env
2
+
3
+ **A config loader built on one Zod schema — the same schema that powers CI validation, codegen, and a [VSCode editor](https://github.com/radarsu/puristic-env/tree/main/_libs/vscode).**
4
+
5
+ `@puristic/env` loads your configuration at runtime. It merges CLI flags, environment variables, and `.env` files (in that order of precedence), validates the result against a [Zod](https://zod.dev) schema, and decrypts any secrets. The schema is plain TypeScript that your app already imports — not a separate DSL or a cloud API. The same definition also powers the [`purenv` CLI](https://www.npmjs.com/package/@puristic/env-cli) and the VSCode extension, so the three can't drift.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @puristic/env # or: npm i @puristic/env
11
+ ```
12
+
13
+ Requires **Node 24+** and `zod` v4.
14
+
15
+ ## Quickstart
16
+
17
+ Define your configuration once. Export the **raw `ConfigDefinition`** (schema + sources), not the result of `loadConfig(...)`. `loadConfig` loads immediately, so it would fail on encrypted secrets without a key:
18
+
19
+ ```ts
20
+ // env.config.ts — the single source of truth
21
+ import { type ConfigDefinition, envFile, env, cliArgs } from "@puristic/env/index.js";
22
+ import { z } from "zod";
23
+
24
+ export default {
25
+ schema: z.object({
26
+ nodeEnv: z.string(),
27
+ server: z.object({
28
+ port: z.coerce.number().int(),
29
+ host: z.string().default("0.0.0.0"),
30
+ }),
31
+ database: z.object({
32
+ url: z.url().meta({ secret: true }),
33
+ }),
34
+ }),
35
+ sources: [envFile(".env"), env(), cliArgs()], // later sources win: CLI > env > .env file
36
+ } satisfies ConfigDefinition<z.ZodType>;
37
+ ```
38
+
39
+ Load it at runtime — validated, secrets decrypted, deep-frozen:
40
+
41
+ ```ts
42
+ import { loadConfig } from "@puristic/env/index.js";
43
+ import definition from "./env.config.js";
44
+
45
+ const config = loadConfig(definition);
46
+ config.server.port; // number
47
+ ```
48
+
49
+ Use `createConfig(definition)` when you want a handle instead: call `.load()` once in your bootstrap, then `.get()` anywhere. `.get()` throws if called before `.load()`.
50
+
51
+ Nested schema paths map to env var names: `["server", "httpsPort"]` → `SERVER_HTTPS_PORT` (and `--server-https-port` for CLI flags):
52
+
53
+ ```sh
54
+ # .env
55
+ NODE_ENV=production
56
+ SERVER_PORT=8080
57
+ DATABASE_URL=encrypted:v1:… # secret — encrypted in place
58
+ ```
59
+
60
+ ## API
61
+
62
+ | Export | Purpose |
63
+ | --- | --- |
64
+ | `loadConfig` / `createConfig` | Load + validate + decrypt + deep-freeze (one-call, or a `load`/`get` handle) |
65
+ | `envFile` · `env` · `cliArgs` | Built-in sources, merged left-to-right with last-source-wins precedence |
66
+ | `extractDefinition` / `loadDefinition` | Resolve a `ConfigDefinition` from an imported / on-disk `env.config.*` |
67
+ | `inspectSchema` · `validateValues` · `classify` | Schema introspection, per-leaf validation, and the shared OK / Missing / Invalid / Unknown / secret status model |
68
+ | `encrypt` · `decrypt` · `generateKeypair` | Post-quantum secret encryption (ML-KEM-512 + AES-256-GCM) |
69
+ | `generateDts` · `generateEnvExample` · `generateJsonSchema` | Codegen from the schema (typed `process.env`, `.env.example`, JSON Schema) |
70
+ | `parseEnv` · `serializeEnv` · `setValue` … | Round-trip `.env` editing that preserves comments, order, quoting, and `export` prefixes |
71
+ | `expandEnv` / `expandValue` | `$VAR` / `${VAR}` expansion against sibling values and the ambient environment |
72
+
73
+ ## Secrets
74
+
75
+ Mark a field secret with `.meta({ secret: true })`. Its value is encrypted **in place** with the project's public key (`.config/purenv-pub.key`), producing an `encrypted:v1:…` envelope sealed with **ML-KEM-512** (a post-quantum KEM) and **AES-256-GCM**. Encryption needs only the public key; loading or decrypting needs the private key. It's fully local, with no cloud account. Generate a keypair with `purenv keygen`.
76
+
77
+ ## Learn more
78
+
79
+ - **[Full project README](https://github.com/radarsu/puristic-env#readme)** — overview, security model, and getting started
80
+ - **[`@puristic/env-cli`](https://www.npmjs.com/package/@puristic/env-cli)** — the `purenv` command line
81
+ - **[VSCode extension](https://github.com/radarsu/puristic-env/tree/main/_libs/vscode)** — the schema-driven `.env` editor
82
+
83
+ ## License
84
+
85
+ MIT
package/package.json CHANGED
@@ -1,6 +1,26 @@
1
1
  {
2
2
  "name": "@puristic/env",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
+ "description": "A config loader built on one Zod schema — the same schema drives CI validation, codegen, and post-quantum encrypted secrets. No DSL, no cloud.",
5
+ "keywords": [
6
+ "env",
7
+ "dotenv",
8
+ "dotenvx",
9
+ "varlock",
10
+ "environment-variables",
11
+ "env-vars",
12
+ "config",
13
+ "configuration",
14
+ "zod",
15
+ "schema",
16
+ "validation",
17
+ "type-safe",
18
+ "typescript",
19
+ "secrets",
20
+ "encryption",
21
+ "post-quantum",
22
+ "12-factor"
23
+ ],
4
24
  "license": "MIT",
5
25
  "type": "module",
6
26
  "repository": {