@geekmidas/envkit 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{EnvironmentBuilder-DfmYRBm-.mjs → EnvironmentBuilder-BSuHZm0y.mjs} +2 -4
- package/dist/EnvironmentBuilder-BSuHZm0y.mjs.map +1 -0
- package/dist/EnvironmentBuilder-DHfDXJUm.d.mts.map +1 -0
- package/dist/{EnvironmentBuilder-W2wku49g.cjs → EnvironmentBuilder-Djr1VsWM.cjs} +2 -4
- package/dist/EnvironmentBuilder-Djr1VsWM.cjs.map +1 -0
- package/dist/EnvironmentBuilder-Xuf2Dd9u.d.cts.map +1 -0
- package/dist/EnvironmentBuilder.cjs +1 -1
- package/dist/EnvironmentBuilder.mjs +1 -1
- package/dist/EnvironmentParser-Bt246UeP.cjs.map +1 -1
- package/dist/{EnvironmentParser-CVWU1ooT.d.mts → EnvironmentParser-CY8TosTN.d.mts} +2 -1
- package/dist/EnvironmentParser-CY8TosTN.d.mts.map +1 -0
- package/dist/{EnvironmentParser-tV-JjCg7.d.cts → EnvironmentParser-DtOL86NU.d.cts} +2 -1
- package/dist/EnvironmentParser-DtOL86NU.d.cts.map +1 -0
- package/dist/EnvironmentParser-c06agx31.mjs.map +1 -1
- package/dist/EnvironmentParser.d.cts +1 -1
- package/dist/EnvironmentParser.d.mts +1 -1
- package/dist/SnifferEnvironmentParser.cjs.map +1 -1
- package/dist/SnifferEnvironmentParser.d.cts +3 -2
- package/dist/SnifferEnvironmentParser.d.cts.map +1 -0
- package/dist/SnifferEnvironmentParser.d.mts +3 -2
- package/dist/SnifferEnvironmentParser.d.mts.map +1 -0
- package/dist/SnifferEnvironmentParser.mjs.map +1 -1
- package/dist/{SstEnvironmentBuilder-DEa3lTUB.mjs → SstEnvironmentBuilder-BEBFSUYr.mjs} +2 -2
- package/dist/SstEnvironmentBuilder-BEBFSUYr.mjs.map +1 -0
- package/dist/SstEnvironmentBuilder-CjURMGjW.d.mts.map +1 -0
- package/dist/SstEnvironmentBuilder-D4oSo_KX.d.cts.map +1 -0
- package/dist/{SstEnvironmentBuilder-BuFw1hCe.cjs → SstEnvironmentBuilder-wFnN2M5O.cjs} +2 -2
- package/dist/SstEnvironmentBuilder-wFnN2M5O.cjs.map +1 -0
- package/dist/SstEnvironmentBuilder.cjs +2 -2
- package/dist/SstEnvironmentBuilder.mjs +2 -2
- package/dist/credentials.cjs +66 -0
- package/dist/credentials.cjs.map +1 -0
- package/dist/credentials.d.cts +31 -0
- package/dist/credentials.d.cts.map +1 -0
- package/dist/credentials.d.mts +31 -0
- package/dist/credentials.d.mts.map +1 -0
- package/dist/credentials.mjs +62 -0
- package/dist/credentials.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/sst.cjs +2 -2
- package/dist/sst.cjs.map +1 -1
- package/dist/sst.d.cts +1 -0
- package/dist/sst.d.cts.map +1 -0
- package/dist/sst.d.mts +1 -0
- package/dist/sst.d.mts.map +1 -0
- package/dist/sst.mjs +2 -2
- package/dist/sst.mjs.map +1 -1
- package/examples/basic-usage.ts +329 -333
- package/package.json +6 -1
- package/src/EnvironmentBuilder.ts +76 -80
- package/src/EnvironmentParser.ts +231 -231
- package/src/SnifferEnvironmentParser.ts +178 -178
- package/src/SstEnvironmentBuilder.ts +127 -127
- package/src/__tests__/ConfigParser.spec.ts +388 -388
- package/src/__tests__/EnvironmentBuilder.spec.ts +245 -265
- package/src/__tests__/EnvironmentParser.spec.ts +828 -828
- package/src/__tests__/SnifferEnvironmentParser.spec.ts +380 -326
- package/src/__tests__/SstEnvironmentBuilder.spec.ts +347 -367
- package/src/__tests__/credentials.integration.spec.ts +239 -0
- package/src/__tests__/credentials.spec.ts +136 -0
- package/src/__tests__/sst.spec.ts +390 -413
- package/src/credentials.ts +99 -0
- package/src/index.ts +11 -11
- package/src/sst.ts +24 -24
- package/sst-env.d.ts +0 -1
- package/tsconfig.json +9 -0
- package/dist/EnvironmentBuilder-DfmYRBm-.mjs.map +0 -1
- package/dist/EnvironmentBuilder-W2wku49g.cjs.map +0 -1
- package/dist/SstEnvironmentBuilder-BuFw1hCe.cjs.map +0 -1
- package/dist/SstEnvironmentBuilder-DEa3lTUB.mjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
ConfigParser,
|
|
4
|
+
type EmptyObject,
|
|
5
|
+
type EnvFetcher,
|
|
6
6
|
} from './EnvironmentParser';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -24,186 +24,186 @@ import {
|
|
|
24
24
|
* const envVars = sniffer.getEnvironmentVariables(); // ['DATABASE_URL', 'API_KEY']
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
export class SnifferEnvironmentParser<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
27
|
+
export class SnifferEnvironmentParser<_T extends EmptyObject = EmptyObject> {
|
|
28
|
+
private readonly accessedVars: Set<string> = new Set();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Wraps a Zod schema to always return mock values.
|
|
32
|
+
* This ensures .parse() and .safeParse() never fail.
|
|
33
|
+
*/
|
|
34
|
+
private wrapSchema = (schema: z.ZodType, name: string): z.ZodType => {
|
|
35
|
+
return new Proxy(schema, {
|
|
36
|
+
get: (target, prop) => {
|
|
37
|
+
if (prop === 'parse') {
|
|
38
|
+
return () => this.getMockValue(target);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (prop === 'safeParse') {
|
|
42
|
+
return () => ({
|
|
43
|
+
success: true as const,
|
|
44
|
+
data: this.getMockValue(target),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const originalProp = target[prop as keyof typeof target];
|
|
49
|
+
if (typeof originalProp === 'function') {
|
|
50
|
+
return (...args: any[]) => {
|
|
51
|
+
const result = originalProp.apply(target, args);
|
|
52
|
+
if (result && typeof result === 'object' && 'parse' in result) {
|
|
53
|
+
return this.wrapSchema(result, name);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return originalProp;
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns a mock value based on the Zod schema type.
|
|
66
|
+
*/
|
|
67
|
+
private getMockValue(schema: z.ZodType): unknown {
|
|
68
|
+
// Return type-appropriate mock values
|
|
69
|
+
if (schema instanceof z.ZodString) return '';
|
|
70
|
+
if (schema instanceof z.ZodNumber) return 0;
|
|
71
|
+
if (schema instanceof z.ZodBoolean) return false;
|
|
72
|
+
if (schema instanceof z.ZodArray) return [];
|
|
73
|
+
if (schema instanceof z.ZodOptional) return undefined;
|
|
74
|
+
if (schema instanceof z.ZodNullable) return null;
|
|
75
|
+
|
|
76
|
+
// For object schemas, build mock object from shape
|
|
77
|
+
if (schema instanceof z.ZodObject && schema.shape) {
|
|
78
|
+
const result: Record<string, unknown> = {};
|
|
79
|
+
for (const [key, value] of Object.entries(schema.shape)) {
|
|
80
|
+
if (value instanceof z.ZodType) {
|
|
81
|
+
result[key] = this.getMockValue(value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return '';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Creates a proxied Zod getter that tracks environment variable access.
|
|
92
|
+
*/
|
|
93
|
+
private getZodGetter = (name: string) => {
|
|
94
|
+
this.accessedVars.add(name);
|
|
95
|
+
|
|
96
|
+
return new Proxy(
|
|
97
|
+
{ ...z },
|
|
98
|
+
{
|
|
99
|
+
get: (target, prop) => {
|
|
100
|
+
// @ts-expect-error
|
|
101
|
+
const value = target[prop];
|
|
102
|
+
|
|
103
|
+
if (typeof value === 'function') {
|
|
104
|
+
return (...args: any[]) => {
|
|
105
|
+
const schema = value(...args);
|
|
106
|
+
return this.wrapSchema(schema, name);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (value && typeof value === 'object') {
|
|
111
|
+
return new Proxy(value, {
|
|
112
|
+
get: (nestedTarget, nestedProp) => {
|
|
113
|
+
const nestedValue =
|
|
114
|
+
nestedTarget[nestedProp as keyof typeof nestedTarget];
|
|
115
|
+
if (typeof nestedValue === 'function') {
|
|
116
|
+
return (...args: any[]) => {
|
|
117
|
+
const schema = nestedValue(...args);
|
|
118
|
+
return this.wrapSchema(schema, name);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return nestedValue;
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return value;
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Creates a ConfigParser that will return mock values when parsed.
|
|
134
|
+
*/
|
|
135
|
+
create<TReturn extends EmptyObject>(
|
|
136
|
+
builder: (get: EnvFetcher) => TReturn,
|
|
137
|
+
): ConfigParser<TReturn> {
|
|
138
|
+
const config = builder(this.getZodGetter);
|
|
139
|
+
return new SnifferConfigParser(config, this.accessedVars);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns all environment variable names that were accessed.
|
|
144
|
+
*/
|
|
145
|
+
getEnvironmentVariables(): string[] {
|
|
146
|
+
return Array.from(this.accessedVars).sort();
|
|
147
|
+
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
151
151
|
* A ConfigParser that always succeeds with mock values.
|
|
152
152
|
*/
|
|
153
153
|
class SnifferConfigParser<
|
|
154
|
-
|
|
154
|
+
TResponse extends EmptyObject,
|
|
155
155
|
> extends ConfigParser<TResponse> {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
156
|
+
override parse(): any {
|
|
157
|
+
return this.parseWithMocks(this.getConfig());
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private getConfig(): TResponse {
|
|
161
|
+
// Access the private config via any cast
|
|
162
|
+
return (this as any).config;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private parseWithMocks<T>(config: T): any {
|
|
166
|
+
const result: EmptyObject = {};
|
|
167
|
+
|
|
168
|
+
if (config && typeof config !== 'object') {
|
|
169
|
+
return config;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const key in config) {
|
|
173
|
+
const schema = config[key];
|
|
174
|
+
|
|
175
|
+
if (schema instanceof z.ZodType) {
|
|
176
|
+
// Use safeParse which will return mock values from our wrapped schema
|
|
177
|
+
const parsed = schema.safeParse(undefined);
|
|
178
|
+
result[key] = parsed.success
|
|
179
|
+
? parsed.data
|
|
180
|
+
: this.getDefaultForSchema(schema);
|
|
181
|
+
} else if (schema && typeof schema === 'object') {
|
|
182
|
+
result[key] = this.parseWithMocks(schema as EmptyObject);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private getDefaultForSchema(schema: z.ZodType): unknown {
|
|
190
|
+
if (schema instanceof z.ZodString) return '';
|
|
191
|
+
if (schema instanceof z.ZodNumber) return 0;
|
|
192
|
+
if (schema instanceof z.ZodBoolean) return false;
|
|
193
|
+
if (schema instanceof z.ZodArray) return [];
|
|
194
|
+
if (schema instanceof z.ZodOptional) return undefined;
|
|
195
|
+
if (schema instanceof z.ZodNullable) return null;
|
|
196
|
+
|
|
197
|
+
if (schema instanceof z.ZodObject && schema.shape) {
|
|
198
|
+
const result: Record<string, unknown> = {};
|
|
199
|
+
for (const [key, value] of Object.entries(schema.shape)) {
|
|
200
|
+
if (value instanceof z.ZodType) {
|
|
201
|
+
result[key] = this.getDefaultForSchema(value);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return '';
|
|
208
|
+
}
|
|
209
209
|
}
|