@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.
- package/README.md +291 -26
- package/docker/docker-entrypoint.sh +13 -0
- package/docker/extract-env-vars.sh +114 -0
- package/docker/nginx.conf +69 -0
- package/esm2022/index.mjs +16 -5
- package/esm2022/lib/env/angular/provide-runtime-config.mjs +161 -0
- package/esm2022/lib/env/angular/provide-static-config.mjs +44 -0
- package/esm2022/lib/env/core/create-env-kit.mjs +81 -0
- package/esm2022/lib/env/core/env-types.mjs +2 -0
- package/esm2022/lib/env/core/parse-env-file.mjs +140 -0
- package/index.d.ts +467 -4
- package/package.json +18 -6
- package/lib/toast/models/toast-state.enum.d.ts +0 -17
- package/lib/toast/models/toast-type.d.ts +0 -8
- package/lib/toast/models/toast.model.d.ts +0 -73
- package/lib/toast/provide-toast.d.ts +0 -3
- package/lib/toast/toast.component.d.ts +0 -24
- package/lib/toast/toast.config.d.ts +0 -35
- package/lib/toast/toast.service.d.ts +0 -98
- package/lib/utils/bootstrap-global-component.d.ts +0 -23
|
@@ -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
|