@riktajs/core 0.3.1 → 0.4.0-beta.2

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.
Files changed (45) hide show
  1. package/README.md +1 -0
  2. package/dist/core/config/abstract-config-provider.d.ts +162 -0
  3. package/dist/core/config/abstract-config-provider.d.ts.map +1 -0
  4. package/dist/core/config/abstract-config-provider.js +215 -0
  5. package/dist/core/config/abstract-config-provider.js.map +1 -0
  6. package/dist/core/config/index.d.ts +2 -0
  7. package/dist/core/config/index.d.ts.map +1 -0
  8. package/dist/core/config/index.js +18 -0
  9. package/dist/core/config/index.js.map +1 -0
  10. package/dist/core/constants.d.ts +34 -0
  11. package/dist/core/constants.d.ts.map +1 -1
  12. package/dist/core/constants.js +38 -1
  13. package/dist/core/constants.js.map +1 -1
  14. package/dist/core/decorators/config-property.decorator.d.ts +129 -0
  15. package/dist/core/decorators/config-property.decorator.d.ts.map +1 -0
  16. package/dist/core/decorators/config-property.decorator.js +205 -0
  17. package/dist/core/decorators/config-property.decorator.js.map +1 -0
  18. package/dist/core/decorators/index.d.ts +2 -0
  19. package/dist/core/decorators/index.d.ts.map +1 -1
  20. package/dist/core/decorators/index.js +2 -0
  21. package/dist/core/decorators/index.js.map +1 -1
  22. package/dist/core/decorators/provider-config.decorator.d.ts +107 -0
  23. package/dist/core/decorators/provider-config.decorator.d.ts.map +1 -0
  24. package/dist/core/decorators/provider-config.decorator.js +156 -0
  25. package/dist/core/decorators/provider-config.decorator.js.map +1 -0
  26. package/dist/core/discovery.d.ts.map +1 -1
  27. package/dist/core/discovery.js +2 -0
  28. package/dist/core/discovery.js.map +1 -1
  29. package/dist/core/exceptions/config.exceptions.d.ts +21 -0
  30. package/dist/core/exceptions/config.exceptions.d.ts.map +1 -0
  31. package/dist/core/exceptions/config.exceptions.js +52 -0
  32. package/dist/core/exceptions/config.exceptions.js.map +1 -0
  33. package/dist/core/exceptions/index.d.ts +1 -0
  34. package/dist/core/exceptions/index.d.ts.map +1 -1
  35. package/dist/core/exceptions/index.js +6 -1
  36. package/dist/core/exceptions/index.js.map +1 -1
  37. package/dist/core/index.d.ts +1 -0
  38. package/dist/core/index.d.ts.map +1 -1
  39. package/dist/core/index.js +1 -0
  40. package/dist/core/index.js.map +1 -1
  41. package/dist/core/registry.d.ts +82 -0
  42. package/dist/core/registry.d.ts.map +1 -1
  43. package/dist/core/registry.js +119 -1
  44. package/dist/core/registry.js.map +1 -1
  45. package/package.json +2 -1
package/README.md CHANGED
@@ -97,6 +97,7 @@ Everything you need to build production-ready APIs.
97
97
  |-------|-------------|
98
98
  | [**Architecture**](./docs/guide/architecture.md) | How Rikta's auto-discovery works under the hood. |
99
99
  | [**Dependency Injection**](./docs/guide/dependency-injection.md) | Using `@Autowired`, tokens, and scopes. |
100
+ | [**Configuration**](./docs/guide/configuration.md) | Type-safe configuration with .env and Zod validation. |
100
101
  | [**Routing**](./docs/guide/routing.md) | Controllers, methods, and parameter handling. |
101
102
  | [**Validation**](./docs/guide/validation.md) | **New!** Type-safe validation with Zod. |
102
103
  | [**Lifecycle**](./docs/guide/lifecycle.md) | Hooks (`OnProviderInit`) and the Event Bus. |
