@ooneex/utils 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/package.json +6 -2
- package/src/capitalizeWord.ts +0 -3
- package/src/dataURLtoFile.ts +0 -12
- package/src/formatRelativeNumber.ts +0 -7
- package/src/index.ts +0 -15
- package/src/millisecondsToHMS.ts +0 -16
- package/src/parseEnvVars.ts +0 -14
- package/src/parseString.ts +0 -47
- package/src/random.ts +0 -13
- package/src/secondsToHMS.ts +0 -16
- package/src/secondsToMS.ts +0 -5
- package/src/sleep.ts +0 -3
- package/src/splitToWords.ts +0 -14
- package/src/toCamelCase.ts +0 -8
- package/src/toKebabCase.ts +0 -6
- package/src/toPascalCase.ts +0 -7
- package/src/trim.ts +0 -8
- package/tests/capitalizeWord.spec.ts +0 -163
- package/tests/dataURLtoFile.spec.ts +0 -472
- package/tests/formatRelativeNumber.spec.ts +0 -303
- package/tests/millisecondsToHMS.spec.ts +0 -209
- package/tests/parseEnvVars.spec.ts +0 -468
- package/tests/parseString.spec.ts +0 -377
- package/tests/random.spec.ts +0 -422
- package/tests/secondsToHMS.spec.ts +0 -341
- package/tests/secondsToMS.spec.ts +0 -467
- package/tests/splitToWords.spec.ts +0 -359
- package/tests/toCamelCase.spec.ts +0 -526
- package/tests/toKebabCase.spec.ts +0 -664
- package/tests/toPascalCase.spec.ts +0 -721
- package/tests/trim.spec.ts +0 -486
- package/tsconfig.json +0 -11
|
@@ -1,468 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { parseEnvVars } from "@/index";
|
|
3
|
-
|
|
4
|
-
describe("parseEnvVars", () => {
|
|
5
|
-
describe("basic functionality", () => {
|
|
6
|
-
test("should convert keys to camelCase and parse values", () => {
|
|
7
|
-
const input = {
|
|
8
|
-
DATABASE_URL: "postgres://localhost:5432/db",
|
|
9
|
-
API_PORT: "3000",
|
|
10
|
-
DEBUG_MODE: "true",
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const result = parseEnvVars(input);
|
|
14
|
-
|
|
15
|
-
expect(result).toEqual({
|
|
16
|
-
databaseUrl: "postgres://localhost:5432/db",
|
|
17
|
-
apiPort: 3000,
|
|
18
|
-
debugMode: true,
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("should handle empty object", () => {
|
|
23
|
-
const result = parseEnvVars({});
|
|
24
|
-
expect(result).toEqual({});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("should handle single environment variable", () => {
|
|
28
|
-
const input = { PORT: "8080" };
|
|
29
|
-
const result = parseEnvVars(input);
|
|
30
|
-
expect(result).toEqual({ port: 8080 });
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe("key transformation", () => {
|
|
35
|
-
test("should convert SCREAMING_SNAKE_CASE to camelCase", () => {
|
|
36
|
-
const input = {
|
|
37
|
-
VERY_LONG_VARIABLE_NAME: "value",
|
|
38
|
-
SIMPLE_VAR: "test",
|
|
39
|
-
A_B_C_D: "abcd",
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const result = parseEnvVars(input);
|
|
43
|
-
|
|
44
|
-
expect(result).toEqual({
|
|
45
|
-
veryLongVariableName: "value",
|
|
46
|
-
simpleVar: "test",
|
|
47
|
-
aBCD: "abcd",
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("should handle keys with numbers", () => {
|
|
52
|
-
const input = {
|
|
53
|
-
API_V2_URL: "https://api.example.com/v2",
|
|
54
|
-
DB_VERSION_1: "1.0.0",
|
|
55
|
-
PORT_3000: "3000",
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const result = parseEnvVars(input);
|
|
59
|
-
|
|
60
|
-
expect(result).toEqual({
|
|
61
|
-
apiV2Url: "https://api.example.com/v2",
|
|
62
|
-
dbVersion1: "1.0.0",
|
|
63
|
-
port3000: 3000,
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("should handle keys with special characters", () => {
|
|
68
|
-
const input = {
|
|
69
|
-
"API-URL": "https://api.example.com",
|
|
70
|
-
"DB.NAME": "mydb",
|
|
71
|
-
"VALUE WITH SPACES": "test",
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const result = parseEnvVars(input);
|
|
75
|
-
|
|
76
|
-
expect(result).toEqual({
|
|
77
|
-
apiUrl: "https://api.example.com",
|
|
78
|
-
dbName: "mydb",
|
|
79
|
-
valueWithSpaces: "test",
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test("should handle already camelCase keys", () => {
|
|
84
|
-
const input = {
|
|
85
|
-
apiUrl: "https://api.example.com",
|
|
86
|
-
databasePort: "5432",
|
|
87
|
-
isEnabled: "true",
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const result = parseEnvVars(input);
|
|
91
|
-
|
|
92
|
-
expect(result).toEqual({
|
|
93
|
-
apiUrl: "https://api.example.com",
|
|
94
|
-
databasePort: 5432,
|
|
95
|
-
isEnabled: true,
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe("value parsing", () => {
|
|
101
|
-
test("should parse integer strings to numbers", () => {
|
|
102
|
-
const input = {
|
|
103
|
-
PORT: "3000",
|
|
104
|
-
TIMEOUT: "5000",
|
|
105
|
-
MAX_CONNECTIONS: "100",
|
|
106
|
-
NEGATIVE_NUMBER: "-50",
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const result = parseEnvVars(input);
|
|
110
|
-
|
|
111
|
-
expect(result).toEqual({
|
|
112
|
-
port: 3000,
|
|
113
|
-
timeout: 5000,
|
|
114
|
-
maxConnections: 100,
|
|
115
|
-
negativeNumber: -50,
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test("should parse float strings to numbers", () => {
|
|
120
|
-
const input = {
|
|
121
|
-
RATE: "1.5",
|
|
122
|
-
PERCENTAGE: "99.99",
|
|
123
|
-
SMALL_DECIMAL: "0.001",
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const result = parseEnvVars(input);
|
|
127
|
-
|
|
128
|
-
expect(result).toEqual({
|
|
129
|
-
rate: 1.5,
|
|
130
|
-
percentage: 99.99,
|
|
131
|
-
smallDecimal: 0.001,
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
test("should parse boolean strings", () => {
|
|
136
|
-
const input = {
|
|
137
|
-
ENABLE_FEATURE: "true",
|
|
138
|
-
DEBUG_MODE: "false",
|
|
139
|
-
IS_PRODUCTION: "TRUE",
|
|
140
|
-
SHOW_LOGS: "FALSE",
|
|
141
|
-
CASE_MIXED: "True",
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const result = parseEnvVars(input);
|
|
145
|
-
|
|
146
|
-
expect(result).toEqual({
|
|
147
|
-
enableFeature: true,
|
|
148
|
-
debugMode: false,
|
|
149
|
-
isProduction: true,
|
|
150
|
-
showLogs: false,
|
|
151
|
-
caseMixed: true,
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
test("should parse null values", () => {
|
|
156
|
-
const input = {
|
|
157
|
-
NULLABLE_FIELD: "null",
|
|
158
|
-
EMPTY_CONFIG: "NULL",
|
|
159
|
-
CASE_MIXED: "Null",
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const result = parseEnvVars(input);
|
|
163
|
-
|
|
164
|
-
expect(result).toEqual({
|
|
165
|
-
nullableField: null,
|
|
166
|
-
emptyConfig: null,
|
|
167
|
-
caseMixed: null,
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
test("should parse array strings", () => {
|
|
172
|
-
const input = {
|
|
173
|
-
ALLOWED_ORIGINS: "[localhost, 127.0.0.1, example.com]",
|
|
174
|
-
PORTS: "[3000, 4000, 5000]",
|
|
175
|
-
FEATURES: "[true, false, true]",
|
|
176
|
-
MIXED_ARRAY: "[1, test, true, null]",
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const result = parseEnvVars(input);
|
|
180
|
-
|
|
181
|
-
expect(result).toEqual({
|
|
182
|
-
allowedOrigins: ["localhost", "127.0.0.1", "example.com"],
|
|
183
|
-
ports: [3000, 4000, 5000],
|
|
184
|
-
features: [true, false, true],
|
|
185
|
-
mixedArray: [1, "test", true, null],
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
test("should parse JSON strings", () => {
|
|
190
|
-
const input = {
|
|
191
|
-
CONFIG_OBJECT: '{"host":"localhost","port":3000}',
|
|
192
|
-
USER_DATA: '{"name":"John","age":30,"active":true}',
|
|
193
|
-
NESTED_JSON: '{"db":{"host":"localhost","port":5432}}',
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const result = parseEnvVars(input);
|
|
197
|
-
|
|
198
|
-
expect(result).toEqual({
|
|
199
|
-
configObject: { host: "localhost", port: 3000 },
|
|
200
|
-
userData: { name: "John", age: 30, active: true },
|
|
201
|
-
nestedJson: { db: { host: "localhost", port: 5432 } },
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
test("should keep strings as strings when they cannot be parsed", () => {
|
|
206
|
-
const input = {
|
|
207
|
-
API_URL: "https://api.example.com",
|
|
208
|
-
DATABASE_NAME: "my-app-db",
|
|
209
|
-
SECRET_KEY: "abc123xyz",
|
|
210
|
-
COMPLEX_STRING: "user@domain.com:password",
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const result = parseEnvVars(input);
|
|
214
|
-
|
|
215
|
-
expect(result).toEqual({
|
|
216
|
-
apiUrl: "https://api.example.com",
|
|
217
|
-
databaseName: "my-app-db",
|
|
218
|
-
secretKey: "abc123xyz",
|
|
219
|
-
complexString: "user@domain.com:password",
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
describe("edge cases", () => {
|
|
225
|
-
test("should handle empty string values", () => {
|
|
226
|
-
const input = {
|
|
227
|
-
EMPTY_VALUE: "",
|
|
228
|
-
ANOTHER_EMPTY: "",
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
const result = parseEnvVars(input);
|
|
232
|
-
|
|
233
|
-
expect(result).toEqual({
|
|
234
|
-
emptyValue: "",
|
|
235
|
-
anotherEmpty: "",
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
test("should handle whitespace values", () => {
|
|
240
|
-
const input = {
|
|
241
|
-
SPACES: " ",
|
|
242
|
-
TABS: "\t\t",
|
|
243
|
-
NEWLINES: "\n\n",
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const result = parseEnvVars(input);
|
|
247
|
-
|
|
248
|
-
expect(result).toEqual({
|
|
249
|
-
spaces: " ",
|
|
250
|
-
tabs: "\t\t",
|
|
251
|
-
newlines: "\n\n",
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
test("should handle special string patterns", () => {
|
|
256
|
-
const input = {
|
|
257
|
-
LOOKS_LIKE_BOOL: "truthy",
|
|
258
|
-
LOOKS_LIKE_NULL: "nullable",
|
|
259
|
-
LOOKS_LIKE_NUMBER: "123abc",
|
|
260
|
-
LOOKS_LIKE_ARRAY: "[not, an, array",
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const result = parseEnvVars(input);
|
|
264
|
-
|
|
265
|
-
expect(result).toEqual({
|
|
266
|
-
looksLikeBool: "truthy",
|
|
267
|
-
looksLikeNull: "nullable",
|
|
268
|
-
looksLikeNumber: "123abc",
|
|
269
|
-
looksLikeArray: "[not, an, array",
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
test("should handle malformed JSON", () => {
|
|
274
|
-
const input = {
|
|
275
|
-
BAD_JSON: '{"incomplete": true',
|
|
276
|
-
INVALID_JSON: "{not: valid}",
|
|
277
|
-
PARTIAL_ARRAY: "[1, 2,",
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const result = parseEnvVars(input);
|
|
281
|
-
|
|
282
|
-
expect(result).toEqual({
|
|
283
|
-
badJson: '{"incomplete": true',
|
|
284
|
-
invalidJson: "{not: valid}",
|
|
285
|
-
partialArray: "[1, 2,",
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
test("should handle infinity values", () => {
|
|
290
|
-
const input = {
|
|
291
|
-
POSITIVE_INFINITY: "Infinity",
|
|
292
|
-
NEGATIVE_INFINITY: "-Infinity",
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const result = parseEnvVars(input);
|
|
296
|
-
|
|
297
|
-
expect(result).toEqual({
|
|
298
|
-
positiveInfinity: "Infinity",
|
|
299
|
-
negativeInfinity: "-Infinity",
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
describe("type safety", () => {
|
|
305
|
-
test("should handle non-string values in input", () => {
|
|
306
|
-
const input = {
|
|
307
|
-
STRING_VAL: "test",
|
|
308
|
-
NUMBER_VAL: 123 as unknown,
|
|
309
|
-
BOOLEAN_VAL: true as unknown,
|
|
310
|
-
NULL_VAL: null as unknown,
|
|
311
|
-
UNDEFINED_VAL: undefined as unknown,
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
const result = parseEnvVars<{ stringVal: string }>(input);
|
|
315
|
-
|
|
316
|
-
// Since parseString expects strings, non-string values might behave unexpectedly
|
|
317
|
-
// But the function should still work
|
|
318
|
-
expect(typeof result).toBe("object");
|
|
319
|
-
expect(result.stringVal).toBe("test");
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
test("should work with generic type parameter", () => {
|
|
323
|
-
interface Config {
|
|
324
|
-
apiUrl: string;
|
|
325
|
-
port: number;
|
|
326
|
-
debugMode: boolean;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const input = {
|
|
330
|
-
API_URL: "https://api.example.com",
|
|
331
|
-
PORT: "3000",
|
|
332
|
-
DEBUG_MODE: "true",
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
const result = parseEnvVars<Config>(input);
|
|
336
|
-
|
|
337
|
-
expect(result).toEqual({
|
|
338
|
-
apiUrl: "https://api.example.com",
|
|
339
|
-
port: 3000,
|
|
340
|
-
debugMode: true,
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
describe("parametrized tests", () => {
|
|
346
|
-
test.each([
|
|
347
|
-
[{ SIMPLE_KEY: "value" }, { simpleKey: "value" }],
|
|
348
|
-
[{ NUMBER_KEY: "42" }, { numberKey: 42 }],
|
|
349
|
-
[{ BOOL_KEY: "true" }, { boolKey: true }],
|
|
350
|
-
[{ NULL_KEY: "null" }, { nullKey: null }],
|
|
351
|
-
[{ ARRAY_KEY: "[1, 2, 3]" }, { arrayKey: [1, 2, 3] }],
|
|
352
|
-
])("parseEnvVars(%o) should return %o", (input, expected: unknown) => {
|
|
353
|
-
const result = parseEnvVars(input);
|
|
354
|
-
expect(result as unknown).toEqual(expected as unknown);
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
describe("real world examples", () => {
|
|
359
|
-
test("should handle typical application environment variables", () => {
|
|
360
|
-
const input = {
|
|
361
|
-
NODE_ENV: "production",
|
|
362
|
-
DATABASE_URL: "postgres://user:pass@localhost:5432/mydb",
|
|
363
|
-
API_PORT: "3000",
|
|
364
|
-
ENABLE_LOGGING: "true",
|
|
365
|
-
MAX_CONNECTIONS: "100",
|
|
366
|
-
ALLOWED_ORIGINS: "[localhost, example.com, api.example.com]",
|
|
367
|
-
JWT_SECRET: "your-secret-key",
|
|
368
|
-
REDIS_TTL: "3600",
|
|
369
|
-
DEBUG_MODE: "false",
|
|
370
|
-
APP_VERSION: "1.2.3",
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
const result = parseEnvVars(input);
|
|
374
|
-
|
|
375
|
-
expect(result).toEqual({
|
|
376
|
-
nodeEnv: "production",
|
|
377
|
-
databaseUrl: "postgres://user:pass@localhost:5432/mydb",
|
|
378
|
-
apiPort: 3000,
|
|
379
|
-
enableLogging: true,
|
|
380
|
-
maxConnections: 100,
|
|
381
|
-
allowedOrigins: ["localhost", "example.com", "api.example.com"],
|
|
382
|
-
jwtSecret: "your-secret-key",
|
|
383
|
-
redisTtl: 3600,
|
|
384
|
-
debugMode: false,
|
|
385
|
-
appVersion: "1.2.3",
|
|
386
|
-
});
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
test("should handle AWS-style environment variables", () => {
|
|
390
|
-
const input = {
|
|
391
|
-
AWS_REGION: "us-east-1",
|
|
392
|
-
AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE",
|
|
393
|
-
AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
394
|
-
S3_BUCKET_NAME: "my-app-bucket",
|
|
395
|
-
LAMBDA_TIMEOUT: "30",
|
|
396
|
-
USE_S3: "true",
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
const result = parseEnvVars(input);
|
|
400
|
-
|
|
401
|
-
expect(result).toEqual({
|
|
402
|
-
awsRegion: "us-east-1",
|
|
403
|
-
awsAccessKeyId: "AKIAIOSFODNN7EXAMPLE",
|
|
404
|
-
awsSecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
405
|
-
s3BucketName: "my-app-bucket",
|
|
406
|
-
lambdaTimeout: 30,
|
|
407
|
-
useS3: true,
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
test("should handle Docker environment variables", () => {
|
|
412
|
-
const input = {
|
|
413
|
-
DOCKER_HOST: "unix:///var/run/docker.sock",
|
|
414
|
-
COMPOSE_PROJECT_NAME: "my-app",
|
|
415
|
-
RESTART_POLICY: "unless-stopped",
|
|
416
|
-
EXPOSE_PORT: "8080",
|
|
417
|
-
ENABLE_HEALTHCHECK: "true",
|
|
418
|
-
MEMORY_LIMIT: "512",
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
const result = parseEnvVars(input);
|
|
422
|
-
|
|
423
|
-
expect(result).toEqual({
|
|
424
|
-
dockerHost: "unix:///var/run/docker.sock",
|
|
425
|
-
composeProjectName: "my-app",
|
|
426
|
-
restartPolicy: "unless-stopped",
|
|
427
|
-
exposePort: 8080,
|
|
428
|
-
enableHealthcheck: true,
|
|
429
|
-
memoryLimit: 512,
|
|
430
|
-
});
|
|
431
|
-
});
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
describe("function behavior", () => {
|
|
435
|
-
test("should not mutate the original input object", () => {
|
|
436
|
-
const input = {
|
|
437
|
-
TEST_KEY: "test_value",
|
|
438
|
-
ANOTHER_KEY: "123",
|
|
439
|
-
};
|
|
440
|
-
const originalInput = { ...input };
|
|
441
|
-
|
|
442
|
-
parseEnvVars(input);
|
|
443
|
-
|
|
444
|
-
expect(input).toEqual(originalInput);
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
test("should return a new object", () => {
|
|
448
|
-
const input = { TEST: "value" };
|
|
449
|
-
const result = parseEnvVars(input);
|
|
450
|
-
|
|
451
|
-
expect(result).not.toBe(input);
|
|
452
|
-
expect(typeof result).toBe("object");
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
test("should handle consecutive calls consistently", () => {
|
|
456
|
-
const input = {
|
|
457
|
-
PORT: "3000",
|
|
458
|
-
DEBUG_MODE: "true",
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
const result1 = parseEnvVars(input);
|
|
462
|
-
const result2 = parseEnvVars(input);
|
|
463
|
-
|
|
464
|
-
expect(result1).toEqual(result2);
|
|
465
|
-
expect(result1).not.toBe(result2);
|
|
466
|
-
});
|
|
467
|
-
});
|
|
468
|
-
});
|