@lindorm/config 0.3.0 → 0.4.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/CHANGELOG.md +6 -0
- package/README.md +17 -14
- package/dist/internal/build-env-overrides.d.ts +5 -0
- package/dist/internal/build-env-overrides.d.ts.map +1 -0
- package/dist/internal/build-env-overrides.js +31 -0
- package/dist/internal/build-env-overrides.js.map +1 -0
- package/dist/internal/deep-override.d.ts +3 -0
- package/dist/internal/deep-override.d.ts.map +1 -0
- package/dist/internal/deep-override.js +20 -0
- package/dist/internal/deep-override.js.map +1 -0
- package/dist/internal/index.d.ts +3 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +3 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/load-config.d.ts +1 -2
- package/dist/internal/load-config.d.ts.map +1 -1
- package/dist/internal/load-config.js +2 -4
- package/dist/internal/load-config.js.map +1 -1
- package/dist/internal/walk-schema.d.ts +7 -0
- package/dist/internal/walk-schema.d.ts.map +1 -0
- package/dist/internal/walk-schema.js +26 -0
- package/dist/internal/walk-schema.js.map +1 -0
- package/dist/utils/configuration.d.ts.map +1 -1
- package/dist/utils/configuration.js +7 -7
- package/dist/utils/configuration.js.map +1 -1
- package/package.json +2 -2
- package/dist/internal/find-process-env-value.d.ts +0 -3
- package/dist/internal/find-process-env-value.d.ts.map +0 -1
- package/dist/internal/find-process-env-value.js +0 -10
- package/dist/internal/find-process-env-value.js.map +0 -1
- package/dist/internal/merge-object-with-process-env.d.ts +0 -4
- package/dist/internal/merge-object-with-process-env.d.ts.map +0 -1
- package/dist/internal/merge-object-with-process-env.js +0 -20
- package/dist/internal/merge-object-with-process-env.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.4.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/config@0.3.0...@lindorm/config@0.4.0) (2026-05-04)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **config:** schema-driven env binding with \_\_ separator ([bdbec63](https://github.com/lindorm-io/monorepo/commit/bdbec6316c7594693d32ed25e2d446e1f3d4271a))
|
|
11
|
+
|
|
6
12
|
# [0.3.0](https://github.com/lindorm-io/monorepo/compare/@lindorm/config@0.2.10...@lindorm/config@0.3.0) (2026-05-02)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ This package is ESM-only. Import it with `import`; `require()` is not supported.
|
|
|
15
15
|
- Validates the merged configuration with a Zod schema you supply.
|
|
16
16
|
- Loads YAML files from a `config/` directory via the [`config`](https://www.npmjs.com/package/config) (node-config) package, layered by `NODE_ENV`.
|
|
17
17
|
- Loads `.env` and `.env.${NODE_ENV}` via [`@dotenvx/dotenvx`](https://www.npmjs.com/package/@dotenvx/dotenvx).
|
|
18
|
-
-
|
|
18
|
+
- **Schema-driven** environment-variable override: every leaf in the schema is checked against an env var named `SEGMENT__SEGMENT__LEAF`, regardless of whether YAML scaffolds the key. A service can run with no YAML at all if every required key is in env.
|
|
19
19
|
- Accepts a full configuration object as JSON in the `NODE_CONFIG` environment variable.
|
|
20
20
|
- Coerces string inputs to the schema's primitive types (numbers, booleans, dates, bigints) and parses JSON-encoded arrays and objects.
|
|
21
21
|
- Resolves the running package's `name` and `version` and exposes them as `config.npm.package`.
|
|
@@ -54,8 +54,8 @@ console.log(config.npm.package.name); // resolved from the nearest package.json
|
|
|
54
54
|
|
|
55
55
|
1. `.env` and `.env.${NODE_ENV}` files (loaded into `process.env` via `@dotenvx/dotenvx`).
|
|
56
56
|
2. YAML files in `./config/` (loaded by the `config` npm package; see its docs for the full list of supported file types and search paths). Keys are normalised to `camelCase`.
|
|
57
|
-
3. `
|
|
58
|
-
4. `
|
|
57
|
+
3. `NODE_CONFIG` — a JSON object passed in a single environment variable.
|
|
58
|
+
4. `process.env` entries derived from the schema's leaves: each leaf path is converted to `CONSTANT_CASE` per segment, joined with `__` (double underscore). Arrays are replaced (not concatenated).
|
|
59
59
|
|
|
60
60
|
The merged object is then coerced and validated against the Zod schema.
|
|
61
61
|
|
|
@@ -94,20 +94,23 @@ is_production: true
|
|
|
94
94
|
|
|
95
95
|
### Environment variables
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
The env-var name for a schema leaf is built segment-by-segment: each path segment becomes `CONSTANT_CASE` (so `maxRetries` ↔ `MAX_RETRIES`), and segments are joined with `__` (double underscore). The double underscore keeps the segment boundary unambiguous when a segment itself contains internal word breaks.
|
|
98
98
|
|
|
99
|
-
| Schema key | Environment variable
|
|
100
|
-
| ----------------------- |
|
|
101
|
-
| `server.port` | `
|
|
102
|
-
| `database.poolSize` | `
|
|
103
|
-
| `nested.some.deepValue` | `
|
|
99
|
+
| Schema key | Environment variable |
|
|
100
|
+
| ----------------------- | -------------------------- |
|
|
101
|
+
| `server.port` | `SERVER__PORT` |
|
|
102
|
+
| `database.poolSize` | `DATABASE__POOL_SIZE` |
|
|
103
|
+
| `nested.some.deepValue` | `NESTED__SOME__DEEP_VALUE` |
|
|
104
|
+
| `pylon.kek` | `PYLON__KEK` |
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
Binding is **schema-driven** — every leaf in your Zod schema is looked up in `process.env`. You don't need a YAML scaffold for env vars to work; if the env supplies every required key, you can run without `config/*.yml` at all.
|
|
107
|
+
|
|
108
|
+
Values are passed through `safelyParse` from `@lindorm/utils`, so JSON-encoded arrays and objects are decoded automatically. Empty-string env values (`MY_VAR=""`) are preserved — they are not treated as "unset". Arrays from env replace (not concatenate) any earlier value:
|
|
106
109
|
|
|
107
110
|
```bash
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
SERVER__PORT=8080
|
|
112
|
+
DATABASE__URL=postgresql://prod-server/myapp
|
|
113
|
+
DATABASE__POOL_SIZE=50
|
|
111
114
|
FEATURES='["feature1","feature2","feature3"]'
|
|
112
115
|
IS_PRODUCTION=true
|
|
113
116
|
```
|
|
@@ -119,7 +122,7 @@ IS_PRODUCTION=true
|
|
|
119
122
|
- `.env.${NODE_ENV}` (only when `NODE_ENV` is set)
|
|
120
123
|
- `.env`
|
|
121
124
|
|
|
122
|
-
The values become part of `process.env` and follow the same `
|
|
125
|
+
The values become part of `process.env` and follow the same `__`-separator binding rules as above.
|
|
123
126
|
|
|
124
127
|
### `NODE_CONFIG`
|
|
125
128
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Dict } from "@lindorm/types";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ProcessEnv } from "../types/index.js";
|
|
4
|
+
export declare const buildEnvOverrides: (schema: z.ZodType, processEnv: ProcessEnv) => Dict;
|
|
5
|
+
//# sourceMappingURL=build-env-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-env-overrides.d.ts","sourceRoot":"","sources":["../../src/internal/build-env-overrides.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AA8CpD,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,EAAE,YAAY,UAAU,KAAG,IAc7E,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { changeCase } from "@lindorm/case";
|
|
2
|
+
import { safelyParse } from "@lindorm/utils";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { walkSchemaLeaves } from "./walk-schema.js";
|
|
5
|
+
const buildEnvName = (path) => path.map((segment) => changeCase(segment, "constant")).join("__");
|
|
6
|
+
const setPathValue = (target, path, value) => {
|
|
7
|
+
let cursor = target;
|
|
8
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
9
|
+
const key = path[i];
|
|
10
|
+
const existing = cursor[key];
|
|
11
|
+
if (existing === undefined || existing === null || typeof existing !== "object") {
|
|
12
|
+
cursor[key] = {};
|
|
13
|
+
}
|
|
14
|
+
cursor = cursor[key];
|
|
15
|
+
}
|
|
16
|
+
cursor[path[path.length - 1]] = value;
|
|
17
|
+
};
|
|
18
|
+
export const buildEnvOverrides = (schema, processEnv) => {
|
|
19
|
+
const result = {};
|
|
20
|
+
for (const { path } of walkSchemaLeaves(schema)) {
|
|
21
|
+
if (path.length === 0)
|
|
22
|
+
continue;
|
|
23
|
+
const envName = buildEnvName(path);
|
|
24
|
+
const raw = processEnv[envName];
|
|
25
|
+
if (raw === undefined)
|
|
26
|
+
continue;
|
|
27
|
+
setPathValue(result, path, safelyParse(raw));
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=build-env-overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-env-overrides.js","sourceRoot":"","sources":["../../src/internal/build-env-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAcpD,MAAM,YAAY,GAAG,CAAC,IAA2B,EAAU,EAAE,CAC3D,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEpE,MAAM,YAAY,GAAG,CACnB,MAAY,EACZ,IAA2B,EAC3B,KAAc,EACR,EAAE;IACR,IAAI,MAAM,GAAS,MAAM,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAChF,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACnB,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,GAAG,CAAS,CAAC;IAC/B,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AACxC,CAAC,CAAC;AAaF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAiB,EAAE,UAAsB,EAAQ,EAAE;IACnF,MAAM,MAAM,GAAS,EAAE,CAAC;IAExB,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEhC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAEhC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-override.d.ts","sourceRoot":"","sources":["../../src/internal/deep-override.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAe3C,eAAO,MAAM,YAAY,GAAI,GAAG,SAAS,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,KAAG,IAiBlE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isObject } from "@lindorm/is";
|
|
2
|
+
export const deepOverride = (...sources) => {
|
|
3
|
+
const result = {};
|
|
4
|
+
for (const source of sources) {
|
|
5
|
+
if (!source)
|
|
6
|
+
continue;
|
|
7
|
+
for (const [key, value] of Object.entries(source)) {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
continue;
|
|
10
|
+
if (isObject(value) && isObject(result[key])) {
|
|
11
|
+
result[key] = deepOverride(result[key], value);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
result[key] = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=deep-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-override.js","sourceRoot":"","sources":["../../src/internal/deep-override.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAgBvC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAG,OAAgC,EAAQ,EAAE;IACxE,MAAM,MAAM,GAAS,EAAE,CAAC;IAExB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAElC,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC7C,MAAM,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export * from "./build-env-overrides.js";
|
|
1
2
|
export * from "./coerce-all.js";
|
|
3
|
+
export * from "./deep-override.js";
|
|
2
4
|
export * from "./load-config.js";
|
|
3
5
|
export * from "./load-node-config.js";
|
|
4
6
|
export * from "./load-npm-info.js";
|
|
7
|
+
export * from "./walk-schema.js";
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
|
package/dist/internal/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export * from "./build-env-overrides.js";
|
|
1
2
|
export * from "./coerce-all.js";
|
|
3
|
+
export * from "./deep-override.js";
|
|
2
4
|
export * from "./load-config.js";
|
|
3
5
|
export * from "./load-node-config.js";
|
|
4
6
|
export * from "./load-npm-info.js";
|
|
7
|
+
export * from "./walk-schema.js";
|
|
5
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/internal/load-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/internal/load-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAY3C,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { changeKeys } from "@lindorm/case";
|
|
2
2
|
import c from "config";
|
|
3
|
-
|
|
4
|
-
export const loadConfig = (processEnv) => {
|
|
3
|
+
export const loadConfig = () => {
|
|
5
4
|
const config = c.util.toObject();
|
|
6
|
-
|
|
7
|
-
return changeKeys(merged, "camel");
|
|
5
|
+
return changeKeys(config, "camel");
|
|
8
6
|
};
|
|
9
7
|
//# sourceMappingURL=load-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/internal/load-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,CAAC,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/internal/load-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,CAAC,MAAM,QAAQ,CAAC;AAWvB,MAAM,CAAC,MAAM,UAAU,GAAG,GAAS,EAAE;IACnC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAU,CAAC;IACzC,OAAO,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-schema.d.ts","sourceRoot":"","sources":["../../src/internal/walk-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;CACnB,CAAC;AAiBF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,CAAC,CAAC,OAAO,EACjB,OAAM,aAAa,CAAC,MAAM,CAAM,KAC/B,KAAK,CAAC,UAAU,CAyBlB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const getDef = (schema) => schema._zod?.def ?? schema._def ?? {};
|
|
3
|
+
export const walkSchemaLeaves = (schema, path = []) => {
|
|
4
|
+
const def = getDef(schema);
|
|
5
|
+
switch (def.type) {
|
|
6
|
+
case "object": {
|
|
7
|
+
const shape = def.shape;
|
|
8
|
+
if (!shape)
|
|
9
|
+
return [{ path, schema }];
|
|
10
|
+
const out = [];
|
|
11
|
+
for (const key of Object.keys(shape)) {
|
|
12
|
+
out.push(...walkSchemaLeaves(shape[key], [...path, key]));
|
|
13
|
+
}
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
case "optional":
|
|
17
|
+
case "nullable":
|
|
18
|
+
case "default":
|
|
19
|
+
case "readonly":
|
|
20
|
+
case "nonoptional":
|
|
21
|
+
return walkSchemaLeaves(def.innerType, path);
|
|
22
|
+
default:
|
|
23
|
+
return [{ path, schema }];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=walk-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-schema.js","sourceRoot":"","sources":["../../src/internal/walk-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,MAAM,MAAM,GAAG,CAAC,MAAiB,EAAuC,EAAE,CACvE,MAAc,CAAC,IAAI,EAAE,GAAG,IAAK,MAAc,CAAC,IAAI,IAAI,EAAE,CAAC;AAc1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,MAAiB,EACjB,OAA8B,EAAE,EACb,EAAE;IACrB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAE3B,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,KAAK,GAAG,GAAG,CAAC,KAA8C,CAAC;YACjE,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAEtC,MAAM,GAAG,GAAsB,EAAE,CAAC;YAClC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,GAAG,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAED,KAAK,UAAU,CAAC;QAChB,KAAK,UAAU,CAAC;QAChB,KAAK,SAAS,CAAC;QACf,KAAK,UAAU,CAAC;QAChB,KAAK,aAAa;YAChB,OAAO,gBAAgB,CAAC,GAAG,CAAC,SAAsB,EAAE,IAAI,CAAC,CAAC;QAE5D;YACE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/utils/configuration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/utils/configuration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG;IAcjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAoBF,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAC/D,QAAQ,CAAC,EACT,UAAS,oBAAyB,KACjC,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAuBzC,CAAC"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import dotenvx from "@dotenvx/dotenvx";
|
|
2
|
-
import { merge } from "@lindorm/utils";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import { coerceAll, loadConfig, loadNodeConfig, loadNpmInfo } from "../internal/index.js";
|
|
3
|
+
import { buildEnvOverrides, coerceAll, deepOverride, loadConfig, loadNodeConfig, loadNpmInfo, } from "../internal/index.js";
|
|
5
4
|
export const configuration = (schema, options = {}) => {
|
|
6
5
|
dotenvx.config({
|
|
7
6
|
path: process.env.NODE_ENV ? [`.env.${process.env.NODE_ENV}`, ".env"] : ".env",
|
|
8
7
|
quiet: true,
|
|
9
8
|
});
|
|
10
|
-
const
|
|
9
|
+
const wrapped = z.object(schema);
|
|
10
|
+
const yaml = loadConfig();
|
|
11
11
|
const node = loadNodeConfig(process.env);
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const parsed =
|
|
12
|
+
const env = buildEnvOverrides(wrapped, process.env);
|
|
13
|
+
const merged = deepOverride(yaml, node, env);
|
|
14
|
+
const parsed = coerceAll(wrapped).parse(merged);
|
|
15
15
|
const npm = {
|
|
16
16
|
npm: {
|
|
17
17
|
package: loadNpmInfo(options.scope),
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
|
-
return
|
|
20
|
+
return deepOverride(parsed, npm);
|
|
21
21
|
};
|
|
22
22
|
//# sourceMappingURL=configuration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/utils/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/utils/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,UAAU,EACV,cAAc,EACd,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAsC9B,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,MAAS,EACT,UAAgC,EAAE,EACQ,EAAE;IAC5C,OAAO,CAAC,MAAM,CAAC;QACb,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;QAC9E,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEhD,MAAM,GAAG,GAAG;QACV,GAAG,EAAE;YACH,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACpC;KACF,CAAC;IAEF,OAAO,YAAY,CAAC,MAAa,EAAE,GAAU,CAAQ,CAAC;AACxD,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lindorm/config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"author": "Jonn Nilsson",
|
|
6
6
|
"repository": {
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"@types/config": "^3.3.5",
|
|
52
52
|
"@types/js-yaml": "^4.0.9"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "9af4f6ada0800042d2309dcfc43c1c672b744085"
|
|
55
55
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-process-env-value.d.ts","sourceRoot":"","sources":["../../src/internal/find-process-env-value.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,eAAO,MAAM,mBAAmB,GAC9B,YAAY,UAAU,EACtB,KAAK,MAAM,EACX,SAAS,MAAM,KACd,GAQF,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { changeCase } from "@lindorm/case";
|
|
2
|
-
import { safelyParse } from "@lindorm/utils";
|
|
3
|
-
export const findProcessEnvValue = (processEnv, key, parent) => {
|
|
4
|
-
const k = changeCase(key, "constant");
|
|
5
|
-
const pkey = parent ? changeCase(parent, "constant") : undefined;
|
|
6
|
-
const search = pkey ? `${pkey}_${k}` : k;
|
|
7
|
-
const value = processEnv[search] ? processEnv[search] : undefined;
|
|
8
|
-
return value ? safelyParse(value) : undefined;
|
|
9
|
-
};
|
|
10
|
-
//# sourceMappingURL=find-process-env-value.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-process-env-value.js","sourceRoot":"","sources":["../../src/internal/find-process-env-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAsB,EACtB,GAAW,EACX,MAAe,EACV,EAAE;IACP,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEjE,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAElE,OAAO,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { Dict } from "@lindorm/types";
|
|
2
|
-
import type { ProcessEnv } from "../types/index.js";
|
|
3
|
-
export declare const mergeObjectWithProcessEnv: (processEnv: ProcessEnv, config: Dict, parent?: string) => Dict;
|
|
4
|
-
//# sourceMappingURL=merge-object-with-process-env.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"merge-object-with-process-env.d.ts","sourceRoot":"","sources":["../../src/internal/merge-object-with-process-env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,eAAO,MAAM,yBAAyB,GACpC,YAAY,UAAU,EACtB,QAAQ,IAAI,EACZ,SAAS,MAAM,KACd,IAqBF,CAAC"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { isObject, isUndefined } from "@lindorm/is";
|
|
2
|
-
import { findProcessEnvValue } from "./find-process-env-value.js";
|
|
3
|
-
export const mergeObjectWithProcessEnv = (processEnv, config, parent) => {
|
|
4
|
-
const result = {};
|
|
5
|
-
for (const [key, value] of Object.entries(config)) {
|
|
6
|
-
const env = findProcessEnvValue(processEnv, key, parent);
|
|
7
|
-
if (!isUndefined(env)) {
|
|
8
|
-
result[key] = env;
|
|
9
|
-
continue;
|
|
10
|
-
}
|
|
11
|
-
if (isObject(value)) {
|
|
12
|
-
const pkey = parent ? `${parent}_${key}` : key;
|
|
13
|
-
result[key] = mergeObjectWithProcessEnv(processEnv, value, pkey);
|
|
14
|
-
continue;
|
|
15
|
-
}
|
|
16
|
-
result[key] = value;
|
|
17
|
-
}
|
|
18
|
-
return result;
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=merge-object-with-process-env.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"merge-object-with-process-env.js","sourceRoot":"","sources":["../../src/internal/merge-object-with-process-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,UAAsB,EACtB,MAAY,EACZ,MAAe,EACT,EAAE;IACR,MAAM,MAAM,GAAS,EAAE,CAAC;IAExB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,mBAAmB,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAEzD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;YAClB,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,yBAAyB,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YACjE,SAAS;QACX,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|