@@ -0,0 +1,162 @@
1
+ import { z, ZodSchema } from 'zod';
2
+ /**
3
+ * Exception thrown when config validation fails
4
+ */
5
+ export declare class ConfigValidationException extends Error {
6
+ readonly errors: z.ZodError;
7
+ constructor(errors: z.ZodError, providerName: string);
8
+ }
9
+ /**
10
+ * Abstract base class for configuration providers
11
+ *
12
+ * This class handles:
13
+ * - Loading .env files (base + environment-specific)
14
+ * - Validating environment variables against a Zod schema
15
+ * - Populating decorated properties with validated values
16
+ * - Caching validated configuration
17
+ *
18
+ * Child classes must:
19
+ * 1. Extend this class
20
+ * 2. Implement the abstract schema() method
21
+ * 3. Decorate properties with @ConfigProperty()
22
+ * 4. Call populate() in their constructor
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { AbstractConfigProvider, ProviderConfig, ConfigProperty } from '@riktajs/core';
27
+ * import { z } from 'zod';
28
+ *
29
+ * @ProviderConfig('APP_CONFIG')
30
+ * export class AppConfigProvider extends AbstractConfigProvider {
31
+ * schema() {
32
+ * return z.object({
33
+ * PORT: z.coerce.number().int().min(1).max(65535),
34
+ * HOST: z.string().default('localhost'),
35
+ * NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
36
+ * });
37
+ * }
38
+ *
39
+ * @ConfigProperty()
40
+ * port!: number;
41
+ *
42
+ * @ConfigProperty()
43
+ * host!: string;
44
+ *
45
+ * @ConfigProperty('NODE_ENV')
46
+ * environment!: 'development' | 'production' | 'test';
47
+ *
48
+ * constructor() {
49
+ * super();
50
+ * this.populate();
51
+ * }
52
+ * }
53
+ * ```
54
+ */
55
+ export declare abstract class AbstractConfigProvider {
56
+ /**
57
+ * Cache for validated configuration
58
+ * Frozen to prevent accidental mutations
59
+ */
60
+ private _cache?;
61
+ /**
62
+ * Flag to track if .env files have been loaded
63
+ */
64
+ private static envLoaded;
65
+ /**
66
+ * Define the Zod schema for this configuration
67
+ *
68
+ * @returns A Zod schema that validates the environment variables
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * schema() {
73
+ * return z.object({
74
+ * DATABASE_URL: z.string().url(),
75
+ * DB_POOL_SIZE: z.coerce.number().int().min(1).max(100).default(10),
76
+ * DB_TIMEOUT: z.coerce.number().int().default(30000),
77
+ * });
78
+ * }
79
+ * ```
80
+ */
81
+ protected abstract schema(): ZodSchema;
82
+ /**
83
+ * Constructor loads .env files if not already loaded
84
+ */
85
+ constructor();
86
+ /**
87
+ * Load .env files with environment-specific precedence
88
+ *
89
+ * Loading order (later files override earlier):
90
+ * 1. .env (base configuration)
91
+ * 2. .env.{NODE_ENV} (environment-specific)
92
+ *
93
+ * @private
94
+ */
95
+ private loadEnvFiles;
96
+ /**
97
+ * Validate and cache the configuration
98
+ *
99
+ * This method runs the Zod schema validation against process.env
100
+ * and caches the result. Subsequent calls return the cached value.
101
+ *
102
+ * @returns The validated and frozen configuration object
103
+ * @throws {ConfigValidationException} If validation fails
104
+ *
105
+ * @private
106
+ */
107
+ private validateAndCache;
108
+ /**
109
+ * Populate decorated properties with validated values
110
+ *
111
+ * This method reads the @ConfigProperty metadata and assigns
112
+ * the corresponding validated environment values to class properties.
113
+ *
114
+ * Must be called in the child class constructor after super().
115
+ *
116
+ * @throws {ConfigValidationException} If validation fails
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * constructor() {
121
+ * super();
122
+ * this.populate(); // Must call this!
123
+ * }
124
+ * ```
125
+ */
126
+ protected populate(): void;
127
+ /**
128
+ * Get the raw validated configuration object
129
+ *
130
+ * This is useful for accessing config values that aren't mapped
131
+ * to properties, or for passing the entire config to other services.
132
+ *
133
+ * @returns The validated and frozen configuration object
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const config = this.getConfig();
138
+ * console.log('All env vars:', config);
139
+ * ```
140
+ */
141
+ protected getConfig(): Readonly<Record<string, unknown>>;
142
+ /**
143
+ * Get a specific configuration value by key
144
+ *
145
+ * @param key - The environment variable name
146
+ * @returns The validated value, or undefined if not found
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * const port = this.get<number>('PORT');
151
+ * const apiKey = this.get<string>('API_KEY');
152
+ * ```
153
+ */
154
+ protected get<T = unknown>(key: string): T | undefined;
155
+ /**
156
+ * Reset the env loaded flag (for testing)
157
+ *
158
+ * @internal
159
+ */
160
+ static resetEnvLoaded(): void;
161
+ }
162
+ //# sourceMappingURL=abstract-config-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract-config-provider.d.ts","sourceRoot":"","sources":["../../../src/core/config/abstract-config-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAMnC;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;aAEhC,MAAM,EAAE,CAAC,CAAC,QAAQ;gBAAlB,MAAM,EAAE,CAAC,CAAC,QAAQ,EAClC,YAAY,EAAE,MAAM;CAYvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,8BAAsB,sBAAsB;IAC1C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,CAAoC;IAEnD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS,CAAS;IAEjC;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,QAAQ,CAAC,MAAM,IAAI,SAAS;IAEtC;;OAEG;;IAQH;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IAiBpB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,QAAQ,IAAI,IAAI;IAgB1B;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIxD;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAKtD;;;;OAIG;IACH,MAAM,CAAC,cAAc,IAAI,IAAI;CAG9B"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractConfigProvider = exports.ConfigValidationException = void 0;
4
+ const zod_1 = require("zod");
5
+ const dotenv_1 = require("dotenv");
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const config_property_decorator_1 = require("../decorators/config-property.decorator");
9
+ /**
10
+ * Exception thrown when config validation fails
11
+ */
12
+ class ConfigValidationException extends Error {
13
+ errors;
14
+ constructor(errors, providerName) {
15
+ const errorMessages = errors.errors
16
+ .map(err => ` - ${err.path.join('.')}: ${err.message}`)
17
+ .join('\n');
18
+ super(`Configuration validation failed for ${providerName}:\n${errorMessages}\n\n` +
19
+ `Please check your .env file and ensure all required variables are set correctly.`);
20
+ this.errors = errors;
21
+ this.name = 'ConfigValidationException';
22
+ }
23
+ }
24
+ exports.ConfigValidationException = ConfigValidationException;
25
+ /**
26
+ * Abstract base class for configuration providers
27
+ *
28
+ * This class handles:
29
+ * - Loading .env files (base + environment-specific)
30
+ * - Validating environment variables against a Zod schema
31
+ * - Populating decorated properties with validated values
32
+ * - Caching validated configuration
33
+ *
34
+ * Child classes must:
35
+ * 1. Extend this class
36
+ * 2. Implement the abstract schema() method
37
+ * 3. Decorate properties with @ConfigProperty()
38
+ * 4. Call populate() in their constructor
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * import { AbstractConfigProvider, ProviderConfig, ConfigProperty } from '@riktajs/core';
43
+ * import { z } from 'zod';
44
+ *
45
+ * @ProviderConfig('APP_CONFIG')
46
+ * export class AppConfigProvider extends AbstractConfigProvider {
47
+ * schema() {
48
+ * return z.object({
49
+ * PORT: z.coerce.number().int().min(1).max(65535),
50
+ * HOST: z.string().default('localhost'),
51
+ * NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
52
+ * });
53
+ * }
54
+ *
55
+ * @ConfigProperty()
56
+ * port!: number;
57
+ *
58
+ * @ConfigProperty()
59
+ * host!: string;
60
+ *
61
+ * @ConfigProperty('NODE_ENV')
62
+ * environment!: 'development' | 'production' | 'test';
63
+ *
64
+ * constructor() {
65
+ * super();
66
+ * this.populate();
67
+ * }
68
+ * }
69
+ * ```
70
+ */
71
+ class AbstractConfigProvider {
72
+ /**
73
+ * Cache for validated configuration
74
+ * Frozen to prevent accidental mutations
75
+ */
76
+ _cache;
77
+ /**
78
+ * Flag to track if .env files have been loaded
79
+ */
80
+ static envLoaded = false;
81
+ /**
82
+ * Constructor loads .env files if not already loaded
83
+ */
84
+ constructor() {
85
+ if (!AbstractConfigProvider.envLoaded) {
86
+ this.loadEnvFiles();
87
+ AbstractConfigProvider.envLoaded = true;
88
+ }
89
+ }
90
+ /**
91
+ * Load .env files with environment-specific precedence
92
+ *
93
+ * Loading order (later files override earlier):
94
+ * 1. .env (base configuration)
95
+ * 2. .env.{NODE_ENV} (environment-specific)
96
+ *
97
+ * @private
98
+ */
99
+ loadEnvFiles() {
100
+ const env = process.env.NODE_ENV || 'development';
101
+ const cwd = process.cwd();
102
+ // Load base .env file
103
+ const baseEnvPath = (0, path_1.resolve)(cwd, '.env');
104
+ if ((0, fs_1.existsSync)(baseEnvPath)) {
105
+ (0, dotenv_1.config)({ path: baseEnvPath, override: false });
106
+ }
107
+ // Load environment-specific .env file (overrides base)
108
+ const envSpecificPath = (0, path_1.resolve)(cwd, `.env.${env}`);
109
+ if ((0, fs_1.existsSync)(envSpecificPath)) {
110
+ (0, dotenv_1.config)({ path: envSpecificPath, override: true });
111
+ }
112
+ }
113
+ /**
114
+ * Validate and cache the configuration
115
+ *
116
+ * This method runs the Zod schema validation against process.env
117
+ * and caches the result. Subsequent calls return the cached value.
118
+ *
119
+ * @returns The validated and frozen configuration object
120
+ * @throws {ConfigValidationException} If validation fails
121
+ *
122
+ * @private
123
+ */
124
+ validateAndCache() {
125
+ if (this._cache) {
126
+ return this._cache;
127
+ }
128
+ try {
129
+ const schema = this.schema();
130
+ const validated = schema.parse(process.env);
131
+ // Freeze the cache to make it immutable (tip from plan)
132
+ this._cache = Object.freeze(validated);
133
+ return this._cache;
134
+ }
135
+ catch (error) {
136
+ if (error instanceof zod_1.z.ZodError) {
137
+ throw new ConfigValidationException(error, this.constructor.name);
138
+ }
139
+ throw error;
140
+ }
141
+ }
142
+ /**
143
+ * Populate decorated properties with validated values
144
+ *
145
+ * This method reads the @ConfigProperty metadata and assigns
146
+ * the corresponding validated environment values to class properties.
147
+ *
148
+ * Must be called in the child class constructor after super().
149
+ *
150
+ * @throws {ConfigValidationException} If validation fails
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * constructor() {
155
+ * super();
156
+ * this.populate(); // Must call this!
157
+ * }
158
+ * ```
159
+ */
160
+ populate() {
161
+ // Validate and get cached config
162
+ const config = this.validateAndCache();
163
+ // Get property mappings from metadata
164
+ const mappings = (0, config_property_decorator_1.getConfigPropertyMappings)(this.constructor);
165
+ // Assign values to properties
166
+ for (const mapping of mappings) {
167
+ const value = config[mapping.envKey];
168
+ // Use type assertion since we know the property exists
169
+ this[mapping.propertyKey] = value;
170
+ }
171
+ }
172
+ /**
173
+ * Get the raw validated configuration object
174
+ *
175
+ * This is useful for accessing config values that aren't mapped
176
+ * to properties, or for passing the entire config to other services.
177
+ *
178
+ * @returns The validated and frozen configuration object
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const config = this.getConfig();
183
+ * console.log('All env vars:', config);
184
+ * ```
185
+ */
186
+ getConfig() {
187
+ return this.validateAndCache();
188
+ }
189
+ /**
190
+ * Get a specific configuration value by key
191
+ *
192
+ * @param key - The environment variable name
193
+ * @returns The validated value, or undefined if not found
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const port = this.get<number>('PORT');
198
+ * const apiKey = this.get<string>('API_KEY');
199
+ * ```
200
+ */
201
+ get(key) {
202
+ const config = this.validateAndCache();
203
+ return config[key];
204
+ }
205
+ /**
206
+ * Reset the env loaded flag (for testing)
207
+ *
208
+ * @internal
209
+ */
210
+ static resetEnvLoaded() {
211
+ AbstractConfigProvider.envLoaded = false;
212
+ }
213
+ }
214
+ exports.AbstractConfigProvider = AbstractConfigProvider;
215
+ //# sourceMappingURL=abstract-config-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract-config-provider.js","sourceRoot":"","sources":["../../../src/core/config/abstract-config-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './abstract-config-provider';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./abstract-config-provider"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/config/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6DAA2C"}
@@ -50,6 +50,40 @@ export declare const AUTOWIRED_METADATA: unique symbol;
50
50
  * Key for storing @Provider() metadata
