@scania-nl/tegel-angular-extensions 0.0.4 → 0.0.5

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.
@@ -0,0 +1,161 @@
1
+ import { inject, Injectable, InjectionToken, makeEnvironmentProviders, provideAppInitializer, } from '@angular/core';
2
+ import { catchError, defer, firstValueFrom, from, map, of, switchMap, tap, } from 'rxjs';
3
+ import { parseEnvFile } from '../core/parse-env-file';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Builds styled console arguments for RuntimeConfig logs.
7
+ *
8
+ * The returned tuple can be spread directly into `console.log`,
9
+ * allowing the browser to render a colored `[RuntimeConfig]` prefix
10
+ * while preserving the original caller location in DevTools.
11
+ *
12
+ * Example:
13
+ * ```ts
14
+ * console.log(...rcArgs('Runtime overrides loaded.'));
15
+ * ```
16
+ *
17
+ * @param msg - The message text to append after the colored prefix.
18
+ * @returns A tuple of arguments (`[format, style, reset]`) for `console.log`.
19
+ */
20
+ const rcArgs = (msg) => [
21
+ '%c[RuntimeConfig]%c ' + msg,
22
+ 'color:#0cf;',
23
+ '',
24
+ ];
25
+ /**
26
+ * Registers providers that:
27
+ * - Fetch a runtime `.env` file at startup,
28
+ * - Parse it to a deep-partial structure via the kit,
29
+ * - Enforce runtime-required keys when appropriate,
30
+ * - Merge with the static environment,
31
+ * - Validate the **final** configuration against the Zod schema,
32
+ * - Expose the resulting config via a generated `InjectionToken`.
33
+ *
34
+ * @typeParam S - Zod schema type describing the full config shape.
35
+ * @typeParam K - List of runtime-required top-level keys.
36
+ *
37
+ * @param kit
38
+ * The `EnvKit` created by `createEnvKit(schema, runtimeRequiredKeys)`.
39
+ *
40
+ * @param options
41
+ * Runtime loading behavior and DI token description. See {@link ProvideRuntimeConfigOptions}.
42
+ *
43
+ * @returns The `EnvironmentProviders` to be added to `appConfig.providers`,
44
+ *
45
+ * @remarks
46
+ * - This uses an Angular **functional app initializer** to perform the load step.
47
+ * - If the server returns an HTML SPA fallback (instead of the `.env` file), the provider
48
+ * quietly uses the static environment (no runtime overrides).
49
+ */
50
+ export function provideRuntimeConfig(kit, staticEnv, { envPath = '/env/runtime.env', debug = false, stopOnError = true, token, } = {}) {
51
+ // Typed token used to expose the final validated config via DI.
52
+ const configToken = token ?? new InjectionToken('ENV_CONFIG');
53
+ /**
54
+ * Angular service that handles fetching, parsing, validating, and caching
55
+ * of the runtime environment configuration.
56
+ */
57
+ class RuntimeConfigService {
58
+ // Cached instance of the validated configuration.
59
+ config;
60
+ /**
61
+ * Loads, parses, merges and validates the runtime configuration.
62
+ * Returns an `Observable<ConfigShape>` and caches the final result.
63
+ */
64
+ load() {
65
+ return defer(() => from(fetch(envPath).then((res) => {
66
+ // Handle HTTP errors explicitly so they go through catchError
67
+ if (!res.ok) {
68
+ throw new Error(`Failed to load runtime config: ${res.status} ${res.statusText}`);
69
+ }
70
+ return res.text();
71
+ })).pipe(
72
+ // 1. SPA fallback guard (server returned HTML instead of .env)
73
+ map((raw) => {
74
+ const trimmed = raw.trim();
75
+ const looksHtml = /^\s*<!doctype/i.test(trimmed) || /^\s*<html[\s>]/i.test(trimmed);
76
+ if (looksHtml) {
77
+ if (debug) {
78
+ console.log(...rcArgs('No runtime environment file detected, using static environment only.'));
79
+ }
80
+ // Signal “no runtime.env, use static only”
81
+ return null;
82
+ }
83
+ return raw;
84
+ }), tap((v) => {
85
+ if (!debug)
86
+ return;
87
+ console.log(...rcArgs(v === null
88
+ ? 'No runtime environment file defined, using static environment'
89
+ : 'Runtime environment file loaded, applying overrides.'));
90
+ }),
91
+ // 2. Either continue the pipe or return defaults
92
+ switchMap((raw) => {
93
+ if (raw === null) {
94
+ return from(kit.mergeAndValidateAsync(staticEnv)).pipe(tap((cfg) => (this.config = cfg)));
95
+ }
96
+ // 3. Parse raw `.env` text -> object, then deep-partial-parse via kit
97
+ const runtimeConfigRaw = parseEnvFile(raw);
98
+ return from(kit.parseRuntimeOverridesAsync(runtimeConfigRaw)).pipe(tap((overrides) => {
99
+ if (debug)
100
+ console.log(...rcArgs('Runtime config (parsed):'), overrides);
101
+ }),
102
+ // 4. Merge static + overrides and validate the final config (async)
103
+ switchMap((overrides) => from(kit.mergeAndValidateAsync(staticEnv, overrides))),
104
+ // 5. Cache the validated config for synchronous access later
105
+ tap((mergedConfig) => {
106
+ if (debug)
107
+ console.log(...rcArgs('Merged config:'), mergedConfig);
108
+ this.config = mergedConfig;
109
+ }));
110
+ }),
111
+ // 6. Error handling: fail fast or gracefully fall back to static-only
112
+ catchError((err) => {
113
+ if (stopOnError) {
114
+ // Reject app initialization (recommended for production)
115
+ throw err;
116
+ }
117
+ console.error(...rcArgs('Error occurred while loading runtime config:'), err);
118
+ return of(this.useDefaults());
119
+ })));
120
+ }
121
+ /**
122
+ * Returns the current configuration.
123
+ * If not yet loaded, returns a validated static-only configuration.
124
+ */
125
+ get() {
126
+ if (!this.config) {
127
+ throw new Error('RuntimeConfigService.get() called before configuration was loaded. ' +
128
+ 'Ensure provideAppInitializer waits for RuntimeConfigService.load().');
129
+ }
130
+ return this.config;
131
+ }
132
+ /**
133
+ * Sets the current configuration to a validated static-only configuration
134
+ * Used when the runtime `.env` file is missing.
135
+ */
136
+ useDefaults() {
137
+ // Note: this uses the static env; merge+validate is performed in `get()` if needed.
138
+ this.config ??= staticEnv;
139
+ return this.config;
140
+ }
141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RuntimeConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
142
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RuntimeConfigService, providedIn: 'root' });
143
+ }
144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.13", ngImport: i0, type: RuntimeConfigService, decorators: [{
145
+ type: Injectable,
146
+ args: [{ providedIn: 'root' }]
147
+ }] });
148
+ // Register the service + initializer + token exposure with Angular DI.
149
+ return makeEnvironmentProviders([
150
+ RuntimeConfigService,
151
+ // Angular 19+ functional initializer (subscribes to the load Observable)
152
+ // Using firstValueFrom to enforece "await until loaded" semantics
153
+ provideAppInitializer(() => firstValueFrom(inject(RuntimeConfigService).load())),
154
+ // Expose the final validated config via the generated token
155
+ {
156
+ provide: configToken,
157
+ useFactory: () => inject(RuntimeConfigService).get(),
158
+ },
159
+ ]);
160
+ }
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1ydW50aW1lLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvdGVnZWwtYW5ndWxhci1leHRlbnNpb25zL3NyYy9saWIvZW52L2FuZ3VsYXIvcHJvdmlkZS1ydW50aW1lLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsTUFBTSxFQUNOLFVBQVUsRUFDVixjQUFjLEVBQ2Qsd0JBQXdCLEVBQ3hCLHFCQUFxQixHQUN0QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsVUFBVSxFQUNWLEtBQUssRUFDTCxjQUFjLEVBQ2QsSUFBSSxFQUNKLEdBQUcsRUFFSCxFQUFFLEVBQ0YsU0FBUyxFQUNULEdBQUcsR0FDSixNQUFNLE1BQU0sQ0FBQztBQUdkLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUFFdEQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLE1BQU0sR0FBRyxDQUFDLEdBQVcsRUFBa0MsRUFBRSxDQUFDO0lBQzlELHNCQUFzQixHQUFHLEdBQUc7SUFDNUIsYUFBYTtJQUNiLEVBQUU7Q0FDSCxDQUFDO0FBa0NGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBSWxDLEdBQWlCLEVBQ2pCLFNBQThCLEVBQzlCLEVBQ0UsT0FBTyxHQUFHLGtCQUFrQixFQUM1QixLQUFLLEdBQUcsS0FBSyxFQUNiLFdBQVcsR0FBRyxJQUFJLEVBQ2xCLEtBQUssTUFDNkIsRUFBRTtJQUt0QyxnRUFBZ0U7SUFDaEUsTUFBTSxXQUFXLEdBQUcsS0FBSyxJQUFJLElBQUksY0FBYyxDQUFZLFlBQVksQ0FBQyxDQUFDO0lBRXpFOzs7T0FHRztJQUNILE1BQ00sb0JBQW9CO1FBQ3hCLGtEQUFrRDtRQUMxQyxNQUFNLENBQWE7UUFFM0I7OztXQUdHO1FBQ0gsSUFBSTtZQUNGLE9BQU8s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LE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLEdBQUcsRUFBRTtTQUNyRDtLQUNGLENBQUMsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRW52aXJvbm1lbnRQcm92aWRlcnMsXG4gIGluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyxcbiAgcHJvdmlkZUFwcEluaXRpYWxpemVyLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIGRlZmVyLFxuICBmaXJzdFZhbHVlRnJvbSxcbiAgZnJvbSxcbiAgbWFwLFxuICBPYnNlcnZhYmxlLFxuICBvZixcbiAgc3dpdGNoTWFwLFxuICB0YXAsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHogZnJvbSAnem9kJztcbmltcG9ydCB7IEVudktpdCwgU2NoZW1hT3V0cHV0LCBTdGF0aWNFbnZGcm9tIH0gZnJvbSAnLi4vY29yZS9lbnYtdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VFbnZGaWxlIH0gZnJvbSAnLi4vY29yZS9wYXJzZS1lbnYtZmlsZSc7XG5cbi8qKlxuICogQnVpbGRzIHN0eWxlZCBjb25zb2xlIGFyZ3VtZW50cyBmb3IgUnVudGltZUNvbmZpZyBsb2dzLlxuICpcbiAqIFRoZSByZXR1cm5lZCB0dXBsZSBjYW4gYmUgc3ByZWFkIGRpcmVjdGx5IGludG8gYGNvbnNvbGUubG9nYCxcbiAqIGFsbG93aW5nIHRoZSBicm93c2VyIHRvIHJlbmRlciBhIGNvbG9yZWQgYFtSdW50aW1lQ29uZmlnXWAgcHJlZml4XG4gKiB3aGlsZSBwcmVzZXJ2aW5nIHRoZSBvcmlnaW5hbCBjYWxsZXIgbG9jYXRpb24gaW4gRGV2VG9vbHMuXG4gKlxuICogRXhhbXBsZTpcbiAqIGBgYHRzXG4gKiBjb25zb2xlLmxvZyguLi5yY0FyZ3MoJ1J1bnRpbWUgb3ZlcnJpZGVzIGxvYWRlZC4nKSk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gbXNnIC0gVGhlIG1lc3NhZ2UgdGV4dCB0byBhcHBlbmQgYWZ0ZXIgdGhlIGNvbG9yZWQgcHJlZml4LlxuICogQHJldHVybnMgQSB0dXBsZSBvZiBhcmd1bWVudHMgKGBbZm9ybWF0LCBzdHlsZSwgcmVzZXRdYCkgZm9yIGBjb25zb2xlLmxvZ2AuXG4gKi9cbmNvbnN0IHJjQXJncyA9IChtc2c6IHN0cmluZyk6IFBhcmFtZXRlcnM8dHlwZW9mIGNvbnNvbGUubG9nPiA9PiBbXG4gICclY1tSdW50aW1lQ29uZmlnXSVjICcgKyBtc2csXG4gICdjb2xvcjojMGNmOycsXG4gICcnLFxuXTtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBjb25maWd1cmluZyB0aGUgQW5ndWxhciBydW50aW1lLWNvbmZpZyBwcm92aWRlci5cbiAqXG4gKiBAcHJvcGVydHkgZW52UGF0aFxuICogVGhlIFVSTCAob3IgcGF0aCkgdG8gdGhlIHJ1bnRpbWUgYC5lbnZgIGZpbGUgdGhhdCB3aWxsIGJlIGZldGNoZWQgYXQgYXBwIHN0YXJ0LlxuICogRGVmYXVsdHMgdG8gYFwiL2Vudi9ydW50aW1lLmVudlwiYC5cbiAqXG4gKiBAcHJvcGVydHkgZGVidWdcbiAqIEVuYWJsZXMgdmVyYm9zZSBjb25zb2xlIGxvZ2dpbmcgd2hlbiBgdHJ1ZWAuIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gKlxuICogQHByb3BlcnR5IHN0b3BPbkVycm9yXG4gKiBJZiBgdHJ1ZWAsIGFueSBmYWlsdXJlIHdoaWxlIGxvYWRpbmcvcGFyc2luZy92YWxpZGF0aW5nIHRoZSBydW50aW1lIGNvbmZpZ1xuICogd2lsbCByZWplY3QgdGhlIGFwcCBpbml0aWFsaXplciBhbmQgKiphYm9ydCBib290KiogKHJlY29tbWVuZGVkIGZvciBwcm9kKS5cbiAqIElmIGBmYWxzZWAsIHRoZSBwcm92aWRlciBmYWxscyBiYWNrIHRvIHRoZSBzdGF0aWMgZW52aXJvbm1lbnQgb25seS5cbiAqIERlZmF1bHRzIHRvIGB0cnVlYC5cbiAqXG4gKiBAcHJvcGVydHkgdG9rZW5cbiAqIE9wdGlvbmFsIGBJbmplY3Rpb25Ub2tlbmAgdXNlZCB0byBleHBvc2UgdGhlIHZhbGlkYXRlZCBjb25maWd1cmF0aW9uXG4gKiB2aWEgQW5ndWxhciBkZXBlbmRlbmN5IGluamVjdGlvbi4gSWYgb21pdHRlZCwgdGhlIHByb3ZpZGVyIHdpbGwgY3JlYXRlIG9uZVxuICogYXV0b21hdGljYWxseSBuYW1lZCBgRU5WX0NPTkZJR2AuXG4gKi9cbmludGVyZmFjZSBQcm92aWRlUnVudGltZUNvbmZpZ09wdGlvbnM8UyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+PiB7XG4gIC8qKiBQYXRoIHRvIHRoZSBydW50aW1lIGVudiBmaWxlIChkZWZhdWx0OiAvZW52L3J1bnRpbWUuZW52KSAqL1xuICBlbnZQYXRoPzogc3RyaW5nO1xuICAvKiogTG9nIGRlYnVnIGluZm8gdG8gY29uc29sZSAqL1xuICBkZWJ1Zz86IGJvb2xlYW47XG4gIC8qKiBUaHJvdyBvbiBlcnJvciB0byBzdG9wIGFwcCBib290IChkZWZhdWx0OiB0cnVlKSAqL1xuICBzdG9wT25FcnJvcj86IGJvb2xlYW47XG4gIC8qKiBJbmplY3Rpb24gdG9rZW4gdXNlZCB0byBwcm92aWRlIHRoZSB2YWxpZGF0ZWQgY29uZmlnIHZpYSBBbmd1bGFyIERJICovXG4gIHRva2VuPzogSW5qZWN0aW9uVG9rZW48U2NoZW1hT3V0cHV0PFM+Pjtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgcHJvdmlkZXJzIHRoYXQ6XG4gKiAtIEZldGNoIGEgcnVudGltZSBgLmVudmAgZmlsZSBhdCBzdGFydHVwLFxuICogLSBQYXJzZSBpdCB0byBhIGRlZXAtcGFydGlhbCBzdHJ1Y3R1cmUgdmlhIHRoZSBraXQsXG4gKiAtIEVuZm9yY2UgcnVudGltZS1yZXF1aXJlZCBrZXlzIHdoZW4gYXBwcm9wcmlhdGUsXG4gKiAtIE1lcmdlIHdpdGggdGhlIHN0YXRpYyBlbnZpcm9ubWVudCxcbiAqIC0gVmFsaWRhdGUgdGhlICoqZmluYWwqKiBjb25maWd1cmF0aW9uIGFnYWluc3QgdGhlIFpvZCBzY2hlbWEsXG4gKiAtIEV4cG9zZSB0aGUgcmVzdWx0aW5nIGNvbmZpZyB2aWEgYSBnZW5lcmF0ZWQgYEluamVjdGlvblRva2VuYC5cbiAqXG4gKiBAdHlwZVBhcmFtIFMgLSBab2Qgc2NoZW1hIHR5cGUgZGVzY3JpYmluZyB0aGUgZnVsbCBjb25maWcgc2hhcGUuXG4gKiBAdHlwZVBhcmFtIEsgLSBMaXN0IG9mIHJ1bnRpbWUtcmVxdWlyZWQgdG9wLWxldmVsIGtleXMuXG4gKlxuICogQHBhcmFtIGtpdFxuICogVGhlIGBFbnZLaXRgIGNyZWF0ZWQgYnkgYGNyZWF0ZUVudktpdChzY2hlbWEsIHJ1bnRpbWVSZXF1aXJlZEtleXMpYC5cbiAqXG4gKiBAcGFyYW0gb3B0aW9uc1xuICogUnVudGltZSBsb2FkaW5nIGJlaGF2aW9yIGFuZCBESSB0b2tlbiBkZXNjcmlwdGlvbi4gU2VlIHtAbGluayBQcm92aWRlUnVudGltZUNvbmZpZ09wdGlvbnN9LlxuICpcbiAqIEByZXR1cm5zIFRoZSBgRW52aXJvbm1lbnRQcm92aWRlcnNgIHRvIGJlIGFkZGVkIHRvIGBhcHBDb25maWcucHJvdmlkZXJzYCxcbiAqXG4gKiBAcmVtYXJrc1xuICogLSBUaGlzIHVzZXMgYW4gQW5ndWxhciAqKmZ1bmN0aW9uYWwgYXBwIGluaXRpYWxpemVyKiogdG8gcGVyZm9ybSB0aGUgbG9hZCBzdGVwLlxuICogLSBJZiB0aGUgc2VydmVyIHJldHVybnMgYW4gSFRNTCBTUEEgZmFsbGJhY2sgKGluc3RlYWQgb2YgdGhlIGAuZW52YCBmaWxlKSwgdGhlIHByb3ZpZGVyXG4gKiAgIHF1aWV0bHkgdXNlcyB0aGUgc3RhdGljIGVudmlyb25tZW50IChubyBydW50aW1lIG92ZXJyaWRlcykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlUnVudGltZUNvbmZpZzxcbiAgUyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+LFxuICBLIGV4dGVuZHMgcmVhZG9ubHkgKGtleW9mIHoub3V0cHV0PFM+KVtdXG4+KFxuICBraXQ6IEVudktpdDxTLCBLPixcbiAgc3RhdGljRW52OiBTdGF0aWNFbnZGcm9tPFMsIEs+LFxuICB7XG4gICAgZW52UGF0aCA9ICcvZW52L3J1bnRpbWUuZW52JyxcbiAgICBkZWJ1ZyA9IGZhbHNlLFxuICAgIHN0b3BPbkVycm9yID0gdHJ1ZSxcbiAgICB0b2tlbixcbiAgfTogUHJvdmlkZVJ1bnRpbWVDb25maWdPcHRpb25zPFM+ID0ge31cbik6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgLy8gVGhlIHZhbGlkYXRlZCBjb25maWcgdHlwZSBkZXJpdmVkIGZyb20gdGhlIHNjaGVtYS5cbiAgdHlwZSBFbnZDb25maWcgPSBTY2hlbWFPdXRwdXQ8Uz47XG5cbiAgLy8gVHlwZWQgdG9rZW4gdXNlZCB0byBleHBvc2UgdGhlIGZpbmFsIHZhbGlkYXRlZCBjb25maWcgdmlhIERJLlxuICBjb25zdCBjb25maWdUb2tlbiA9IHRva2VuID8/IG5ldyBJbmplY3Rpb25Ub2tlbjxFbnZDb25maWc+KCdFTlZfQ09ORklHJyk7XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgc2VydmljZSB0aGF0IGhhbmRsZXMgZmV0Y2hpbmcsIHBhcnNpbmcsIHZhbGlkYXRpbmcsIGFuZCBjYWNoaW5nXG4gICAqIG9mIHRoZSBydW50aW1lIGVudmlyb25tZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuICBjbGFzcyBSdW50aW1lQ29uZmlnU2VydmljZSB7XG4gICAgLy8gQ2FjaGVkIGluc3RhbmNlIG9mIHRoZSB2YWxpZGF0ZWQgY29uZmlndXJhdGlvbi5cbiAgICBwcml2YXRlIGNvbmZpZz86IEVudkNvbmZpZztcblxuICAgIC8qKlxuICAgICAqIExvYWRzLCBwYXJzZXMsIG1lcmdlcyBhbmQgdmFsaWRhdGVzIHRoZSBydW50aW1lIGNvbmZpZ3VyYXRpb24uXG4gICAgICogUmV0dXJucyBhbiBgT2JzZXJ2YWJsZTxDb25maWdTaGFwZT5gIGFuZCBjYWNoZXMgdGhlIGZpbmFsIHJlc3VsdC5cbiAgICAgKi9cbiAgICBsb2FkKCk6IE9ic2VydmFibGU8RW52Q29uZmlnPiB7XG4gICAgICByZXR1cm4gZGVmZXIoKCkgPT5cbiAgICAgICAgZnJvbShcbiAgICAgICAgICBmZXRjaChlbnZQYXRoKS50aGVuKChyZXMpID0+IHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBIVFRQIGVycm9ycyBleHBsaWNpdGx5IHNvIHRoZXkgZ28gdGhyb3VnaCBjYXRjaEVycm9yXG4gICAgICAgICAgICBpZiAoIXJlcy5vaykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgYEZhaWxlZCB0byBsb2FkIHJ1bnRpbWUgY29uZmlnOiAke3Jlcy5zdGF0dXN9ICR7cmVzLnN0YXR1c1RleHR9YFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlcy50ZXh0KCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKS5waXBlKFxuICAgICAgICAgIC8vIDEuIFNQQSBmYWxsYmFjayBndWFyZCAoc2VydmVyIHJldHVybmVkIEhUTUwgaW5zdGVhZCBvZiAuZW52KVxuICAgICAgICAgIG1hcCgocmF3OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyaW1tZWQgPSByYXcudHJpbSgpO1xuICAgICAgICAgICAgY29uc3QgbG9va3NIdG1sID1cbiAgICAgICAgICAgICAgL15cXHMqPCFkb2N0eXBlL2kudGVzdCh0cmltbWVkKSB8fCAvXlxccyo8aHRtbFtcXHM+XS9pLnRlc3QodHJpbW1lZCk7XG4gICAgICAgICAgICBpZiAobG9va3NIdG1sKSB7XG4gICAgICAgICAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgLi4ucmNBcmdzKFxuICAgICAgICAgICAgICAgICAgICAnTm8gcnVudGltZSBlbnZpcm9ubWVudCBmaWxlIGRldGVjdGVkLCB1c2luZyBzdGF0aWMgZW52aXJvbm1lbnQgb25seS4nXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyBTaWduYWwg4oCcbm8gcnVudGltZS5lbnYsIHVzZSBzdGF0aWMgb25seeKAnVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByYXc7XG4gICAgICAgICAgfSksXG4gICAgICAgICAgdGFwKCh2OiBzdHJpbmcgfCBudWxsKSA9PiB7XG4gICAgICAgICAgICBpZiAoIWRlYnVnKSByZXR1cm47XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgLi4ucmNBcmdzKFxuICAgICAgICAgICAgICAgIHYgPT09IG51bGxcbiAgICAgICAgICAgICAgICAgID8gJ05vIHJ1bnRpbWUgZW52aXJvbm1lbnQgZmlsZSBkZWZpbmVkLCB1c2luZyBzdGF0aWMgZW52aXJvbm1lbnQnXG4gICAgICAgICAgICAgICAgICA6ICdSdW50aW1lIGVudmlyb25tZW50IGZpbGUgbG9hZGVkLCBhcHBseWluZyBvdmVycmlkZXMuJ1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIC8vIDIuIEVpdGhlciBjb250aW51ZSB0aGUgcGlwZSBvciByZXR1cm4gZGVmYXVsdHNcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJhdzogc3RyaW5nIHwgbnVsbCk6IE9ic2VydmFibGU8RW52Q29uZmlnPiA9PiB7XG4gICAgICAgICAgICBpZiAocmF3ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmcm9tKGtpdC5tZXJnZUFuZFZhbGlkYXRlQXN5bmMoc3RhdGljRW52KSkucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKGNmZykgPT4gKHRoaXMuY29uZmlnID0gY2ZnKSlcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gMy4gUGFyc2UgcmF3IGAuZW52YCB0ZXh0IC0+IG9iamVjdCwgdGhlbiBkZWVwLXBhcnRpYWwtcGFyc2UgdmlhIGtpdFxuICAgICAgICAgICAgY29uc3QgcnVudGltZUNvbmZpZ1JhdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSBwYXJzZUVudkZpbGUocmF3KTtcbiAgICAgICAgICAgIHJldHVybiBmcm9tKGtpdC5wYXJzZVJ1bnRpbWVPdmVycmlkZXNBc3luYyhydW50aW1lQ29uZmlnUmF3KSkucGlwZShcbiAgICAgICAgICAgICAgdGFwKChvdmVycmlkZXM6IFBhcnRpYWw8RW52Q29uZmlnPikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKC4uLnJjQXJncygnUnVudGltZSBjb25maWcgKHBhcnNlZCk6JyksIG92ZXJyaWRlcyk7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAvLyA0LiBNZXJnZSBzdGF0aWMgKyBvdmVycmlkZXMgYW5kIHZhbGlkYXRlIHRoZSBmaW5hbCBjb25maWcgKGFzeW5jKVxuICAgICAgICAgICAgICBzd2l0Y2hNYXAoXG4gICAgICAgICAgICAgICAgKG92ZXJyaWRlczogUGFydGlhbDxFbnZDb25maWc+KTogT2JzZXJ2YWJsZTxFbnZDb25maWc+ID0+XG4gICAgICAgICAgICAgICAgICBmcm9tKGtpdC5tZXJnZUFuZFZhbGlkYXRlQXN5bmMoc3RhdGljRW52LCBvdmVycmlkZXMpKVxuICAgICAgICAgICAgICApLFxuXG4gICAgICAgICAgICAgIC8vIDUuIENhY2hlIHRoZSB2YWxpZGF0ZWQgY29uZmlnIGZvciBzeW5jaHJvbm91cyBhY2Nlc3MgbGF0ZXJcbiAgICAgICAgICAgICAgdGFwKChtZXJnZWRDb25maWc6IEVudkNvbmZpZykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKC4uLnJjQXJncygnTWVyZ2VkIGNvbmZpZzonKSwgbWVyZ2VkQ29uZmlnKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZyA9IG1lcmdlZENvbmZpZztcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSksXG5cbiAgICAgICAgICAvLyA2LiBFcnJvciBoYW5kbGluZzogZmFpbCBmYXN0IG9yIGdyYWNlZnVsbHkgZmFsbCBiYWNrIHRvIHN0YXRpYy1vbmx5XG4gICAgICAgICAgY2F0Y2hFcnJvcigoZXJyOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICBpZiAoc3RvcE9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgLy8gUmVqZWN0IGFwcCBpbml0aWFsaXphdGlvbiAocmVjb21tZW5kZWQgZm9yIHByb2R1Y3Rpb24pXG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgIC4uLnJjQXJncygnRXJyb3Igb2NjdXJyZWQgd2hpbGUgbG9hZGluZyBydW50aW1lIGNvbmZpZzonKSxcbiAgICAgICAgICAgICAgZXJyXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICByZXR1cm4gb2YodGhpcy51c2VEZWZhdWx0cygpKTtcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbi5cbiAgICAgKiBJZiBub3QgeWV0IGxvYWRlZCwgcmV0dXJucyBhIHZhbGlkYXRlZCBzdGF0aWMtb25seSBjb25maWd1cmF0aW9uLlxuICAgICAqL1xuICAgIGdldCgpOiBFbnZDb25maWcge1xuICAgICAgaWYgKCF0aGlzLmNvbmZpZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1J1bnRpbWVDb25maWdTZXJ2aWNlLmdldCgpIGNhbGxlZCBiZWZvcmUgY29uZmlndXJhdGlvbiB3YXMgbG9hZGVkLiAnICtcbiAgICAgICAgICAgICdFbnN1cmUgcHJvdmlkZUFwcEluaXRpYWxpemVyIHdhaXRzIGZvciBSdW50aW1lQ29uZmlnU2VydmljZS5sb2FkKCkuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb25maWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIHRvIGEgdmFsaWRhdGVkIHN0YXRpYy1vbmx5IGNvbmZpZ3VyYXRpb25cbiAgICAgKiBVc2VkIHdoZW4gdGhlIHJ1bnRpbWUgYC5lbnZgIGZpbGUgaXMgbWlzc2luZy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHVzZURlZmF1bHRzKCk6IEVudkNvbmZpZyB7XG4gICAgICAvLyBOb3RlOiB0aGlzIHVzZXMgdGhlIHN0YXRpYyBlbnY7IG1lcmdlK3ZhbGlkYXRlIGlzIHBlcmZvcm1lZCBpbiBgZ2V0KClgIGlmIG5lZWRlZC5cbiAgICAgIHRoaXMuY29uZmlnID8/PSBzdGF0aWNFbnYgYXMgRW52Q29uZmlnO1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlZ2lzdGVyIHRoZSBzZXJ2aWNlICsgaW5pdGlhbGl6ZXIgKyB0b2tlbiBleHBvc3VyZSB3aXRoIEFuZ3VsYXIgREkuXG4gIHJldHVybiBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMoW1xuICAgIFJ1bnRpbWVDb25maWdTZXJ2aWNlLFxuXG4gICAgLy8gQW5ndWxhciAxOSsgZnVuY3Rpb25hbCBpbml0aWFsaXplciAoc3Vic2NyaWJlcyB0byB0aGUgbG9hZCBPYnNlcnZhYmxlKVxuICAgIC8vIFVzaW5nIGZpcnN0VmFsdWVGcm9tIHRvIGVuZm9yZWNlIFwiYXdhaXQgdW50aWwgbG9hZGVkXCIgc2VtYW50aWNzXG4gICAgcHJvdmlkZUFwcEluaXRpYWxpemVyKCgpID0+XG4gICAgICBmaXJzdFZhbHVlRnJvbShpbmplY3QoUnVudGltZUNvbmZpZ1NlcnZpY2UpLmxvYWQoKSlcbiAgICApLFxuXG4gICAgLy8gRXhwb3NlIHRoZSBmaW5hbCB2YWxpZGF0ZWQgY29uZmlnIHZpYSB0aGUgZ2VuZXJhdGVkIHRva2VuXG4gICAge1xuICAgICAgcHJvdmlkZTogY29uZmlnVG9rZW4sXG4gICAgICB1c2VGYWN0b3J5OiAoKSA9PiBpbmplY3QoUnVudGltZUNvbmZpZ1NlcnZpY2UpLmdldCgpLFxuICAgIH0sXG4gIF0pO1xufVxuIl19
@@ -0,0 +1,44 @@
1
+ import { makeEnvironmentProviders, } from '@angular/core';
2
+ /**
3
+ * Registers providers that:
4
+ * - Expose a **static** environment configuration object via Angular DI,
5
+ * - Perform **no** runtime `.env` fetching or asynchronous initialization,
6
+ * - Mirror Angular’s standard build-time pattern:
7
+ *
8
+ * { provide: SOME_TOKEN, useValue: environment }
9
+ *
10
+ * This is intended for applications that:
11
+ * - Use only `environment.ts` build-time configuration,
12
+ * - Do not require runtime overrides or external `.env` files,
13
+ * - Wish to keep bootstrap logic minimal and predictable,
14
+ * - Or are running in unit tests where a fixed static config is sufficient.
15
+ *
16
+ * @typeParam T - The shape of the static configuration object.
17
+ *
18
+ * @param env
19
+ * The static configuration instance to expose via DI. Defaults to an empty
20
+ * object if omitted, enabling callers to provide minimal configuration
21
+ * without boilerplate.
22
+ *
23
+ * @param options
24
+ * A `ProvideStaticConfigOptions<T>` containing the **required**
25
+ * `InjectionToken<T>` under which the configuration will be registered.
26
+ * Angular DI resolves providers solely by token instance identity, so the
27
+ * caller must supply the exact token that consumers will inject.
28
+ *
29
+ * @returns The `EnvironmentProviders` to be added to `appConfig.providers`.
30
+ *
31
+ * @remarks
32
+ * The static provider is intentionally minimal, offering a lightweight
33
+ * counterpart to `provideRuntimeConfig` for apps that rely on build-time
34
+ * environment values only.
35
+ */
36
+ export function provideStaticConfig(env = {}, options) {
37
+ return makeEnvironmentProviders([
38
+ {
39
+ provide: options.token,
40
+ useValue: env,
41
+ },
42
+ ]);
43
+ }
44
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZS1zdGF0aWMtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy90ZWdlbC1hbmd1bGFyLWV4dGVuc2lvbnMvc3JjL2xpYi9lbnYvYW5ndWxhci9wcm92aWRlLXN0YXRpYy1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLHdCQUF3QixHQUN6QixNQUFNLGVBQWUsQ0FBQztBQWN2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUNHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUNqQyxNQUFZLEVBQUUsRUFDZCxPQUFzQztJQUV0QyxPQUFPLHdCQUF3QixDQUFDO1FBQzlCO1lBQ0UsT0FBTyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1lBQ3RCLFFBQVEsRUFBRSxHQUFHO1NBQ2Q7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRW52aXJvbm1lbnRQcm92aWRlcnMsXG4gIEluamVjdGlvblRva2VuLFxuICBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIHRoZSBBbmd1bGFyIHN0YXRpYy1jb25maWcgcHJvdmlkZXIuXG4gKlxuICogQHByb3BlcnR5IHRva2VuXG4gKiBBIHJlcXVpcmVkIGBJbmplY3Rpb25Ub2tlbjxUPmAgdW5kZXIgd2hpY2ggdGhlIHN0YXRpYyBlbnZpcm9ubWVudFxuICogY29uZmlndXJhdGlvbiB3aWxsIGJlIHJlZ2lzdGVyZWQuIEFuZ3VsYXIgcmVzb2x2ZXMgcHJvdmlkZXJzIGV4Y2x1c2l2ZWx5XG4gKiBieSAqKnRva2VuIGluc3RhbmNlIGlkZW50aXR5KiosIG5vdCBieSB0b2tlbiBuYW1lIG9yIGRlc2NyaXB0aW9uLCBzbyB0aGVcbiAqIGNhbGxlciBtdXN0IHN1cHBseSB0aGUgZXhhY3QgYEluamVjdGlvblRva2VuPFQ+YCB0aGF0IGNvbnN1bWVycyB3aWxsIHVzZVxuICogd2hlbiBpbmplY3RpbmcgdGhlIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCB0eXBlIFByb3ZpZGVTdGF0aWNDb25maWdPcHRpb25zPFQ+ID0geyB0b2tlbjogSW5qZWN0aW9uVG9rZW48VD4gfTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgcHJvdmlkZXJzIHRoYXQ6XG4gKiAtIEV4cG9zZSBhICoqc3RhdGljKiogZW52aXJvbm1lbnQgY29uZmlndXJhdGlvbiBvYmplY3QgdmlhIEFuZ3VsYXIgREksXG4gKiAtIFBlcmZvcm0gKipubyoqIHJ1bnRpbWUgYC5lbnZgIGZldGNoaW5nIG9yIGFzeW5jaHJvbm91cyBpbml0aWFsaXphdGlvbixcbiAqIC0gTWlycm9yIEFuZ3VsYXLigJlzIHN0YW5kYXJkIGJ1aWxkLXRpbWUgcGF0dGVybjpcbiAqXG4gKiAgICAgeyBwcm92aWRlOiBTT01FX1RPS0VOLCB1c2VWYWx1ZTogZW52aXJvbm1lbnQgfVxuICpcbiAqIFRoaXMgaXMgaW50ZW5kZWQgZm9yIGFwcGxpY2F0aW9ucyB0aGF0OlxuICogLSBVc2Ugb25seSBgZW52aXJvbm1lbnQudHNgIGJ1aWxkLXRpbWUgY29uZmlndXJhdGlvbixcbiAqIC0gRG8gbm90IHJlcXVpcmUgcnVudGltZSBvdmVycmlkZXMgb3IgZXh0ZXJuYWwgYC5lbnZgIGZpbGVzLFxuICogLSBXaXNoIHRvIGtlZXAgYm9vdHN0cmFwIGxvZ2ljIG1pbmltYWwgYW5kIHByZWRpY3RhYmxlLFxuICogLSBPciBhcmUgcnVubmluZyBpbiB1bml0IHRlc3RzIHdoZXJlIGEgZml4ZWQgc3RhdGljIGNvbmZpZyBpcyBzdWZmaWNpZW50LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSBzaGFwZSBvZiB0aGUgc3RhdGljIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSBlbnZcbiAqIFRoZSBzdGF0aWMgY29uZmlndXJhdGlvbiBpbnN0YW5jZSB0byBleHBvc2UgdmlhIERJLiBEZWZhdWx0cyB0byBhbiBlbXB0eVxuICogb2JqZWN0IGlmIG9taXR0ZWQsIGVuYWJsaW5nIGNhbGxlcnMgdG8gcHJvdmlkZSBtaW5pbWFsIGNvbmZpZ3VyYXRpb25cbiAqIHdpdGhvdXQgYm9pbGVycGxhdGUuXG4gKlxuICogQHBhcmFtIG9wdGlvbnNcbiAqIEEgYFByb3ZpZGVTdGF0aWNDb25maWdPcHRpb25zPFQ+YCBjb250YWluaW5nIHRoZSAqKnJlcXVpcmVkKipcbiAqIGBJbmplY3Rpb25Ub2tlbjxUPmAgdW5kZXIgd2hpY2ggdGhlIGNvbmZpZ3VyYXRpb24gd2lsbCBiZSByZWdpc3RlcmVkLlxuICogQW5ndWxhciBESSByZXNvbHZlcyBwcm92aWRlcnMgc29sZWx5IGJ5IHRva2VuIGluc3RhbmNlIGlkZW50aXR5LCBzbyB0aGVcbiAqIGNhbGxlciBtdXN0IHN1cHBseSB0aGUgZXhhY3QgdG9rZW4gdGhhdCBjb25zdW1lcnMgd2lsbCBpbmplY3QuXG4gKlxuICogQHJldHVybnMgVGhlIGBFbnZpcm9ubWVudFByb3ZpZGVyc2AgdG8gYmUgYWRkZWQgdG8gYGFwcENvbmZpZy5wcm92aWRlcnNgLlxuICpcbiAqIEByZW1hcmtzXG4gKiBUaGUgc3RhdGljIHByb3ZpZGVyIGlzIGludGVudGlvbmFsbHkgbWluaW1hbCwgb2ZmZXJpbmcgYSBsaWdodHdlaWdodFxuICogY291bnRlcnBhcnQgdG8gYHByb3ZpZGVSdW50aW1lQ29uZmlnYCBmb3IgYXBwcyB0aGF0IHJlbHkgb24gYnVpbGQtdGltZVxuICogZW52aXJvbm1lbnQgdmFsdWVzIG9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlU3RhdGljQ29uZmlnPFQ+KFxuICBlbnY6IFQgPSA8VD57fSxcbiAgb3B0aW9uczogUHJvdmlkZVN0YXRpY0NvbmZpZ09wdGlvbnM8VD5cbik6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAge1xuICAgICAgcHJvdmlkZTogb3B0aW9ucy50b2tlbixcbiAgICAgIHVzZVZhbHVlOiBlbnYsXG4gICAgfSxcbiAgXSk7XG59XG4iXX0=
@@ -0,0 +1,81 @@
1
+ import { zx } from '@traversable/zod';
2
+ /**
3
+ * Builds a **type-safe environment kit** around a Zod schema.
4
+ *
5
+ * This utility encapsulates all environment configuration logic in a reusable,
6
+ * strongly-typed structure that:
7
+ * - Validates **deep-partial** runtime overrides using `zx.deepPartial(schema)`.
8
+ * - Ensures that **runtime-required keys** are provided when `production=true`.
9
+ * - Merges static defaults with runtime overrides and validates the **final config** asynchronously.
10
+ *
11
+ * @typeParam S - The Zod schema type describing the full environment configuration.
12
+ * @typeParam K - The list of top-level keys that must be supplied at runtime in production builds.
13
+ *
14
+ * @param params.schema - The full Zod schema defining the configuration structure.
15
+ * @param params.runtimeRequiredKeys - Keys that must be present in runtime overrides for production.
16
+ *
17
+ * @returns A fully-typed {@link EnvKit} instance exposing validation helpers, runtime parsers, and type tokens.
18
+ */
19
+ export function createEnvKit(params) {
20
+ const { schema, runtimeRequiredKeys } = params;
21
+ /** Deep-partial schema — allows validation of incomplete runtime overrides. */
22
+ const runtimeOverridesSchema = zx.deepPartial(schema);
23
+ /**
24
+ * Parses a raw `.env` object into a **deep-partial** structure matching the schema.
25
+ * @param raw - The raw key-value object parsed from a `.env` file.
26
+ * @returns A validated deep-partial configuration matching the schema shape.
27
+ * @throws ZodError if the structure is invalid.
28
+ */
29
+ function parseRuntimeOverridesAsync(raw) {
30
+ return runtimeOverridesSchema.parseAsync(raw);
31
+ }
32
+ /**
33
+ * Validates that all runtime-required keys are defined when `production=true`.
34
+ * Prevents missing values from being silently filled from static defaults.
35
+ *
36
+ * @param overrides - The runtime overrides to inspect.
37
+ * @param production - Whether the environment is running in production mode.
38
+ * @throws Error if any runtime-required key is missing.
39
+ */
40
+ function ensureRuntimeKeysPresent(overrides, production) {
41
+ if (!production)
42
+ return;
43
+ const missing = runtimeRequiredKeys.filter((k) => overrides[k] === undefined);
44
+ console.log('Overrides', overrides);
45
+ if (missing.length) {
46
+ throw new Error(`Missing required runtime overrides for production: ${missing.join(', ')}`);
47
+ }
48
+ }
49
+ /**
50
+ * Merges the provided static environment with runtime overrides,
51
+ * enforces runtime key presence when necessary, and validates the
52
+ * **final merged configuration** against the full schema.
53
+ *
54
+ * @param staticEnv - The static environment configuration (dev or prod).
55
+ * @param overrides - The runtime overrides to merge in.
56
+ * @returns A fully validated, strongly typed configuration object.
57
+ * @throws ZodError if validation fails, or Error if required keys are missing in production.
58
+ */
59
+ function mergeAndValidateAsync(staticEnv, overrides = {}) {
60
+ // Determine production mode; runtime override takes precedence if defined
61
+ const effectiveProduction = (overrides['production'] ?? staticEnv.production) === true;
62
+ ensureRuntimeKeysPresent(overrides, effectiveProduction);
63
+ // Validate the merged result asynchronously with the full schema
64
+ return schema.parseAsync({ ...staticEnv, ...overrides });
65
+ }
66
+ return {
67
+ /** The full Zod schema provided by the consumer. */
68
+ schema,
69
+ /** Deep-partial schema used for validating runtime overrides (via `zx.deepPartial`). */
70
+ runtimeOverridesSchema,
71
+ /** Keys that must be provided in runtime overrides when `production=true`. */
72
+ runtimeRequiredKeys,
73
+ /** Parses a raw `.env` object into deep-partial runtime overrides (async). */
74
+ parseRuntimeOverridesAsync,
75
+ /** Merges static + runtime configs and validates the final schema (async). */
76
+ mergeAndValidateAsync,
77
+ /** Type tokens for compile-time inference; erased at runtime. */
78
+ types: {},
79
+ };
80
+ }
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLWVudi1raXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3RlZ2VsLWFuZ3VsYXItZXh0ZW5zaW9ucy9zcmMvbGliL2Vudi9jb3JlL2NyZWF0ZS1lbnYta2l0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQVd0Qzs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxZQUFZLENBRzFCLE1BS0Q7SUFDQyxNQUFNLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFLEdBQUcsTUFBTSxDQUFDO0lBSy9DLCtFQUErRTtJQUMvRSxNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFdEQ7Ozs7O09BS0c7SUFDSCxTQUFTLDBCQUEwQixDQUNqQyxHQUE0QjtRQUU1QixPQUFPLHNCQUFzQixDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILFNBQVMsd0JBQXdCLENBQy9CLFNBQTZCLEVBQzdCLFVBQW1CO1FBRW5CLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUN4QixNQUFNLE9BQU8sR0FDWCxtQkFDRCxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBRTVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRXBDLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQ2Isc0RBQXNELE9BQU8sQ0FBQyxJQUFJLENBQ2hFLElBQUksQ0FDTCxFQUFFLENBQ0osQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsU0FBUyxxQkFBcUIsQ0FDNUIsU0FBMkQsRUFDM0QsWUFBZ0MsRUFBRTtRQUVsQywwRUFBMEU7UUFDMUUsTUFBTSxtQkFBbUIsR0FDdkIsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQyxLQUFLLElBQUksQ0FBQztRQUU3RCx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUV6RCxpRUFBaUU7UUFDakUsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxTQUFTLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxPQUFPO1FBQ0wsb0RBQW9EO1FBQ3BELE1BQU07UUFFTix3RkFBd0Y7UUFDeEYsc0JBQXNCO1FBRXRCLDhFQUE4RTtRQUM5RSxtQkFBbUI7UUFFbkIsOEVBQThFO1FBQzlFLDBCQUEwQjtRQUUxQiw4RUFBOEU7UUFDOUUscUJBQXFCO1FBRXJCLGlFQUFpRTtRQUNqRSxLQUFLLEVBQUUsRUFPTjtLQUNGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgenggfSBmcm9tICdAdHJhdmVyc2FibGUvem9kJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QnO1xuaW1wb3J0IHtcbiAgRGV2RGVmYXVsdHNGcm9tLFxuICBEZXZTdGF0aWNFbnZGcm9tLFxuICBFbnZLaXQsXG4gIFByb2RTdGF0aWNFbnZGcm9tLFxuICBTY2hlbWFPdXRwdXQsXG4gIFN0YXRpY0VudkZyb20sXG59IGZyb20gJy4vZW52LXR5cGVzJztcblxuLyoqXG4gKiBCdWlsZHMgYSAqKnR5cGUtc2FmZSBlbnZpcm9ubWVudCBraXQqKiBhcm91bmQgYSBab2Qgc2NoZW1hLlxuICpcbiAqIFRoaXMgdXRpbGl0eSBlbmNhcHN1bGF0ZXMgYWxsIGVudmlyb25tZW50IGNvbmZpZ3VyYXRpb24gbG9naWMgaW4gYSByZXVzYWJsZSxcbiAqIHN0cm9uZ2x5LXR5cGVkIHN0cnVjdHVyZSB0aGF0OlxuICogLSBWYWxpZGF0ZXMgKipkZWVwLXBhcnRpYWwqKiBydW50aW1lIG92ZXJyaWRlcyB1c2luZyBgenguZGVlcFBhcnRpYWwoc2NoZW1hKWAuXG4gKiAtIEVuc3VyZXMgdGhhdCAqKnJ1bnRpbWUtcmVxdWlyZWQga2V5cyoqIGFyZSBwcm92aWRlZCB3aGVuIGBwcm9kdWN0aW9uPXRydWVgLlxuICogLSBNZXJnZXMgc3RhdGljIGRlZmF1bHRzIHdpdGggcnVudGltZSBvdmVycmlkZXMgYW5kIHZhbGlkYXRlcyB0aGUgKipmaW5hbCBjb25maWcqKiBhc3luY2hyb25vdXNseS5cbiAqXG4gKiBAdHlwZVBhcmFtIFMgLSBUaGUgWm9kIHNjaGVtYSB0eXBlIGRlc2NyaWJpbmcgdGhlIGZ1bGwgZW52aXJvbm1lbnQgY29uZmlndXJhdGlvbi5cbiAqIEB0eXBlUGFyYW0gSyAtIFRoZSBsaXN0IG9mIHRvcC1sZXZlbCBrZXlzIHRoYXQgbXVzdCBiZSBzdXBwbGllZCBhdCBydW50aW1lIGluIHByb2R1Y3Rpb24gYnVpbGRzLlxuICpcbiAqIEBwYXJhbSBwYXJhbXMuc2NoZW1hIC0gVGhlIGZ1bGwgWm9kIHNjaGVtYSBkZWZpbmluZyB0aGUgY29uZmlndXJhdGlvbiBzdHJ1Y3R1cmUuXG4gKiBAcGFyYW0gcGFyYW1zLnJ1bnRpbWVSZXF1aXJlZEtleXMgLSBLZXlzIHRoYXQgbXVzdCBiZSBwcmVzZW50IGluIHJ1bnRpbWUgb3ZlcnJpZGVzIGZvciBwcm9kdWN0aW9uLlxuICpcbiAqIEByZXR1cm5zIEEgZnVsbHktdHlwZWQge0BsaW5rIEVudktpdH0gaW5zdGFuY2UgZXhwb3NpbmcgdmFsaWRhdGlvbiBoZWxwZXJzLCBydW50aW1lIHBhcnNlcnMsIGFuZCB0eXBlIHRva2Vucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVudktpdDxcbiAgUyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+LFxuICBLIGV4dGVuZHMgcmVhZG9ubHkgKGtleW9mIHoub3V0cHV0PFM+KVtdXG4+KHBhcmFtczoge1xuICAvKiogVGhlIGZ1bGwgWm9kIHNjaGVtYSBkZXNjcmliaW5nIHRoZSBhcHAncyBjb25maWd1cmF0aW9uIHNoYXBlLiAqL1xuICBzY2hlbWE6IFM7XG4gIC8qKiBLZXlzIHRoYXQgbXVzdCBiZSBwcm92aWRlZCBhdCBydW50aW1lIHdoZW4gYHByb2R1Y3Rpb249dHJ1ZWAuICovXG4gIHJ1bnRpbWVSZXF1aXJlZEtleXM6IEs7XG59KTogRW52S2l0PFMsIEs+IHtcbiAgY29uc3QgeyBzY2hlbWEsIHJ1bnRpbWVSZXF1aXJlZEtleXMgfSA9IHBhcmFtcztcblxuICAvKiogQ29uY3JldGUgc2NoZW1hIG91dHB1dCB0eXBlIGZvciBjb252ZW5pZW5jZSBpbnNpZGUgdGhpcyBmYWN0b3J5LiAqL1xuICB0eXBlIEVudkNvbmZpZyA9IFNjaGVtYU91dHB1dDxTPjtcblxuICAvKiogRGVlcC1wYXJ0aWFsIHNjaGVtYSDigJQgYWxsb3dzIHZhbGlkYXRpb24gb2YgaW5jb21wbGV0ZSBydW50aW1lIG92ZXJyaWRlcy4gKi9cbiAgY29uc3QgcnVudGltZU92ZXJyaWRlc1NjaGVtYSA9IHp4LmRlZXBQYXJ0aWFsKHNjaGVtYSk7XG5cbiAgLyoqXG4gICAqIFBhcnNlcyBhIHJhdyBgLmVudmAgb2JqZWN0IGludG8gYSAqKmRlZXAtcGFydGlhbCoqIHN0cnVjdHVyZSBtYXRjaGluZyB0aGUgc2NoZW1hLlxuICAgKiBAcGFyYW0gcmF3IC0gVGhlIHJhdyBrZXktdmFsdWUgb2JqZWN0IHBhcnNlZCBmcm9tIGEgYC5lbnZgIGZpbGUuXG4gICAqIEByZXR1cm5zIEEgdmFsaWRhdGVkIGRlZXAtcGFydGlhbCBjb25maWd1cmF0aW9uIG1hdGNoaW5nIHRoZSBzY2hlbWEgc2hhcGUuXG4gICAqIEB0aHJvd3MgWm9kRXJyb3IgaWYgdGhlIHN0cnVjdHVyZSBpcyBpbnZhbGlkLlxuICAgKi9cbiAgZnVuY3Rpb24gcGFyc2VSdW50aW1lT3ZlcnJpZGVzQXN5bmMoXG4gICAgcmF3OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICApOiBQcm9taXNlPFBhcnRpYWw8RW52Q29uZmlnPj4ge1xuICAgIHJldHVybiBydW50aW1lT3ZlcnJpZGVzU2NoZW1hLnBhcnNlQXN5bmMocmF3KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhhdCBhbGwgcnVudGltZS1yZXF1aXJlZCBrZXlzIGFyZSBkZWZpbmVkIHdoZW4gYHByb2R1Y3Rpb249dHJ1ZWAuXG4gICAqIFByZXZlbnRzIG1pc3NpbmcgdmFsdWVzIGZyb20gYmVpbmcgc2lsZW50bHkgZmlsbGVkIGZyb20gc3RhdGljIGRlZmF1bHRzLlxuICAgKlxuICAgKiBAcGFyYW0gb3ZlcnJpZGVzIC0gVGhlIHJ1bnRpbWUgb3ZlcnJpZGVzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSBwcm9kdWN0aW9uIC0gV2hldGhlciB0aGUgZW52aXJvbm1lbnQgaXMgcnVubmluZyBpbiBwcm9kdWN0aW9uIG1vZGUuXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgYW55IHJ1bnRpbWUtcmVxdWlyZWQga2V5IGlzIG1pc3NpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBlbnN1cmVSdW50aW1lS2V5c1ByZXNlbnQoXG4gICAgb3ZlcnJpZGVzOiBQYXJ0aWFsPEVudkNvbmZpZz4sXG4gICAgcHJvZHVjdGlvbjogYm9vbGVhblxuICApOiB2b2lkIHtcbiAgICBpZiAoIXByb2R1Y3Rpb24pIHJldHVybjtcbiAgICBjb25zdCBtaXNzaW5nID0gKFxuICAgICAgcnVudGltZVJlcXVpcmVkS2V5cyBhcyByZWFkb25seSAoa2V5b2YgRW52Q29uZmlnKVtdXG4gICAgKS5maWx0ZXIoKGspID0+IG92ZXJyaWRlc1trXSA9PT0gdW5kZWZpbmVkKTtcblxuICAgIGNvbnNvbGUubG9nKCdPdmVycmlkZXMnLCBvdmVycmlkZXMpO1xuXG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBNaXNzaW5nIHJlcXVpcmVkIHJ1bnRpbWUgb3ZlcnJpZGVzIGZvciBwcm9kdWN0aW9uOiAke21pc3Npbmcuam9pbihcbiAgICAgICAgICAnLCAnXG4gICAgICAgICl9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2VzIHRoZSBwcm92aWRlZCBzdGF0aWMgZW52aXJvbm1lbnQgd2l0aCBydW50aW1lIG92ZXJyaWRlcyxcbiAgICogZW5mb3JjZXMgcnVudGltZSBrZXkgcHJlc2VuY2Ugd2hlbiBuZWNlc3NhcnksIGFuZCB2YWxpZGF0ZXMgdGhlXG4gICAqICoqZmluYWwgbWVyZ2VkIGNvbmZpZ3VyYXRpb24qKiBhZ2FpbnN0IHRoZSBmdWxsIHNjaGVtYS5cbiAgICpcbiAgICogQHBhcmFtIHN0YXRpY0VudiAtIFRoZSBzdGF0aWMgZW52aXJvbm1lbnQgY29uZmlndXJhdGlvbiAoZGV2IG9yIHByb2QpLlxuICAgKiBAcGFyYW0gb3ZlcnJpZGVzIC0gVGhlIHJ1bnRpbWUgb3ZlcnJpZGVzIHRvIG1lcmdlIGluLlxuICAgKiBAcmV0dXJucyBBIGZ1bGx5IHZhbGlkYXRlZCwgc3Ryb25nbHkgdHlwZWQgY29uZmlndXJhdGlvbiBvYmplY3QuXG4gICAqIEB0aHJvd3MgWm9kRXJyb3IgaWYgdmFsaWRhdGlvbiBmYWlscywgb3IgRXJyb3IgaWYgcmVxdWlyZWQga2V5cyBhcmUgbWlzc2luZyBpbiBwcm9kdWN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gbWVyZ2VBbmRWYWxpZGF0ZUFzeW5jKFxuICAgIHN0YXRpY0VudjogRGV2U3RhdGljRW52RnJvbTxTLCBLPiB8IFByb2RTdGF0aWNFbnZGcm9tPFMsIEs+LFxuICAgIG92ZXJyaWRlczogUGFydGlhbDxFbnZDb25maWc+ID0ge31cbiAgKTogUHJvbWlzZTxFbnZDb25maWc+IHtcbiAgICAvLyBEZXRlcm1pbmUgcHJvZHVjdGlvbiBtb2RlOyBydW50aW1lIG92ZXJyaWRlIHRha2VzIHByZWNlZGVuY2UgaWYgZGVmaW5lZFxuICAgIGNvbnN0IGVmZmVjdGl2ZVByb2R1Y3Rpb24gPVxuICAgICAgKG92ZXJyaWRlc1sncHJvZHVjdGlvbiddID8/IHN0YXRpY0Vudi5wcm9kdWN0aW9uKSA9PT0gdHJ1ZTtcblxuICAgIGVuc3VyZVJ1bnRpbWVLZXlzUHJlc2VudChvdmVycmlkZXMsIGVmZmVjdGl2ZVByb2R1Y3Rpb24pO1xuXG4gICAgLy8gVmFsaWRhdGUgdGhlIG1lcmdlZCByZXN1bHQgYXN5bmNocm9ub3VzbHkgd2l0aCB0aGUgZnVsbCBzY2hlbWFcbiAgICByZXR1cm4gc2NoZW1hLnBhcnNlQXN5bmMoeyAuLi5zdGF0aWNFbnYsIC4uLm92ZXJyaWRlcyB9KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLyoqIFRoZSBmdWxsIFpvZCBzY2hlbWEgcHJvdmlkZWQgYnkgdGhlIGNvbnN1bWVyLiAqL1xuICAgIHNjaGVtYSxcblxuICAgIC8qKiBEZWVwLXBhcnRpYWwgc2NoZW1hIHVzZWQgZm9yIHZhbGlkYXRpbmcgcnVudGltZSBvdmVycmlkZXMgKHZpYSBgenguZGVlcFBhcnRpYWxgKS4gKi9cbiAgICBydW50aW1lT3ZlcnJpZGVzU2NoZW1hLFxuXG4gICAgLyoqIEtleXMgdGhhdCBtdXN0IGJlIHByb3ZpZGVkIGluIHJ1bnRpbWUgb3ZlcnJpZGVzIHdoZW4gYHByb2R1Y3Rpb249dHJ1ZWAuICovXG4gICAgcnVudGltZVJlcXVpcmVkS2V5cyxcblxuICAgIC8qKiBQYXJzZXMgYSByYXcgYC5lbnZgIG9iamVjdCBpbnRvIGRlZXAtcGFydGlhbCBydW50aW1lIG92ZXJyaWRlcyAoYXN5bmMpLiAqL1xuICAgIHBhcnNlUnVudGltZU92ZXJyaWRlc0FzeW5jLFxuXG4gICAgLyoqIE1lcmdlcyBzdGF0aWMgKyBydW50aW1lIGNvbmZpZ3MgYW5kIHZhbGlkYXRlcyB0aGUgZmluYWwgc2NoZW1hIChhc3luYykuICovXG4gICAgbWVyZ2VBbmRWYWxpZGF0ZUFzeW5jLFxuXG4gICAgLyoqIFR5cGUgdG9rZW5zIGZvciBjb21waWxlLXRpbWUgaW5mZXJlbmNlOyBlcmFzZWQgYXQgcnVudGltZS4gKi9cbiAgICB0eXBlczoge30gYXMge1xuICAgICAgRW52Q29uZmlnOiBFbnZDb25maWc7XG4gICAgICBEZXZEZWZhdWx0czogRGV2RGVmYXVsdHNGcm9tPFMsIEs+O1xuICAgICAgRGV2U3RhdGljRW52OiBEZXZTdGF0aWNFbnZGcm9tPFMsIEs+O1xuICAgICAgUHJvZFN0YXRpY0VudjogUHJvZFN0YXRpY0VudkZyb208UywgSz47XG4gICAgICBTdGF0aWNFbnY6IFN0YXRpY0VudkZyb208UywgSz47XG4gICAgICBSdW50aW1lUmVxdWlyZWQ6IEtbbnVtYmVyXTtcbiAgICB9LFxuICB9O1xufVxuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW52LXR5cGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy90ZWdlbC1hbmd1bGFyLWV4dGVuc2lvbnMvc3JjL2xpYi9lbnYvY29yZS9lbnYtdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHp4IH0gZnJvbSAnQHRyYXZlcnNhYmxlL3pvZCc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJztcblxuLy8gPT09PT09PT09PSBDb3JlIHR5cGUgaGVscGVycyA9PT09PT09PT09XG4vKipcbiAqIEV4dHJhY3RzIHRoZSAqKm91dHB1dCB0eXBlKiogKHZhbGlkYXRlZCBydW50aW1lIHNoYXBlKVxuICogZnJvbSBhIFpvZCBvYmplY3Qgc2NoZW1hIOKAlCBlLmcuIGB6Lm91dHB1dDx0eXBlb2YgTXlTY2hlbWE+YC5cbiAqL1xuZXhwb3J0IHR5cGUgU2NoZW1hT3V0cHV0PFMgZXh0ZW5kcyB6LlpvZE9iamVjdDx6LlpvZFJhd1NoYXBlPj4gPSB6Lm91dHB1dDxTPjtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSAqKnRvcC1sZXZlbCBwcm9wZXJ0eSBrZXlzKiogb2YgdGhlIFpvZCBzY2hlbWHigJlzIG91dHB1dCB0eXBlLlxuICogRXF1aXZhbGVudCB0byBga2V5b2Ygei5vdXRwdXQ8dHlwZW9mIE15U2NoZW1hPmAuXG4gKi9cbmV4cG9ydCB0eXBlIEtleXNPZjxTIGV4dGVuZHMgei5ab2RPYmplY3Q8ei5ab2RSYXdTaGFwZT4+ID1cbiAga2V5b2YgU2NoZW1hT3V0cHV0PFM+O1xuXG4vKipcbiAqIEEgcmVhZG9ubHkgbGlzdCBvZiBrZXlzIHJlcHJlc2VudGluZyAqKnJ1bnRpbWUtcmVxdWlyZWQgcHJvcGVydGllcyoqXG4gKiB0aGF0IG11c3QgYmUgcHJvdmlkZWQgZnJvbSB0aGUgZW52aXJvbm1lbnQgd2hlbiBgcHJvZHVjdGlvbj10cnVlYC5cbiAqL1xuZXhwb3J0IHR5cGUgUnVudGltZUtleUxpc3Q8UyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+PiA9XG4gIHJlYWRvbmx5IChrZXlvZiBTY2hlbWFPdXRwdXQ8Uz4pW107XG5cbi8qKlxuICogUmVwcmVzZW50cyBhICoqZGV2ZWxvcG1lbnQtdGltZSBzdGF0aWMgZW52aXJvbm1lbnQqKiBjb25maWd1cmF0aW9uLlxuICogLSBgcHJvZHVjdGlvbmAgaXMgYWx3YXlzIGBmYWxzZWAuXG4gKiAtIFJ1bnRpbWUtcmVxdWlyZWQga2V5cyAoZS5nLiBBUEkgVVJMcykgYXJlICoqb3B0aW9uYWwqKiBhbmQgbWF5IGJlIHNldCBmb3IgbG9jYWwgZGV2LlxuICovXG5leHBvcnQgdHlwZSBEZXZTdGF0aWNFbnZGcm9tPFxuICBTIGV4dGVuZHMgei5ab2RPYmplY3Q8ei5ab2RSYXdTaGFwZT4sXG4gIEsgZXh0ZW5kcyByZWFkb25seSAoa2V5b2YgU2NoZW1hT3V0cHV0PFM+KVtdXG4+ID0gT21pdDxTY2hlbWFPdXRwdXQ8Uz4sIEtbbnVtYmVyXT4gJiB7IHByb2R1Y3Rpb246IGZhbHNlIH0gJiBQYXJ0aWFsPFxuICAgIFBpY2s8U2NoZW1hT3V0cHV0PFM+LCBLW251bWJlcl0+XG4gID47XG5cbi8qKlxuICogUmVwcmVzZW50cyBhICoqcHJvZHVjdGlvbi10aW1lIHN0YXRpYyBlbnZpcm9ubWVudCoqIGNvbmZpZ3VyYXRpb24uXG4gKiAtIGBwcm9kdWN0aW9uYCBpcyBhbHdheXMgYHRydWVgLlxuICogLSBSdW50aW1lLXJlcXVpcmVkIGtleXMgYXJlICoqZm9yYmlkZGVuKiogaGVyZSBhbmQgbXVzdCBiZSBwcm92aWRlZCBhdCBydW50aW1lLlxuICovXG5leHBvcnQgdHlwZSBQcm9kU3RhdGljRW52RnJvbTxcbiAgUyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+LFxuICBLIGV4dGVuZHMgcmVhZG9ubHkgKGtleW9mIFNjaGVtYU91dHB1dDxTPilbXVxuPiA9IE9taXQ8U2NoZW1hT3V0cHV0PFM+LCBLW251bWJlcl0+ICYgeyBwcm9kdWN0aW9uOiB0cnVlIH0gJiB7XG4gIFtQIGluIEtbbnVtYmVyXV0/OiBuZXZlcjtcbn07XG5cbi8qKlxuICogVW5pb24gdHlwZSBjb21iaW5pbmcgYm90aCBkZXZlbG9wbWVudCBhbmQgcHJvZHVjdGlvbiBzdGF0aWMgZW52aXJvbm1lbnRzLlxuICogVXNlZCBieSBgZW52aXJvbm1lbnQudHNgIGFuZCBgZW52aXJvbm1lbnQucHJvZC50c2AgdG8gZW5zdXJlIGNvcnJlY3Qga2V5IHJ1bGVzIHBlciBtb2RlLlxuICovXG5leHBvcnQgdHlwZSBTdGF0aWNFbnZGcm9tPFxuICBTIGV4dGVuZHMgei5ab2RPYmplY3Q8ei5ab2RSYXdTaGFwZT4sXG4gIEsgZXh0ZW5kcyByZWFkb25seSAoa2V5b2YgU2NoZW1hT3V0cHV0PFM+KVtdXG4+ID0gRGV2U3RhdGljRW52RnJvbTxTLCBLPiB8IFByb2RTdGF0aWNFbnZGcm9tPFMsIEs+O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlICoqYmFzZSBkZWZhdWx0IGVudmlyb25tZW50KiogZm9yIGRldmVsb3BtZW50IGJ1aWxkcy5cbiAqIC0gQ29udGFpbnMgYWxsIGNvbW1vbiBkZWZhdWx0cy5cbiAqIC0gRXhjbHVkZXMgcnVudGltZS1yZXF1aXJlZCBrZXlzIGVudGlyZWx5IGZyb20gaXRzIHR5cGUuXG4gKiAtIGBwcm9kdWN0aW9uYCBpcyBmaXhlZCB0byBgZmFsc2VgLlxuICovXG5leHBvcnQgdHlwZSBEZXZEZWZhdWx0c0Zyb208XG4gIFMgZXh0ZW5kcyB6LlpvZE9iamVjdDx6LlpvZFJhd1NoYXBlPixcbiAgSyBleHRlbmRzIHJlYWRvbmx5IChrZXlvZiBTY2hlbWFPdXRwdXQ8Uz4pW11cbj4gPSBPbWl0PFNjaGVtYU91dHB1dDxTPiwgS1tudW1iZXJdPiAmIHsgcHJvZHVjdGlvbjogZmFsc2UgfTtcblxuLy8gPT09PT09PT09PSBQdWJsaWMgS2l0IEludGVyZmFjZSA9PT09PT09PT09XG4vKipcbiAqIEdlbmVyaWMgaW50ZXJmYWNlIHJldHVybmVkIGJ5IGBjcmVhdGVFbnZLaXRgLlxuICogRGVmaW5lcyBhbGwgaGVscGVyIG1ldGhvZHMgYW5kIHN0YXRpYyB0eXBpbmcgZm9yIGEgZnVsbHkgdHlwZS1zYWZlIGVudmlyb25tZW50IGNvbmZpZ3VyYXRpb24gc3lzdGVtLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVudktpdDxcbiAgUyBleHRlbmRzIHouWm9kT2JqZWN0PHouWm9kUmF3U2hhcGU+LFxuICBLIGV4dGVuZHMgcmVhZG9ubHkgKGtleW9mIFNjaGVtYU91dHB1dDxTPilbXVxuPiB7XG4gIC8qKiBGdWxsIFpvZCBzY2hlbWEgcHJvdmlkZWQgYnkgdGhlIGNvbnN1bWVyICovXG4gIHNjaGVtYTogUztcblxuICAvKiogRGVlcC1wYXJ0aWFsIHNjaGVtYSAoY3JlYXRlZCB2aWEgYHp4LmRlZXBQYXJ0aWFsKHNjaGVtYSlgKSB1c2VkIGZvciBydW50aW1lIG92ZXJyaWRlIHZhbGlkYXRpb24gKi9cbiAgcnVudGltZU92ZXJyaWRlc1NjaGVtYTogenguZGVlcFBhcnRpYWwuU2VtYW50aWM8Uz47XG5cbiAgLyoqIExpc3Qgb2YgdG9wLWxldmVsIGtleXMgdGhhdCBtdXN0IGJlIGRlZmluZWQgYXQgcnVudGltZSB3aGVuIGBwcm9kdWN0aW9uPXRydWVgICovXG4gIHJ1bnRpbWVSZXF1aXJlZEtleXM6IEs7XG5cbiAgLyoqIFBhcnNlIHJhdyBgLmVudmAgY29udGVudCBpbnRvIGEgdmFsaWRhdGVkLCBkZWVwLXBhcnRpYWwgb3ZlcnJpZGUgb2JqZWN0ICovXG4gIHBhcnNlUnVudGltZU92ZXJyaWRlc0FzeW5jKFxuICAgIHJhdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgKTogUHJvbWlzZTxQYXJ0aWFsPFNjaGVtYU91dHB1dDxTPj4+O1xuXG4gIC8qKiBNZXJnZSBzdGF0aWMgZW52aXJvbm1lbnQgKyBydW50aW1lIG92ZXJyaWRlcywgdGhlbiB2YWxpZGF0ZSB1c2luZyB0aGUgWm9kIHNjaGVtYSAoYXN5bmMpICovXG4gIG1lcmdlQW5kVmFsaWRhdGVBc3luYyhcbiAgICBzdGF0aWNFbnY6IFN0YXRpY0VudkZyb208UywgSz4sXG4gICAgb3ZlcnJpZGVzPzogUGFydGlhbDxTY2hlbWFPdXRwdXQ8Uz4+XG4gICk6IFByb21pc2U8U2NoZW1hT3V0cHV0PFM+PjtcblxuICAvKiogVHlwZSB0b2tlbnMgKGVyYXNlZCBhdCBydW50aW1lKSBmb3IgY29tcGlsZS10aW1lIGluZmVyZW5jZSBjb252ZW5pZW5jZSAqL1xuICB0eXBlczoge1xuICAgIC8qKiBUaGUgZnVsbCB2YWxpZGF0ZWQgY29uZmlnIHR5cGUgKFpvZCBvdXRwdXQpICovXG4gICAgRW52Q29uZmlnOiBTY2hlbWFPdXRwdXQ8Uz47XG4gICAgLyoqIFRoZSBkZXYtb25seSBkZWZhdWx0cyB0eXBlIChubyBydW50aW1lLXJlcXVpcmVkIGtleXMpICovXG4gICAgRGV2RGVmYXVsdHM6IERldkRlZmF1bHRzRnJvbTxTLCBLPjtcbiAgICAvKiogRGV2IGVudmlyb25tZW50IHR5cGUgKHJ1bnRpbWUga2V5cyBvcHRpb25hbCkgKi9cbiAgICBEZXZTdGF0aWNFbnY6IERldlN0YXRpY0VudkZyb208UywgSz47XG4gICAgLyoqIFByb2QgZW52aXJvbm1lbnQgdHlwZSAocnVudGltZSBrZXlzIGZvcmJpZGRlbikgKi9cbiAgICBQcm9kU3RhdGljRW52OiBQcm9kU3RhdGljRW52RnJvbTxTLCBLPjtcbiAgICAvKiogQ29tYmluZWQgdHlwZSBvZiBhbGwgc3RhdGljIGVudnMgKi9cbiAgICBTdGF0aWNFbnY6IFN0YXRpY0VudkZyb208UywgSz47XG4gICAgLyoqIFRoZSB1bmlvbiBvZiBhbGwgcnVudGltZS1yZXF1aXJlZCBrZXkgbmFtZXMgKi9cbiAgICBSdW50aW1lUmVxdWlyZWQ6IEtbbnVtYmVyXTtcbiAgfTtcbn1cbiJdfQ==
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Parses the contents of a `.env`-style file into a nested JavaScript object.
3
+ *
4
+ * Each line in the input string is expected to follow the format `KEY=VALUE`.
5
+ * Nested keys can be created using a configurable delimiter (default: `"__"`).
6
+ * Lines starting with `#` or containing only whitespace are ignored.
7
+ *
8
+ * Examples:
9
+ * ```env
10
+ * API_URL=https://api.local
11
+ * LOG__LEVEL=debug
12
+ * DB__CONNECTION__TIMEOUT=30
13
+ * ```
14
+ * Produces:
15
+ * ```ts
16
+ * {
17
+ * API_URL: "https://api.local",
18
+ * LOG: { LEVEL: "debug" },
19
+ * DB: { CONNECTION: { TIMEOUT: "30" } }
20
+ * }
21
+ * ```
22
+ *
23
+ * @param raw - The raw `.env` file content as a string.
24
+ * @param delimiter - The delimiter used to represent nested keys (default: `"__"`).
25
+ * @returns A nested object representing all parsed key-value pairs.
26
+ */
27
+ export function parseEnvFile(raw, delimiter = '__') {
28
+ const result = {};
29
+ // Normalize CRLF -> LF and split into lines
30
+ const lines = raw.replace(/\r/g, '').split('\n');
31
+ for (const rawLine of lines) {
32
+ const line = rawLine.trim();
33
+ // Skip blank lines and comments
34
+ if (!line || line.startsWith('#'))
35
+ continue;
36
+ // Split "KEY=VALUE" (first '=' only)
37
+ const { key, value } = splitEnvLine(line);
38
+ if (!key)
39
+ continue; // malformed line with no key
40
+ // Support nesting via delimiter: "A__B__C" -> ["A","B","C"]
41
+ const path = key.split(delimiter).filter(Boolean);
42
+ // Coerce value (handles simple arrays)
43
+ const parsedValue = parseEnvValue(value);
44
+ // Write into `result` at nested path, creating objects as needed
45
+ assignNested(result, path, parsedValue);
46
+ }
47
+ return result;
48
+ }
49
+ /**
50
+ * Parses an environment variable value into a typed representation.
51
+ *
52
+ * Supports array syntax in square brackets:
53
+ * ```
54
+ * [one, two, three] -> ['one', 'two', 'three']
55
+ * ["a", "b", "c"] -> ['"a"', '"b"', '"c"']
56
+ * ```
57
+ * All other values are returned as raw strings.
58
+ *
59
+ * @param value - The raw string value to parse from a `.env` line.
60
+ * @returns The parsed value (string or array of strings).
61
+ */
62
+ function parseEnvValue(value) {
63
+ // Remove leading/trailing whitespace
64
+ const trimmed = value.trim();
65
+ // Detect array syntax: [item1, item2, item3]
66
+ if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
67
+ // Remove surrounding brackets and trim inner content
68
+ const inner = trimmed.slice(1, -1).trim();
69
+ if (!inner)
70
+ return []; // Empty array → []
71
+ // Split by comma and trim each entry
72
+ return inner.split(',').map((item) => item.trim());
73
+ }
74
+ // For non-array values, return as-is
75
+ return value;
76
+ }
77
+ /**
78
+ * Writes a value into a nested object structure using a key path.
79
+ *
80
+ * Example:
81
+ * ```ts
82
+ * const obj = {};
83
+ * assignNested(obj, ['Database', 'Host'], 'localhost');
84
+ * // Result: { Database: { Host: 'localhost' } }
85
+ * ```
86
+ *
87
+ * Intermediate objects are created automatically if they do not exist.
88
+ *
89
+ * @typeParam T - The type of the value being assigned.
90
+ * @param target - The root object to modify.
91
+ * @param path - The array of path segments (e.g., ['A','B','C']).
92
+ * @param value - The value to assign at the final key.
93
+ */
94
+ function assignNested(target, path, value) {
95
+ // Start from the root object reference
96
+ let ref = target;
97
+ // Walk through all path segments except the last one
98
+ for (let i = 0; i < path.length - 1; i++) {
99
+ const seg = path[i];
100
+ // Ensure that each segment points to a plain object;
101
+ // replace invalid types (null, arrays, primitives) with {}
102
+ if (typeof ref[seg] !== 'object' ||
103
+ ref[seg] === null ||
104
+ Array.isArray(ref[seg])) {
105
+ ref[seg] = {};
106
+ }
107
+ // Move deeper into the structure
108
+ ref = ref[seg];
109
+ }
110
+ // Set the final property to the given value
111
+ ref[path[path.length - 1]] = value;
112
+ }
113
+ /**
114
+ * Splits a `.env` line into its key and value components.
115
+ *
116
+ * Example:
117
+ * ```
118
+ * "API_URL=https://api.example.com"
119
+ * -> { key: "API_URL", value: "https://api.example.com" }
120
+ * ```
121
+ *
122
+ * The split occurs at the **first** '=' character only.
123
+ * If the line does not contain '=', an empty `{ key: '', value: '' }` is returned.
124
+ *
125
+ * @param line - A single `.env` line to split.
126
+ * @returns An object containing the key and value strings.
127
+ */
128
+ function splitEnvLine(line) {
129
+ // Find first '='; keys in .env files never contain '='
130
+ const eq = line.indexOf('=');
131
+ // Skip malformed lines
132
+ if (eq === -1)
133
+ return { key: '', value: '' };
134
+ // Extract key before '=' and value after '='
135
+ const key = line.slice(0, eq).trim();
136
+ const value = line.slice(eq + 1).trim();
137
+ // Return key-value pair
138
+ return { key, value };
139
+ }
140
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtZW52LWZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3RlZ2VsLWFuZ3VsYXItZXh0ZW5zaW9ucy9zcmMvbGliL2Vudi9jb3JlL3BhcnNlLWVudi1maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FDMUIsR0FBVyxFQUNYLFNBQVMsR0FBRyxJQUFJO0lBRWhCLE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7SUFFM0MsNENBQTRDO0lBQzVDLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVqRCxLQUFLLE1BQU0sT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzVCLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUU1QixnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztZQUFFLFNBQVM7UUFFNUMscUNBQXFDO1FBQ3JDLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxHQUFHO1lBQUUsU0FBUyxDQUFDLDZCQUE2QjtRQUVqRCw0REFBNEQ7UUFDNUQsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFbEQsdUNBQXVDO1FBQ3ZDLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV6QyxpRUFBaUU7UUFDakUsWUFBWSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFTLGFBQWEsQ0FBQyxLQUFhO0lBQ2xDLHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFN0IsNkNBQTZDO0lBQzdDLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDckQscURBQXFEO1FBQ3JELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLG1CQUFtQjtRQUUxQyxxQ0FBcUM7UUFDckMsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELHFDQUFxQztJQUNyQyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILFNBQVMsWUFBWSxDQUNuQixNQUF5QixFQUN6QixJQUFjLEVBQ2QsS0FBUTtJQUVSLHVDQUF1QztJQUN2QyxJQUFJLEdBQUcsR0FBNEIsTUFBTSxDQUFDO0lBRTFDLHFEQUFxRDtJQUNyRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN6QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEIscURBQXFEO1FBQ3JELDJEQUEyRDtRQUMzRCxJQUNFLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVE7WUFDNUIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLElBQUk7WUFDakIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDdkIsQ0FBQztZQUNELEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDaEIsQ0FBQztRQUVELGlDQUFpQztRQUNqQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBNEIsQ0FBQztJQUM1QyxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztBQUNyQyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxJQUFZO0lBQ2hDLHVEQUF1RDtJQUN2RCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTdCLHVCQUF1QjtJQUN2QixJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFFN0MsNkNBQTZDO0lBQzdDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRXhDLHdCQUF3QjtJQUN4QixPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFBhcnNlcyB0aGUgY29udGVudHMgb2YgYSBgLmVudmAtc3R5bGUgZmlsZSBpbnRvIGEgbmVzdGVkIEphdmFTY3JpcHQgb2JqZWN0LlxuICpcbiAqIEVhY2ggbGluZSBpbiB0aGUgaW5wdXQgc3RyaW5nIGlzIGV4cGVjdGVkIHRvIGZvbGxvdyB0aGUgZm9ybWF0IGBLRVk9VkFMVUVgLlxuICogTmVzdGVkIGtleXMgY2FuIGJlIGNyZWF0ZWQgdXNpbmcgYSBjb25maWd1cmFibGUgZGVsaW1pdGVyIChkZWZhdWx0OiBgXCJfX1wiYCkuXG4gKiBMaW5lcyBzdGFydGluZyB3aXRoIGAjYCBvciBjb250YWluaW5nIG9ubHkgd2hpdGVzcGFjZSBhcmUgaWdub3JlZC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqIGBgYGVudlxuICogQVBJX1VSTD1odHRwczovL2FwaS5sb2NhbFxuICogTE9HX19MRVZFTD1kZWJ1Z1xuICogREJfX0NPTk5FQ1RJT05fX1RJTUVPVVQ9MzBcbiAqIGBgYFxuICogUHJvZHVjZXM6XG4gKiBgYGB0c1xuICoge1xuICogICBBUElfVVJMOiBcImh0dHBzOi8vYXBpLmxvY2FsXCIsXG4gKiAgIExPRzogeyBMRVZFTDogXCJkZWJ1Z1wiIH0sXG4gKiAgIERCOiB7IENPTk5FQ1RJT046IHsgVElNRU9VVDogXCIzMFwiIH0gfVxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHJhdyAtIFRoZSByYXcgYC5lbnZgIGZpbGUgY29udGVudCBhcyBhIHN0cmluZy5cbiAqIEBwYXJhbSBkZWxpbWl0ZXIgLSBUaGUgZGVsaW1pdGVyIHVzZWQgdG8gcmVwcmVzZW50IG5lc3RlZCBrZXlzIChkZWZhdWx0OiBgXCJfX1wiYCkuXG4gKiBAcmV0dXJucyBBIG5lc3RlZCBvYmplY3QgcmVwcmVzZW50aW5nIGFsbCBwYXJzZWQga2V5LXZhbHVlIHBhaXJzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VFbnZGaWxlKFxuICByYXc6IHN0cmluZyxcbiAgZGVsaW1pdGVyID0gJ19fJ1xuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgLy8gTm9ybWFsaXplIENSTEYgLT4gTEYgYW5kIHNwbGl0IGludG8gbGluZXNcbiAgY29uc3QgbGluZXMgPSByYXcucmVwbGFjZSgvXFxyL2csICcnKS5zcGxpdCgnXFxuJyk7XG5cbiAgZm9yIChjb25zdCByYXdMaW5lIG9mIGxpbmVzKSB7XG4gICAgY29uc3QgbGluZSA9IHJhd0xpbmUudHJpbSgpO1xuXG4gICAgLy8gU2tpcCBibGFuayBsaW5lcyBhbmQgY29tbWVudHNcbiAgICBpZiAoIWxpbmUgfHwgbGluZS5zdGFydHNXaXRoKCcjJykpIGNvbnRpbnVlO1xuXG4gICAgLy8gU3BsaXQgXCJLRVk9VkFMVUVcIiAoZmlyc3QgJz0nIG9ubHkpXG4gICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSBzcGxpdEVudkxpbmUobGluZSk7XG4gICAgaWYgKCFrZXkpIGNvbnRpbnVlOyAvLyBtYWxmb3JtZWQgbGluZSB3aXRoIG5vIGtleVxuXG4gICAgLy8gU3VwcG9ydCBuZXN0aW5nIHZpYSBkZWxpbWl0ZXI6IFwiQV9fQl9fQ1wiIC0+IFtcIkFcIixcIkJcIixcIkNcIl1cbiAgICBjb25zdCBwYXRoID0ga2V5LnNwbGl0KGRlbGltaXRlcikuZmlsdGVyKEJvb2xlYW4pO1xuXG4gICAgLy8gQ29lcmNlIHZhbHVlIChoYW5kbGVzIHNpbXBsZSBhcnJheXMpXG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSBwYXJzZUVudlZhbHVlKHZhbHVlKTtcblxuICAgIC8vIFdyaXRlIGludG8gYHJlc3VsdGAgYXQgbmVzdGVkIHBhdGgsIGNyZWF0aW5nIG9iamVjdHMgYXMgbmVlZGVkXG4gICAgYXNzaWduTmVzdGVkKHJlc3VsdCwgcGF0aCwgcGFyc2VkVmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYW4gZW52aXJvbm1lbnQgdmFyaWFibGUgdmFsdWUgaW50byBhIHR5cGVkIHJlcHJlc2VudGF0aW9uLlxuICpcbiAqIFN1cHBvcnRzIGFycmF5IHN5bnRheCBpbiBzcXVhcmUgYnJhY2tldHM6XG4gKiBgYGBcbiAqIFtvbmUsIHR3bywgdGhyZWVdICAtPiBbJ29uZScsICd0d28nLCAndGhyZWUnXVxuICogW1wiYVwiLCBcImJcIiwgXCJjXCJdICAgIC0+IFsnXCJhXCInLCAnXCJiXCInLCAnXCJjXCInXVxuICogYGBgXG4gKiBBbGwgb3RoZXIgdmFsdWVzIGFyZSByZXR1cm5lZCBhcyByYXcgc3RyaW5ncy5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgcmF3IHN0cmluZyB2YWx1ZSB0byBwYXJzZSBmcm9tIGEgYC5lbnZgIGxpbmUuXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHZhbHVlIChzdHJpbmcgb3IgYXJyYXkgb2Ygc3RyaW5ncykuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlRW52VmFsdWUodmFsdWU6IHN0cmluZyk6IHVua25vd24ge1xuICAvLyBSZW1vdmUgbGVhZGluZy90cmFpbGluZyB3aGl0ZXNwYWNlXG4gIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKCk7XG5cbiAgLy8gRGV0ZWN0IGFycmF5IHN5bnRheDogW2l0ZW0xLCBpdGVtMiwgaXRlbTNdXG4gIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoJ1snKSAmJiB0cmltbWVkLmVuZHNXaXRoKCddJykpIHtcbiAgICAvLyBSZW1vdmUgc3Vycm91bmRpbmcgYnJhY2tldHMgYW5kIHRyaW0gaW5uZXIgY29udGVudFxuICAgIGNvbnN0IGlubmVyID0gdHJpbW1lZC5zbGljZSgxLCAtMSkudHJpbSgpO1xuICAgIGlmICghaW5uZXIpIHJldHVybiBbXTsgLy8gRW1wdHkgYXJyYXkg4oaSIFtdXG5cbiAgICAvLyBTcGxpdCBieSBjb21tYSBhbmQgdHJpbSBlYWNoIGVudHJ5XG4gICAgcmV0dXJuIGlubmVyLnNwbGl0KCcsJykubWFwKChpdGVtKSA9PiBpdGVtLnRyaW0oKSk7XG4gIH1cblxuICAvLyBGb3Igbm9uLWFycmF5IHZhbHVlcywgcmV0dXJuIGFzLWlzXG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBXcml0ZXMgYSB2YWx1ZSBpbnRvIGEgbmVzdGVkIG9iamVjdCBzdHJ1Y3R1cmUgdXNpbmcgYSBrZXkgcGF0aC5cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgdHNcbiAqIGNvbnN0IG9iaiA9IHt9O1xuICogYXNzaWduTmVzdGVkKG9iaiwgWydEYXRhYmFzZScsICdIb3N0J10sICdsb2NhbGhvc3QnKTtcbiAqIC8vIFJlc3VsdDogeyBEYXRhYmFzZTogeyBIb3N0OiAnbG9jYWxob3N0JyB9IH1cbiAqIGBgYFxuICpcbiAqIEludGVybWVkaWF0ZSBvYmplY3RzIGFyZSBjcmVhdGVkIGF1dG9tYXRpY2FsbHkgaWYgdGhleSBkbyBub3QgZXhpc3QuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIHZhbHVlIGJlaW5nIGFzc2lnbmVkLlxuICogQHBhcmFtIHRhcmdldCAtIFRoZSByb290IG9iamVjdCB0byBtb2RpZnkuXG4gKiBAcGFyYW0gcGF0aCAtIFRoZSBhcnJheSBvZiBwYXRoIHNlZ21lbnRzIChlLmcuLCBbJ0EnLCdCJywnQyddKS5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBhc3NpZ24gYXQgdGhlIGZpbmFsIGtleS5cbiAqL1xuZnVuY3Rpb24gYXNzaWduTmVzdGVkPFQ+KFxuICB0YXJnZXQ6IFJlY29yZDxzdHJpbmcsIFQ+LFxuICBwYXRoOiBzdHJpbmdbXSxcbiAgdmFsdWU6IFRcbik6IHZvaWQge1xuICAvLyBTdGFydCBmcm9tIHRoZSByb290IG9iamVjdCByZWZlcmVuY2VcbiAgbGV0IHJlZjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB0YXJnZXQ7XG5cbiAgLy8gV2FsayB0aHJvdWdoIGFsbCBwYXRoIHNlZ21lbnRzIGV4Y2VwdCB0aGUgbGFzdCBvbmVcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIGNvbnN0IHNlZyA9IHBhdGhbaV07XG5cbiAgICAvLyBFbnN1cmUgdGhhdCBlYWNoIHNlZ21lbnQgcG9pbnRzIHRvIGEgcGxhaW4gb2JqZWN0O1xuICAgIC8vIHJlcGxhY2UgaW52YWxpZCB0eXBlcyAobnVsbCwgYXJyYXlzLCBwcmltaXRpdmVzKSB3aXRoIHt9XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIHJlZltzZWddICE9PSAnb2JqZWN0JyB8fFxuICAgICAgcmVmW3NlZ10gPT09IG51bGwgfHxcbiAgICAgIEFycmF5LmlzQXJyYXkocmVmW3NlZ10pXG4gICAgKSB7XG4gICAgICByZWZbc2VnXSA9IHt9O1xuICAgIH1cblxuICAgIC8vIE1vdmUgZGVlcGVyIGludG8gdGhlIHN0cnVjdHVyZVxuICAgIHJlZiA9IHJlZltzZWddIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBmaW5hbCBwcm9wZXJ0eSB0byB0aGUgZ2l2ZW4gdmFsdWVcbiAgcmVmW3BhdGhbcGF0aC5sZW5ndGggLSAxXV0gPSB2YWx1ZTtcbn1cblxuLyoqXG4gKiBTcGxpdHMgYSBgLmVudmAgbGluZSBpbnRvIGl0cyBrZXkgYW5kIHZhbHVlIGNvbXBvbmVudHMuXG4gKlxuICogRXhhbXBsZTpcbiAqIGBgYFxuICogXCJBUElfVVJMPWh0dHBzOi8vYXBpLmV4YW1wbGUuY29tXCJcbiAqICAgLT4geyBrZXk6IFwiQVBJX1VSTFwiLCB2YWx1ZTogXCJodHRwczovL2FwaS5leGFtcGxlLmNvbVwiIH1cbiAqIGBgYFxuICpcbiAqIFRoZSBzcGxpdCBvY2N1cnMgYXQgdGhlICoqZmlyc3QqKiAnPScgY2hhcmFjdGVyIG9ubHkuXG4gKiBJZiB0aGUgbGluZSBkb2VzIG5vdCBjb250YWluICc9JywgYW4gZW1wdHkgYHsga2V5OiAnJywgdmFsdWU6ICcnIH1gIGlzIHJldHVybmVkLlxuICpcbiAqIEBwYXJhbSBsaW5lIC0gQSBzaW5nbGUgYC5lbnZgIGxpbmUgdG8gc3BsaXQuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgY29udGFpbmluZyB0aGUga2V5IGFuZCB2YWx1ZSBzdHJpbmdzLlxuICovXG5mdW5jdGlvbiBzcGxpdEVudkxpbmUobGluZTogc3RyaW5nKTogeyBrZXk6IHN0cmluZzsgdmFsdWU6IHN0cmluZyB9IHtcbiAgLy8gRmluZCBmaXJzdCAnPSc7IGtleXMgaW4gLmVudiBmaWxlcyBuZXZlciBjb250YWluICc9J1xuICBjb25zdCBlcSA9IGxpbmUuaW5kZXhPZignPScpO1xuXG4gIC8vIFNraXAgbWFsZm9ybWVkIGxpbmVzXG4gIGlmIChlcSA9PT0gLTEpIHJldHVybiB7IGtleTogJycsIHZhbHVlOiAnJyB9O1xuXG4gIC8vIEV4dHJhY3Qga2V5IGJlZm9yZSAnPScgYW5kIHZhbHVlIGFmdGVyICc9J1xuICBjb25zdCBrZXkgPSBsaW5lLnNsaWNlKDAsIGVxKS50cmltKCk7XG4gIGNvbnN0IHZhbHVlID0gbGluZS5zbGljZShlcSArIDEpLnRyaW0oKTtcblxuICAvLyBSZXR1cm4ga2V5LXZhbHVlIHBhaXJcbiAgcmV0dXJuIHsga2V5LCB2YWx1ZSB9O1xufVxuIl19