@owlmeans/server-context 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,516 @@
1
+ # @owlmeans/server-context
2
+
3
+ Server-side context and dependency injection system for OwlMeans Common applications. This package extends the base OwlMeans context system with server-specific functionality, configuration management, and authentication capabilities for building secure backend services.
4
+
5
+ ## Overview
6
+
7
+ The `@owlmeans/server-context` package provides server-specific extensions to the OwlMeans context system, offering:
8
+
9
+ - **Server Context Management**: Enhanced context with server-specific capabilities
10
+ - **Configuration Integration**: Built-in configuration resource management
11
+ - **Authentication Guards**: Pre-configured Ed25519 authentication guards
12
+ - **Middleware System**: Server-optimized middleware for request processing
13
+ - **Service Registration**: Streamlined service registration for server components
14
+ - **File Configuration**: File-based configuration reading capabilities
15
+ - **Security Defaults**: Secure-by-default configuration for production servers
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @owlmeans/server-context
21
+ ```
22
+
23
+ ## Core Concepts
24
+
25
+ ### Server Context
26
+
27
+ The `ServerContext` extends the basic OwlMeans context with server-specific functionality, including configuration resource management and enhanced service capabilities.
28
+
29
+ ### Server Configuration
30
+
31
+ The `ServerConfig` combines server and client configuration options, providing a unified configuration structure for fullstack applications.
32
+
33
+ ### Security Integration
34
+
35
+ Built-in integration with authentication guards and middleware for secure service-to-service communication.
36
+
37
+ ## API Reference
38
+
39
+ ### Types
40
+
41
+ #### `ServerConfig`
42
+ Extended configuration interface for server applications.
43
+
44
+ ```typescript
45
+ interface ServerConfig extends BasicServerConfig, BasicClientConfig {
46
+ services: Record<string, ServiceRoute>
47
+ }
48
+ ```
49
+
50
+ #### `ServerContext<C extends ServerConfig>`
51
+ Enhanced context interface with server capabilities.
52
+
53
+ ```typescript
54
+ interface ServerContext<C extends ServerConfig> extends BasicContext<C>, ConfigResourceAppend {
55
+ // Inherits all BasicContext functionality plus configuration resource management
56
+ }
57
+ ```
58
+
59
+ ### Factory Functions
60
+
61
+ #### `makeServerContext<C, T>(cfg: C): T`
62
+ Creates a server context with enhanced capabilities.
63
+
64
+ **Parameters:**
65
+ - `cfg`: Server configuration object
66
+
67
+ **Returns:** Configured server context instance
68
+
69
+ **Features:**
70
+ - Registers file configuration reader middleware
71
+ - Adds configuration resource management
72
+ - Sets up trusted entity resource
73
+ - Configures plugin resource management
74
+ - Registers Ed25519 authentication guard
75
+ - Adds authentication middleware
76
+
77
+ #### `config<C>(service: string, cfg?: Partial<C>): C`
78
+ Creates a server configuration with default settings.
79
+
80
+ **Parameters:**
81
+ - `service`: Service name identifier
82
+ - `cfg`: Optional partial configuration
83
+
84
+ **Returns:** Complete server configuration
85
+
86
+ ## Usage Examples
87
+
88
+ ### Basic Server Setup
89
+
90
+ ```typescript
91
+ import { makeServerContext, config } from '@owlmeans/server-context'
92
+
93
+ // Create server configuration
94
+ const serverConfig = config('my-service', {
95
+ port: 3000,
96
+ host: 'localhost',
97
+ services: {
98
+ database: {
99
+ protocol: 'mongodb',
100
+ host: 'localhost',
101
+ port: 27017
102
+ }
103
+ }
104
+ })
105
+
106
+ // Create server context
107
+ const context = makeServerContext(serverConfig)
108
+
109
+ // Initialize the context
110
+ await context.init()
111
+ ```
112
+
113
+ ### Configuration with Resources
114
+
115
+ ```typescript
116
+ import { makeServerContext, config } from '@owlmeans/server-context'
117
+
118
+ const serverConfig = config('api-server', {
119
+ // Database configurations
120
+ dbs: [
121
+ {
122
+ service: 'mongo',
123
+ alias: 'primary',
124
+ host: 'localhost',
125
+ port: 27017,
126
+ schema: 'myapp'
127
+ }
128
+ ],
129
+
130
+ // Trusted services for authentication
131
+ trusted: [
132
+ {
133
+ id: 'internal-service',
134
+ recordType: 'trusted-source',
135
+ name: 'Internal Service',
136
+ entityId: 'internal',
137
+ scopes: ['api:*']
138
+ }
139
+ ],
140
+
141
+ // Service routes
142
+ services: {
143
+ 'user-service': {
144
+ protocol: 'https',
145
+ host: 'user-service.internal',
146
+ port: 443
147
+ },
148
+ 'auth-service': {
149
+ protocol: 'https',
150
+ host: 'auth-service.internal',
151
+ port: 443
152
+ }
153
+ }
154
+ })
155
+
156
+ const context = makeServerContext(serverConfig)
157
+ ```
158
+
159
+ ### Service Registration
160
+
161
+ ```typescript
162
+ import { makeServerContext, config } from '@owlmeans/server-context'
163
+ import { createDbService } from '@owlmeans/mongo'
164
+
165
+ const context = makeServerContext(config('my-service'))
166
+
167
+ // Register database service
168
+ const dbService = createDbService('primary')
169
+ context.registerService(dbService)
170
+
171
+ // Register custom service
172
+ const customService = {
173
+ alias: 'custom-logic',
174
+ initialized: false,
175
+ init: async () => {
176
+ console.log('Custom service initialized')
177
+ return true
178
+ }
179
+ }
180
+ context.registerService(customService)
181
+ ```
182
+
183
+ ### Authentication Setup
184
+
185
+ ```typescript
186
+ import { makeServerContext, config } from '@owlmeans/server-context'
187
+
188
+ const serverConfig = config('secure-service', {
189
+ trusted: [
190
+ {
191
+ id: 'client-app',
192
+ recordType: 'trusted-source',
193
+ name: 'Client Application',
194
+ credential: 'base64-encoded-public-key',
195
+ scopes: ['read', 'write']
196
+ }
197
+ ]
198
+ })
199
+
200
+ const context = makeServerContext(serverConfig)
201
+
202
+ // The Ed25519 guard is automatically registered
203
+ // Authentication middleware is automatically added
204
+ // Requests with valid signatures will be authenticated
205
+ ```
206
+
207
+ ### Custom Middleware Registration
208
+
209
+ ```typescript
210
+ import { makeServerContext, config } from '@owlmeans/server-context'
211
+ import { MiddlewareType, MiddlewareStage } from '@owlmeans/context'
212
+
213
+ const context = makeServerContext(config('my-service'))
214
+
215
+ // Add custom middleware
216
+ context.registerMiddleware({
217
+ type: MiddlewareType.Context,
218
+ stage: MiddlewareStage.Loading,
219
+ apply: async (ctx) => {
220
+ console.log('Custom middleware executed')
221
+ // Custom logic here
222
+ }
223
+ })
224
+ ```
225
+
226
+ ### Configuration File Reading
227
+
228
+ ```typescript
229
+ // config.json
230
+ {
231
+ "service": "file-config-service",
232
+ "port": 8080,
233
+ "dbs": [
234
+ {
235
+ "service": "mongo",
236
+ "host": "mongodb://localhost:27017",
237
+ "schema": "production"
238
+ }
239
+ ]
240
+ }
241
+ ```
242
+
243
+ ```typescript
244
+ import { makeServerContext } from '@owlmeans/server-context'
245
+
246
+ // File configuration is automatically read via middleware
247
+ const context = makeServerContext({} as any)
248
+
249
+ // Configuration will be populated from files
250
+ await context.init()
251
+
252
+ // Access configuration
253
+ const config = context.cfg
254
+ console.log(`Service running on port ${config.port}`)
255
+ ```
256
+
257
+ ### Resource Management
258
+
259
+ ```typescript
260
+ import { makeServerContext, config } from '@owlmeans/server-context'
261
+
262
+ const context = makeServerContext(config('resource-service'))
263
+
264
+ // Access configuration resources
265
+ const configResource = context.getConfigResource()
266
+ const trustedResource = context.getConfigResource('trusted')
267
+ const pluginResource = context.getConfigResource('plugin')
268
+
269
+ // Create new configuration records
270
+ await configResource.create({
271
+ id: 'feature-flag',
272
+ recordType: 'feature',
273
+ enabled: true,
274
+ description: 'Enable new feature'
275
+ })
276
+
277
+ // Query trusted entities
278
+ const trustedEntities = await trustedResource.list({
279
+ criteria: { scopes: ['admin'] }
280
+ })
281
+ ```
282
+
283
+ ### Plugin System Integration
284
+
285
+ ```typescript
286
+ import { makeServerContext, config } from '@owlmeans/server-context'
287
+
288
+ const serverConfig = config('plugin-host', {
289
+ plugins: [
290
+ {
291
+ id: 'auth-plugin',
292
+ recordType: 'plugin',
293
+ name: 'Authentication Plugin',
294
+ version: '1.0.0',
295
+ enabled: true,
296
+ config: {
297
+ provider: 'oauth2',
298
+ clientId: 'app-client-id'
299
+ }
300
+ }
301
+ ]
302
+ })
303
+
304
+ const context = makeServerContext(serverConfig)
305
+
306
+ // Access plugin configuration
307
+ const pluginResource = context.getConfigResource('plugin')
308
+ const authPlugin = await pluginResource.get('auth-plugin')
309
+
310
+ if (authPlugin.enabled) {
311
+ // Initialize plugin
312
+ console.log(`Loading ${authPlugin.name} v${authPlugin.version}`)
313
+ }
314
+ ```
315
+
316
+ ### Multi-Service Architecture
317
+
318
+ ```typescript
319
+ import { makeServerContext, config } from '@owlmeans/server-context'
320
+
321
+ // Gateway service configuration
322
+ const gatewayConfig = config('api-gateway', {
323
+ services: {
324
+ 'user-service': {
325
+ protocol: 'http',
326
+ host: 'user-service',
327
+ port: 3001
328
+ },
329
+ 'order-service': {
330
+ protocol: 'http',
331
+ host: 'order-service',
332
+ port: 3002
333
+ },
334
+ 'payment-service': {
335
+ protocol: 'https',
336
+ host: 'payment-service.external',
337
+ port: 443
338
+ }
339
+ },
340
+
341
+ trusted: [
342
+ {
343
+ id: 'user-service',
344
+ recordType: 'trusted-source',
345
+ name: 'User Service',
346
+ scopes: ['users:*']
347
+ },
348
+ {
349
+ id: 'order-service',
350
+ recordType: 'trusted-source',
351
+ name: 'Order Service',
352
+ scopes: ['orders:*', 'users:read']
353
+ }
354
+ ]
355
+ })
356
+
357
+ const gateway = makeServerContext(gatewayConfig)
358
+
359
+ // Service can now route to other services with authentication
360
+ ```
361
+
362
+ ### Error Handling
363
+
364
+ ```typescript
365
+ import { makeServerContext, config } from '@owlmeans/server-context'
366
+
367
+ try {
368
+ const context = makeServerContext(config('error-service'))
369
+ await context.init()
370
+ } catch (error) {
371
+ console.error('Failed to initialize server context:', error)
372
+
373
+ // Handle specific initialization errors
374
+ if (error.message.includes('database')) {
375
+ console.error('Database connection failed')
376
+ } else if (error.message.includes('config')) {
377
+ console.error('Configuration error')
378
+ }
379
+
380
+ process.exit(1)
381
+ }
382
+ ```
383
+
384
+ ## Advanced Features
385
+
386
+ ### Custom Context Extensions
387
+
388
+ ```typescript
389
+ import { makeServerContext, ServerContext, ServerConfig } from '@owlmeans/server-context'
390
+
391
+ interface CustomConfig extends ServerConfig {
392
+ customFeature: boolean
393
+ apiKeys: string[]
394
+ }
395
+
396
+ interface CustomContext extends ServerContext<CustomConfig> {
397
+ customMethod: () => void
398
+ }
399
+
400
+ const createCustomContext = (cfg: CustomConfig): CustomContext => {
401
+ const context = makeServerContext(cfg) as CustomContext
402
+
403
+ context.customMethod = () => {
404
+ console.log('Custom context method')
405
+ }
406
+
407
+ return context
408
+ }
409
+ ```
410
+
411
+ ### Dynamic Service Discovery
412
+
413
+ ```typescript
414
+ import { makeServerContext, config } from '@owlmeans/server-context'
415
+
416
+ const context = makeServerContext(config('discovery-service'))
417
+
418
+ // Dynamic service registration
419
+ const discoverServices = async () => {
420
+ const services = await fetchAvailableServices()
421
+
422
+ services.forEach(service => {
423
+ context.cfg.services[service.name] = {
424
+ protocol: service.protocol,
425
+ host: service.host,
426
+ port: service.port
427
+ }
428
+ })
429
+ }
430
+
431
+ await discoverServices()
432
+ ```
433
+
434
+ ### Health Checks
435
+
436
+ ```typescript
437
+ import { makeServerContext, config } from '@owlmeans/server-context'
438
+
439
+ const context = makeServerContext(config('health-service'))
440
+
441
+ const healthCheck = async () => {
442
+ try {
443
+ // Check all registered services
444
+ const services = Object.keys(context.cfg.services)
445
+ const healthStatuses = await Promise.all(
446
+ services.map(async service => {
447
+ try {
448
+ await context.service(service)
449
+ return { service, status: 'healthy' }
450
+ } catch (error) {
451
+ return { service, status: 'unhealthy', error: error.message }
452
+ }
453
+ })
454
+ )
455
+
456
+ return healthStatuses
457
+ } catch (error) {
458
+ return { status: 'error', message: error.message }
459
+ }
460
+ }
461
+ ```
462
+
463
+ ## Integration with OwlMeans Ecosystem
464
+
465
+ The `@owlmeans/server-context` package integrates with:
466
+
467
+ - **@owlmeans/context**: Base context and dependency injection system
468
+ - **@owlmeans/config**: Configuration management and resource handling
469
+ - **@owlmeans/server-config**: Server-specific configuration structures
470
+ - **@owlmeans/client-config**: Client configuration for fullstack apps
471
+ - **@owlmeans/server-route**: Service routing and discovery
472
+ - **@owlmeans/auth-common**: Authentication middleware and guards
473
+ - **@owlmeans/mongo**: Database service integration
474
+ - **@owlmeans/redis**: Cache service integration
475
+
476
+ ## Security Features
477
+
478
+ ### Built-in Authentication
479
+ - Ed25519 signature-based authentication guard
480
+ - Automatic authentication middleware
481
+ - Trusted entity management
482
+ - Secure service-to-service communication
483
+
484
+ ### Configuration Security
485
+ - Secure file configuration reading
486
+ - Environment variable support
487
+ - Secret management integration
488
+ - Access control for configuration resources
489
+
490
+ ## Best Practices
491
+
492
+ ### Configuration Management
493
+ - Use environment-specific configuration files
494
+ - Store secrets in secure environment variables
495
+ - Implement configuration validation
496
+ - Use typed configuration interfaces
497
+
498
+ ### Service Architecture
499
+ - Register services during context initialization
500
+ - Implement proper service lifecycle management
501
+ - Use dependency injection for service access
502
+ - Handle service failures gracefully
503
+
504
+ ### Security
505
+ - Always use authentication guards for protected services
506
+ - Implement proper authorization checks
507
+ - Validate all incoming requests
508
+ - Use secure communication protocols
509
+
510
+ ### Performance
511
+ - Initialize context once during application startup
512
+ - Cache frequently accessed configuration
513
+ - Use lazy service initialization where appropriate
514
+ - Monitor resource usage and optimize accordingly
515
+
516
+ Fixes #32.
package/build/.gitkeep ADDED
File without changes
@@ -0,0 +1,3 @@
1
+ import type { ServerConfig } from './types.js';
2
+ export declare const config: <C extends ServerConfig>(service: string, cfg?: Partial<C>) => C;
3
+ //# 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,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,YAAY,WAAW,MAAM,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAG,CAKlF,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { AppType, makeBasicConfig } from '@owlmeans/context';
2
+ export const config = (service, cfg) => {
3
+ const config = makeBasicConfig(AppType.Backend, service, cfg);
4
+ config.trusted = config.trusted ?? [];
5
+ return config;
6
+ };
7
+ //# 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,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAG5D,MAAM,CAAC,MAAM,MAAM,GAAG,CAAyB,OAAe,EAAE,GAAgB,EAAK,EAAE;IACrF,MAAM,MAAM,GAAM,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAA;IAChE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;IAErC,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { ServerConfig, ServerContext } from './types.js';
2
+ export declare const makeServerContext: <C extends ServerConfig, T extends ServerContext<C>>(cfg: C) => T;
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAMxD,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,KAAG,CAc9F,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { appendConfigResource, PLUGIN_RECORD } from '@owlmeans/config';
2
+ import { fileConfigReader } from './utils/context.js';
3
+ import { makeBasicContext } from '@owlmeans/context';
4
+ import { PLUGINS, TRUSTED } from '@owlmeans/config';
5
+ import { authMiddleware, makeBasicEd25519Guard } from '@owlmeans/auth-common';
6
+ export const makeServerContext = (cfg) => {
7
+ const context = makeBasicContext(cfg);
8
+ context.registerMiddleware(fileConfigReader);
9
+ context.makeContext = makeServerContext;
10
+ appendConfigResource(context);
11
+ appendConfigResource(context, TRUSTED, TRUSTED);
12
+ appendConfigResource(context, PLUGINS, PLUGIN_RECORD);
13
+ context.registerService(makeBasicEd25519Guard(TRUSTED));
14
+ context.registerMiddleware(authMiddleware);
15
+ return context;
16
+ };
17
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAqD,GAAM,EAAK,EAAE;IACjG,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAM,CAAA;IAE1C,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAE5C,OAAO,CAAC,WAAW,GAAG,iBAA+C,CAAA;IAErE,oBAAoB,CAAO,OAAO,CAAC,CAAA;IACnC,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrD,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;IAC3D,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA;IACvD,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAE1C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from './context.js';
2
+ export * from './config.js';
3
+ export type * from './types.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;AAE5B,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './context.js';
2
+ // export * from './consts.js'
3
+ export * from './config.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,8BAA8B;AAC9B,cAAc,aAAa,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { ServiceRoute } from '@owlmeans/server-route';
2
+ import type { ConfigResourceAppend } from '@owlmeans/config';
3
+ import type { BasicServerConfig } from '@owlmeans/server-config';
4
+ import type { BasicClientConfig } from '@owlmeans/client-config';
5
+ import type { BasicContext } from '@owlmeans/context';
6
+ export interface ServerConfig extends BasicServerConfig, BasicClientConfig {
7
+ services: Record<string, ServiceRoute>;
8
+ }
9
+ export interface ServerContext<C extends ServerConfig> extends BasicContext<C>, ConfigResourceAppend {
10
+ }
11
+ //# 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,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,WAAW,YAAa,SAAQ,iBAAiB,EAAE,iBAAiB;IACxE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,YAAY,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC,EAAE,oBAAoB;CACnG"}
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":""}
@@ -0,0 +1,3 @@
1
+ import type { Middleware } from '@owlmeans/context';
2
+ export declare const fileConfigReader: Middleware;
3
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,eAAO,MAAM,gBAAgB,EAAE,UAO9B,CAAA"}
@@ -0,0 +1,26 @@
1
+ import { MiddlewareStage, MiddlewareType } from '@owlmeans/context';
2
+ import { readConfigValue } from '@owlmeans/server-config';
3
+ export const fileConfigReader = {
4
+ type: MiddlewareType.Config,
5
+ stage: MiddlewareStage.Configuration,
6
+ apply: async (context) => {
7
+ const tree = context.cfg;
8
+ visitConfigLeafs(tree);
9
+ }
10
+ };
11
+ // @TODO Move to server config
12
+ const visitConfigLeafs = (tree) => tree != null ? Object.entries(tree).forEach(([key, value]) => {
13
+ if (typeof value === 'string') {
14
+ const descriptor = Object.getOwnPropertyDescriptor(tree, key);
15
+ if (descriptor?.writable) {
16
+ tree[key] = readConfigValue(value);
17
+ }
18
+ }
19
+ else if (Array.isArray(value)) {
20
+ value.forEach(tree => { visitConfigLeafs(tree); });
21
+ }
22
+ else if (typeof value === 'object') {
23
+ visitConfigLeafs(value);
24
+ }
25
+ }) : tree;
26
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,cAAc,CAAC,MAAM;IAC3B,KAAK,EAAE,eAAe,CAAC,aAAa;IACpC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,IAAI,GAAS,OAAO,CAAC,GAAsB,CAAA;QACjD,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;CACF,CAAA;AAED,8BAA8B;AAC9B,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAE,EAAE,CACtC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7D,IAAI,UAAU,EAAE,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,gBAAgB,CAAC,IAAY,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,gBAAgB,CAAC,KAAa,CAAC,CAAA;IACjC,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './context.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './context.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@owlmeans/server-context",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "tsc -b",
7
+ "dev": "sleep 288 && 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
+ "./utils": {
22
+ "import": "./build/utils/index.js",
23
+ "require": "./build/utils/index.js",
24
+ "default": "./build/utils/index.js",
25
+ "module": "./build/utils/index.js",
26
+ "types": "./build/utils/index.d.ts"
27
+ }
28
+ },
29
+ "dependencies": {
30
+ "@owlmeans/client-config": "^0.1.0",
31
+ "@owlmeans/config": "^0.1.0",
32
+ "@owlmeans/context": "^0.1.0",
33
+ "@owlmeans/route": "^0.1.0",
34
+ "@owlmeans/server-config": "^0.1.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.5.0",
38
+ "nodemon": "^3.1.7",
39
+ "typescript": "^5.6.3"
40
+ },
41
+ "private": false,
42
+ "publishConfig": {
43
+ "access": "public"
44
+ }
45
+ }
package/src/config.ts ADDED
@@ -0,0 +1,10 @@
1
+
2
+ import { AppType, makeBasicConfig } from '@owlmeans/context'
3
+ import type { ServerConfig } from './types.js'
4
+
5
+ export const config = <C extends ServerConfig>(service: string, cfg?: Partial<C>): C => {
6
+ const config: C = makeBasicConfig(AppType.Backend, service, cfg)
7
+ config.trusted = config.trusted ?? []
8
+
9
+ return config
10
+ }
package/src/consts.ts ADDED
@@ -0,0 +1 @@
1
+
package/src/context.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { appendConfigResource, PLUGIN_RECORD } from '@owlmeans/config'
2
+ import { ServerConfig, ServerContext } from './types.js'
3
+ import { fileConfigReader } from './utils/context.js'
4
+ import { makeBasicContext } from '@owlmeans/context'
5
+ import { PLUGINS, TRUSTED } from '@owlmeans/config'
6
+ import { authMiddleware, makeBasicEd25519Guard } from '@owlmeans/auth-common'
7
+
8
+ export const makeServerContext = <C extends ServerConfig, T extends ServerContext<C>>(cfg: C): T => {
9
+ const context = makeBasicContext(cfg) as T
10
+
11
+ context.registerMiddleware(fileConfigReader)
12
+
13
+ context.makeContext = makeServerContext as typeof context.makeContext
14
+
15
+ appendConfigResource<C, T>(context)
16
+ appendConfigResource<C, T>(context, TRUSTED, TRUSTED)
17
+ appendConfigResource<C, T>(context, PLUGINS, PLUGIN_RECORD)
18
+ context.registerService(makeBasicEd25519Guard(TRUSTED))
19
+ context.registerMiddleware(authMiddleware)
20
+
21
+ return context
22
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+
2
+ export * from './context.js'
3
+ // export * from './consts.js'
4
+ export * from './config.js'
5
+ export type * from './types.js'
package/src/types.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { ServiceRoute } from '@owlmeans/server-route'
2
+ import type { ConfigResourceAppend } from '@owlmeans/config'
3
+ import type { BasicServerConfig } from '@owlmeans/server-config'
4
+ import type { BasicClientConfig } from '@owlmeans/client-config'
5
+ import type { BasicContext } from '@owlmeans/context'
6
+
7
+ export interface ServerConfig extends BasicServerConfig, BasicClientConfig {
8
+ services: Record<string, ServiceRoute>
9
+ }
10
+
11
+ export interface ServerContext<C extends ServerConfig> extends BasicContext<C>, ConfigResourceAppend {
12
+ }
@@ -0,0 +1,32 @@
1
+
2
+ import { MiddlewareStage, MiddlewareType } from '@owlmeans/context'
3
+ import type { Middleware } from '@owlmeans/context'
4
+ import { readConfigValue } from '@owlmeans/server-config'
5
+
6
+ export const fileConfigReader: Middleware = {
7
+ type: MiddlewareType.Config,
8
+ stage: MiddlewareStage.Configuration,
9
+ apply: async (context) => {
10
+ const tree: Tree = context.cfg as unknown as Tree
11
+ visitConfigLeafs(tree)
12
+ }
13
+ }
14
+
15
+ // @TODO Move to server config
16
+ const visitConfigLeafs = (tree: Tree) =>
17
+ tree != null ? Object.entries(tree).forEach(([key, value]) => {
18
+ if (typeof value === 'string') {
19
+ const descriptor = Object.getOwnPropertyDescriptor(tree, key)
20
+ if (descriptor?.writable) {
21
+ tree[key] = readConfigValue(value)
22
+ }
23
+ } else if (Array.isArray(value)) {
24
+ value.forEach(tree => { visitConfigLeafs(tree as Tree) })
25
+ } else if (typeof value === 'object') {
26
+ visitConfigLeafs(value as Tree)
27
+ }
28
+ }) : tree
29
+
30
+ type TreeKey = string | number | symbol
31
+ type TreeValue = unknown | Array<unknown> | string
32
+ interface Tree extends Record<TreeKey, TreeValue | Tree> { }
@@ -0,0 +1,2 @@
1
+
2
+ export * from './context.js'
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": [
3
+ "../tsconfig.default.json",
4
+ ],
5
+ "compilerOptions": {
6
+ "rootDir": "./src/", /* Specify the root folder within your source files. */
7
+ "outDir": "./build/", /* Specify an output folder for all emitted files. */
8
+ },
9
+ "exclude": [
10
+ "./dist/**/*",
11
+ "./build/**/*",
12
+ "./*.ts"
13
+ ]
14
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/config.ts","./src/consts.ts","./src/context.ts","./src/index.ts","./src/types.ts","./src/utils/context.ts","./src/utils/index.ts"],"version":"5.6.3"}