@bymax-one/nest-config 1.2.1 → 1.2.3

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.
@@ -1,4 +1,4 @@
1
- import { createValidatedConfig, BymaxConfigModule, resolveSourceNames } from '@bymax-one/nest-config/internal';
1
+ import { BymaxConfigModule, assertDistinctVariables, resolveSourceNames, createValidatedConfig, BymaxConfigValidationError } 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
- if (def.format === "url") return synthesizeUrl(lengths);
63
- if (def.format === "email") return synthesizeEmail(lengths);
64
- return synthesizePlainString(lengths);
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,44 @@ 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 !== void 0) entries.set(binding.variable, String(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 buildTestSource(schema, overrides) {
158
- return applyOverrides(schema, synthesizePlaceholderSource(schema), overrides);
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
+ assertDistinctVariables(resolveSourceNames(schema));
202
+ const overridden = /* @__PURE__ */ new Set();
203
+ const source = applyOverrides(schema, synthesizePlaceholderSource(schema), overrides, overridden);
204
+ try {
205
+ return { source, config: createValidatedConfig({ schema, source }) };
206
+ } catch (error) {
207
+ throw error instanceof BymaxConfigValidationError ? explainUnsatisfiedLeaves(error, overridden) : error;
208
+ }
159
209
  }
160
210
  function createTestConfig(schema, overrides) {
161
- return createValidatedConfig({ schema, source: buildTestSource(schema, overrides) });
211
+ return prepareTestConfig(schema, overrides).config;
162
212
  }
163
213
  function configTestingModule(schema, overrides) {
164
- const source = buildTestSource(schema, overrides);
214
+ const { source } = prepareTestConfig(schema, overrides);
165
215
  return BymaxConfigModule.forRoot({ schema, source });
166
216
  }
167
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-config",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
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",