@owlmeans/server-config 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -477
- package/package.json +5 -4
- package/tsconfig.json +9 -6
package/README.md
CHANGED
|
@@ -1,507 +1,58 @@
|
|
|
1
1
|
# @owlmeans/server-config
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Server-specific configuration utilities: `sservice()` helper and config-file reader.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
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.
|
|
7
|
+
- `sservice()` adds a named service route to a server config (analogous to `service()` from `@owlmeans/config`, but for `BasicServerConfig`)
|
|
8
|
+
- `readConfigValue()` reads a config value from a JSON file or falls back to an environment variable
|
|
9
|
+
- Re-exported via `@owlmeans/server-app` as `sservice`
|
|
21
10
|
|
|
22
11
|
## Installation
|
|
23
12
|
|
|
24
13
|
```bash
|
|
25
|
-
|
|
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 || {}))
|
|
14
|
+
bun add @owlmeans/server-config
|
|
242
15
|
```
|
|
243
16
|
|
|
244
|
-
|
|
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'
|
|
17
|
+
## Usage
|
|
277
18
|
|
|
278
|
-
|
|
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
|
-
```
|
|
19
|
+
Add a service endpoint to a backend config (via `@owlmeans/server-app`):
|
|
293
20
|
|
|
294
|
-
### Configuration Validation
|
|
295
21
|
```typescript
|
|
296
|
-
import { sservice } from '@owlmeans/server-
|
|
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
|
|
22
|
+
import { config, sservice, AppType } from '@owlmeans/server-app'
|
|
323
23
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
-
})
|
|
24
|
+
const appConfig = config(
|
|
25
|
+
AppType.Backend,
|
|
26
|
+
'manager-api',
|
|
27
|
+
sservice({ service: 'auth', host: 'auth-service', port: 3001 })
|
|
28
|
+
)
|
|
378
29
|
```
|
|
379
30
|
|
|
380
|
-
|
|
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
|
-
```
|
|
31
|
+
Read a secret from file or environment:
|
|
404
32
|
|
|
405
33
|
```typescript
|
|
406
34
|
import { readConfigValue } from '@owlmeans/server-config'
|
|
407
35
|
|
|
408
|
-
|
|
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
|
-
}
|
|
36
|
+
const dbPassword = await readConfigValue('DB_PASSWORD', '/run/secrets/db_password')
|
|
427
37
|
```
|
|
428
38
|
|
|
429
|
-
|
|
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
|
|
39
|
+
## API
|
|
481
40
|
|
|
482
|
-
|
|
41
|
+
### `sservice<C>(route, cfg?): Partial<C>`
|
|
483
42
|
|
|
484
|
-
|
|
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
|
|
43
|
+
Adds a service route to a `BasicServerConfig`. The `service` field of `route` becomes the service alias.
|
|
488
44
|
|
|
489
|
-
###
|
|
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
|
|
45
|
+
### `readConfigValue(envVar, filePath?): Promise<string>`
|
|
493
46
|
|
|
494
|
-
|
|
495
|
-
- **[@owlmeans/basic-keys](../basic-keys)**: Cryptographic key management for secure configuration
|
|
496
|
-
- **[@owlmeans/auth-common](../auth-common)**: Authentication configuration patterns
|
|
47
|
+
Returns the value of `envVar` from the environment. If `filePath` is provided and the file exists, reads from there instead (useful for Docker secrets).
|
|
497
48
|
|
|
498
|
-
|
|
49
|
+
### `BasicServerConfig`
|
|
499
50
|
|
|
500
|
-
|
|
51
|
+
Extends `CommonConfig` with:
|
|
52
|
+
- `port?: number`
|
|
53
|
+
- `security?: { unsecure?: boolean }`
|
|
501
54
|
|
|
502
|
-
|
|
503
|
-
- **config**: Core configuration utilities (`sservice`)
|
|
504
|
-
- **helpers**: Configuration reading utilities (`readConfigValue`)
|
|
505
|
-
- **index**: Main export aggregation
|
|
55
|
+
## Related Packages
|
|
506
56
|
|
|
507
|
-
|
|
57
|
+
- [`@owlmeans/config`](../config) — `service()` for client-accessible services; `makeConfig` base factory
|
|
58
|
+
- [`@owlmeans/server-app`](../server-app) — re-exports `sservice`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-config",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -21,13 +21,14 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@owlmeans/config": "^0.1.
|
|
25
|
-
"@owlmeans/server-route": "^0.1.
|
|
24
|
+
"@owlmeans/config": "^0.1.4",
|
|
25
|
+
"@owlmeans/server-route": "^0.1.4"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@owlmeans/dep-config": "workspace:*",
|
|
28
29
|
"@types/node": "^24.10.1",
|
|
29
30
|
"nodemon": "^3.1.11",
|
|
30
|
-
"typescript": "^
|
|
31
|
+
"typescript": "^6.0.2"
|
|
31
32
|
},
|
|
32
33
|
"publishConfig": {
|
|
33
34
|
"access": "public"
|
package/tsconfig.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends":
|
|
2
|
+
"extends": [
|
|
3
|
+
"@owlmeans/dep-config/tsconfig.base.json",
|
|
4
|
+
"@owlmeans/dep-config/tsconfig.node.json"
|
|
5
|
+
],
|
|
3
6
|
"compilerOptions": {
|
|
4
|
-
"rootDir": "./src/",
|
|
5
|
-
"outDir": "./build/"
|
|
6
|
-
"moduleResolution": "Bundler"
|
|
7
|
+
"rootDir": "./src/",
|
|
8
|
+
"outDir": "./build/"
|
|
7
9
|
},
|
|
8
10
|
"exclude": [
|
|
9
11
|
"./dist/**/*",
|
|
10
|
-
"./build/**/*"
|
|
12
|
+
"./build/**/*",
|
|
13
|
+
"./*.ts"
|
|
11
14
|
]
|
|
12
|
-
}
|
|
15
|
+
}
|