51
51
  */
52
52
  export declare const PROVIDER_METADATA: unique symbol;
53
+ /**
54
+ * Key for storing @ProviderConfig() metadata on config provider classes.
55
+ *
56
+ * This metadata stores the injection token that identifies the config provider,
57
+ * allowing the auto-discovery mechanism to register it with the DI container.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * @ProviderConfig('APP_CONFIG')
62
+ * class AppConfigProvider extends AbstractConfigProvider {
63
+ * // Token 'APP_CONFIG' is stored in metadata
64
+ * }
65
+ * ```
66
+ */
67
+ export declare const CONFIG_PROVIDER_METADATA: unique symbol;
68
+ /**
69
+ * Key for storing @ConfigProperty() metadata on config class properties.
70
+ *
71
+ * This metadata maps class properties to environment variable names,
72
+ * supporting both explicit mapping and automatic upper_snake_case conversion.
73
+ * Stored as an array of `{ propertyKey: string, envKey: string }` objects.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * class DatabaseConfig {
78
+ * @ConfigProperty('DB_HOST') // explicit mapping
79
+ * host: string;
80
+ *
81
+ * @ConfigProperty() // auto-mapped to 'DB_PORT'
82
+ * dbPort: number;
83
+ * }
84
+ * ```
85
+ */
86
+ export declare const CONFIG_PROPERTY_METADATA: unique symbol;
53
87
  /**
54
88
  * Parameter types for injection
55
89
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAE7D;;GAEG;AACH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,cAAc,eAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,qBAAqB,eAAkC,CAAC;AAErE;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAE3D;;GAEG;AACH,eAAO,MAAM,eAAe,eAA4B,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAgC,CAAC;AAEjE;;GAEG;AACH,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,eAA8B,CAAC;AAM7D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAE3E;;GAEG;AACH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;CAKjB,CAAC"}
@@ -3,7 +3,7 @@
3
3
  // Metadata Keys for Reflect API
4
4
  // ============================================================================
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DEFAULT_CONFIG = exports.ParamType = exports.PROVIDER_METADATA = exports.AUTOWIRED_METADATA = exports.ZOD_SCHEMA_METADATA = exports.INJECT_METADATA = exports.HEADERS_METADATA = exports.HTTP_CODE_METADATA = exports.MIDDLEWARE_METADATA = exports.INTERCEPTORS_METADATA = exports.GUARDS_METADATA = exports.PARAM_METADATA = exports.INJECTABLE_METADATA = exports.ROUTES_METADATA = exports.CONTROLLER_METADATA = void 0;
6
+ exports.DEFAULT_CONFIG = exports.ParamType = exports.CONFIG_PROPERTY_METADATA = exports.CONFIG_PROVIDER_METADATA = exports.PROVIDER_METADATA = exports.AUTOWIRED_METADATA = exports.ZOD_SCHEMA_METADATA = exports.INJECT_METADATA = exports.HEADERS_METADATA = exports.HTTP_CODE_METADATA = exports.MIDDLEWARE_METADATA = exports.INTERCEPTORS_METADATA = exports.GUARDS_METADATA = exports.PARAM_METADATA = exports.INJECTABLE_METADATA = exports.ROUTES_METADATA = exports.CONTROLLER_METADATA = void 0;
7
7
  /**
8
8
  * Key for storing controller metadata (prefix, routes)
9
9
  */
