glasswork 0.1.0 → 0.2.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/README.md +22 -43
- package/dist/config/config-service.d.ts +101 -0
- package/dist/config/config-service.d.ts.map +1 -0
- package/dist/config/config-service.js +164 -0
- package/dist/config/config-service.js.map +1 -0
- package/dist/config/helpers.d.ts +101 -0
- package/dist/config/helpers.d.ts.map +1 -0
- package/dist/config/helpers.js +122 -0
- package/dist/config/helpers.js.map +1 -0
- package/dist/config/index.d.ts +39 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +41 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/providers.d.ts +163 -0
- package/dist/config/providers.d.ts.map +1 -0
- package/dist/config/providers.js +188 -0
- package/dist/config/providers.js.map +1 -0
- package/dist/config/types.d.ts +98 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +7 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/bootstrap.js +9 -3
- package/dist/core/bootstrap.js.map +1 -1
- package/dist/core/types.d.ts +2 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/http/error-response.dto.d.ts +76 -0
- package/dist/http/error-response.dto.d.ts.map +1 -0
- package/dist/http/error-response.dto.js +67 -0
- package/dist/http/error-response.dto.js.map +1 -0
- package/dist/http/errors.d.ts +39 -0
- package/dist/http/errors.d.ts.map +1 -1
- package/dist/http/errors.js +78 -0
- package/dist/http/errors.js.map +1 -1
- package/dist/http/route-helpers.d.ts +13 -6
- package/dist/http/route-helpers.d.ts.map +1 -1
- package/dist/http/route-helpers.js +29 -1
- package/dist/http/route-helpers.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +2 -16
- package/dist/middleware/rate-limit.js.map +1 -1
- package/dist/openapi/defaults.d.ts.map +1 -1
- package/dist/openapi/defaults.js +6 -38
- package/dist/openapi/defaults.js.map +1 -1
- package/dist/openapi/openapi.d.ts +1 -1
- package/dist/openapi/openapi.d.ts.map +1 -1
- package/dist/openapi/openapi.js +21 -3
- package/dist/openapi/openapi.js.map +1 -1
- package/package.json +25 -2
- package/dist/bootstrap.d.ts +0 -55
- package/dist/bootstrap.d.ts.map +0 -1
- package/dist/bootstrap.js +0 -359
- package/dist/bootstrap.js.map +0 -1
- package/dist/environment.d.ts +0 -21
- package/dist/environment.d.ts.map +0 -1
- package/dist/environment.js +0 -29
- package/dist/environment.js.map +0 -1
- package/dist/error-handler.d.ts +0 -33
- package/dist/error-handler.d.ts.map +0 -1
- package/dist/error-handler.js +0 -53
- package/dist/error-handler.js.map +0 -1
- package/dist/errors.d.ts +0 -36
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -65
- package/dist/errors.js.map +0 -1
- package/dist/get-client-ip.d.ts +0 -24
- package/dist/get-client-ip.d.ts.map +0 -1
- package/dist/get-client-ip.js +0 -49
- package/dist/get-client-ip.js.map +0 -1
- package/dist/logger.d.ts +0 -37
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -52
- package/dist/logger.js.map +0 -1
- package/dist/module.d.ts +0 -21
- package/dist/module.d.ts.map +0 -1
- package/dist/module.js +0 -85
- package/dist/module.js.map +0 -1
- package/dist/omit.d.ts +0 -20
- package/dist/omit.d.ts.map +0 -1
- package/dist/omit.js +0 -28
- package/dist/omit.js.map +0 -1
- package/dist/openapi-defaults.d.ts +0 -11
- package/dist/openapi-defaults.d.ts.map +0 -1
- package/dist/openapi-defaults.js +0 -127
- package/dist/openapi-defaults.js.map +0 -1
- package/dist/openapi-hooks.d.ts +0 -14
- package/dist/openapi-hooks.d.ts.map +0 -1
- package/dist/openapi-hooks.js +0 -80
- package/dist/openapi-hooks.js.map +0 -1
- package/dist/openapi.d.ts +0 -24
- package/dist/openapi.d.ts.map +0 -1
- package/dist/openapi.js +0 -106
- package/dist/openapi.js.map +0 -1
- package/dist/pagination.d.ts +0 -48
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js +0 -43
- package/dist/pagination.js.map +0 -1
- package/dist/pick.d.ts +0 -20
- package/dist/pick.d.ts.map +0 -1
- package/dist/pick.js +0 -28
- package/dist/pick.js.map +0 -1
- package/dist/rate-limit.d.ts +0 -7
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js +0 -180
- package/dist/rate-limit.js.map +0 -1
- package/dist/route-helpers.d.ts +0 -172
- package/dist/route-helpers.d.ts.map +0 -1
- package/dist/route-helpers.js +0 -249
- package/dist/route-helpers.js.map +0 -1
- package/dist/serialize-dates.d.ts +0 -27
- package/dist/serialize-dates.d.ts.map +0 -1
- package/dist/serialize-dates.js +0 -39
- package/dist/serialize-dates.js.map +0 -1
- package/dist/testing.d.ts +0 -87
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -94
- package/dist/testing.js.map +0 -1
- package/dist/types.d.ts +0 -273
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -9
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -31
- package/dist/utils.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,51 +4,32 @@
|
|
|
4
4
|
[](https://www.typescriptlang.org/)
|
|
5
5
|
[](https://github.com/yourusername/glasswork)
|
|
6
6
|
|
|
7
|
-
**A transparent,
|
|
7
|
+
**A transparent, serverless-optimized web framework for building OpenAPI-compliant REST APIs.**
|
|
8
8
|
|
|
9
|
-
Built on Hono, Awilix, and
|
|
9
|
+
Built on Hono, Awilix, and Valibot, Glasswork provides automatic OpenAPI spec generation, type-safe routing, dependency injection, and clean modular architecture.
|
|
10
10
|
|
|
11
11
|
## Why Glasswork?
|
|
12
12
|
|
|
13
|
-
**
|
|
13
|
+
**NestJS-style architecture with serverless-first design.**
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Glasswork combines the best patterns from NestJS (modules, DI, OpenAPI) with the performance characteristics needed for serverless:
|
|
16
16
|
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
17
|
+
- **Small & Fast** - tiny bundles (~1MB incl Prisma), no decorators, no reflection
|
|
18
|
+
- **Clean Architecture** - Module system with dependency injection (Awilix)
|
|
19
|
+
- **OpenAPI Built-in** - Automatic spec generation from Valibot schemas
|
|
20
|
+
- **Framework-Agnostic Services** - Test business logic without HTTP mocking
|
|
21
|
+
- **Transparent** - Direct access to Hono, no heavy abstractions
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
NestJS is excellent for professional projects, but on Lambda it has issues:
|
|
26
|
-
|
|
27
|
-
- Large bundle size = slower cold starts
|
|
28
|
-
- Decorators and reflection = harder to tree-shake
|
|
29
|
-
- Heavy abstractions = less control over the HTTP layer
|
|
30
|
-
- Requires containers for full features (not Lambda-friendly)
|
|
31
|
-
|
|
32
|
-
### The Glasswork Solution
|
|
33
|
-
|
|
34
|
-
Keep what's great about NestJS (modules, DI, OpenAPI), but:
|
|
35
|
-
|
|
36
|
-
- ~1MB bundles with fast cold starts
|
|
37
|
-
- No decorators, no reflection - just TypeScript
|
|
38
|
-
- Direct access to Hono, Awilix, Prisma (no framework lock-in)
|
|
39
|
-
- Built specifically for Lambda deployment
|
|
40
|
-
- Still maintain clean architecture and testability
|
|
41
|
-
|
|
42
|
-
**Perfect for:** Hobby projects, MVPs, side APIs, serverless-first applications
|
|
23
|
+
**Perfect for:** Lambda-first projects, MVPs, hobby APIs, or anywhere you want NestJS patterns without the bundle size.
|
|
43
24
|
|
|
44
25
|
## Features
|
|
45
26
|
|
|
46
27
|
- **OpenAPI-First**: Automatic spec generation from Valibot schemas - write code, get docs
|
|
47
28
|
- **Type-Safe Routes**: Request/response validation with full TypeScript inference
|
|
48
29
|
- **Module System**: Organize your API into logical, testable modules
|
|
49
|
-
- **Dependency Injection**: Powered by Awilix with
|
|
30
|
+
- **Dependency Injection**: Powered by Awilix with serverless-compatible PROXY mode
|
|
50
31
|
- **Framework-Agnostic Services**: Test business logic without any HTTP mocking
|
|
51
|
-
- **
|
|
32
|
+
- **Production-Ready**: Small bundles, fast cold starts, works anywhere Node.js runs
|
|
52
33
|
|
|
53
34
|
## Installation
|
|
54
35
|
|
|
@@ -152,26 +133,24 @@ export default app; // Ready for Lambda or local server
|
|
|
152
133
|
|
|
153
134
|
## When to Use Glasswork
|
|
154
135
|
|
|
155
|
-
**Choose Glasswork
|
|
136
|
+
**Choose Glasswork when you want:**
|
|
156
137
|
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
- Prefer transparency over heavy abstractions
|
|
138
|
+
- NestJS-style architecture with smaller bundles
|
|
139
|
+
- Automatic OpenAPI generation without decorators
|
|
140
|
+
- Serverless-first design (Lambda, Cloudflare Workers, etc.)
|
|
141
|
+
- Clean, testable code with dependency injection
|
|
162
142
|
|
|
163
|
-
**Consider alternatives
|
|
143
|
+
**Consider alternatives:**
|
|
164
144
|
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
145
|
+
- **GraphQL?** Use Apollo Server or Pothos
|
|
146
|
+
- **Container deployment?** NestJS is excellent for this
|
|
147
|
+
- **Full-stack app?** Use Next.js or Remix
|
|
148
|
+
- **Minimal framework?** Use Hono directly
|
|
169
149
|
|
|
170
150
|
## Requirements
|
|
171
151
|
|
|
172
152
|
- Node.js 18+
|
|
173
153
|
- TypeScript 5+
|
|
174
|
-
- (Optional) AWS Lambda for serverless deployment
|
|
175
154
|
|
|
176
155
|
## Contributing
|
|
177
156
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core configuration service implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module config/config-service
|
|
5
|
+
*/
|
|
6
|
+
import { type BaseIssue, type BaseSchema } from 'valibot';
|
|
7
|
+
import type { Config, ConfigOptions } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Exception thrown when config validation fails.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ConfigValidationException extends Error {
|
|
12
|
+
readonly issues: unknown[];
|
|
13
|
+
constructor(message: string, issues: unknown[]);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates a configuration service that loads from multiple providers
|
|
17
|
+
* and validates with Valibot.
|
|
18
|
+
*
|
|
19
|
+
* Providers are executed in order and their results are merged together,
|
|
20
|
+
* with later providers taking precedence. The merged config is then
|
|
21
|
+
* validated against the provided Valibot schema.
|
|
22
|
+
*
|
|
23
|
+
* @template TSchema - Valibot schema for validation
|
|
24
|
+
* @param options - Configuration options
|
|
25
|
+
* @returns Promise resolving to validated Config
|
|
26
|
+
*
|
|
27
|
+
* @throws {ConfigValidationException} If validation fails
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { object, string, number } from 'valibot';
|
|
32
|
+
*
|
|
33
|
+
* const schema = object({
|
|
34
|
+
* nodeEnv: string(),
|
|
35
|
+
* port: number(),
|
|
36
|
+
* databaseUrl: string(),
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* const config = await createConfig({
|
|
40
|
+
* schema,
|
|
41
|
+
* providers: [
|
|
42
|
+
* dotenvProvider({ path: '.env' }),
|
|
43
|
+
* envProvider(), // env vars override .env
|
|
44
|
+
* ],
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Fully typed access
|
|
48
|
+
* const port = config.get('port'); // number
|
|
49
|
+
* const dbUrl = config.get('databaseUrl'); // string
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* // With key transformation (SNAKE_CASE -> camelCase)
|
|
55
|
+
* const config = await createConfig({
|
|
56
|
+
* schema,
|
|
57
|
+
* providers: [envProvider()],
|
|
58
|
+
* transformKey: (key) =>
|
|
59
|
+
* key.toLowerCase().replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* // Register as DI service
|
|
66
|
+
* export const AppModule = defineModule({
|
|
67
|
+
* name: 'app',
|
|
68
|
+
* providers: [
|
|
69
|
+
* {
|
|
70
|
+
* name: 'config',
|
|
71
|
+
* useFactory: async () =>
|
|
72
|
+
* await createConfig({
|
|
73
|
+
* schema: appConfigSchema,
|
|
74
|
+
* providers: [dotenvProvider(), envProvider()],
|
|
75
|
+
* }),
|
|
76
|
+
* lifetime: 'SINGLETON',
|
|
77
|
+
* },
|
|
78
|
+
* ],
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function createConfig<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>>(options: ConfigOptions<TSchema>): Promise<Config<TSchema>>;
|
|
83
|
+
/**
|
|
84
|
+
* Synchronously validates config that's already loaded.
|
|
85
|
+
* Useful when you have config in memory and just need validation.
|
|
86
|
+
*
|
|
87
|
+
* @template TSchema - Valibot schema for validation
|
|
88
|
+
* @param schema - Valibot schema
|
|
89
|
+
* @param data - Raw config data to validate
|
|
90
|
+
* @returns Validated Config
|
|
91
|
+
*
|
|
92
|
+
* @throws {ConfigValidationException} If validation fails
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const rawConfig = { nodeEnv: 'production', port: 3000 };
|
|
97
|
+
* const config = validateConfig(schema, rawConfig);
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function validateConfig<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>>(schema: TSchema, data: Record<string, unknown>): Config<TSchema>;
|
|
101
|
+
//# sourceMappingURL=config-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.d.ts","sourceRoot":"","sources":["../../src/config/config-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAsC,MAAM,SAAS,CAAC;AAG9F,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAExD;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;aAGhC,MAAM,EAAE,OAAO,EAAE;gBADjC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,OAAO,EAAE;CAKpC;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAsB,YAAY,CAChC,OAAO,SAAS,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,EAChE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAyC3D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,OAAO,SAAS,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,EAC7F,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAAC,OAAO,CAAC,CAUjB"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core configuration service implementation.
|
|
3
|
+
*
|
|
4
|
+
* @module config/config-service
|
|
5
|
+
*/
|
|
6
|
+
import { parse, safeParse } from 'valibot';
|
|
7
|
+
import { deepMerge } from '../utils/deep-merge.js';
|
|
8
|
+
import { envProvider } from './providers.js';
|
|
9
|
+
/**
|
|
10
|
+
* Exception thrown when config validation fails.
|
|
11
|
+
*/
|
|
12
|
+
export class ConfigValidationException extends Error {
|
|
13
|
+
issues;
|
|
14
|
+
constructor(message, issues) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.issues = issues;
|
|
17
|
+
this.name = 'ConfigValidationException';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Implementation of the Config interface.
|
|
22
|
+
*/
|
|
23
|
+
class ConfigImpl {
|
|
24
|
+
data;
|
|
25
|
+
constructor(data) {
|
|
26
|
+
this.data = data;
|
|
27
|
+
}
|
|
28
|
+
get(key) {
|
|
29
|
+
return this.data[key];
|
|
30
|
+
}
|
|
31
|
+
getOrDefault(key, defaultValue) {
|
|
32
|
+
const value = this.data[key];
|
|
33
|
+
return value !== undefined ? value : defaultValue;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Creates a configuration service that loads from multiple providers
|
|
38
|
+
* and validates with Valibot.
|
|
39
|
+
*
|
|
40
|
+
* Providers are executed in order and their results are merged together,
|
|
41
|
+
* with later providers taking precedence. The merged config is then
|
|
42
|
+
* validated against the provided Valibot schema.
|
|
43
|
+
*
|
|
44
|
+
* @template TSchema - Valibot schema for validation
|
|
45
|
+
* @param options - Configuration options
|
|
46
|
+
* @returns Promise resolving to validated Config
|
|
47
|
+
*
|
|
48
|
+
* @throws {ConfigValidationException} If validation fails
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { object, string, number } from 'valibot';
|
|
53
|
+
*
|
|
54
|
+
* const schema = object({
|
|
55
|
+
* nodeEnv: string(),
|
|
56
|
+
* port: number(),
|
|
57
|
+
* databaseUrl: string(),
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* const config = await createConfig({
|
|
61
|
+
* schema,
|
|
62
|
+
* providers: [
|
|
63
|
+
* dotenvProvider({ path: '.env' }),
|
|
64
|
+
* envProvider(), // env vars override .env
|
|
65
|
+
* ],
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* // Fully typed access
|
|
69
|
+
* const port = config.get('port'); // number
|
|
70
|
+
* const dbUrl = config.get('databaseUrl'); // string
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* // With key transformation (SNAKE_CASE -> camelCase)
|
|
76
|
+
* const config = await createConfig({
|
|
77
|
+
* schema,
|
|
78
|
+
* providers: [envProvider()],
|
|
79
|
+
* transformKey: (key) =>
|
|
80
|
+
* key.toLowerCase().replace(/_([a-z])/g, (_, c) => c.toUpperCase()),
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* // Register as DI service
|
|
87
|
+
* export const AppModule = defineModule({
|
|
88
|
+
* name: 'app',
|
|
89
|
+
* providers: [
|
|
90
|
+
* {
|
|
91
|
+
* name: 'config',
|
|
92
|
+
* useFactory: async () =>
|
|
93
|
+
* await createConfig({
|
|
94
|
+
* schema: appConfigSchema,
|
|
95
|
+
* providers: [dotenvProvider(), envProvider()],
|
|
96
|
+
* }),
|
|
97
|
+
* lifetime: 'SINGLETON',
|
|
98
|
+
* },
|
|
99
|
+
* ],
|
|
100
|
+
* });
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export async function createConfig(options) {
|
|
104
|
+
const { schema, providers = [envProvider()], transformKey, allowUnknownKeys = true } = options;
|
|
105
|
+
// Load config from all providers
|
|
106
|
+
let rawConfig = {};
|
|
107
|
+
for (const provider of providers) {
|
|
108
|
+
const providerConfig = await provider();
|
|
109
|
+
rawConfig = deepMerge(rawConfig, providerConfig);
|
|
110
|
+
}
|
|
111
|
+
// Transform keys if requested
|
|
112
|
+
if (transformKey) {
|
|
113
|
+
const transformed = {};
|
|
114
|
+
for (const [key, value] of Object.entries(rawConfig)) {
|
|
115
|
+
transformed[transformKey(key)] = value;
|
|
116
|
+
}
|
|
117
|
+
rawConfig = transformed;
|
|
118
|
+
}
|
|
119
|
+
// Filter unknown keys if requested
|
|
120
|
+
if (!allowUnknownKeys && typeof schema === 'object' && 'entries' in schema) {
|
|
121
|
+
const entries = schema.entries;
|
|
122
|
+
const schemaKeys = new Set(Object.keys(entries));
|
|
123
|
+
const filtered = {};
|
|
124
|
+
for (const [key, value] of Object.entries(rawConfig)) {
|
|
125
|
+
if (schemaKeys.has(key)) {
|
|
126
|
+
filtered[key] = value;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
rawConfig = filtered;
|
|
130
|
+
}
|
|
131
|
+
// Validate with Valibot
|
|
132
|
+
const result = safeParse(schema, rawConfig);
|
|
133
|
+
if (!result.success) {
|
|
134
|
+
throw new ConfigValidationException('Configuration validation failed', result.issues);
|
|
135
|
+
}
|
|
136
|
+
return new ConfigImpl(result.output);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Synchronously validates config that's already loaded.
|
|
140
|
+
* Useful when you have config in memory and just need validation.
|
|
141
|
+
*
|
|
142
|
+
* @template TSchema - Valibot schema for validation
|
|
143
|
+
* @param schema - Valibot schema
|
|
144
|
+
* @param data - Raw config data to validate
|
|
145
|
+
* @returns Validated Config
|
|
146
|
+
*
|
|
147
|
+
* @throws {ConfigValidationException} If validation fails
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const rawConfig = { nodeEnv: 'production', port: 3000 };
|
|
152
|
+
* const config = validateConfig(schema, rawConfig);
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export function validateConfig(schema, data) {
|
|
156
|
+
try {
|
|
157
|
+
const validated = parse(schema, data);
|
|
158
|
+
return new ConfigImpl(validated);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
throw new ConfigValidationException('Configuration validation failed', error.issues || []);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=config-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-service.js","sourceRoot":"","sources":["../../src/config/config-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for working with configuration.
|
|
3
|
+
*
|
|
4
|
+
* @module config/helpers
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Transforms a SNAKE_CASE or kebab-case string to camelCase.
|
|
8
|
+
*
|
|
9
|
+
* Useful as a transformKey function when environment variables
|
|
10
|
+
* use UPPER_SNAKE_CASE but your schema uses camelCase.
|
|
11
|
+
*
|
|
12
|
+
* @param key - The key to transform
|
|
13
|
+
* @returns Transformed key in camelCase
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* toCamelCase('DATABASE_URL') // 'databaseUrl'
|
|
18
|
+
* toCamelCase('api-key') // 'apiKey'
|
|
19
|
+
* toCamelCase('NODE_ENV') // 'nodeEnv'
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Use with createConfig
|
|
25
|
+
* const config = await createConfig({
|
|
26
|
+
* schema,
|
|
27
|
+
* transformKey: toCamelCase,
|
|
28
|
+
* providers: [envProvider()],
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function toCamelCase(key: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Transforms a string to UPPER_SNAKE_CASE.
|
|
35
|
+
*
|
|
36
|
+
* Useful for reverse transformation or normalization.
|
|
37
|
+
*
|
|
38
|
+
* @param key - The key to transform
|
|
39
|
+
* @returns Transformed key in UPPER_SNAKE_CASE
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* toSnakeCase('databaseUrl') // 'DATABASE_URL'
|
|
44
|
+
* toSnakeCase('apiKey') // 'API_KEY'
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function toSnakeCase(key: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Parses a string value to boolean.
|
|
50
|
+
*
|
|
51
|
+
* Useful for environment variables that come as strings.
|
|
52
|
+
* Recognizes: 'true', '1', 'yes', 'on' as true (case-insensitive).
|
|
53
|
+
*
|
|
54
|
+
* @param value - String value to parse
|
|
55
|
+
* @returns Boolean value
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* parseBoolean('true') // true
|
|
60
|
+
* parseBoolean('1') // true
|
|
61
|
+
* parseBoolean('yes') // true
|
|
62
|
+
* parseBoolean('on') // true
|
|
63
|
+
* parseBoolean('false') // false
|
|
64
|
+
* parseBoolean('0') // false
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function parseBoolean(value: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Parses a comma-separated string into an array.
|
|
70
|
+
*
|
|
71
|
+
* Useful for environment variables that contain lists.
|
|
72
|
+
*
|
|
73
|
+
* @param value - String value to parse
|
|
74
|
+
* @param trim - Whether to trim whitespace from items
|
|
75
|
+
* @returns Array of strings
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* parseArray('a,b,c') // ['a', 'b', 'c']
|
|
80
|
+
* parseArray('a, b, c', true) // ['a', 'b', 'c']
|
|
81
|
+
* parseArray('') // []
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function parseArray(value: string, trim?: boolean): string[];
|
|
85
|
+
/**
|
|
86
|
+
* Parses a JSON string safely.
|
|
87
|
+
*
|
|
88
|
+
* Useful for environment variables that contain JSON objects.
|
|
89
|
+
* Returns undefined if parsing fails instead of throwing.
|
|
90
|
+
*
|
|
91
|
+
* @param value - JSON string to parse
|
|
92
|
+
* @returns Parsed object or undefined
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* parseJson('{"key": "value"}') // { key: 'value' }
|
|
97
|
+
* parseJson('invalid') // undefined
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function parseJson(value: string): unknown;
|
|
101
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/config/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,UAAO,GAAG,MAAM,EAAE,CAG/D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAMhD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper functions for working with configuration.
|
|
3
|
+
*
|
|
4
|
+
* @module config/helpers
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Transforms a SNAKE_CASE or kebab-case string to camelCase.
|
|
8
|
+
*
|
|
9
|
+
* Useful as a transformKey function when environment variables
|
|
10
|
+
* use UPPER_SNAKE_CASE but your schema uses camelCase.
|
|
11
|
+
*
|
|
12
|
+
* @param key - The key to transform
|
|
13
|
+
* @returns Transformed key in camelCase
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* toCamelCase('DATABASE_URL') // 'databaseUrl'
|
|
18
|
+
* toCamelCase('api-key') // 'apiKey'
|
|
19
|
+
* toCamelCase('NODE_ENV') // 'nodeEnv'
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Use with createConfig
|
|
25
|
+
* const config = await createConfig({
|
|
26
|
+
* schema,
|
|
27
|
+
* transformKey: toCamelCase,
|
|
28
|
+
* providers: [envProvider()],
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function toCamelCase(key) {
|
|
33
|
+
return key.toLowerCase().replace(/[_-]([a-z0-9])/g, (_, char) => char.toUpperCase());
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Transforms a string to UPPER_SNAKE_CASE.
|
|
37
|
+
*
|
|
38
|
+
* Useful for reverse transformation or normalization.
|
|
39
|
+
*
|
|
40
|
+
* @param key - The key to transform
|
|
41
|
+
* @returns Transformed key in UPPER_SNAKE_CASE
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* toSnakeCase('databaseUrl') // 'DATABASE_URL'
|
|
46
|
+
* toSnakeCase('apiKey') // 'API_KEY'
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function toSnakeCase(key) {
|
|
50
|
+
return key
|
|
51
|
+
.replace(/([A-Z])/g, '_$1')
|
|
52
|
+
.replace(/^_/, '')
|
|
53
|
+
.toUpperCase();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parses a string value to boolean.
|
|
57
|
+
*
|
|
58
|
+
* Useful for environment variables that come as strings.
|
|
59
|
+
* Recognizes: 'true', '1', 'yes', 'on' as true (case-insensitive).
|
|
60
|
+
*
|
|
61
|
+
* @param value - String value to parse
|
|
62
|
+
* @returns Boolean value
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* parseBoolean('true') // true
|
|
67
|
+
* parseBoolean('1') // true
|
|
68
|
+
* parseBoolean('yes') // true
|
|
69
|
+
* parseBoolean('on') // true
|
|
70
|
+
* parseBoolean('false') // false
|
|
71
|
+
* parseBoolean('0') // false
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function parseBoolean(value) {
|
|
75
|
+
const normalized = value.toLowerCase().trim();
|
|
76
|
+
return ['true', '1', 'yes', 'on'].includes(normalized);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parses a comma-separated string into an array.
|
|
80
|
+
*
|
|
81
|
+
* Useful for environment variables that contain lists.
|
|
82
|
+
*
|
|
83
|
+
* @param value - String value to parse
|
|
84
|
+
* @param trim - Whether to trim whitespace from items
|
|
85
|
+
* @returns Array of strings
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* parseArray('a,b,c') // ['a', 'b', 'c']
|
|
90
|
+
* parseArray('a, b, c', true) // ['a', 'b', 'c']
|
|
91
|
+
* parseArray('') // []
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export function parseArray(value, trim = true) {
|
|
95
|
+
if (!value)
|
|
96
|
+
return [];
|
|
97
|
+
return value.split(',').map((item) => (trim ? item.trim() : item));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parses a JSON string safely.
|
|
101
|
+
*
|
|
102
|
+
* Useful for environment variables that contain JSON objects.
|
|
103
|
+
* Returns undefined if parsing fails instead of throwing.
|
|
104
|
+
*
|
|
105
|
+
* @param value - JSON string to parse
|
|
106
|
+
* @returns Parsed object or undefined
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* parseJson('{"key": "value"}') // { key: 'value' }
|
|
111
|
+
* parseJson('invalid') // undefined
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export function parseJson(value) {
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(value);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/config/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACvF,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;SAC1B,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACjB,WAAW,EAAE,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC9C,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAI,GAAG,IAAI;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration management for Glasswork applications.
|
|
3
|
+
*
|
|
4
|
+
* Provides a flexible, type-safe way to load and validate configuration
|
|
5
|
+
* from multiple sources (environment variables, .env files, AWS SSM, etc.)
|
|
6
|
+
* using Valibot schemas.
|
|
7
|
+
*
|
|
8
|
+
* @module config
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { object, string, number } from 'valibot';
|
|
13
|
+
* import { createConfig, dotenvProvider, envProvider } from 'glasswork';
|
|
14
|
+
*
|
|
15
|
+
* // Define schema
|
|
16
|
+
* const configSchema = object({
|
|
17
|
+
* nodeEnv: string(),
|
|
18
|
+
* port: number(),
|
|
19
|
+
* databaseUrl: string(),
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Create config with multiple providers
|
|
23
|
+
* const config = await createConfig({
|
|
24
|
+
* schema: configSchema,
|
|
25
|
+
* providers: [
|
|
26
|
+
* dotenvProvider({ path: '.env' }),
|
|
27
|
+
* envProvider(), // Env vars override .env
|
|
28
|
+
* ],
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Type-safe access
|
|
32
|
+
* const port = config.get('port'); // number
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export { ConfigValidationException, createConfig, validateConfig } from './config-service.js';
|
|
36
|
+
export { parseArray, parseBoolean, parseJson, toCamelCase, toSnakeCase, } from './helpers.js';
|
|
37
|
+
export { type DotenvProviderOptions, dotenvProvider, type EnvProviderOptions, envProvider, objectProvider, type SsmProviderOptions, ssmProvider, } from './providers.js';
|
|
38
|
+
export type { Config, ConfigOptions, ConfigProvider } from './types.js';
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE9F,OAAO,EACL,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,KAAK,qBAAqB,EAC1B,cAAc,EACd,KAAK,kBAAkB,EACvB,WAAW,EACX,cAAc,EACd,KAAK,kBAAkB,EACvB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|