@owlmeans/server-config 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 OwlMeans Common — Fullstack typescript framework
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,507 @@
1
+ # @owlmeans/server-config
2
+
3
+ The **@owlmeans/server-config** package provides server-specific configuration utilities for OwlMeans Common Libraries, offering helper functions for reading configuration values from files and managing service configurations in server environments.
4
+
5
+ ## Purpose
6
+
7
+ This package serves as a server configuration management layer, designed for:
8
+
9
+ - **File-based Configuration**: Read configuration values from files using path references
10
+ - **Service Registration**: Simplified service configuration with automatic type detection
11
+ - **Server-specific Config**: Configuration utilities tailored for server environments
12
+ - **Path Resolution**: Automatic resolution of file paths and URLs for configuration values
13
+
14
+ ## Key Concepts
15
+
16
+ ### File Path Resolution
17
+ Automatically detects and reads configuration values from files when paths are provided, enabling secure storage of secrets and configuration outside of code.
18
+
19
+ ### Service Configuration
20
+ Provides utilities for registering and configuring backend services with proper routing and resolution information.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @owlmeans/server-config
26
+ ```
27
+
28
+ ## API Reference
29
+
30
+ ### Core Functions
31
+
32
+ The package provides utility functions following OwlMeans Common patterns for server-side configuration management:
33
+
34
+ #### `readConfigValue<T extends string | null>(value: T | undefined, def: T): T`
35
+
36
+ Reads configuration values with support for file path resolution and fallback defaults.
37
+
38
+ ```typescript
39
+ import { readConfigValue } from '@owlmeans/server-config'
40
+
41
+ // Environment variable with default
42
+ const apiKey = readConfigValue(process.env.API_KEY, 'default-key')
43
+
44
+ // File-based secret reading
45
+ const dbPassword = readConfigValue('/secrets/db-password', '')
46
+
47
+ // URL-style file path
48
+ const privateKey = readConfigValue('file:///etc/ssl/private.key', '')
49
+ ```
50
+
51
+ **Purpose**: Provides flexible configuration value resolution supporting both direct values and file-based configuration for secure secret management.
52
+
53
+ **Behavior**:
54
+ - **Direct values**: Returns the value as-is if not a file path
55
+ - **File path resolution**: Automatically reads file content when value starts with `/` or `file://`
56
+ - **Fallback handling**: Returns default value when input is `undefined`
57
+ - **Trimming**: Automatically trims whitespace from file content
58
+
59
+ **Parameters**:
60
+ - `value: T | undefined`: Configuration value or file path to read
61
+ - `def: T`: Default value returned when `value` is `undefined` (defaults to `null`)
62
+
63
+ **Returns**: `T` - Resolved configuration value
64
+
65
+ **Generic Type Parameter**:
66
+ - `T extends string | null`: Type of the configuration value, typically string
67
+
68
+ **File Path Support**:
69
+ - Absolute paths starting with `/`: `/config/database-url`
70
+ - URL-style paths: `file:///secrets/api-key`
71
+ - Relative paths are treated as direct values, not file paths
72
+
73
+ **Error Handling**: Throws filesystem errors if file cannot be read (e.g., permission denied, file not found)
74
+
75
+ #### `sservice<C extends BasicServerConfig>(service: Omit<ServiceRoute, "resolved" | "type">, cfg?: Partial<C>): C`
76
+
77
+ Creates or updates server configuration with service registration and routing information.
78
+
79
+ ```typescript
80
+ import { sservice } from '@owlmeans/server-config'
81
+ import type { BasicServerConfig } from '@owlmeans/server-config'
82
+
83
+ // Register database service
84
+ const config = sservice({
85
+ service: 'database',
86
+ host: 'localhost',
87
+ port: 5432,
88
+ internalHost: 'postgres.internal'
89
+ })
90
+
91
+ // Chain multiple services
92
+ const fullConfig = sservice({
93
+ service: 'redis',
94
+ host: 'redis-cluster.example.com',
95
+ port: 6379
96
+ }, sservice({
97
+ service: 'auth',
98
+ host: 'auth-service.example.com',
99
+ port: 8080
100
+ }))
101
+
102
+ // With existing configuration
103
+ const existingConfig: BasicServerConfig = { /* ... */ }
104
+ const updatedConfig = sservice({
105
+ service: 'monitoring',
106
+ host: 'metrics.internal',
107
+ port: 9090
108
+ }, existingConfig)
109
+ ```
110
+
111
+ **Purpose**: Registers services with the server configuration, enabling service discovery and routing within OwlMeans applications.
112
+
113
+ **Behavior**:
114
+ - **Service registration**: Adds service configuration to `cfg.services` object
115
+ - **Type enforcement**: Automatically sets service type to `AppType.Backend`
116
+ - **Host resolution**: Uses `host` if available, falls back to `internalHost`
117
+ - **Resolution status**: Marks service as resolved if either host is provided
118
+ - **Configuration merging**: Safely merges with existing configuration
119
+
120
+ **Parameters**:
121
+ - `service: Omit<ServiceRoute, "resolved" | "type">`: Service configuration excluding auto-managed fields
122
+ - `service: string`: Unique service identifier
123
+ - `host?: string`: Public/external hostname
124
+ - `internalHost?: string`: Internal network hostname
125
+ - `port?: number`: Service port
126
+ - Additional ServiceRoute properties
127
+ - `cfg?: Partial<C>`: Existing configuration to extend (optional)
128
+
129
+ **Returns**: `C extends BasicServerConfig` - Updated configuration with service registered
130
+
131
+ **Generic Type Parameter**:
132
+ - `C extends BasicServerConfig`: Configuration type, typically extends BasicServerConfig
133
+
134
+ **Service Resolution Logic**:
135
+ - Service is marked as `resolved: true` if `host` or `internalHost` is provided
136
+ - Final `host` value is `service.host ?? service.internalHost`
137
+ - Allows services to have different internal vs external addresses
138
+
139
+ **Configuration Structure**:
140
+ The function ensures the configuration has a `services` object and adds/updates the service entry:
141
+ ```typescript
142
+ config.services[serviceName] = {
143
+ type: AppType.Backend,
144
+ resolved: boolean,
145
+ host: string,
146
+ ...serviceProperties
147
+ }
148
+ ```
149
+
150
+ ### Type Definitions
151
+
152
+ #### `BasicServerConfig`
153
+ Base configuration interface for server applications.
154
+
155
+ ```typescript
156
+ interface BasicServerConfig extends BasicConfig {
157
+ services?: Record<string, ServiceRoute>
158
+ // Additional server-specific configuration
159
+ }
160
+ ```
161
+
162
+ **Properties**:
163
+ - `services`: Object mapping service names to their routing configuration
164
+ - Extends `BasicConfig` from `@owlmeans/config` for common configuration properties
165
+
166
+ ### Constants and Utilities
167
+
168
+ The package integrates with OwlMeans configuration constants:
169
+
170
+ #### File Path Conventions
171
+ - **Secrets**: `/secrets/` directory for sensitive configuration
172
+ - **Config**: `/config/` directory for non-sensitive configuration
173
+ - **SSL/TLS**: `/etc/ssl/` for certificate and key files
174
+ - **Logs**: `/var/log/` for log configuration files
175
+
176
+ ## Advanced Usage Examples
177
+
178
+ ### Environment-Aware Configuration
179
+ ```typescript
180
+ import { readConfigValue, sservice } from '@owlmeans/server-config'
181
+
182
+ // Environment-specific configuration loading
183
+ const getEnvironmentConfig = () => {
184
+ const env = process.env.NODE_ENV || 'development'
185
+
186
+ return {
187
+ database: {
188
+ host: readConfigValue(process.env.DB_HOST, `${env}-postgres`),
189
+ port: parseInt(readConfigValue(process.env.DB_PORT, '5432')),
190
+ // File-based secrets in production
191
+ password: readConfigValue(
192
+ env === 'production' ? '/secrets/db-password' : process.env.DB_PASSWORD,
193
+ ''
194
+ )
195
+ },
196
+ api: {
197
+ port: parseInt(readConfigValue(process.env.API_PORT, '3000')),
198
+ // Different secret strategies per environment
199
+ jwtSecret: readConfigValue(
200
+ env === 'production' ? 'file:///secrets/jwt-secret' : process.env.JWT_SECRET,
201
+ 'dev-secret'
202
+ )
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### Microservice Configuration Pattern
209
+ ```typescript
210
+ import { sservice } from '@owlmeans/server-config'
211
+ import type { BasicServerConfig } from '@owlmeans/server-config'
212
+
213
+ // Build configuration for microservice architecture
214
+ const buildMicroserviceConfig = (): BasicServerConfig => {
215
+ // Start with base configuration
216
+ let config = sservice({
217
+ service: 'user-service',
218
+ host: readConfigValue(process.env.USER_SERVICE_HOST, 'users.internal'),
219
+ port: parseInt(readConfigValue(process.env.USER_SERVICE_PORT, '8001'))
220
+ })
221
+
222
+ // Add authentication service
223
+ config = sservice({
224
+ service: 'auth-service',
225
+ host: readConfigValue(process.env.AUTH_SERVICE_HOST, 'auth.internal'),
226
+ port: parseInt(readConfigValue(process.env.AUTH_SERVICE_PORT, '8002'))
227
+ }, config)
228
+
229
+ // Add external services
230
+ config = sservice({
231
+ service: 'payment-gateway',
232
+ host: readConfigValue(process.env.PAYMENT_HOST, 'api.stripe.com'),
233
+ port: 443
234
+ }, config)
235
+
236
+ return config
237
+ }
238
+
239
+ // Use in application
240
+ const appConfig = buildMicroserviceConfig()
241
+ console.log('Registered services:', Object.keys(appConfig.services || {}))
242
+ ```
243
+
244
+ ### Kubernetes ConfigMap Integration
245
+ ```typescript
246
+ import { readConfigValue } from '@owlmeans/server-config'
247
+
248
+ // Kubernetes-style configuration mounting
249
+ const kubernetesConfig = {
250
+ // ConfigMap-mounted configuration
251
+ database: {
252
+ host: readConfigValue('/etc/config/database/host', 'localhost'),
253
+ port: parseInt(readConfigValue('/etc/config/database/port', '5432')),
254
+ name: readConfigValue('/etc/config/database/name', 'myapp')
255
+ },
256
+
257
+ // Secret-mounted sensitive data
258
+ credentials: {
259
+ dbPassword: readConfigValue('/etc/secrets/database/password', ''),
260
+ apiKey: readConfigValue('/etc/secrets/api/key', ''),
261
+ jwtSecret: readConfigValue('/etc/secrets/jwt/secret', '')
262
+ },
263
+
264
+ // Environment-specific overrides
265
+ features: {
266
+ debugMode: readConfigValue(process.env.DEBUG_MODE, 'false') === 'true',
267
+ logLevel: readConfigValue(process.env.LOG_LEVEL, 'info')
268
+ }
269
+ }
270
+ ```
271
+
272
+ ## Error Handling and Best Practices
273
+
274
+ ### File Reading Errors
275
+ ```typescript
276
+ import { readConfigValue } from '@owlmeans/server-config'
277
+
278
+ const safeConfigRead = (path: string, defaultValue: string) => {
279
+ try {
280
+ return readConfigValue(path, defaultValue)
281
+ } catch (error) {
282
+ console.error(`Failed to read config from ${path}:`, error.message)
283
+ return defaultValue
284
+ }
285
+ }
286
+
287
+ // Use with error handling
288
+ const dbPassword = safeConfigRead('/secrets/db-password', '')
289
+ if (!dbPassword) {
290
+ throw new Error('Database password is required but not configured')
291
+ }
292
+ ```
293
+
294
+ ### Configuration Validation
295
+ ```typescript
296
+ import { sservice } from '@owlmeans/server-config'
297
+
298
+ const validateAndBuildConfig = () => {
299
+ const requiredServices = ['database', 'redis', 'auth']
300
+
301
+ let config = {}
302
+
303
+ for (const serviceName of requiredServices) {
304
+ const host = readConfigValue(`/config/${serviceName}-host`, '')
305
+ const port = readConfigValue(`/config/${serviceName}-port`, '')
306
+
307
+ if (!host || !port) {
308
+ throw new Error(`Missing configuration for ${serviceName} service`)
309
+ }
310
+
311
+ config = sservice({
312
+ service: serviceName,
313
+ host,
314
+ port: parseInt(port)
315
+ }, config)
316
+ }
317
+
318
+ return config
319
+ }
320
+ ```
321
+
322
+ ## Security Considerations
323
+
324
+ ### File System Security
325
+ 1. **File Permissions**: Ensure secret files have restricted permissions (600 or 400)
326
+ 2. **Path Validation**: Validate file paths to prevent directory traversal attacks
327
+ 3. **Secret Rotation**: Implement mechanism to reload configuration when files change
328
+ 4. **Audit Logging**: Log configuration file access for security monitoring
329
+
330
+ ### Configuration Security
331
+ 1. **Secrets Management**: Never log or expose file-based secrets
332
+ 2. **Environment Separation**: Use different secret files per environment
333
+ 3. **Encryption at Rest**: Consider encrypting configuration files containing sensitive data
334
+ 4. **Network Security**: Protect configuration files during container deployment
335
+
336
+ ## Performance Considerations
337
+
338
+ ### File I/O Optimization
339
+ - **Caching**: File reads happen on every call - consider caching for frequently accessed config
340
+ - **Startup Loading**: Load all file-based configuration at application startup
341
+ - **Error Handling**: File system errors can be slow - implement timeouts for production
342
+
343
+ ### Memory Usage
344
+ - **String Duplication**: `readConfigValue` creates new strings - be mindful with large configuration files
345
+ - **Service Objects**: Each `sservice` call creates new configuration objects
346
+
347
+ ## Integration Patterns
348
+
349
+ ### Express.js Application Configuration
350
+ ```typescript
351
+ import express from 'express'
352
+ import { readConfigValue, sservice } from '@owlmeans/server-config'
353
+
354
+ const app = express()
355
+
356
+ // Configure application from files and environment
357
+ const config = {
358
+ server: {
359
+ port: parseInt(readConfigValue(process.env.PORT, '3000')),
360
+ host: readConfigValue(process.env.HOST, '0.0.0.0')
361
+ },
362
+ cors: {
363
+ origin: readConfigValue('/config/cors-origins', 'http://localhost:3000')
364
+ .split(',').map(s => s.trim())
365
+ }
366
+ }
367
+
368
+ // Register external services
369
+ const serviceConfig = sservice({
370
+ service: 'user-database',
371
+ host: readConfigValue('/config/database-host', 'localhost'),
372
+ port: parseInt(readConfigValue('/config/database-port', '5432'))
373
+ })
374
+
375
+ app.listen(config.server.port, config.server.host, () => {
376
+ console.log(`Server running on ${config.server.host}:${config.server.port}`)
377
+ })
378
+ ```
379
+
380
+ ### OwlMeans Context Integration
381
+ ```typescript
382
+ import { makeServerContext } from '@owlmeans/server-context'
383
+ import { sservice, readConfigValue } from '@owlmeans/server-config'
384
+
385
+ // Build configuration with services
386
+ let config = sservice({
387
+ service: 'primary-db',
388
+ host: readConfigValue('/config/database-primary', 'localhost'),
389
+ port: 5432
390
+ })
391
+
392
+ config = sservice({
393
+ service: 'cache',
394
+ host: readConfigValue('/config/redis-host', 'localhost'),
395
+ port: 6379
396
+ }, config)
397
+
398
+ // Create context with enhanced configuration
399
+ const context = makeServerContext(config)
400
+
401
+ // Services are now available through context
402
+ // context.service('database-client') can now find primary-db service
403
+ ```
404
+
405
+ ```typescript
406
+ import { readConfigValue } from '@owlmeans/server-config'
407
+
408
+ // Configuration that can come from files or environment variables
409
+ const databaseUrl = readConfigValue(
410
+ process.env.DATABASE_URL || '/config/database-url',
411
+ 'postgresql://localhost:5432/defaultdb'
412
+ )
413
+
414
+ const jwtSecret = readConfigValue(
415
+ '/secrets/jwt-secret',
416
+ 'development-secret'
417
+ )
418
+
419
+ const config = {
420
+ database: {
421
+ url: databaseUrl
422
+ },
423
+ auth: {
424
+ jwtSecret: jwtSecret
425
+ }
426
+ }
427
+ ```
428
+
429
+ ### Service Configuration
430
+
431
+ ```typescript
432
+ import { sservice } from '@owlmeans/server-config'
433
+
434
+ // Build configuration with multiple services
435
+ let config = {}
436
+
437
+ // Add database service
438
+ config = sservice({
439
+ service: 'postgres',
440
+ host: 'postgres.example.com',
441
+ port: 5432,
442
+ internalHost: 'postgres-internal'
443
+ }, config)
444
+
445
+ // Add cache service
446
+ config = sservice({
447
+ service: 'redis',
448
+ host: 'redis.example.com',
449
+ port: 6379
450
+ ## Best Practices
451
+
452
+ 1. **Secure Secrets Management**: Always use file paths for sensitive configuration like passwords and API keys
453
+ 2. **Environment Flexibility**: Support both environment variables and file-based configuration with appropriate fallbacks
454
+ 3. **Sensible Defaults**: Provide development-friendly defaults while enforcing production security
455
+ 4. **Service Registration**: Use `sservice` for consistent service configuration and discovery
456
+ 5. **Type Safety**: Leverage TypeScript generics for compile-time configuration validation
457
+ 6. **Error Handling**: Implement proper error handling for file system operations
458
+ 7. **Configuration Validation**: Validate critical configuration values at startup
459
+ 8. **Caching Strategy**: Cache file-based configuration for performance in production
460
+
461
+ ## Error Types and Handling
462
+
463
+ The package may throw the following errors:
464
+
465
+ ### File System Errors
466
+ - **ENOENT**: File not found - occurs when configuration file doesn't exist
467
+ - **EACCES**: Permission denied - occurs when process lacks read permissions
468
+ - **EISDIR**: Is a directory - occurs when path points to directory instead of file
469
+
470
+ ### Configuration Errors
471
+ - **Missing Required Configuration**: Critical services without proper configuration
472
+ - **Invalid Port Numbers**: Non-numeric port configuration values
473
+ - **Service Registration Conflicts**: Duplicate service names in configuration
474
+
475
+ ## Dependencies
476
+
477
+ This package depends on:
478
+ - **@owlmeans/config**: Core configuration utilities and types (`BasicConfig`, `AppType`)
479
+ - **@owlmeans/server-route**: Server route definitions and service routing types (`ServiceRoute`)
480
+ - **Node.js fs module**: File system operations for reading configuration files
481
+
482
+ ## Related OwlMeans Packages
483
+
484
+ ### Core Configuration Ecosystem
485
+ - **[@owlmeans/config](../config)**: Core configuration management and base types
486
+ - **[@owlmeans/client-config](../client-config)**: Client-side configuration utilities
487
+ - **[@owlmeans/api-config](../api-config)**: Shared configuration between client and server
488
+
489
+ ### Server Framework Integration
490
+ - **[@owlmeans/server-context](../server-context)**: Server context management and dependency injection
491
+ - **[@owlmeans/server-route](../server-route)**: Server routing functionality and definitions
492
+ - **[@owlmeans/server-auth](../server-auth)**: Server authentication configuration
493
+
494
+ ### Security and Secrets Management
495
+ - **[@owlmeans/basic-keys](../basic-keys)**: Cryptographic key management for secure configuration
496
+ - **[@owlmeans/auth-common](../auth-common)**: Authentication configuration patterns
497
+
498
+ ## Package Structure
499
+
500
+ Following OwlMeans Common library structure:
501
+
502
+ - **types**: TypeScript interface definitions (`BasicServerConfig`)
503
+ - **config**: Core configuration utilities (`sservice`)
504
+ - **helpers**: Configuration reading utilities (`readConfigValue`)
505
+ - **index**: Main export aggregation
506
+
507
+ The package maintains a minimal, focused API surface while providing comprehensive functionality for server configuration management in OwlMeans applications.
package/build/.gitkeep ADDED
File without changes
@@ -0,0 +1,4 @@
1
+ import type { BasicServerConfig } from './types.js';
2
+ import type { ServiceRoute } from '@owlmeans/server-route';
3
+ export declare const sservice: <C extends BasicServerConfig>(service: Omit<ServiceRoute, "resolved" | "type">, cfg?: Partial<C>) => C;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAC,MAAO,YAAY,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,iBAAiB,WAAW,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,MAAM,CAAC,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAG,CAc1H,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { AppType } from '@owlmeans/config';
2
+ export const sservice = (service, cfg) => {
3
+ const _cfg = (cfg ?? {});
4
+ if (_cfg.services == null) {
5
+ _cfg.services = {};
6
+ }
7
+ _cfg.services[service.service] = {
8
+ type: AppType.Backend,
9
+ ..._cfg.services[service.service],
10
+ ...service,
11
+ resolved: service.host != null || service.internalHost != null,
12
+ host: service.host ?? service.internalHost
13
+ };
14
+ return _cfg;
15
+ };
16
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAI1C,MAAM,CAAC,MAAM,QAAQ,GAAG,CAA8B,OAAgD,EAAE,GAAgB,EAAK,EAAE;IAC7H,MAAM,IAAI,GAAM,CAAC,GAAG,IAAI,EAAE,CAAM,CAAA;IAChC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;IACpB,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG;QAC/B,IAAI,EAAE,OAAO,CAAC,OAAO;QACrB,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;QACjC,GAAG,OAAO;QACV,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC,YAAY,IAAI,IAAI;QAC9D,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY;KAC3C,CAAA;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const readConfigValue: <T extends string | null>(value: T | undefined, def?: T) => T;
2
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,GAAG,IAAI,SAAS,CAAC,GAAG,SAAS,QAAO,CAAC,KAAe,CASnG,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { readFileSync } from 'node:fs';
2
+ export const readConfigValue = (value, def = null) => {
3
+ if (value === undefined) {
4
+ return def;
5
+ }
6
+ if (value != null && (value.startsWith('/') || value.startsWith('file://'))) {
7
+ return readFileSync(value, 'utf-8').trim();
8
+ }
9
+ return value;
10
+ };
11
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,CAAC,MAAM,eAAe,GAAG,CAA0B,KAAoB,EAAE,MAAS,IAAS,EAAK,EAAE;IACtG,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAC5E,OAAO,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,EAAO,CAAA;IACjD,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './helpers.js';
2
+ export type * from './types.js';
3
+ export * from './config.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './helpers.js';
2
+ export * from './config.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAE5B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { CommonConfig } from '@owlmeans/config';
2
+ export interface BasicServerConfig extends CommonConfig {
3
+ secrets: Record<string, string>;
4
+ }
5
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@owlmeans/server-config",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "tsc -b",
7
+ "dev": "sleep 282 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
8
+ "watch": "tsc -b -w --preserveWatchOutput --pretty"
9
+ },
10
+ "main": "build/index.js",
11
+ "module": "build/index.js",
12
+ "types": "build/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./build/index.js",
16
+ "require": "./build/index.js",
17
+ "default": "./build/index.js",
18
+ "module": "./build/index.js",
19
+ "types": "./build/index.d.ts"
20
+ }
21
+ },
22
+ "dependencies": {
23
+ "@owlmeans/config": "^0.1.0",
24
+ "@owlmeans/server-route": "^0.1.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^22.7.8",
28
+ "nodemon": "^3.1.7",
29
+ "typescript": "^5.6.3"
30
+ },
31
+ "private": false,
32
+ "publishConfig": {
33
+ "access": "public"
34
+ }
35
+ }
package/src/config.ts ADDED
@@ -0,0 +1,20 @@
1
+
2
+ import { AppType } from '@owlmeans/config'
3
+ import type { BasicServerConfig} from './types.js'
4
+ import type { ServiceRoute } from '@owlmeans/server-route'
5
+
6
+ export const sservice = <C extends BasicServerConfig>(service: Omit<ServiceRoute, "resolved" | "type">, cfg?: Partial<C>): C => {
7
+ const _cfg: C = (cfg ?? {}) as C
8
+ if (_cfg.services == null) {
9
+ _cfg.services = {}
10
+ }
11
+ _cfg.services[service.service] = {
12
+ type: AppType.Backend,
13
+ ..._cfg.services[service.service],
14
+ ...service,
15
+ resolved: service.host != null || service.internalHost != null,
16
+ host: service.host ?? service.internalHost
17
+ }
18
+
19
+ return _cfg
20
+ }
package/src/helpers.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { readFileSync } from 'node:fs'
2
+
3
+ export const readConfigValue = <T extends string | null>(value: T | undefined, def: T = null as T): T => {
4
+ if (value === undefined) {
5
+ return def
6
+ }
7
+ if (value != null && (value.startsWith('/') || value.startsWith('file://'))) {
8
+ return readFileSync(value, 'utf-8').trim() as T
9
+ }
10
+
11
+ return value
12
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+
2
+ export * from './helpers.js'
3
+ export type * from './types.js'
4
+ export * from './config.js'
5
+
package/src/types.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { CommonConfig } from '@owlmeans/config'
2
+
3
+ export interface BasicServerConfig extends CommonConfig {
4
+ secrets: Record<string, string>
5
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../tsconfig.default.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./src/", /* Specify the root folder within your source files. */
5
+ "outDir": "./build/", /* Specify an output folder for all emitted files. */
6
+ "moduleResolution": "Bundler"
7
+ },
8
+ "exclude": [
9
+ "./dist/**/*",
10
+ "./build/**/*"
11
+ ]
12
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/config.ts","./src/helpers.ts","./src/index.ts","./src/types.ts"],"version":"5.6.3"}