@@ -56,6 +56,43 @@ exports.AUTOWIRED_METADATA = Symbol('autowired:metadata');
56
56
  * Key for storing @Provider() metadata
57
57
  */
58
58
  exports.PROVIDER_METADATA = Symbol('provider:metadata');
59
+ // ============================================================================
60
+ // Configuration Metadata Keys
61
+ // ============================================================================
62
+ /**
63
+ * Key for storing @ProviderConfig() metadata on config provider classes.
64
+ *
65
+ * This metadata stores the injection token that identifies the config provider,
66
+ * allowing the auto-discovery mechanism to register it with the DI container.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * @ProviderConfig('APP_CONFIG')
71
+ * class AppConfigProvider extends AbstractConfigProvider {
72
+ * // Token 'APP_CONFIG' is stored in metadata
73
+ * }
74
+ * ```
75
+ */
76
+ exports.CONFIG_PROVIDER_METADATA = Symbol('config:provider:metadata');
77
+ /**
78
+ * Key for storing @ConfigProperty() metadata on config class properties.
79
+ *
80
+ * This metadata maps class properties to environment variable names,
81
+ * supporting both explicit mapping and automatic upper_snake_case conversion.
82
+ * Stored as an array of `{ propertyKey: string, envKey: string }` objects.
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * class DatabaseConfig {
87
+ * @ConfigProperty('DB_HOST') // explicit mapping
88
+ * host: string;
89
+ *
90
+ * @ConfigProperty() // auto-mapped to 'DB_PORT'
91
+ * dbPort: number;
92
+ * }
93
+ * ```
94
+ */
95
+ exports.CONFIG_PROPERTY_METADATA = Symbol('config:property:metadata');
59
96
  /**
60
97
  * Parameter types for injection
61
98
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;;;AAE/E;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAErE;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE7D;;GAEG;AACH,IAAY,SAQX;AARD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,4BAAe,CAAA;IACf,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,4BAAe,CAAA;IACf,gCAAmB,CAAA;AACrB,CAAC,EARW,SAAS,yBAAT,SAAS,QAQpB;AAED;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,EAAE;CACF,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;;;AAE/E;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,qBAAqB,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAErE;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D;;GAEG;AACU,QAAA,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAEzD;;GAEG;AACU,QAAA,mBAAmB,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAEjE;;GAEG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE/D;;GAEG;AACU,QAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAE7D,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E;;;;;;;;;;;;;GAaG;AACU,QAAA,wBAAwB,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAE3E;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,wBAAwB,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAE3E;;GAEG;AACH,IAAY,SAQX;AARD,WAAY,SAAS;IACnB,0BAAa,CAAA;IACb,4BAAe,CAAA;IACf,4BAAe,CAAA;IACf,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,4BAAe,CAAA;IACf,gCAAmB,CAAA;AACrB,CAAC,EARW,SAAS,yBAAT,SAAS,QAQpB;AAED;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,EAAE;CACF,CAAC"}
@@ -0,0 +1,129 @@
1
+ import 'reflect-metadata';
2
+ /**
3
+ * Metadata for a single config property mapping
4
+ */
5
+ export interface ConfigPropertyMapping {
6
+ /**
7
+ * The property name on the class
8
+ */
9
+ propertyKey: string;
10
+ /**
11
+ * The environment variable name to map from
12
+ */
13
+ envKey: string;
14
+ }
15
+ /**
16
+ * @ConfigProperty() decorator
17
+ *
18
+ * Maps a class property to an environment variable. If no explicit env key is provided,
19
+ * automatically converts the property name from camelCase to UPPER_SNAKE_CASE.
20
+ *
21
+ * This decorator stores metadata that will be read by AbstractConfigProvider
22
+ * during the populate() phase to assign validated environment values to properties.
23
+ *
24
+ * @param envKey - Optional explicit environment variable name (must be UPPERCASE)
25
+ *
26
+ * @example Auto-mapping (property name → UPPER_SNAKE_CASE):
27
+ * ```typescript
28
+ * import { ConfigProperty, ProviderConfig, AbstractConfigProvider } from '@riktajs/core';
29
+ * import { z } from 'zod';
30
+ *
31
+ * @ProviderConfig()
32
+ * export class DatabaseConfigProvider extends AbstractConfigProvider {
33
+ * schema() {
34
+ * return z.object({
35
+ * DB_HOST: z.string(),
36
+ * DB_PORT: z.coerce.number().int(),
37
+ * DB_NAME: z.string(),
38
+ * });
39
+ * }
40
+ *
41
+ * @ConfigProperty() // Maps to 'DB_HOST'
42
+ * dbHost!: string;
43
+ *
44
+ * @ConfigProperty() // Maps to 'DB_PORT'
45
+ * dbPort!: number;
46
+ *
47
+ * @ConfigProperty() // Maps to 'DB_NAME'
48
+ * dbName!: string;
49
+ * }
50
+ * ```
51
+ *
52
+ * @example Custom env key mapping:
53
+ * ```typescript
54
+ * @ProviderConfig()
55
+ * export class AppConfigProvider extends AbstractConfigProvider {
56
+ * schema() {
57
+ * return z.object({
58
+ * PORT: z.coerce.number().int(),
59
+ * NODE_ENV: z.enum(['development', 'production', 'test']),
60
+ * API_SECRET_KEY: z.string(),
61
+ * });
62
+ * }
63
+ *
64
+ * @ConfigProperty('PORT')
65
+ * serverPort!: number;
66
+ *
67
+ * @ConfigProperty('NODE_ENV')
68
+ * environment!: 'development' | 'production' | 'test';
69
+ *
70
+ * @ConfigProperty('API_SECRET_KEY')
71
+ * secret!: string;
72
+ * }
73
+ * ```
74
+ *
75
+ * @example Mixed auto and custom mapping:
76
+ * ```typescript
77
+ * @ProviderConfig()
78
+ * export class ApiConfigProvider extends AbstractConfigProvider {
79
+ * schema() {
80
+ * return z.object({
81
+ * API_KEY: z.string(),
82
+ * API_URL: z.string().url(),
83
+ * TIMEOUT: z.coerce.number().int(),
84
+ * });
85
+ * }
86
+ *
87
+ * @ConfigProperty() // Auto: apiKey → API_KEY
88
+ * apiKey!: string;
89
+ *
90
+ * @ConfigProperty() // Auto: apiUrl → API_URL
91
+ * apiUrl!: string;
92
+ *
93
+ * @ConfigProperty('TIMEOUT') // Custom mapping
94
+ * requestTimeout!: number;
95
+ * }
96
+ * ```
97
+ */
98
+ export declare function ConfigProperty(envKey?: string): PropertyDecorator;
99
+ /**
100
+ * Helper to retrieve all config property mappings from a class
101
+ *
102
+ * @param target - The class constructor to retrieve mappings from
103
+ * @returns Array of property mappings, or empty array if none defined
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const mappings = getConfigPropertyMappings(AppConfigProvider);
108
+ * console.log(mappings);
109
+ * // [
110
+ * // { propertyKey: 'dbHost', envKey: 'DB_HOST' },
111
+ * // { propertyKey: 'dbPort', envKey: 'DB_PORT' }
112
+ * // ]
113
+ * ```
114
+ */
115
+ export declare function getConfigPropertyMappings(target: Function): ConfigPropertyMapping[];
116
+ /**
117
+ * Check if a class has any @ConfigProperty decorated properties
118
+ *
119
+ * @param target - The class constructor to check
120
+ * @returns True if the class has at least one @ConfigProperty
121
+ */
122
+ export declare function hasConfigProperties(target: Function): boolean;
123
+ /**
124
+ * Clear the property name conversion cache
125
+ *
126
+ * @internal Used for testing
127
+ */
128
+ export declare function clearPropertyNameCache(): void;
129
+ //# sourceMappingURL=config-property.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-property.decorator.d.ts","sourceRoot":"","sources":["../../../src/core/decorators/config-property.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAG1B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAwCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CA8DjE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,QAAQ,GAAG,qBAAqB,EAAE,CAEnF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAG7D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}