@bymax-one/nest-config 1.0.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 +106 -0
- package/LICENSE +21 -0
- package/README.md +572 -0
- package/dist/index.cjs +34 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/internal/index.cjs +423 -0
- package/dist/internal/index.d.cts +571 -0
- package/dist/internal/index.d.ts +571 -0
- package/dist/internal/index.mjs +415 -0
- package/dist/testing/index.cjs +171 -0
- package/dist/testing/index.d.cts +88 -0
- package/dist/testing/index.d.ts +88 -0
- package/dist/testing/index.mjs +168 -0
- package/package.json +161 -0
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var common = require('@nestjs/common');
|
|
4
|
+
var zod = require('zod');
|
|
5
|
+
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
8
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
9
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
10
|
+
if (decorator = decorators[i])
|
|
11
|
+
result = (decorator(result)) || result;
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
15
|
+
|
|
16
|
+
// src/config.tokens.ts
|
|
17
|
+
var BYMAX_CONFIG_OPTIONS = /* @__PURE__ */ Symbol("BYMAX_CONFIG_OPTIONS");
|
|
18
|
+
var BYMAX_CONFIG = /* @__PURE__ */ Symbol("BYMAX_CONFIG");
|
|
19
|
+
|
|
20
|
+
// src/config.module-definition.ts
|
|
21
|
+
var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = new common.ConfigurableModuleBuilder({
|
|
22
|
+
optionsInjectionToken: BYMAX_CONFIG_OPTIONS
|
|
23
|
+
}).setClassMethodName("forRoot").setExtras({ isGlobal: true }, (definition, extras) => ({
|
|
24
|
+
...definition,
|
|
25
|
+
global: extras.isGlobal
|
|
26
|
+
})).build();
|
|
27
|
+
|
|
28
|
+
// src/deep-freeze.ts
|
|
29
|
+
function isFreezable(value) {
|
|
30
|
+
return typeof value === "object" && value !== null;
|
|
31
|
+
}
|
|
32
|
+
function deepFreeze(value) {
|
|
33
|
+
if (!isFreezable(value) || Object.isFrozen(value)) {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
Object.freeze(value);
|
|
37
|
+
for (const nested of Object.values(value)) {
|
|
38
|
+
deepFreeze(nested);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/report-formatter.ts
|
|
44
|
+
var REPORT_INDENT = " ";
|
|
45
|
+
var MIN_VARIABLE_COLUMN = 20;
|
|
46
|
+
var VARIABLE_GUTTER = 2;
|
|
47
|
+
var REPORT_HEADER = "environment validation failed";
|
|
48
|
+
var REPORT_FOOTER = "Fix the variables above and restart the process.";
|
|
49
|
+
function pluralizeIssues(count) {
|
|
50
|
+
const noun = count === 1 ? "issue" : "issues";
|
|
51
|
+
return `${count} ${noun}`;
|
|
52
|
+
}
|
|
53
|
+
function computeColumnWidth(issues) {
|
|
54
|
+
let longest = MIN_VARIABLE_COLUMN;
|
|
55
|
+
for (const issue of issues) {
|
|
56
|
+
longest = Math.max(longest, issue.variable.length);
|
|
57
|
+
}
|
|
58
|
+
return longest + VARIABLE_GUTTER;
|
|
59
|
+
}
|
|
60
|
+
function formatIssueLine(issue, columnWidth) {
|
|
61
|
+
return `${REPORT_INDENT}${issue.variable.padEnd(columnWidth)}${issue.message}`;
|
|
62
|
+
}
|
|
63
|
+
function formatIssueReport(issues) {
|
|
64
|
+
const columnWidth = computeColumnWidth(issues);
|
|
65
|
+
const lines = issues.map((issue) => formatIssueLine(issue, columnWidth));
|
|
66
|
+
const header = `${REPORT_HEADER} (${pluralizeIssues(issues.length)})`;
|
|
67
|
+
return [header, "", ...lines, "", REPORT_FOOTER].join("\n");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/errors.ts
|
|
71
|
+
var ConfigErrorCode = Object.freeze({
|
|
72
|
+
/** Top-level error code: one or more schema violations were collected. */
|
|
73
|
+
VALIDATION: "BYMAX_CONFIG_VALIDATION",
|
|
74
|
+
/** Issue code: a required variable is absent from the source. */
|
|
75
|
+
MISSING: "BYMAX_CONFIG_MISSING",
|
|
76
|
+
/** Issue code: a variable is present but violates its constraint. */
|
|
77
|
+
INVALID: "BYMAX_CONFIG_INVALID",
|
|
78
|
+
/** Issue code: strict mode found a source variable matching no declared leaf. */
|
|
79
|
+
UNKNOWN_KEY: "BYMAX_CONFIG_UNKNOWN_KEY"
|
|
80
|
+
});
|
|
81
|
+
var BymaxConfigValidationError = class _BymaxConfigValidationError extends Error {
|
|
82
|
+
/**
|
|
83
|
+
* Build the aggregated error from a list of value-free issues.
|
|
84
|
+
*
|
|
85
|
+
* @param issues - Every collected violation; copied and frozen so neither the
|
|
86
|
+
* caller nor consumer code can mutate the reported list.
|
|
87
|
+
*/
|
|
88
|
+
constructor(issues) {
|
|
89
|
+
const normalized = issues.map(
|
|
90
|
+
(issue) => Object.freeze({
|
|
91
|
+
path: issue.path,
|
|
92
|
+
variable: issue.variable,
|
|
93
|
+
code: issue.code,
|
|
94
|
+
message: issue.message
|
|
95
|
+
})
|
|
96
|
+
);
|
|
97
|
+
super(formatIssueReport(normalized));
|
|
98
|
+
/** The stable top-level error code. */
|
|
99
|
+
this.code = ConfigErrorCode.VALIDATION;
|
|
100
|
+
Object.defineProperty(this, "name", {
|
|
101
|
+
value: "BymaxConfigValidationError",
|
|
102
|
+
enumerable: false,
|
|
103
|
+
writable: false,
|
|
104
|
+
configurable: false
|
|
105
|
+
});
|
|
106
|
+
this.issues = Object.freeze(normalized);
|
|
107
|
+
Object.setPrototypeOf(this, _BymaxConfigValidationError.prototype);
|
|
108
|
+
Object.defineProperty(this, "code", { writable: false, configurable: false });
|
|
109
|
+
Object.defineProperty(this, "issues", { writable: false, configurable: false });
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// src/source-mapping.ts
|
|
114
|
+
function toScreamingSnake(segment) {
|
|
115
|
+
return segment.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toUpperCase();
|
|
116
|
+
}
|
|
117
|
+
function readEnvOverride(leaf) {
|
|
118
|
+
const override = leaf.meta()?.env;
|
|
119
|
+
return typeof override === "string" && override.length > 0 ? override : void 0;
|
|
120
|
+
}
|
|
121
|
+
function deriveVariable(namespace, leafKey) {
|
|
122
|
+
return `${toScreamingSnake(namespace)}_${toScreamingSnake(leafKey)}`;
|
|
123
|
+
}
|
|
124
|
+
function resolveSourceNames(schema) {
|
|
125
|
+
return Object.entries(schema.shape).flatMap(
|
|
126
|
+
([namespace, namespaceSchema]) => Object.entries(namespaceSchema.shape).map(([leafKey, leafSchema]) => ({
|
|
127
|
+
path: `${namespace}.${leafKey}`,
|
|
128
|
+
variable: readEnvOverride(leafSchema) ?? deriveVariable(namespace, leafKey)
|
|
129
|
+
}))
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
function resolveNamespacePrefixes(schema) {
|
|
133
|
+
return Object.keys(schema.shape).map((namespace) => ({
|
|
134
|
+
namespace,
|
|
135
|
+
prefix: `${toScreamingSnake(namespace)}_`
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/env-validator.ts
|
|
140
|
+
var UNKNOWN_KEY_MESSAGE = "unknown variable not declared in the schema";
|
|
141
|
+
var MISSING_MESSAGE = "missing required value";
|
|
142
|
+
function collectPresentLeaves(bindings, source) {
|
|
143
|
+
const present = [];
|
|
144
|
+
for (const binding of bindings) {
|
|
145
|
+
const value = source.get(binding.variable);
|
|
146
|
+
if (value === void 0) continue;
|
|
147
|
+
const separator = binding.path.indexOf(".");
|
|
148
|
+
present.push({
|
|
149
|
+
namespace: binding.path.slice(0, separator),
|
|
150
|
+
leaf: binding.path.slice(separator + 1),
|
|
151
|
+
value
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return present;
|
|
155
|
+
}
|
|
156
|
+
function buildCandidate(namespaces, present) {
|
|
157
|
+
return Object.fromEntries(
|
|
158
|
+
namespaces.map((namespace) => [
|
|
159
|
+
namespace,
|
|
160
|
+
Object.fromEntries(
|
|
161
|
+
present.filter((leaf) => leaf.namespace === namespace).map((leaf) => [leaf.leaf, leaf.value])
|
|
162
|
+
)
|
|
163
|
+
])
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function formatEnumValues(values) {
|
|
167
|
+
return values.map(String).join(", ");
|
|
168
|
+
}
|
|
169
|
+
function describeConstraint(issue) {
|
|
170
|
+
switch (issue.code) {
|
|
171
|
+
case "invalid_type":
|
|
172
|
+
return `invalid value (expected: ${issue.expected})`;
|
|
173
|
+
case "invalid_format":
|
|
174
|
+
return `invalid format (expected: ${issue.format})`;
|
|
175
|
+
case "invalid_value":
|
|
176
|
+
return `invalid value (expected one of: ${formatEnumValues(issue.values)})`;
|
|
177
|
+
case "too_small":
|
|
178
|
+
return issue.origin === "string" ? `too short (expected: string, minimum ${issue.minimum} characters)` : `out of range (expected: ${issue.origin} >= ${issue.minimum})`;
|
|
179
|
+
case "too_big":
|
|
180
|
+
return issue.origin === "string" ? `too long (expected: string, maximum ${issue.maximum} characters)` : `out of range (expected: ${issue.origin} <= ${issue.maximum})`;
|
|
181
|
+
default:
|
|
182
|
+
return "invalid value";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function toConfigIssue(binding, issue, source) {
|
|
186
|
+
const isMissing = source.get(binding.variable) === void 0;
|
|
187
|
+
return {
|
|
188
|
+
path: binding.path,
|
|
189
|
+
variable: binding.variable,
|
|
190
|
+
code: isMissing ? ConfigErrorCode.MISSING : ConfigErrorCode.INVALID,
|
|
191
|
+
message: isMissing ? MISSING_MESSAGE : describeConstraint(issue)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function translateIssues(zodIssues, bindings, source) {
|
|
195
|
+
const issueByPath = /* @__PURE__ */ new Map();
|
|
196
|
+
for (const issue of zodIssues) {
|
|
197
|
+
const path = issue.path.slice(0, 2).join(".");
|
|
198
|
+
if (!issueByPath.has(path)) {
|
|
199
|
+
issueByPath.set(path, issue);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const result = [];
|
|
203
|
+
for (const binding of bindings) {
|
|
204
|
+
const issue = issueByPath.get(binding.path);
|
|
205
|
+
if (issue === void 0) continue;
|
|
206
|
+
result.push(toConfigIssue(binding, issue, source));
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
function longestMatchingPrefix(prefixes, key) {
|
|
211
|
+
let match;
|
|
212
|
+
for (const entry of prefixes) {
|
|
213
|
+
if (!key.startsWith(entry.prefix)) continue;
|
|
214
|
+
if (match === void 0 || entry.prefix.length > match.prefix.length) {
|
|
215
|
+
match = entry;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return match;
|
|
219
|
+
}
|
|
220
|
+
function detectUnknownKeys(prefixes, bindings, source) {
|
|
221
|
+
const declared = new Set(bindings.map((binding) => binding.variable));
|
|
222
|
+
const issues = [];
|
|
223
|
+
for (const key of source.keys()) {
|
|
224
|
+
if (declared.has(key)) continue;
|
|
225
|
+
if (source.get(key) === void 0) continue;
|
|
226
|
+
const match = longestMatchingPrefix(prefixes, key);
|
|
227
|
+
if (match === void 0) continue;
|
|
228
|
+
issues.push({
|
|
229
|
+
path: match.namespace,
|
|
230
|
+
variable: key,
|
|
231
|
+
code: ConfigErrorCode.UNKNOWN_KEY,
|
|
232
|
+
message: UNKNOWN_KEY_MESSAGE
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
return issues.sort(
|
|
236
|
+
(left, right) => Number(left.variable > right.variable) - Number(left.variable < right.variable)
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
function validateEnv(schema, source, options) {
|
|
240
|
+
const bindings = resolveSourceNames(schema);
|
|
241
|
+
const sourceMap = new Map(Object.entries(source));
|
|
242
|
+
const namespaces = Object.keys(schema.shape);
|
|
243
|
+
const candidate = buildCandidate(namespaces, collectPresentLeaves(bindings, sourceMap));
|
|
244
|
+
const result = schema.safeParse(candidate);
|
|
245
|
+
const unknown = options?.strict === true ? detectUnknownKeys(resolveNamespacePrefixes(schema), bindings, sourceMap) : [];
|
|
246
|
+
if (result.success) {
|
|
247
|
+
if (unknown.length === 0) return result.data;
|
|
248
|
+
throw new BymaxConfigValidationError(unknown);
|
|
249
|
+
}
|
|
250
|
+
const issues = translateIssues(result.error.issues, bindings, sourceMap);
|
|
251
|
+
throw new BymaxConfigValidationError([...issues, ...unknown]);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// src/config.providers.ts
|
|
255
|
+
function reportIssues(hook, issues) {
|
|
256
|
+
if (hook === void 0) return;
|
|
257
|
+
try {
|
|
258
|
+
hook(issues);
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function createValidatedConfig(options) {
|
|
263
|
+
const source = options.source ?? process.env;
|
|
264
|
+
try {
|
|
265
|
+
return deepFreeze(validateEnv(options.schema, source, { strict: options.strict === true }));
|
|
266
|
+
} catch (error) {
|
|
267
|
+
if (error instanceof BymaxConfigValidationError) {
|
|
268
|
+
reportIssues(options.onValidationError, error.issues);
|
|
269
|
+
}
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
var bymaxConfigProvider = {
|
|
274
|
+
provide: BYMAX_CONFIG,
|
|
275
|
+
useFactory: createValidatedConfig,
|
|
276
|
+
inject: [BYMAX_CONFIG_OPTIONS]
|
|
277
|
+
};
|
|
278
|
+
exports.ConfigService = class ConfigService {
|
|
279
|
+
/**
|
|
280
|
+
* Bind the accessor to the frozen configuration object.
|
|
281
|
+
*
|
|
282
|
+
* Builds a flat `namespace.leaf` lookup once so `get`/`has` are constant-time
|
|
283
|
+
* and never rebuild a map per call. Iteration over entries (rather than dynamic
|
|
284
|
+
* bracket indexing) avoids introducing a non-literal property sink.
|
|
285
|
+
*
|
|
286
|
+
* @param config - The validated, deep-frozen config injected via {@link BYMAX_CONFIG}.
|
|
287
|
+
*/
|
|
288
|
+
constructor(config) {
|
|
289
|
+
this.config = config;
|
|
290
|
+
const leaves = /* @__PURE__ */ new Map();
|
|
291
|
+
for (const [namespace, value] of Object.entries(config)) {
|
|
292
|
+
for (const [leaf, leafValue] of Object.entries(value)) {
|
|
293
|
+
leaves.set(`${namespace}.${leaf}`, leafValue);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
this.leaves = leaves;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Read a leaf value by its `namespace.leaf` dot-path.
|
|
300
|
+
*
|
|
301
|
+
* The return type is inferred from the path, so `get('server.port')` is typed
|
|
302
|
+
* `number` with no cast. Never throws for a declared path: validation ran once
|
|
303
|
+
* at bootstrap. An optional leaf without a default may still resolve to
|
|
304
|
+
* `undefined` when its type includes it.
|
|
305
|
+
*
|
|
306
|
+
* @typeParam TPath - A declared path drawn from {@link Path}<TConfig>.
|
|
307
|
+
* @param path - The two-level dot-path to resolve.
|
|
308
|
+
* @returns The leaf value, typed as {@link PathValue}<TConfig, TPath>.
|
|
309
|
+
* @example
|
|
310
|
+
* ```typescript
|
|
311
|
+
* const port = config.get('server.port'); // number
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
get(path) {
|
|
315
|
+
return this.resolve(path);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Return the whole validated configuration as its deep-frozen root.
|
|
319
|
+
*
|
|
320
|
+
* Yields the same frozen reference the module registered, fully typed for
|
|
321
|
+
* arbitrary depth, which is the escape hatch for nesting deeper than the
|
|
322
|
+
* two-level dot-path inference covers.
|
|
323
|
+
*
|
|
324
|
+
* @returns The frozen configuration root.
|
|
325
|
+
* @example
|
|
326
|
+
* ```typescript
|
|
327
|
+
* const everything = config.getAll(); // Readonly<AppConfig>
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
getAll() {
|
|
331
|
+
return this.config;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Report whether a declared path resolves to a defined value.
|
|
335
|
+
*
|
|
336
|
+
* Returns `false` when the leaf resolved to `undefined` (an optional leaf
|
|
337
|
+
* without a default), distinguishing "declared but unset" from "declared and
|
|
338
|
+
* set" without a truthiness pitfall on falsy values such as `0` or `''`.
|
|
339
|
+
*
|
|
340
|
+
* @param path - The two-level dot-path to check.
|
|
341
|
+
* @returns True when the resolved value is not `undefined`.
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* if (config.has('redis.url')) connectRedis(config.get('redis.url'));
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
has(path) {
|
|
348
|
+
return this.resolve(path) !== void 0;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Resolve a two-level dot-path to its raw leaf value.
|
|
352
|
+
*
|
|
353
|
+
* Looks the path up in the precomputed `namespace.leaf` map, so an unset leaf
|
|
354
|
+
* (or, defensively, an unexpected path) yields `undefined` instead of throwing.
|
|
355
|
+
*
|
|
356
|
+
* @param path - The declared two-level dot-path.
|
|
357
|
+
* @returns The leaf value as `unknown`, or `undefined` when the leaf is unset.
|
|
358
|
+
*/
|
|
359
|
+
resolve(path) {
|
|
360
|
+
return this.leaves.get(String(path));
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
exports.ConfigService = __decorateClass([
|
|
364
|
+
common.Injectable(),
|
|
365
|
+
__decorateParam(0, common.Inject(BYMAX_CONFIG))
|
|
366
|
+
], exports.ConfigService);
|
|
367
|
+
|
|
368
|
+
// src/config.module.ts
|
|
369
|
+
function appendTo(list, ...items) {
|
|
370
|
+
return list === void 0 ? [...items] : [...list, ...items];
|
|
371
|
+
}
|
|
372
|
+
exports.BymaxConfigModule = class BymaxConfigModule extends ConfigurableModuleClass {
|
|
373
|
+
/**
|
|
374
|
+
* Register the module synchronously from a static schema.
|
|
375
|
+
*
|
|
376
|
+
* @param options - The module options plus the optional `isGlobal` extra.
|
|
377
|
+
* @returns The dynamic module augmented with the frozen config provider.
|
|
378
|
+
*/
|
|
379
|
+
static forRoot(options) {
|
|
380
|
+
return exports.BymaxConfigModule.withConfigProvider(super.forRoot(options));
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Register the module asynchronously, resolving options through a factory.
|
|
384
|
+
*
|
|
385
|
+
* @param options - The async options with `useFactory` and explicit `inject`.
|
|
386
|
+
* @returns The dynamic module augmented with the frozen config provider.
|
|
387
|
+
*/
|
|
388
|
+
static forRootAsync(options) {
|
|
389
|
+
return exports.BymaxConfigModule.withConfigProvider(super.forRootAsync(options));
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Append the config provider and typed accessor to a generated definition.
|
|
393
|
+
*
|
|
394
|
+
* Registers the frozen {@link BYMAX_CONFIG} provider and the {@link ConfigService}
|
|
395
|
+
* accessor (which injects that token), then exports both so consumers can
|
|
396
|
+
* inject either the raw frozen object or the typed service.
|
|
397
|
+
*
|
|
398
|
+
* @param definition - The dynamic module produced by the builder base class.
|
|
399
|
+
* @returns A definition that provides and exports {@link BYMAX_CONFIG} and
|
|
400
|
+
* {@link ConfigService}.
|
|
401
|
+
*/
|
|
402
|
+
static withConfigProvider(definition) {
|
|
403
|
+
return {
|
|
404
|
+
...definition,
|
|
405
|
+
providers: appendTo(definition.providers, bymaxConfigProvider, exports.ConfigService),
|
|
406
|
+
exports: appendTo(definition.exports, BYMAX_CONFIG, exports.ConfigService)
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
exports.BymaxConfigModule = __decorateClass([
|
|
411
|
+
common.Module({})
|
|
412
|
+
], exports.BymaxConfigModule);
|
|
413
|
+
function defineEnv(shape) {
|
|
414
|
+
return zod.z.object(shape);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
exports.BYMAX_CONFIG = BYMAX_CONFIG;
|
|
418
|
+
exports.BYMAX_CONFIG_OPTIONS = BYMAX_CONFIG_OPTIONS;
|
|
419
|
+
exports.BymaxConfigValidationError = BymaxConfigValidationError;
|
|
420
|
+
exports.ConfigErrorCode = ConfigErrorCode;
|
|
421
|
+
exports.createValidatedConfig = createValidatedConfig;
|
|
422
|
+
exports.defineEnv = defineEnv;
|
|
423
|
+
exports.resolveSourceNames = resolveSourceNames;
|