@bymax-one/nest-config 1.2.0 → 1.2.2
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 +96 -3
- package/README.md +224 -30
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/internal/index.cjs +49 -13
- package/dist/internal/index.d.cts +30 -17
- package/dist/internal/index.d.ts +30 -17
- package/dist/internal/index.mjs +49 -13
- package/dist/testing/index.cjs +58 -9
- package/dist/testing/index.d.cts +4 -1
- package/dist/testing/index.d.ts +4 -1
- package/dist/testing/index.mjs +59 -10
- package/package.json +3 -3
package/dist/testing/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createValidatedConfig,
|
|
1
|
+
import { BymaxConfigModule, createValidatedConfig, BymaxConfigValidationError, resolveSourceNames } from '@bymax-one/nest-config/internal';
|
|
2
2
|
|
|
3
3
|
// src/testing/create-test-config.ts
|
|
4
4
|
var FILLER_CHARACTER = "a";
|
|
@@ -7,6 +7,10 @@ var PLACEHOLDER_EMAIL_DOMAIN = "@placeholder.local";
|
|
|
7
7
|
var DEFAULT_NUMBER = 1;
|
|
8
8
|
var DEFAULT_STRING_LENGTH = 1;
|
|
9
9
|
var PLACEHOLDER_BOOLEAN = "true";
|
|
10
|
+
var PLACEHOLDER_UUID = "00000000-0000-4000-8000-000000000000";
|
|
11
|
+
var PLACEHOLDER_DATETIME = "2000-01-01T00:00:00.000Z";
|
|
12
|
+
var PLACEHOLDER_DATE = "2000-01-01";
|
|
13
|
+
var PLACEHOLDER_TIME = "00:00:00";
|
|
10
14
|
function readDef(leaf) {
|
|
11
15
|
return leaf._zod.def;
|
|
12
16
|
}
|
|
@@ -57,11 +61,23 @@ function synthesizePlainString(lengths) {
|
|
|
57
61
|
const bounded = target > lengths.max ? lengths.max : target;
|
|
58
62
|
return FILLER_CHARACTER.repeat(bounded);
|
|
59
63
|
}
|
|
64
|
+
function formatOf(def) {
|
|
65
|
+
const declared = checksOf(def).map((wrapper) => wrapper._zod.def).find((check) => check.check === "string_format");
|
|
66
|
+
return def.format ?? declared?.format;
|
|
67
|
+
}
|
|
68
|
+
var FIXED_FORMATS = /* @__PURE__ */ new Map([
|
|
69
|
+
["uuid", PLACEHOLDER_UUID],
|
|
70
|
+
["datetime", PLACEHOLDER_DATETIME],
|
|
71
|
+
["date", PLACEHOLDER_DATE],
|
|
72
|
+
["time", PLACEHOLDER_TIME]
|
|
73
|
+
]);
|
|
60
74
|
function synthesizeString(def) {
|
|
61
75
|
const lengths = readStringLengths(def);
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
return
|
|
76
|
+
const format = formatOf(def);
|
|
77
|
+
if (format === "url") return synthesizeUrl(lengths);
|
|
78
|
+
if (format === "email") return synthesizeEmail(lengths);
|
|
79
|
+
const fixed = format === void 0 ? void 0 : FIXED_FORMATS.get(format);
|
|
80
|
+
return fixed ?? synthesizePlainString(lengths);
|
|
65
81
|
}
|
|
66
82
|
function selectNumber(bounds) {
|
|
67
83
|
const { lower, upper, integer } = bounds;
|
|
@@ -97,20 +113,35 @@ function synthesizeEnum(def) {
|
|
|
97
113
|
const [first] = Object.values(def.entries);
|
|
98
114
|
return String(first);
|
|
99
115
|
}
|
|
116
|
+
function withoutOptional(leaf) {
|
|
117
|
+
const def = readDef(leaf);
|
|
118
|
+
return def.type === "optional" ? withoutOptional(def.innerType) : leaf;
|
|
119
|
+
}
|
|
100
120
|
function synthesizeLeaf(leaf) {
|
|
101
121
|
const def = readDef(leaf);
|
|
102
122
|
switch (def.type) {
|
|
103
123
|
case "default":
|
|
124
|
+
case "prefault":
|
|
125
|
+
case "catch":
|
|
104
126
|
case "optional":
|
|
105
127
|
return void 0;
|
|
106
128
|
case "nullable":
|
|
129
|
+
case "readonly":
|
|
107
130
|
return synthesizeLeaf(def.innerType);
|
|
131
|
+
case "nonoptional":
|
|
132
|
+
return synthesizeLeaf(withoutOptional(def.innerType));
|
|
133
|
+
case "pipe":
|
|
134
|
+
return readDef(def.out).type === "boolean" && readDef(def.in).type === "string" ? PLACEHOLDER_BOOLEAN : synthesizeLeaf(def.in);
|
|
108
135
|
case "string":
|
|
109
136
|
return synthesizeString(def);
|
|
110
137
|
case "number":
|
|
111
138
|
return synthesizeNumber(def);
|
|
112
139
|
case "boolean":
|
|
113
140
|
return PLACEHOLDER_BOOLEAN;
|
|
141
|
+
case "date":
|
|
142
|
+
return PLACEHOLDER_DATETIME;
|
|
143
|
+
case "literal":
|
|
144
|
+
return String(def.values[0]);
|
|
114
145
|
case "enum":
|
|
115
146
|
return synthesizeEnum(def);
|
|
116
147
|
default:
|
|
@@ -143,25 +174,43 @@ function flattenOverrides(overrides) {
|
|
|
143
174
|
}
|
|
144
175
|
return flat;
|
|
145
176
|
}
|
|
146
|
-
function applyOverrides(schema, base, overrides) {
|
|
177
|
+
function applyOverrides(schema, base, overrides, overridden) {
|
|
147
178
|
const flat = flattenOverrides(overrides ?? {});
|
|
148
179
|
const entries = new Map(Object.entries(base));
|
|
149
180
|
for (const binding of resolveSourceNames(schema)) {
|
|
150
181
|
const value = flat.get(binding.path);
|
|
151
|
-
if (value
|
|
182
|
+
if (value === void 0) continue;
|
|
183
|
+
entries.set(binding.variable, String(value));
|
|
184
|
+
overridden.add(binding.variable);
|
|
152
185
|
}
|
|
153
186
|
const source = /* @__PURE__ */ Object.create(null);
|
|
154
187
|
for (const [variable, value] of entries) source[variable] = value;
|
|
155
188
|
return source;
|
|
156
189
|
}
|
|
157
|
-
function
|
|
158
|
-
return
|
|
190
|
+
function explainUnsatisfiedLeaves(error, overridden) {
|
|
191
|
+
return new BymaxConfigValidationError(
|
|
192
|
+
error.issues.map(
|
|
193
|
+
(issue) => !issue.path.includes(".") || overridden.has(issue.variable) ? issue : {
|
|
194
|
+
...issue,
|
|
195
|
+
message: `no placeholder satisfies this leaf (${issue.message}); pass an override for ${issue.path}`
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
function prepareTestConfig(schema, overrides) {
|
|
201
|
+
const overridden = /* @__PURE__ */ new Set();
|
|
202
|
+
const source = applyOverrides(schema, synthesizePlaceholderSource(schema), overrides, overridden);
|
|
203
|
+
try {
|
|
204
|
+
return { source, config: createValidatedConfig({ schema, source }) };
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw error instanceof BymaxConfigValidationError ? explainUnsatisfiedLeaves(error, overridden) : error;
|
|
207
|
+
}
|
|
159
208
|
}
|
|
160
209
|
function createTestConfig(schema, overrides) {
|
|
161
|
-
return
|
|
210
|
+
return prepareTestConfig(schema, overrides).config;
|
|
162
211
|
}
|
|
163
212
|
function configTestingModule(schema, overrides) {
|
|
164
|
-
const source =
|
|
213
|
+
const { source } = prepareTestConfig(schema, overrides);
|
|
165
214
|
return BymaxConfigModule.forRoot({ schema, source });
|
|
166
215
|
}
|
|
167
216
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-config",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Typed and validated environment configuration entry point for NestJS 11 applications, built on Zod v4.",
|
|
5
5
|
"author": "Bymax One <support@bymax.one>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"@nestjs/common": "^11.0.16",
|
|
92
92
|
"@nestjs/core": "^11.1.18",
|
|
93
93
|
"reflect-metadata": "^0.2.0",
|
|
94
|
-
"zod": "^4.
|
|
94
|
+
"zod": "^4.6.6"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"ts-node": "^10.9.2",
|
|
127
127
|
"tsup": "^8.5.1",
|
|
128
128
|
"typescript": "^5.9.3",
|
|
129
|
-
"zod": "^4.
|
|
129
|
+
"zod": "^4.6.7"
|
|
130
130
|
},
|
|
131
131
|
"keywords": [
|
|
132
132
|
"nestjs",
|