@tyravel/config 0.1.0 → 0.2.1

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/dist/env.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ type EnvDefault = string | number | boolean | null | undefined;
2
+ export declare function env(key: string): string | undefined;
3
+ export declare function env(key: string, defaultValue: string): string;
4
+ export declare function env<T extends EnvDefault>(key: string, defaultValue: T): T;
5
+ export declare function envBool(key: string, defaultValue?: boolean): boolean;
6
+ export declare function envInt(key: string, defaultValue: number): number;
7
+ export {};
8
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE/D,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AACrD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;AAC/D,wBAAgB,GAAG,CAAC,CAAC,SAAS,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC;AAmB3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,OAAO,CAMlE;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAQhE"}
package/dist/env.js ADDED
@@ -0,0 +1,58 @@
1
+ export function env(key, defaultValue) {
2
+ const raw = process.env[key];
3
+ if (raw === undefined) {
4
+ return defaultValue;
5
+ }
6
+ if (raw === '') {
7
+ return defaultValue ?? '';
8
+ }
9
+ if (defaultValue === undefined) {
10
+ return raw;
11
+ }
12
+ return castEnvValue(raw, defaultValue);
13
+ }
14
+ export function envBool(key, defaultValue = false) {
15
+ const value = env(key);
16
+ if (value === undefined || value === '') {
17
+ return defaultValue;
18
+ }
19
+ return parseBool(value);
20
+ }
21
+ export function envInt(key, defaultValue) {
22
+ const value = env(key);
23
+ if (value === undefined || value === '') {
24
+ return defaultValue;
25
+ }
26
+ const parsed = Number.parseInt(value, 10);
27
+ return Number.isNaN(parsed) ? defaultValue : parsed;
28
+ }
29
+ function castEnvValue(value, defaultValue) {
30
+ if (typeof defaultValue === 'boolean') {
31
+ return parseBool(value);
32
+ }
33
+ if (typeof defaultValue === 'number') {
34
+ const parsed = Number(value);
35
+ return (Number.isNaN(parsed) ? defaultValue : parsed);
36
+ }
37
+ if (defaultValue === null && value.toLowerCase() === 'null') {
38
+ return null;
39
+ }
40
+ return value;
41
+ }
42
+ function parseBool(value) {
43
+ switch (value.trim().toLowerCase()) {
44
+ case '1':
45
+ case 'true':
46
+ case 'on':
47
+ case 'yes':
48
+ return true;
49
+ case '0':
50
+ case 'false':
51
+ case 'off':
52
+ case 'no':
53
+ return false;
54
+ default:
55
+ return false;
56
+ }
57
+ }
58
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,GAAG,CAAuB,GAAW,EAAE,YAAgB;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,OAAO,YAAY,IAAI,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,YAAY,GAAG,KAAK;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,YAAoB;IACtD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;AACtD,CAAC;AAED,SAAS,YAAY,CAAuB,KAAa,EAAE,YAAe;IACxE,IAAI,OAAO,YAAY,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC,KAAK,CAAM,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAM,CAAC;IAC7D,CAAC;IAED,IAAI,YAAY,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;QAC5D,OAAO,IAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAU,CAAC;AACpB,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACnC,KAAK,GAAG,CAAC;QACT,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,KAAK;YACR,OAAO,IAAI,CAAC;QACd,KAAK,GAAG,CAAC;QACT,KAAK,OAAO,CAAC;QACb,KAAK,KAAK,CAAC;QACX,KAAK,IAAI;YACP,OAAO,KAAK,CAAC;QACf;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=env.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.test.d.ts","sourceRoot":"","sources":["../src/env.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { afterEach, describe, expect, it } from 'vitest';
2
+ import { env, envBool, envInt } from './env.js';
3
+ const ORIGINAL_ENV = { ...process.env };
4
+ afterEach(() => {
5
+ for (const key of Object.keys(process.env)) {
6
+ delete process.env[key];
7
+ }
8
+ Object.assign(process.env, ORIGINAL_ENV);
9
+ });
10
+ describe('env', () => {
11
+ it('returns defaults and casts booleans and numbers', () => {
12
+ process.env.APP_DEBUG = 'true';
13
+ process.env.APP_PORT = '3000';
14
+ process.env.APP_NAME = 'Tyravel';
15
+ expect(env('APP_NAME')).toBe('Tyravel');
16
+ expect(env('MISSING', 'fallback')).toBe('fallback');
17
+ expect(env('APP_DEBUG', false)).toBe(true);
18
+ expect(env('APP_PORT', 8080)).toBe(3000);
19
+ expect(env('EMPTY', 'default')).toBe('default');
20
+ });
21
+ it('provides typed helpers', () => {
22
+ process.env.FEATURE_FLAG = 'yes';
23
+ process.env.RETRIES = '3';
24
+ expect(envBool('FEATURE_FLAG')).toBe(true);
25
+ expect(envBool('MISSING')).toBe(false);
26
+ expect(envInt('RETRIES', 1)).toBe(3);
27
+ expect(envInt('MISSING', 5)).toBe(5);
28
+ });
29
+ });
30
+ //# sourceMappingURL=env.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.test.js","sourceRoot":"","sources":["../src/env.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEhD,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAExC,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,MAAM,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,SAAS,CAAC;QAEjC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC;QAE1B,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
+ export { env, envBool, envInt } from './env.js';
1
2
  export { loadConfig } from './loader.js';
3
+ export { loadEnv, parseEnv } from './load-env.js';
4
+ export type { LoadEnvOptions } from './load-env.js';
2
5
  export { ConfigRepository } from './repository.js';
3
6
  export type { ConfigTree } from './repository.js';
