@geekmidas/envkit 0.0.3 → 0.0.4
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/{EnvironmentParser-Bz9IoLJs.cjs → EnvironmentParser-Bo2CCl_K.cjs} +56 -43
- package/dist/{EnvironmentParser-Boj5EFmL.mjs → EnvironmentParser-jKrGMBhP.mjs} +52 -2
- package/dist/EnvironmentParser.cjs +1 -1
- package/dist/EnvironmentParser.mjs +1 -1
- package/dist/__tests__/ConfigParser.spec.cjs +53 -52
- package/dist/__tests__/ConfigParser.spec.mjs +27 -27
- package/dist/__tests__/EnvironmentParser.spec.cjs +79 -78
- package/dist/__tests__/EnvironmentParser.spec.mjs +41 -41
- package/dist/chunk-CUT6urMc.cjs +30 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/sst.cjs +131 -0
- package/dist/sst.mjs +128 -0
- package/package.json +10 -3
- package/src/EnvironmentParser.ts +80 -3
- package/src/sst.ts +221 -0
- package/dist/magic-string.es-BrLHy2bw.cjs +0 -1015
- package/dist/magic-string.es-u4lFXMgd.mjs +0 -1014
- package/dist/vi.bdSIJ99Y-CT9xbG7X.cjs +0 -14895
- package/dist/vi.bdSIJ99Y-CkiV-M6Y.mjs +0 -14903
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { EnvironmentParser } from "../EnvironmentParser-Boj5EFmL.mjs";
|
|
1
|
+
import { EnvironmentParser } from "../EnvironmentParser-jKrGMBhP.mjs";
|
|
3
2
|
import { z } from "zod/v4";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
4
|
|
|
5
5
|
//#region src/__tests__/EnvironmentParser.spec.ts
|
|
6
6
|
describe("EnvironmentParser", () => {
|
|
@@ -9,7 +9,7 @@ describe("EnvironmentParser", () => {
|
|
|
9
9
|
const env = { APP_NAME: "Test App" };
|
|
10
10
|
const parser = new EnvironmentParser(env);
|
|
11
11
|
const config = parser.create((get) => ({ appName: get("APP_NAME").string() })).parse();
|
|
12
|
-
|
|
12
|
+
expect(config).toEqual({ appName: "Test App" });
|
|
13
13
|
});
|
|
14
14
|
it("should parse with default values when env var is missing", () => {
|
|
15
15
|
const env = {};
|
|
@@ -18,7 +18,7 @@ describe("EnvironmentParser", () => {
|
|
|
18
18
|
appName: get("APP_NAME").string().default("Default App"),
|
|
19
19
|
port: get("PORT").string().transform(Number).default(3e3)
|
|
20
20
|
})).parse();
|
|
21
|
-
|
|
21
|
+
expect(config).toEqual({
|
|
22
22
|
appName: "Default App",
|
|
23
23
|
port: 3e3
|
|
24
24
|
});
|
|
@@ -27,7 +27,7 @@ describe("EnvironmentParser", () => {
|
|
|
27
27
|
const env = { PORT: "8080" };
|
|
28
28
|
const parser = new EnvironmentParser(env);
|
|
29
29
|
const config = parser.create((get) => ({ port: get("PORT").string().transform(Number) })).parse();
|
|
30
|
-
|
|
30
|
+
expect(config).toEqual({ port: 8080 });
|
|
31
31
|
});
|
|
32
32
|
it("should transform string to boolean", () => {
|
|
33
33
|
const env = {
|
|
@@ -41,7 +41,7 @@ describe("EnvironmentParser", () => {
|
|
|
41
41
|
disabled: get("FEATURE_DISABLED").string().transform((v) => v === "true"),
|
|
42
42
|
truthy: get("FEATURE_TRUTHY").string().transform((v) => v === "true")
|
|
43
43
|
})).parse();
|
|
44
|
-
|
|
44
|
+
expect(config).toEqual({
|
|
45
45
|
enabled: true,
|
|
46
46
|
disabled: false,
|
|
47
47
|
truthy: false
|
|
@@ -54,7 +54,7 @@ describe("EnvironmentParser", () => {
|
|
|
54
54
|
required: get("REQUIRED").string(),
|
|
55
55
|
optional: get("OPTIONAL").string().optional()
|
|
56
56
|
})).parse();
|
|
57
|
-
|
|
57
|
+
expect(config).toEqual({
|
|
58
58
|
required: "value",
|
|
59
59
|
optional: void 0
|
|
60
60
|
});
|
|
@@ -69,7 +69,7 @@ describe("EnvironmentParser", () => {
|
|
|
69
69
|
apiUrl: get("VALID_URL").string().url(),
|
|
70
70
|
dbUrl: get("DATABASE_URL").string().url()
|
|
71
71
|
})).parse();
|
|
72
|
-
|
|
72
|
+
expect(config).toEqual({
|
|
73
73
|
apiUrl: "https://example.com",
|
|
74
74
|
dbUrl: "postgresql://user:pass@localhost:5432/db"
|
|
75
75
|
});
|
|
@@ -78,7 +78,7 @@ describe("EnvironmentParser", () => {
|
|
|
78
78
|
const env = { ADMIN_EMAIL: "admin@example.com" };
|
|
79
79
|
const parser = new EnvironmentParser(env);
|
|
80
80
|
const config = parser.create((get) => ({ adminEmail: get("ADMIN_EMAIL").string().email() })).parse();
|
|
81
|
-
|
|
81
|
+
expect(config).toEqual({ adminEmail: "admin@example.com" });
|
|
82
82
|
});
|
|
83
83
|
it("should validate enums", () => {
|
|
84
84
|
const env = { NODE_ENV: "production" };
|
|
@@ -88,7 +88,7 @@ describe("EnvironmentParser", () => {
|
|
|
88
88
|
"staging",
|
|
89
89
|
"production"
|
|
90
90
|
]) })).parse();
|
|
91
|
-
|
|
91
|
+
expect(config).toEqual({ env: "production" });
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
94
|
describe("Nested configuration", () => {
|
|
@@ -112,7 +112,7 @@ describe("EnvironmentParser", () => {
|
|
|
112
112
|
url: get("API_URL").string().url()
|
|
113
113
|
}
|
|
114
114
|
})).parse();
|
|
115
|
-
|
|
115
|
+
expect(config).toEqual({
|
|
116
116
|
database: {
|
|
117
117
|
host: "localhost",
|
|
118
118
|
port: 5432,
|
|
@@ -142,7 +142,7 @@ describe("EnvironmentParser", () => {
|
|
|
142
142
|
ttl: get("FEATURE_CACHE_TTL").string().transform(Number)
|
|
143
143
|
}
|
|
144
144
|
} })).parse();
|
|
145
|
-
|
|
145
|
+
expect(config).toEqual({ features: {
|
|
146
146
|
authentication: {
|
|
147
147
|
enabled: true,
|
|
148
148
|
provider: "oauth"
|
|
@@ -171,7 +171,7 @@ describe("EnvironmentParser", () => {
|
|
|
171
171
|
ttl: get("REDIS_TTL").string().transform(Number)
|
|
172
172
|
} }
|
|
173
173
|
})).parse();
|
|
174
|
-
|
|
174
|
+
expect(config).toEqual({
|
|
175
175
|
database: {
|
|
176
176
|
host: "custom-host",
|
|
177
177
|
port: 5432,
|
|
@@ -189,7 +189,7 @@ describe("EnvironmentParser", () => {
|
|
|
189
189
|
it("should throw ZodError for missing required values", () => {
|
|
190
190
|
const env = {};
|
|
191
191
|
const parser = new EnvironmentParser(env);
|
|
192
|
-
|
|
192
|
+
expect(() => {
|
|
193
193
|
parser.create((get) => ({ required: get("REQUIRED_VAR").string() })).parse();
|
|
194
194
|
}).toThrow(z.ZodError);
|
|
195
195
|
});
|
|
@@ -202,24 +202,24 @@ describe("EnvironmentParser", () => {
|
|
|
202
202
|
dbUrl: get("DATABASE_URL").string().url()
|
|
203
203
|
})).parse();
|
|
204
204
|
} catch (error) {
|
|
205
|
-
|
|
205
|
+
expect(error).toBeInstanceOf(z.ZodError);
|
|
206
206
|
const zodError = error;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
207
|
+
expect(zodError.issues).toHaveLength(2);
|
|
208
|
+
expect(zodError.issues[0].message).toContain("Environment variable \"API_KEY\"");
|
|
209
|
+
expect(zodError.issues[1].message).toContain("Environment variable \"DATABASE_URL\"");
|
|
210
210
|
}
|
|
211
211
|
});
|
|
212
212
|
it("should validate minimum string length", () => {
|
|
213
213
|
const env = { API_KEY: "short" };
|
|
214
214
|
const parser = new EnvironmentParser(env);
|
|
215
|
-
|
|
215
|
+
expect(() => {
|
|
216
216
|
parser.create((get) => ({ apiKey: get("API_KEY").string().min(32) })).parse();
|
|
217
217
|
}).toThrow(z.ZodError);
|
|
218
218
|
});
|
|
219
219
|
it("should validate maximum string length", () => {
|
|
220
220
|
const env = { SHORT_TEXT: "a".repeat(100) };
|
|
221
221
|
const parser = new EnvironmentParser(env);
|
|
222
|
-
|
|
222
|
+
expect(() => {
|
|
223
223
|
parser.create((get) => ({ shortText: get("SHORT_TEXT").string().max(50) })).parse();
|
|
224
224
|
}).toThrow(z.ZodError);
|
|
225
225
|
});
|
|
@@ -230,29 +230,29 @@ describe("EnvironmentParser", () => {
|
|
|
230
230
|
};
|
|
231
231
|
const parser = new EnvironmentParser(env);
|
|
232
232
|
const validConfig = parser.create((get) => ({ key: get("VALID_KEY").string().length(32) })).parse();
|
|
233
|
-
|
|
234
|
-
|
|
233
|
+
expect(validConfig).toEqual({ key: "a".repeat(32) });
|
|
234
|
+
expect(() => {
|
|
235
235
|
parser.create((get) => ({ key: get("INVALID_KEY").string().length(32) })).parse();
|
|
236
236
|
}).toThrow(z.ZodError);
|
|
237
237
|
});
|
|
238
238
|
it("should validate invalid URLs", () => {
|
|
239
239
|
const env = { INVALID_URL: "not-a-url" };
|
|
240
240
|
const parser = new EnvironmentParser(env);
|
|
241
|
-
|
|
241
|
+
expect(() => {
|
|
242
242
|
parser.create((get) => ({ url: get("INVALID_URL").string().url() })).parse();
|
|
243
243
|
}).toThrow(z.ZodError);
|
|
244
244
|
});
|
|
245
245
|
it("should validate invalid email addresses", () => {
|
|
246
246
|
const env = { INVALID_EMAIL: "not-an-email" };
|
|
247
247
|
const parser = new EnvironmentParser(env);
|
|
248
|
-
|
|
248
|
+
expect(() => {
|
|
249
249
|
parser.create((get) => ({ email: get("INVALID_EMAIL").string().email() })).parse();
|
|
250
250
|
}).toThrow(z.ZodError);
|
|
251
251
|
});
|
|
252
252
|
it("should validate invalid enum values", () => {
|
|
253
253
|
const env = { NODE_ENV: "invalid" };
|
|
254
254
|
const parser = new EnvironmentParser(env);
|
|
255
|
-
|
|
255
|
+
expect(() => {
|
|
256
256
|
parser.create((get) => ({ env: get("NODE_ENV").enum([
|
|
257
257
|
"development",
|
|
258
258
|
"staging",
|
|
@@ -268,18 +268,18 @@ describe("EnvironmentParser", () => {
|
|
|
268
268
|
};
|
|
269
269
|
const parser = new EnvironmentParser(env);
|
|
270
270
|
const validConfig = parser.create((get) => ({ port: get("VALID_PORT").coerce.number().min(1).max(65535) })).parse();
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
expect(validConfig).toEqual({ port: 8080 });
|
|
272
|
+
expect(() => {
|
|
273
273
|
parser.create((get) => ({ port: get("INVALID_PORT_LOW").coerce.number().min(1).max(65535) })).parse();
|
|
274
274
|
}).toThrow(z.ZodError);
|
|
275
|
-
|
|
275
|
+
expect(() => {
|
|
276
276
|
parser.create((get) => ({ port: get("INVALID_PORT_HIGH").coerce.number().min(1).max(65535) })).parse();
|
|
277
277
|
}).toThrow(z.ZodError);
|
|
278
278
|
});
|
|
279
279
|
it("should handle transformation errors", () => {
|
|
280
280
|
const env = { INVALID_NUMBER: "not-a-number" };
|
|
281
281
|
const parser = new EnvironmentParser(env);
|
|
282
|
-
|
|
282
|
+
expect(() => {
|
|
283
283
|
parser.create((get) => ({ number: get("INVALID_NUMBER").string().transform((v) => {
|
|
284
284
|
const num = Number(v);
|
|
285
285
|
if (isNaN(num)) throw new Error("Invalid number");
|
|
@@ -299,7 +299,7 @@ describe("EnvironmentParser", () => {
|
|
|
299
299
|
cors: { origins: get("ALLOWED_ORIGINS").string().transform((origins) => origins.split(",").map((o) => o.trim())) },
|
|
300
300
|
features: get("FEATURE_FLAGS").string().transform((flags) => flags.split(",").map((f) => f.trim()))
|
|
301
301
|
})).parse();
|
|
302
|
-
|
|
302
|
+
expect(config).toEqual({
|
|
303
303
|
cors: { origins: [
|
|
304
304
|
"http://localhost:3000",
|
|
305
305
|
"https://example.com",
|
|
@@ -325,7 +325,7 @@ describe("EnvironmentParser", () => {
|
|
|
325
325
|
window: z.number()
|
|
326
326
|
}))
|
|
327
327
|
})).parse();
|
|
328
|
-
|
|
328
|
+
expect(config).toEqual({
|
|
329
329
|
features: {
|
|
330
330
|
auth: true,
|
|
331
331
|
cache: false,
|
|
@@ -347,7 +347,7 @@ describe("EnvironmentParser", () => {
|
|
|
347
347
|
cors: { origins: get("CORS_ORIGINS").string().transform((origins) => origins.split(",").map((o) => o.trim())).refine((origins) => origins.every((o) => o.startsWith("https://")), { message: "All CORS origins must use HTTPS" }) },
|
|
348
348
|
apiKeys: get("API_KEYS").string().transform((keys) => keys.split(",").map((k) => k.trim())).pipe(z.array(z.string().min(32)))
|
|
349
349
|
})).parse();
|
|
350
|
-
|
|
350
|
+
expect(config).toEqual({
|
|
351
351
|
cors: { origins: ["https://example.com", "https://app.example.com"] },
|
|
352
352
|
apiKeys: ["key1234567890123456789012345678901", "key2345678901234567890123456789012"]
|
|
353
353
|
});
|
|
@@ -355,7 +355,7 @@ describe("EnvironmentParser", () => {
|
|
|
355
355
|
it("should fail refinements with descriptive errors", () => {
|
|
356
356
|
const env = { CORS_ORIGINS: "http://example.com,https://app.example.com" };
|
|
357
357
|
const parser = new EnvironmentParser(env);
|
|
358
|
-
|
|
358
|
+
expect(() => {
|
|
359
359
|
parser.create((get) => ({ cors: { origins: get("CORS_ORIGINS").string().transform((origins) => origins.split(",").map((o) => o.trim())).refine((origins) => origins.every((o) => o.startsWith("https://")), { message: "All CORS origins must use HTTPS" }) } })).parse();
|
|
360
360
|
}).toThrow(z.ZodError);
|
|
361
361
|
});
|
|
@@ -367,8 +367,8 @@ describe("EnvironmentParser", () => {
|
|
|
367
367
|
const config = parser.create((get) => ({ appName: get("APP_NAME").string() })).parse();
|
|
368
368
|
const _typeCheck = true;
|
|
369
369
|
const _typeCheck2 = true;
|
|
370
|
-
|
|
371
|
-
|
|
370
|
+
expect(_typeCheck).toBe(true);
|
|
371
|
+
expect(_typeCheck2).toBe(true);
|
|
372
372
|
});
|
|
373
373
|
it("should correctly infer number types after transformation", () => {
|
|
374
374
|
const env = { PORT: "3000" };
|
|
@@ -376,8 +376,8 @@ describe("EnvironmentParser", () => {
|
|
|
376
376
|
const config = parser.create((get) => ({ port: get("PORT").string().transform(Number) })).parse();
|
|
377
377
|
const _typeCheck = true;
|
|
378
378
|
const _typeCheck2 = true;
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
expect(_typeCheck).toBe(true);
|
|
380
|
+
expect(_typeCheck2).toBe(true);
|
|
381
381
|
});
|
|
382
382
|
it("should correctly infer boolean types after transformation", () => {
|
|
383
383
|
const env = { FEATURE_ENABLED: "true" };
|
|
@@ -385,8 +385,8 @@ describe("EnvironmentParser", () => {
|
|
|
385
385
|
const config = parser.create((get) => ({ enabled: get("FEATURE_ENABLED").string().transform((v) => v === "true") })).parse();
|
|
386
386
|
const _typeCheck = true;
|
|
387
387
|
const _typeCheck2 = true;
|
|
388
|
-
|
|
389
|
-
|
|
388
|
+
expect(_typeCheck).toBe(true);
|
|
389
|
+
expect(_typeCheck2).toBe(true);
|
|
390
390
|
});
|
|
391
391
|
it("should correctly infer optional types", () => {
|
|
392
392
|
const env = { REQUIRED: "value" };
|
|
@@ -412,8 +412,8 @@ describe("EnvironmentParser", () => {
|
|
|
412
412
|
})).parse();
|
|
413
413
|
const _typeCheck = true;
|
|
414
414
|
const _typeCheck2 = true;
|
|
415
|
-
|
|
416
|
-
|
|
415
|
+
expect(_typeCheck).toBe(true);
|
|
416
|
+
expect(_typeCheck2).toBe(true);
|
|
417
417
|
});
|
|
418
418
|
});
|
|
419
419
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
|
|
25
|
+
Object.defineProperty(exports, '__toESM', {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return __toESM;
|
|
29
|
+
}
|
|
30
|
+
});
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
package/dist/sst.cjs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
const lodash_snakecase = require_chunk.__toESM(require("lodash.snakecase"));
|
|
3
|
+
|
|
4
|
+
//#region src/sst.ts
|
|
5
|
+
/**
|
|
6
|
+
* Converts a string to environment variable case format (UPPER_SNAKE_CASE).
|
|
7
|
+
* Numbers following underscores are preserved without the underscore.
|
|
8
|
+
*
|
|
9
|
+
* @param name - The string to convert
|
|
10
|
+
* @returns The converted string in environment variable format
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* environmentCase('myVariable') // 'MY_VARIABLE'
|
|
14
|
+
* environmentCase('api_v2') // 'APIV2'
|
|
15
|
+
*/
|
|
16
|
+
function environmentCase(name) {
|
|
17
|
+
return (0, lodash_snakecase.default)(name).toUpperCase().replace(/_\d+/g, (r) => {
|
|
18
|
+
return r.replace("_", "");
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Enumeration of supported SST (Serverless Stack Toolkit) resource types.
|
|
23
|
+
* Used to identify and process different AWS and SST resources.
|
|
24
|
+
*/
|
|
25
|
+
let ResourceType = /* @__PURE__ */ function(ResourceType$1) {
|
|
26
|
+
ResourceType$1["ApiGatewayV2"] = "sst.aws.ApiGatewayV2";
|
|
27
|
+
ResourceType$1["Postgres"] = "sst.aws.Postgres";
|
|
28
|
+
ResourceType$1["Function"] = "sst.aws.Function";
|
|
29
|
+
ResourceType$1["Bucket"] = "sst.aws.Bucket";
|
|
30
|
+
ResourceType$1["Vpc"] = "sst.aws.Vpc";
|
|
31
|
+
ResourceType$1["Secret"] = "sst.sst.Secret";
|
|
32
|
+
ResourceType$1["SSTSecret"] = "sst:sst:Secret";
|
|
33
|
+
ResourceType$1["SSTFunction"] = "sst:sst:Function";
|
|
34
|
+
ResourceType$1["SSTApiGatewayV2"] = "sst:aws:ApiGatewayV2";
|
|
35
|
+
ResourceType$1["SSTPostgres"] = "sst:aws:Postgres";
|
|
36
|
+
ResourceType$1["SSTBucket"] = "sst:aws:Bucket";
|
|
37
|
+
return ResourceType$1;
|
|
38
|
+
}({});
|
|
39
|
+
/**
|
|
40
|
+
* Processes a Secret resource into environment variables.
|
|
41
|
+
*
|
|
42
|
+
* @param name - The resource name
|
|
43
|
+
* @param value - The Secret resource
|
|
44
|
+
* @returns Object with environment variable mappings
|
|
45
|
+
*/
|
|
46
|
+
const secret = (name, value) => ({ [environmentCase(name)]: value.value });
|
|
47
|
+
/**
|
|
48
|
+
* Processes a Postgres database resource into environment variables.
|
|
49
|
+
* Creates multiple environment variables for database connection details.
|
|
50
|
+
*
|
|
51
|
+
* @param key - The resource key
|
|
52
|
+
* @param value - The Postgres resource
|
|
53
|
+
* @returns Object with database connection environment variables
|
|
54
|
+
*/
|
|
55
|
+
const postgres = (key, value) => {
|
|
56
|
+
const prefix = `${environmentCase(key)}`;
|
|
57
|
+
return {
|
|
58
|
+
[`${prefix}_NAME`]: value.database,
|
|
59
|
+
[`${prefix}_HOST`]: value.host,
|
|
60
|
+
[`${prefix}_PASSWORD`]: value.password,
|
|
61
|
+
[`${prefix}_PORT`]: value.port,
|
|
62
|
+
[`${prefix}_USERNAME`]: value.username
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Processes a Bucket resource into environment variables.
|
|
67
|
+
*
|
|
68
|
+
* @param name - The resource name
|
|
69
|
+
* @param value - The Bucket resource
|
|
70
|
+
* @returns Object with bucket name environment variable
|
|
71
|
+
*/
|
|
72
|
+
const bucket = (name, value) => {
|
|
73
|
+
const prefix = `${environmentCase(name)}`;
|
|
74
|
+
return { [`${prefix}_NAME`]: value.name };
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* No-operation processor for resources that don't require environment variables.
|
|
78
|
+
*
|
|
79
|
+
* @param name - The resource name (unused)
|
|
80
|
+
* @param value - The resource value (unused)
|
|
81
|
+
* @returns Empty object
|
|
82
|
+
*/
|
|
83
|
+
const noop = (name, value) => ({});
|
|
84
|
+
/**
|
|
85
|
+
* Map of resource types to their corresponding processor functions.
|
|
86
|
+
* Each processor converts resource data into environment variables.
|
|
87
|
+
*/
|
|
88
|
+
const processors = {
|
|
89
|
+
[ResourceType.ApiGatewayV2]: noop,
|
|
90
|
+
[ResourceType.Function]: noop,
|
|
91
|
+
[ResourceType.Vpc]: noop,
|
|
92
|
+
[ResourceType.Secret]: secret,
|
|
93
|
+
[ResourceType.Postgres]: postgres,
|
|
94
|
+
[ResourceType.Bucket]: bucket,
|
|
95
|
+
[ResourceType.SSTSecret]: secret,
|
|
96
|
+
[ResourceType.SSTBucket]: bucket,
|
|
97
|
+
[ResourceType.SSTFunction]: noop,
|
|
98
|
+
[ResourceType.SSTPostgres]: postgres,
|
|
99
|
+
[ResourceType.SSTApiGatewayV2]: noop
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Normalizes SST resources and plain strings into environment variables.
|
|
103
|
+
* Processes resources based on their type and converts names to environment case.
|
|
104
|
+
*
|
|
105
|
+
* @param record - Object containing resources and/or string values
|
|
106
|
+
* @returns Normalized environment variables object
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* normalizeResourceEnv({
|
|
110
|
+
* apiUrl: 'https://api.example.com',
|
|
111
|
+
* database: { type: ResourceType.Postgres, ... }
|
|
112
|
+
* })
|
|
113
|
+
*/
|
|
114
|
+
function normalizeResourceEnv(record) {
|
|
115
|
+
const env = {};
|
|
116
|
+
for (const [k, value] of Object.entries(record)) {
|
|
117
|
+
if (typeof value === "string") {
|
|
118
|
+
env[environmentCase(k)] = value;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const processor = processors[value.type];
|
|
122
|
+
if (processor) Object.assign(env, processor(k, value));
|
|
123
|
+
else console.warn(`No processor found for resource type: `, { value });
|
|
124
|
+
}
|
|
125
|
+
return env;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//#endregion
|
|
129
|
+
exports.ResourceType = ResourceType;
|
|
130
|
+
exports.environmentCase = environmentCase;
|
|
131
|
+
exports.normalizeResourceEnv = normalizeResourceEnv;
|
package/dist/sst.mjs
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import snakecase from "lodash.snakecase";
|
|
2
|
+
|
|
3
|
+
//#region src/sst.ts
|
|
4
|
+
/**
|
|
5
|
+
* Converts a string to environment variable case format (UPPER_SNAKE_CASE).
|
|
6
|
+
* Numbers following underscores are preserved without the underscore.
|
|
7
|
+
*
|
|
8
|
+
* @param name - The string to convert
|
|
9
|
+
* @returns The converted string in environment variable format
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* environmentCase('myVariable') // 'MY_VARIABLE'
|
|
13
|
+
* environmentCase('api_v2') // 'APIV2'
|
|
14
|
+
*/
|
|
15
|
+
function environmentCase(name) {
|
|
16
|
+
return snakecase(name).toUpperCase().replace(/_\d+/g, (r) => {
|
|
17
|
+
return r.replace("_", "");
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Enumeration of supported SST (Serverless Stack Toolkit) resource types.
|
|
22
|
+
* Used to identify and process different AWS and SST resources.
|
|
23
|
+
*/
|
|
24
|
+
let ResourceType = /* @__PURE__ */ function(ResourceType$1) {
|
|
25
|
+
ResourceType$1["ApiGatewayV2"] = "sst.aws.ApiGatewayV2";
|
|
26
|
+
ResourceType$1["Postgres"] = "sst.aws.Postgres";
|
|
27
|
+
ResourceType$1["Function"] = "sst.aws.Function";
|
|
28
|
+
ResourceType$1["Bucket"] = "sst.aws.Bucket";
|
|
29
|
+
ResourceType$1["Vpc"] = "sst.aws.Vpc";
|
|
30
|
+
ResourceType$1["Secret"] = "sst.sst.Secret";
|
|
31
|
+
ResourceType$1["SSTSecret"] = "sst:sst:Secret";
|
|
32
|
+
ResourceType$1["SSTFunction"] = "sst:sst:Function";
|
|
33
|
+
ResourceType$1["SSTApiGatewayV2"] = "sst:aws:ApiGatewayV2";
|
|
34
|
+
ResourceType$1["SSTPostgres"] = "sst:aws:Postgres";
|
|
35
|
+
ResourceType$1["SSTBucket"] = "sst:aws:Bucket";
|
|
36
|
+
return ResourceType$1;
|
|
37
|
+
}({});
|
|
38
|
+
/**
|
|
39
|
+
* Processes a Secret resource into environment variables.
|
|
40
|
+
*
|
|
41
|
+
* @param name - The resource name
|
|
42
|
+
* @param value - The Secret resource
|
|
43
|
+
* @returns Object with environment variable mappings
|
|
44
|
+
*/
|
|
45
|
+
const secret = (name, value) => ({ [environmentCase(name)]: value.value });
|
|
46
|
+
/**
|
|
47
|
+
* Processes a Postgres database resource into environment variables.
|
|
48
|
+
* Creates multiple environment variables for database connection details.
|
|
49
|
+
*
|
|
50
|
+
* @param key - The resource key
|
|
51
|
+
* @param value - The Postgres resource
|
|
52
|
+
* @returns Object with database connection environment variables
|
|
53
|
+
*/
|
|
54
|
+
const postgres = (key, value) => {
|
|
55
|
+
const prefix = `${environmentCase(key)}`;
|
|
56
|
+
return {
|
|
57
|
+
[`${prefix}_NAME`]: value.database,
|
|
58
|
+
[`${prefix}_HOST`]: value.host,
|
|
59
|
+
[`${prefix}_PASSWORD`]: value.password,
|
|
60
|
+
[`${prefix}_PORT`]: value.port,
|
|
61
|
+
[`${prefix}_USERNAME`]: value.username
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Processes a Bucket resource into environment variables.
|
|
66
|
+
*
|
|
67
|
+
* @param name - The resource name
|
|
68
|
+
* @param value - The Bucket resource
|
|
69
|
+
* @returns Object with bucket name environment variable
|
|
70
|
+
*/
|
|
71
|
+
const bucket = (name, value) => {
|
|
72
|
+
const prefix = `${environmentCase(name)}`;
|
|
73
|
+
return { [`${prefix}_NAME`]: value.name };
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* No-operation processor for resources that don't require environment variables.
|
|
77
|
+
*
|
|
78
|
+
* @param name - The resource name (unused)
|
|
79
|
+
* @param value - The resource value (unused)
|
|
80
|
+
* @returns Empty object
|
|
81
|
+
*/
|
|
82
|
+
const noop = (name, value) => ({});
|
|
83
|
+
/**
|
|
84
|
+
* Map of resource types to their corresponding processor functions.
|
|
85
|
+
* Each processor converts resource data into environment variables.
|
|
86
|
+
*/
|
|
87
|
+
const processors = {
|
|
88
|
+
[ResourceType.ApiGatewayV2]: noop,
|
|
89
|
+
[ResourceType.Function]: noop,
|
|
90
|
+
[ResourceType.Vpc]: noop,
|
|
91
|
+
[ResourceType.Secret]: secret,
|
|
92
|
+
[ResourceType.Postgres]: postgres,
|
|
93
|
+
[ResourceType.Bucket]: bucket,
|
|
94
|
+
[ResourceType.SSTSecret]: secret,
|
|
95
|
+
[ResourceType.SSTBucket]: bucket,
|
|
96
|
+
[ResourceType.SSTFunction]: noop,
|
|
97
|
+
[ResourceType.SSTPostgres]: postgres,
|
|
98
|
+
[ResourceType.SSTApiGatewayV2]: noop
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Normalizes SST resources and plain strings into environment variables.
|
|
102
|
+
* Processes resources based on their type and converts names to environment case.
|
|
103
|
+
*
|
|
104
|
+
* @param record - Object containing resources and/or string values
|
|
105
|
+
* @returns Normalized environment variables object
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* normalizeResourceEnv({
|
|
109
|
+
* apiUrl: 'https://api.example.com',
|
|
110
|
+
* database: { type: ResourceType.Postgres, ... }
|
|
111
|
+
* })
|
|
112
|
+
*/
|
|
113
|
+
function normalizeResourceEnv(record) {
|
|
114
|
+
const env = {};
|
|
115
|
+
for (const [k, value] of Object.entries(record)) {
|
|
116
|
+
if (typeof value === "string") {
|
|
117
|
+
env[environmentCase(k)] = value;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const processor = processors[value.type];
|
|
121
|
+
if (processor) Object.assign(env, processor(k, value));
|
|
122
|
+
else console.warn(`No processor found for resource type: `, { value });
|
|
123
|
+
}
|
|
124
|
+
return env;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
export { ResourceType, environmentCase, normalizeResourceEnv };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/envkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
"import": "./dist/index.mjs",
|
|
9
9
|
"require": "./dist/index.cjs",
|
|
10
10
|
"types": "./src/index.ts"
|
|
11
|
+
},
|
|
12
|
+
"./sst": {
|
|
13
|
+
"import": "./dist/sst.mjs",
|
|
14
|
+
"require": "./dist/sst.cjs",
|
|
15
|
+
"types": "./src/sst.ts"
|
|
11
16
|
}
|
|
12
17
|
},
|
|
13
18
|
"publishConfig": {
|
|
@@ -17,10 +22,12 @@
|
|
|
17
22
|
"dependencies": {
|
|
18
23
|
"zod": "~3.25.67",
|
|
19
24
|
"lodash.set": "~4.3.2",
|
|
20
|
-
"lodash.get": "~4.4.2"
|
|
25
|
+
"lodash.get": "~4.4.2",
|
|
26
|
+
"lodash.snakecase": "~4.1.1"
|
|
21
27
|
},
|
|
22
28
|
"devDependencies": {
|
|
23
29
|
"@types/lodash.set": "~4.3.9",
|
|
24
|
-
"@types/lodash.get": "~4.4.9"
|
|
30
|
+
"@types/lodash.get": "~4.4.9",
|
|
31
|
+
"@types/lodash.snakecase": "~4.1.9"
|
|
25
32
|
}
|
|
26
33
|
}
|