4
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export { env, envBool, envInt } from './env.js';
1
2
  export { loadConfig } from './loader.js';
3
+ export { loadEnv, parseEnv } from './load-env.js';
2
4
  export { ConfigRepository } from './repository.js';
3
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface LoadEnvOptions {
2
+ /** Path to the env file. Defaults to `<basePath>/.env`. */
3
+ path?: string;
4
+ /** When true, values from the file overwrite existing `process.env` entries. */
5
+ override?: boolean;
6
+ }
7
+ export declare function loadEnv(basePath: string, options?: LoadEnvOptions): boolean;
8
+ export declare function parseEnv(content: string): Record<string, string>;
9
+ //# sourceMappingURL=load-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.d.ts","sourceRoot":"","sources":["../src/load-env.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAiB/E;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAchE"}
@@ -0,0 +1,61 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export function loadEnv(basePath, options = {}) {
4
+ const envPath = options.path ?? join(basePath, '.env');
5
+ if (!existsSync(envPath)) {
6
+ return false;
7
+ }
8
+ const content = readFileSync(envPath, 'utf8');
9
+ const variables = parseEnv(content);
10
+ for (const [key, value] of Object.entries(variables)) {
11
+ if (options.override || process.env[key] === undefined) {
12
+ process.env[key] = value;
13
+ }
14
+ }
15
+ return true;
16
+ }
17
+ export function parseEnv(content) {
18
+ const variables = {};
19
+ for (const rawLine of content.split(/\r?\n/u)) {
20
+ const parsed = parseEnvLine(rawLine);
21
+ if (!parsed) {
22
+ continue;
23
+ }
24
+ const [key, value] = parsed;
25
+ variables[key] = value;
26
+ }
27
+ return variables;
28
+ }
29
+ function parseEnvLine(line) {
30
+ const trimmed = line.trim();
31
+ if (!trimmed || trimmed.startsWith('#')) {
32
+ return null;
33
+ }
34
+ if (trimmed.startsWith('export ')) {
35
+ return parseEnvLine(trimmed.slice('export '.length));
36
+ }
37
+ const separator = trimmed.indexOf('=');
38
+ if (separator === -1) {
39
+ return null;
40
+ }
41
+ const key = trimmed.slice(0, separator).trim();
42
+ if (!key) {
43
+ return null;
44
+ }
45
+ let value = trimmed.slice(separator + 1).trim();
46
+ if ((value.startsWith('"') && value.endsWith('"')) ||
47
+ (value.startsWith("'") && value.endsWith("'"))) {
48
+ const quote = value[0];
49
+ value = value.slice(1, -1);
50
+ if (quote === '"') {
51
+ value = value
52
+ .replaceAll('\\n', '\n')
53
+ .replaceAll('\\r', '\r')
54
+ .replaceAll('\\t', '\t')
55
+ .replaceAll('\\"', '"')
56
+ .replaceAll('\\\\', '\\');
57
+ }
58
+ }
59
+ return [key, value];
60
+ }
61
+ //# sourceMappingURL=load-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.js","sourceRoot":"","sources":["../src/load-env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=load-env.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.test.d.ts","sourceRoot":"","sources":["../src/load-env.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ import { afterEach, describe, expect, it } from 'vitest';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { loadEnv, parseEnv } from './load-env.js';
4
+ const fixturePath = fileURLToPath(new URL('./fixtures/.env.sample', import.meta.url));
5
+ const ORIGINAL_ENV = { ...process.env };
6
+ afterEach(() => {
7
+ for (const key of Object.keys(process.env)) {
8
+ delete process.env[key];
9
+ }
10
+ Object.assign(process.env, ORIGINAL_ENV);
11
+ });
12
+ describe('parseEnv', () => {
13
+ it('parses comments, quotes, exports, and escapes', () => {
14
+ const parsed = parseEnv(`
15
+ # comment
16
+ APP_NAME=Tyravel
17
+ export APP_DEBUG=true
18
+ APP_URL="http://127.0.0.1:3000"
19
+ MESSAGE="line1\\nline2"
20
+ EMPTY=
21
+ `);
22
+ expect(parsed).toEqual({
23
+ APP_NAME: 'Tyravel',
24
+ APP_DEBUG: 'true',
25
+ APP_URL: 'http://127.0.0.1:3000',
26
+ MESSAGE: 'line1\nline2',
27
+ EMPTY: '',
28
+ });
29
+ });
30
+ });
31
+ describe('loadEnv', () => {
32
+ it('does not override existing environment variables by default', () => {
33
+ process.env.EXISTING = 'from-shell';
34
+ loadEnv(process.cwd(), {
35
+ path: fixturePath,
36
+ override: false,
37
+ });
38
+ expect(process.env.EXISTING).toBe('from-shell');
39
+ expect(process.env.APP_NAME).toBe('FixtureApp');
40
+ });
41
+ it('can override existing variables when requested', () => {
42
+ process.env.APP_NAME = 'OldName';
43
+ loadEnv(process.cwd(), {
44
+ path: fixturePath,
45
+ override: true,
46
+ });
47
+ expect(process.env.APP_NAME).toBe('FixtureApp');
48
+ });
49
+ });
50
+ //# sourceMappingURL=load-env.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.test.js","sourceRoot":"","sources":["../src/load-env.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,WAAW,GAAG,aAAa,CAC/B,IAAI,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACnD,CAAC;AAEF,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;AAExC,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG,QAAQ,CAAC;;;;;;;KAOvB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,cAAc;YACvB,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAC;QAEpC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACrB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,SAAS,CAAC;QAEjC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YACrB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tyravel/config",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",