@owlmeans/server-app 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 +21 -0
- package/README.md +638 -0
- package/build/.gitkeep +0 -0
- package/build/context.d.ts +3 -0
- package/build/context.d.ts.map +1 -0
- package/build/context.js +21 -0
- package/build/context.js.map +1 -0
- package/build/exports.d.ts +21 -0
- package/build/exports.d.ts.map +1 -0
- package/build/exports.js +16 -0
- package/build/exports.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/build/main.d.ts +5 -0
- package/build/main.d.ts.map +1 -0
- package/build/main.js +8 -0
- package/build/main.js.map +1 -0
- package/build/modules.d.ts +2 -0
- package/build/modules.d.ts.map +1 -0
- package/build/modules.js +4 -0
- package/build/modules.js.map +1 -0
- package/build/types.d.ts +11 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +48 -0
- package/src/context.ts +27 -0
- package/src/exports.ts +21 -0
- package/src/index.ts +6 -0
- package/src/main.ts +15 -0
- package/src/modules.ts +4 -0
- package/src/types.ts +13 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
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,638 @@
|
|
|
1
|
+
# @owlmeans/server-app
|
|
2
|
+
|
|
3
|
+
The **@owlmeans/server-app** package provides a comprehensive server application framework for OwlMeans Common Libraries, offering a complete foundation for building secure, scalable backend applications with authentication, API services, and module management.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This package serves as a high-level application framework that combines multiple OwlMeans packages into a cohesive server application foundation, specifically designed for:
|
|
8
|
+
|
|
9
|
+
- **Complete Application Setup**: Quickly bootstrap full-featured server applications
|
|
10
|
+
- **Integrated Authentication**: Built-in authentication and authorization capabilities
|
|
11
|
+
- **API Server Management**: Automated API server configuration and lifecycle management
|
|
12
|
+
- **Module System Integration**: Seamless integration with the OwlMeans module system
|
|
13
|
+
- **Socket Support**: WebSocket functionality for real-time communication
|
|
14
|
+
- **Static Resource Serving**: Static file serving capabilities
|
|
15
|
+
- **Kubernetes Integration**: Optional Kubernetes deployment and management features
|
|
16
|
+
- **Configuration Management**: Comprehensive configuration handling
|
|
17
|
+
|
|
18
|
+
## Key Concepts
|
|
19
|
+
|
|
20
|
+
### Application Framework
|
|
21
|
+
This package acts as a meta-framework that combines and orchestrates multiple OwlMeans packages to create a complete server application environment.
|
|
22
|
+
|
|
23
|
+
### Context-driven Architecture
|
|
24
|
+
Uses the OwlMeans context system to manage dependencies, services, and application lifecycle in a structured manner.
|
|
25
|
+
|
|
26
|
+
### Module-first Design
|
|
27
|
+
Built around the OwlMeans module system where functionality is organized as URL units that can be transformed into API routes with handlers.
|
|
28
|
+
|
|
29
|
+
### Integrated Services
|
|
30
|
+
Automatically sets up and configures essential services like authentication, API handling, socket communication, and static resource serving.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @owlmeans/server-app
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API Reference
|
|
39
|
+
|
|
40
|
+
### Types
|
|
41
|
+
|
|
42
|
+
#### `AppConfig`
|
|
43
|
+
Application configuration interface extending ServerConfig.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface AppConfig extends ServerConfig, KlusterConfig {
|
|
47
|
+
services: Record<string, ServiceRoute>
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
#### `AppContext<C extends AppConfig = AppConfig>`
|
|
52
|
+
Application context interface with integrated service capabilities.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
interface AppContext<C extends AppConfig = AppConfig> extends ServerContext<C>,
|
|
56
|
+
AuthServiceAppend,
|
|
57
|
+
ApiServerAppend { }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Core Functions
|
|
61
|
+
|
|
62
|
+
#### `makeContext<C extends AppConfig, T extends AppContext<C>>(cfg: C, customize?: boolean): T`
|
|
63
|
+
|
|
64
|
+
Creates a fully configured application context with all necessary services and middleware.
|
|
65
|
+
|
|
66
|
+
**Parameters:**
|
|
67
|
+
- `cfg`: Application configuration object
|
|
68
|
+
- `customize`: Whether to skip default authentication setup (defaults to false)
|
|
69
|
+
|
|
70
|
+
**Returns:** Configured application context
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { makeContext } from '@owlmeans/server-app'
|
|
74
|
+
|
|
75
|
+
const config = {
|
|
76
|
+
service: 'my-app',
|
|
77
|
+
layer: Layer.System,
|
|
78
|
+
type: AppType.Backend,
|
|
79
|
+
services: {
|
|
80
|
+
'database': { host: 'localhost', port: 5432 }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const context = makeContext(config)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### `main<R, C extends AppConfig, T extends AppContext<C>>(ctx: T, modules: (CommonModule | ServerModule<R>)[]): Promise<void>`
|
|
88
|
+
|
|
89
|
+
Main application entry point that registers modules, initializes the context, and starts the API server.
|
|
90
|
+
|
|
91
|
+
**Parameters:**
|
|
92
|
+
- `ctx`: Application context instance
|
|
93
|
+
- `modules`: Array of modules to register with the application
|
|
94
|
+
|
|
95
|
+
**Returns:** Promise that resolves when the application is running
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { main, makeContext } from '@owlmeans/server-app'
|
|
99
|
+
import { modules as defaultModules } from '@owlmeans/server-app'
|
|
100
|
+
|
|
101
|
+
const context = makeContext(config)
|
|
102
|
+
const allModules = [...defaultModules, ...customModules]
|
|
103
|
+
|
|
104
|
+
await main(context, allModules)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Pre-configured Modules
|
|
108
|
+
|
|
109
|
+
#### `modules`
|
|
110
|
+
Default set of modules that provide essential server functionality.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const modules: CommonModule[]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Includes:
|
|
117
|
+
- Server authentication modules
|
|
118
|
+
- API configuration modules
|
|
119
|
+
|
|
120
|
+
### Exported Utilities
|
|
121
|
+
|
|
122
|
+
The package re-exports commonly used utilities from various OwlMeans packages:
|
|
123
|
+
|
|
124
|
+
#### Configuration
|
|
125
|
+
```typescript
|
|
126
|
+
export { config } from '@owlmeans/server-context'
|
|
127
|
+
export { sservice } from '@owlmeans/server-config'
|
|
128
|
+
export { addWebService } from '@owlmeans/client-config'
|
|
129
|
+
export { service, toConfigRecord, PLUGINS } from '@owlmeans/config'
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Module System
|
|
133
|
+
```typescript
|
|
134
|
+
export { parent, filter, body, params, ModuleOutcome } from '@owlmeans/module'
|
|
135
|
+
export { elevate, module, guard } from '@owlmeans/server-module'
|
|
136
|
+
export { elevate as celevate } from '@owlmeans/client-module'
|
|
137
|
+
export { route as broute } from '@owlmeans/server-route'
|
|
138
|
+
export { route } from '@owlmeans/route'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### API Handling
|
|
142
|
+
```typescript
|
|
143
|
+
export { handleRequest, handleBody, handleParams } from '@owlmeans/server-api'
|
|
144
|
+
export type { AbstractRequest as Request, AbstractResponse as Response } from '@owlmeans/module'
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Resource Management
|
|
148
|
+
```typescript
|
|
149
|
+
export { createListSchema, filterObject } from '@owlmeans/resource'
|
|
150
|
+
export type { ListResult } from '@owlmeans/resource'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### Context and Authentication
|
|
154
|
+
```typescript
|
|
155
|
+
export { AppType, BASE, Layer, assertContext } from '@owlmeans/context'
|
|
156
|
+
export { DEFAULT_ALIAS as DAUTH_GUARD } from '@owlmeans/server-auth'
|
|
157
|
+
export { GUARD_ED25519, BED255_CASHE_RESOURCE } from '@owlmeans/auth-common'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Kubernetes Integration
|
|
161
|
+
```typescript
|
|
162
|
+
export { klusterize } from '@owlmeans/kluster'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Usage Examples
|
|
166
|
+
|
|
167
|
+
### Basic Application Setup
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { makeContext, main, modules, config, service } from '@owlmeans/server-app'
|
|
171
|
+
import { AppType, Layer } from '@owlmeans/context'
|
|
172
|
+
|
|
173
|
+
// Create application configuration
|
|
174
|
+
const appConfig = config(
|
|
175
|
+
AppType.Backend,
|
|
176
|
+
'my-server-app',
|
|
177
|
+
service('database', {
|
|
178
|
+
host: process.env.DB_HOST || 'localhost',
|
|
179
|
+
port: parseInt(process.env.DB_PORT || '5432')
|
|
180
|
+
}),
|
|
181
|
+
{
|
|
182
|
+
layer: Layer.System,
|
|
183
|
+
port: 3000,
|
|
184
|
+
services: {
|
|
185
|
+
'auth-service': { host: 'localhost', port: 3001 },
|
|
186
|
+
'api-gateway': { host: 'localhost', port: 3002 }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
// Create application context
|
|
192
|
+
const context = makeContext(appConfig)
|
|
193
|
+
|
|
194
|
+
// Start the application
|
|
195
|
+
await main(context, modules)
|
|
196
|
+
console.log('Server started on port 3000')
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Custom Module Integration
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import {
|
|
203
|
+
makeContext,
|
|
204
|
+
main,
|
|
205
|
+
modules,
|
|
206
|
+
module,
|
|
207
|
+
route,
|
|
208
|
+
guard,
|
|
209
|
+
filter,
|
|
210
|
+
body,
|
|
211
|
+
handleRequest
|
|
212
|
+
} from '@owlmeans/server-app'
|
|
213
|
+
|
|
214
|
+
// Create custom modules
|
|
215
|
+
const userModule = module(
|
|
216
|
+
route('users', '/api/users', { method: 'GET' }),
|
|
217
|
+
guard('authenticated')
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
elevate(userModule, 'users', handleRequest(async (req, res) => {
|
|
221
|
+
const users = await getUsersFromDatabase()
|
|
222
|
+
res.resolve(users)
|
|
223
|
+
}))
|
|
224
|
+
|
|
225
|
+
const createUserModule = module(
|
|
226
|
+
route('create-user', '/api/users', { method: 'POST' }),
|
|
227
|
+
filter(body({
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
name: { type: 'string' },
|
|
231
|
+
email: { type: 'string' }
|
|
232
|
+
},
|
|
233
|
+
required: ['name', 'email']
|
|
234
|
+
}), guard('authenticated'))
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
elevate(createUserModule, 'create-user', handleRequest(async (req, res) => {
|
|
238
|
+
const userData = req.body
|
|
239
|
+
const user = await createUser(userData)
|
|
240
|
+
res.resolve(user, ModuleOutcome.Created)
|
|
241
|
+
}))
|
|
242
|
+
|
|
243
|
+
// Combine with default modules
|
|
244
|
+
const allModules = [...modules, userModule, createUserModule]
|
|
245
|
+
|
|
246
|
+
// Create and start application
|
|
247
|
+
const context = makeContext(appConfig)
|
|
248
|
+
await main(context, allModules)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Database Integration
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { makeContext, main, service, config } from '@owlmeans/server-app'
|
|
255
|
+
|
|
256
|
+
// Configure database service
|
|
257
|
+
const appConfig = config(
|
|
258
|
+
AppType.Backend,
|
|
259
|
+
'data-app',
|
|
260
|
+
service('mongodb', {
|
|
261
|
+
uri: process.env.MONGODB_URI || 'mongodb://localhost:27017',
|
|
262
|
+
database: 'myapp'
|
|
263
|
+
}),
|
|
264
|
+
service('redis', {
|
|
265
|
+
host: process.env.REDIS_HOST || 'localhost',
|
|
266
|
+
port: parseInt(process.env.REDIS_PORT || '6379')
|
|
267
|
+
})
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
const context = makeContext(appConfig)
|
|
271
|
+
|
|
272
|
+
// Register database-related modules
|
|
273
|
+
const databaseModules = [
|
|
274
|
+
// Your database modules here
|
|
275
|
+
]
|
|
276
|
+
|
|
277
|
+
await main(context, [...modules, ...databaseModules])
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Authentication and Authorization
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import {
|
|
284
|
+
makeContext,
|
|
285
|
+
main,
|
|
286
|
+
modules,
|
|
287
|
+
module,
|
|
288
|
+
route,
|
|
289
|
+
guard,
|
|
290
|
+
DAUTH_GUARD,
|
|
291
|
+
GUARD_ED25519
|
|
292
|
+
} from '@owlmeans/server-app'
|
|
293
|
+
|
|
294
|
+
// Create protected admin module
|
|
295
|
+
const adminModule = module(
|
|
296
|
+
route('admin', '/api/admin', { method: 'GET' }),
|
|
297
|
+
guard([DAUTH_GUARD, GUARD_ED25519]) // Multiple guards
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
elevate(adminModule, 'admin', handleRequest(async (req, res) => {
|
|
301
|
+
// Only authenticated users with proper keys can access
|
|
302
|
+
const adminData = await getAdminData()
|
|
303
|
+
res.resolve(adminData)
|
|
304
|
+
}))
|
|
305
|
+
|
|
306
|
+
const context = makeContext(appConfig)
|
|
307
|
+
await main(context, [...modules, adminModule])
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### WebSocket Integration
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
import { makeContext, main, modules } from '@owlmeans/server-app'
|
|
314
|
+
|
|
315
|
+
// WebSocket is automatically configured in makeContext
|
|
316
|
+
const context = makeContext(appConfig)
|
|
317
|
+
|
|
318
|
+
// Access socket service if needed
|
|
319
|
+
await context.configure().init()
|
|
320
|
+
const socketService = context.service('socket')
|
|
321
|
+
|
|
322
|
+
// Register socket event handlers
|
|
323
|
+
socketService.on('user-connected', (socket, data) => {
|
|
324
|
+
console.log('User connected:', data.userId)
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
await main(context, modules)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Static File Serving
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import { makeContext, main, modules } from '@owlmeans/server-app'
|
|
334
|
+
|
|
335
|
+
const appConfig = config(
|
|
336
|
+
AppType.Backend,
|
|
337
|
+
'web-server',
|
|
338
|
+
{
|
|
339
|
+
staticPath: './public',
|
|
340
|
+
staticRoute: '/static'
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
// Static resource serving is automatically configured
|
|
345
|
+
const context = makeContext(appConfig)
|
|
346
|
+
await main(context, modules)
|
|
347
|
+
|
|
348
|
+
// Now files in ./public are served at /static/*
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Custom Context Configuration
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { makeContext, main, appendCustomService } from '@owlmeans/server-app'
|
|
355
|
+
|
|
356
|
+
// Create context with custom flag to skip default auth
|
|
357
|
+
const context = makeContext(appConfig, true) // customize = true
|
|
358
|
+
|
|
359
|
+
// Add custom services
|
|
360
|
+
const customService = createService('custom-service', {
|
|
361
|
+
process: async (data) => {
|
|
362
|
+
return processData(data)
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
context.registerService(customService)
|
|
367
|
+
|
|
368
|
+
// Add custom authentication if needed
|
|
369
|
+
// ... custom auth setup
|
|
370
|
+
|
|
371
|
+
await main(context, modules)
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Environment-based Configuration
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
import {
|
|
378
|
+
makeContext,
|
|
379
|
+
main,
|
|
380
|
+
modules,
|
|
381
|
+
config,
|
|
382
|
+
service,
|
|
383
|
+
toConfigRecord
|
|
384
|
+
} from '@owlmeans/server-app'
|
|
385
|
+
|
|
386
|
+
// Create environment-aware configuration
|
|
387
|
+
const appConfig = config(
|
|
388
|
+
AppType.Backend,
|
|
389
|
+
process.env.SERVICE_NAME || 'default-app',
|
|
390
|
+
...toConfigRecord({
|
|
391
|
+
'database': {
|
|
392
|
+
host: process.env.DB_HOST || 'localhost',
|
|
393
|
+
port: parseInt(process.env.DB_PORT || '5432'),
|
|
394
|
+
ssl: process.env.NODE_ENV === 'production'
|
|
395
|
+
},
|
|
396
|
+
'redis': {
|
|
397
|
+
host: process.env.REDIS_HOST || 'localhost',
|
|
398
|
+
port: parseInt(process.env.REDIS_PORT || '6379')
|
|
399
|
+
}
|
|
400
|
+
}),
|
|
401
|
+
{
|
|
402
|
+
layer: process.env.NODE_ENV === 'production' ? Layer.Service : Layer.System,
|
|
403
|
+
port: parseInt(process.env.PORT || '3000'),
|
|
404
|
+
debug: {
|
|
405
|
+
all: process.env.NODE_ENV !== 'production'
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
const context = makeContext(appConfig)
|
|
411
|
+
await main(context, modules)
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### API Route Management
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import {
|
|
418
|
+
module,
|
|
419
|
+
route,
|
|
420
|
+
broute,
|
|
421
|
+
filter,
|
|
422
|
+
body,
|
|
423
|
+
params,
|
|
424
|
+
guard,
|
|
425
|
+
handleRequest,
|
|
426
|
+
handleBody,
|
|
427
|
+
handleParams
|
|
428
|
+
} from '@owlmeans/server-app'
|
|
429
|
+
|
|
430
|
+
// Create REST API modules
|
|
431
|
+
const userRoutes = [
|
|
432
|
+
// GET /api/users
|
|
433
|
+
module(
|
|
434
|
+
broute('list-users', '/api/users'),
|
|
435
|
+
guard('authenticated')
|
|
436
|
+
),
|
|
437
|
+
|
|
438
|
+
// GET /api/users/:id
|
|
439
|
+
module(
|
|
440
|
+
broute('get-user', '/api/users/:id'),
|
|
441
|
+
filter(params({
|
|
442
|
+
type: 'object',
|
|
443
|
+
properties: {
|
|
444
|
+
id: { type: 'string', pattern: '^[0-9]+$' }
|
|
445
|
+
},
|
|
446
|
+
required: ['id']
|
|
447
|
+
}), guard('authenticated'))
|
|
448
|
+
),
|
|
449
|
+
|
|
450
|
+
// POST /api/users
|
|
451
|
+
module(
|
|
452
|
+
broute('create-user', '/api/users', { method: 'POST' }),
|
|
453
|
+
filter(body({
|
|
454
|
+
type: 'object',
|
|
455
|
+
properties: {
|
|
456
|
+
name: { type: 'string', minLength: 1 },
|
|
457
|
+
email: { type: 'string', format: 'email' }
|
|
458
|
+
},
|
|
459
|
+
required: ['name', 'email']
|
|
460
|
+
}), guard('authenticated'))
|
|
461
|
+
)
|
|
462
|
+
]
|
|
463
|
+
|
|
464
|
+
// Add handlers
|
|
465
|
+
userRoutes.forEach(userModule => {
|
|
466
|
+
switch (userModule.getAlias()) {
|
|
467
|
+
case 'list-users':
|
|
468
|
+
elevate(userModule, 'list-users', handleRequest(async (req, res) => {
|
|
469
|
+
const users = await listUsers()
|
|
470
|
+
res.resolve(users)
|
|
471
|
+
}))
|
|
472
|
+
break
|
|
473
|
+
case 'get-user':
|
|
474
|
+
elevate(userModule, 'get-user', handleParams(async (req, res) => {
|
|
475
|
+
const user = await getUserById(req.params.id)
|
|
476
|
+
res.resolve(user)
|
|
477
|
+
}))
|
|
478
|
+
break
|
|
479
|
+
case 'create-user':
|
|
480
|
+
elevate(userModule, 'create-user', handleBody(async (req, res) => {
|
|
481
|
+
const user = await createUser(req.body)
|
|
482
|
+
res.resolve(user, ModuleOutcome.Created)
|
|
483
|
+
}))
|
|
484
|
+
break
|
|
485
|
+
}
|
|
486
|
+
})
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Integration Patterns
|
|
490
|
+
|
|
491
|
+
### Microservice Architecture
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
import { makeContext, main, klusterize } from '@owlmeans/server-app'
|
|
495
|
+
|
|
496
|
+
// Configure for Kubernetes deployment
|
|
497
|
+
const appConfig = config(
|
|
498
|
+
AppType.Backend,
|
|
499
|
+
'user-service',
|
|
500
|
+
klusterize({
|
|
501
|
+
namespace: 'production',
|
|
502
|
+
serviceName: 'user-service',
|
|
503
|
+
replicas: 3
|
|
504
|
+
}),
|
|
505
|
+
{
|
|
506
|
+
port: 8080,
|
|
507
|
+
services: {
|
|
508
|
+
'auth-service': {
|
|
509
|
+
host: 'auth-service.production.svc.cluster.local',
|
|
510
|
+
port: 8080
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
const context = makeContext(appConfig)
|
|
517
|
+
await main(context, [...modules, ...userServiceModules])
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### API Gateway Pattern
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
// API Gateway service
|
|
524
|
+
const gatewayConfig = config(
|
|
525
|
+
AppType.Backend,
|
|
526
|
+
'api-gateway',
|
|
527
|
+
{
|
|
528
|
+
port: 80,
|
|
529
|
+
services: {
|
|
530
|
+
'user-service': { host: 'user-service', port: 8080 },
|
|
531
|
+
'order-service': { host: 'order-service', port: 8080 },
|
|
532
|
+
'payment-service': { host: 'payment-service', port: 8080 }
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
// Proxy modules that forward requests to appropriate services
|
|
538
|
+
const proxyModules = [
|
|
539
|
+
createProxyModule('/api/users', 'user-service'),
|
|
540
|
+
createProxyModule('/api/orders', 'order-service'),
|
|
541
|
+
createProxyModule('/api/payments', 'payment-service')
|
|
542
|
+
]
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Development vs Production
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
import { makeContext, main, modules } from '@owlmeans/server-app'
|
|
549
|
+
|
|
550
|
+
const isDevelopment = process.env.NODE_ENV === 'development'
|
|
551
|
+
|
|
552
|
+
const appConfig = config(
|
|
553
|
+
AppType.Backend,
|
|
554
|
+
'app',
|
|
555
|
+
{
|
|
556
|
+
port: isDevelopment ? 3000 : 8080,
|
|
557
|
+
debug: { all: isDevelopment },
|
|
558
|
+
layer: isDevelopment ? Layer.System : Layer.Service,
|
|
559
|
+
services: isDevelopment ? {
|
|
560
|
+
'database': { host: 'localhost', port: 5432 }
|
|
561
|
+
} : {
|
|
562
|
+
'database': {
|
|
563
|
+
host: 'postgres.production.svc.cluster.local',
|
|
564
|
+
port: 5432
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
const context = makeContext(appConfig)
|
|
571
|
+
await main(context, modules)
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
## Error Handling
|
|
575
|
+
|
|
576
|
+
```typescript
|
|
577
|
+
import { main, makeContext } from '@owlmeans/server-app'
|
|
578
|
+
|
|
579
|
+
try {
|
|
580
|
+
const context = makeContext(appConfig)
|
|
581
|
+
await main(context, modules)
|
|
582
|
+
} catch (error) {
|
|
583
|
+
console.error('Application failed to start:', error)
|
|
584
|
+
|
|
585
|
+
// Graceful shutdown
|
|
586
|
+
process.exit(1)
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Handle process signals
|
|
590
|
+
process.on('SIGINT', async () => {
|
|
591
|
+
console.log('Received SIGINT, shutting down gracefully')
|
|
592
|
+
// Cleanup logic here
|
|
593
|
+
process.exit(0)
|
|
594
|
+
})
|
|
595
|
+
|
|
596
|
+
process.on('SIGTERM', async () => {
|
|
597
|
+
console.log('Received SIGTERM, shutting down gracefully')
|
|
598
|
+
// Cleanup logic here
|
|
599
|
+
process.exit(0)
|
|
600
|
+
})
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## Best Practices
|
|
604
|
+
|
|
605
|
+
1. **Configuration Management**: Use environment variables for configuration
|
|
606
|
+
2. **Module Organization**: Group related functionality into modules
|
|
607
|
+
3. **Authentication**: Always implement proper authentication and authorization
|
|
608
|
+
4. **Error Handling**: Implement comprehensive error handling and logging
|
|
609
|
+
5. **Monitoring**: Add health check endpoints and monitoring capabilities
|
|
610
|
+
6. **Security**: Follow security best practices for API development
|
|
611
|
+
7. **Documentation**: Document your API endpoints and their contracts
|
|
612
|
+
8. **Testing**: Write comprehensive tests for your modules and handlers
|
|
613
|
+
|
|
614
|
+
## Dependencies
|
|
615
|
+
|
|
616
|
+
This package depends on:
|
|
617
|
+
- `@owlmeans/api` - API framework
|
|
618
|
+
- `@owlmeans/client-config` - Client configuration utilities
|
|
619
|
+
- `@owlmeans/config` - Configuration management
|
|
620
|
+
- `@owlmeans/context` - Context management system
|
|
621
|
+
- `@owlmeans/kluster` - Kubernetes integration
|
|
622
|
+
- `@owlmeans/module` - Module system
|
|
623
|
+
- `@owlmeans/route` - Routing functionality
|
|
624
|
+
- `@owlmeans/server-api` - Server API framework
|
|
625
|
+
- `@owlmeans/server-auth` - Server authentication
|
|
626
|
+
- `@owlmeans/server-context` - Server context management
|
|
627
|
+
- `@owlmeans/server-module` - Server module system
|
|
628
|
+
- `@owlmeans/server-route` - Server routing
|
|
629
|
+
- `@owlmeans/server-socket` - WebSocket support
|
|
630
|
+
- `@owlmeans/static-resource` - Static file serving
|
|
631
|
+
|
|
632
|
+
## Related Packages
|
|
633
|
+
|
|
634
|
+
- [`@owlmeans/server-context`](../server-context) - Server context management
|
|
635
|
+
- [`@owlmeans/server-api`](../server-api) - Server API framework
|
|
636
|
+
- [`@owlmeans/server-auth`](../server-auth) - Server authentication
|
|
637
|
+
- [`@owlmeans/server-module`](../server-module) - Server module system
|
|
638
|
+
- [`@owlmeans/kluster`](../kluster) - Kubernetes integration
|
package/build/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAMvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,cAAa,OAAO,MAkBnG,CAAA"}
|
package/build/context.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { appendAuthService, AUTH_CACHE } from '@owlmeans/server-auth';
|
|
2
|
+
import { makeServerContext } from '@owlmeans/server-context';
|
|
3
|
+
import { appendApiServer } from '@owlmeans/server-api';
|
|
4
|
+
import { appendApiClient } from '@owlmeans/api';
|
|
5
|
+
import { appendStaticResource } from '@owlmeans/static-resource';
|
|
6
|
+
import { appendSocketService, createSocketMiddleware } from '@owlmeans/server-socket';
|
|
7
|
+
export const makeContext = (cfg, customize = false) => {
|
|
8
|
+
const context = makeServerContext(cfg);
|
|
9
|
+
appendApiServer(context);
|
|
10
|
+
appendApiClient(context);
|
|
11
|
+
appendSocketService(context);
|
|
12
|
+
context.registerMiddleware(createSocketMiddleware());
|
|
13
|
+
appendStaticResource(context);
|
|
14
|
+
if (!customize && !context.hasResource(AUTH_CACHE)) {
|
|
15
|
+
appendStaticResource(context, AUTH_CACHE);
|
|
16
|
+
appendAuthService(context);
|
|
17
|
+
}
|
|
18
|
+
context.makeContext = cfg => makeContext(cfg, customize);
|
|
19
|
+
return context;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAErF,MAAM,CAAC,MAAM,WAAW,GAAG,CAA+C,GAAM,EAAE,YAAqB,KAAK,EAAE,EAAE;IAC9G,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAM,CAAA;IAE3C,eAAe,CAAO,OAAO,CAAC,CAAA;IAC9B,eAAe,CAAO,OAAO,CAAC,CAAA;IAC9B,mBAAmB,CAAO,OAAO,CAAC,CAAA;IAElC,OAAO,CAAC,kBAAkB,CAAC,sBAAsB,EAAE,CAAC,CAAA;IAEpD,oBAAoB,CAAO,OAAO,CAAC,CAAA;IACnC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QACnD,oBAAoB,CAAO,OAAO,EAAE,UAAU,CAAC,CAAA;QAC/C,iBAAiB,CAAO,OAAO,CAAC,CAAA;IAClC,CAAC;IAED,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,CAAQ,CAAA;IAE/D,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { config } from '@owlmeans/server-context';
|
|
2
|
+
export { sservice } from '@owlmeans/server-config';
|
|
3
|
+
export { addWebService } from '@owlmeans/client-config';
|
|
4
|
+
export { service, toConfigRecord, PLUGINS } from '@owlmeans/config';
|
|
5
|
+
export { parent, filter, body, params, ModuleOutcome } from '@owlmeans/module';
|
|
6
|
+
export type { AbstractRequest as Request, AbstractResponse as Response } from '@owlmeans/module';
|
|
7
|
+
export { createListSchema, filterObject } from '@owlmeans/resource';
|
|
8
|
+
export type { ListResult } from '@owlmeans/resource';
|
|
9
|
+
export { AppType, BASE, Layer, assertContext } from '@owlmeans/context';
|
|
10
|
+
export { elevate, module, guard } from '@owlmeans/server-module';
|
|
11
|
+
export { elevate as celevate } from '@owlmeans/client-module';
|
|
12
|
+
export type { ServerModule as Module, RefedModuleHandler } from '@owlmeans/server-module';
|
|
13
|
+
export type { ClientModule } from '@owlmeans/client-module';
|
|
14
|
+
export { route as broute } from '@owlmeans/server-route';
|
|
15
|
+
export { handleRequest, handleBody, handleParams } from '@owlmeans/server-api';
|
|
16
|
+
export { route } from '@owlmeans/route';
|
|
17
|
+
export { DEFAULT_ALIAS as DAUTH_GUARD } from '@owlmeans/server-auth';
|
|
18
|
+
export { klusterize } from '@owlmeans/kluster';
|
|
19
|
+
export type { PluginConfig } from '@owlmeans/config';
|
|
20
|
+
export { GUARD_ED25519, BED255_CASHE_RESOURCE } from '@owlmeans/auth-common';
|
|
21
|
+
//# sourceMappingURL=exports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAC9E,YAAY,EAAE,eAAe,IAAI,OAAO,EAAE,gBAAgB,IAAI,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACnE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC7D,YAAY,EAAE,YAAY,IAAI,MAAM,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACzF,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,KAAK,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA"}
|
package/build/exports.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { config } from '@owlmeans/server-context';
|
|
2
|
+
export { sservice } from '@owlmeans/server-config';
|
|
3
|
+
export { addWebService } from '@owlmeans/client-config';
|
|
4
|
+
export { service, toConfigRecord, PLUGINS } from '@owlmeans/config';
|
|
5
|
+
export { parent, filter, body, params, ModuleOutcome } from '@owlmeans/module';
|
|
6
|
+
export { createListSchema, filterObject } from '@owlmeans/resource';
|
|
7
|
+
export { AppType, BASE, Layer, assertContext } from '@owlmeans/context';
|
|
8
|
+
export { elevate, module, guard } from '@owlmeans/server-module';
|
|
9
|
+
export { elevate as celevate } from '@owlmeans/client-module';
|
|
10
|
+
export { route as broute } from '@owlmeans/server-route';
|
|
11
|
+
export { handleRequest, handleBody, handleParams } from '@owlmeans/server-api';
|
|
12
|
+
export { route } from '@owlmeans/route';
|
|
13
|
+
export { DEFAULT_ALIAS as DAUTH_GUARD } from '@owlmeans/server-auth';
|
|
14
|
+
export { klusterize } from '@owlmeans/kluster';
|
|
15
|
+
export { GUARD_ED25519, BED255_CASHE_RESOURCE } from '@owlmeans/auth-common';
|
|
16
|
+
//# sourceMappingURL=exports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports.js","sourceRoot":"","sources":["../src/exports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEnE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAG7D,OAAO,EAAE,KAAK,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,aAAa,IAAI,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,mBAAmB,YAAY,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AAEzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
|
package/build/main.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ServerModule } from '@owlmeans/server-module';
|
|
2
|
+
import type { CommonModule } from '@owlmeans/module';
|
|
3
|
+
import type { AppContext, AppConfig } from './types.js';
|
|
4
|
+
export declare const main: <R, C extends AppConfig, T extends AppContext<C>>(ctx: T, modules: (CommonModule | ServerModule<R>)[]) => Promise<void>;
|
|
5
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAIvD,eAAO,MAAM,IAAI,GAAU,CAAC,EAAE,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,OACnE,CAAC,WAAW,CAAC,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,kBAKpD,CAAA"}
|
package/build/main.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @TODO Remove or refactor request types. We actually don't use them and this make
|
|
2
|
+
// a mess with <R
|
|
3
|
+
export const main = async (ctx, modules) => {
|
|
4
|
+
ctx.registerModules(modules);
|
|
5
|
+
await ctx.configure().init();
|
|
6
|
+
await ctx.getApiServer().listen();
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAMA,mFAAmF;AACnF,iBAAiB;AACjB,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EACvB,GAAM,EAAE,OAA2C,EACnD,EAAE;IACF,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAC5B,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,CAAA;IAC5B,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,CAAA;AACnC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,2DAA0B,CAAA"}
|
package/build/modules.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAEvD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,SAAS,CAAC,CAAA"}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ServerContext, ServerConfig } from '@owlmeans/server-context';
|
|
2
|
+
import type { AuthServiceAppend } from '@owlmeans/server-auth';
|
|
3
|
+
import type { KlusterConfig } from '@owlmeans/kluster';
|
|
4
|
+
import type { ServiceRoute } from '@owlmeans/server-route';
|
|
5
|
+
import type { ApiServerAppend } from '@owlmeans/server-api';
|
|
6
|
+
export interface AppConfig extends ServerConfig, KlusterConfig {
|
|
7
|
+
services: Record<string, ServiceRoute>;
|
|
8
|
+
}
|
|
9
|
+
export interface AppContext<C extends AppConfig = AppConfig> extends ServerContext<C>, AuthServiceAppend, ApiServerAppend {
|
|
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,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE3D,MAAM,WAAW,SAAU,SAAQ,YAAY,EAAE,aAAa;IAC5D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EACnF,iBAAiB,EACjB,eAAe;CAAI"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owlmeans/server-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsc -b",
|
|
7
|
+
"dev": "sleep 270 && 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/api": "^0.1.0",
|
|
24
|
+
"@owlmeans/client-config": "^0.1.0",
|
|
25
|
+
"@owlmeans/client-module": "^0.1.0",
|
|
26
|
+
"@owlmeans/config": "^0.1.0",
|
|
27
|
+
"@owlmeans/context": "^0.1.0",
|
|
28
|
+
"@owlmeans/kluster": "^0.1.0",
|
|
29
|
+
"@owlmeans/module": "^0.1.0",
|
|
30
|
+
"@owlmeans/route": "^0.1.0",
|
|
31
|
+
"@owlmeans/server-api": "^0.1.0",
|
|
32
|
+
"@owlmeans/server-auth": "^0.1.0",
|
|
33
|
+
"@owlmeans/server-context": "^0.1.0",
|
|
34
|
+
"@owlmeans/server-module": "^0.1.0",
|
|
35
|
+
"@owlmeans/server-route": "^0.1.0",
|
|
36
|
+
"@owlmeans/server-socket": "^0.1.0",
|
|
37
|
+
"@owlmeans/static-resource": "^0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^22.7.8",
|
|
41
|
+
"nodemon": "^3.1.7",
|
|
42
|
+
"typescript": "^5.6.3"
|
|
43
|
+
},
|
|
44
|
+
"private": false,
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { appendAuthService, AUTH_CACHE } from '@owlmeans/server-auth'
|
|
2
|
+
import { makeServerContext } from '@owlmeans/server-context'
|
|
3
|
+
import type { AppConfig, AppContext } from './types.js'
|
|
4
|
+
import { appendApiServer } from '@owlmeans/server-api'
|
|
5
|
+
import { appendApiClient } from '@owlmeans/api'
|
|
6
|
+
import { appendStaticResource } from '@owlmeans/static-resource'
|
|
7
|
+
import { appendSocketService, createSocketMiddleware } from '@owlmeans/server-socket'
|
|
8
|
+
|
|
9
|
+
export const makeContext = <C extends AppConfig, T extends AppContext<C>>(cfg: C, customize: boolean = false) => {
|
|
10
|
+
const context = makeServerContext(cfg) as T
|
|
11
|
+
|
|
12
|
+
appendApiServer<C, T>(context)
|
|
13
|
+
appendApiClient<C, T>(context)
|
|
14
|
+
appendSocketService<C, T>(context)
|
|
15
|
+
|
|
16
|
+
context.registerMiddleware(createSocketMiddleware())
|
|
17
|
+
|
|
18
|
+
appendStaticResource<C, T>(context)
|
|
19
|
+
if (!customize && !context.hasResource(AUTH_CACHE)) {
|
|
20
|
+
appendStaticResource<C, T>(context, AUTH_CACHE)
|
|
21
|
+
appendAuthService<C, T>(context)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
context.makeContext = cfg => makeContext(cfg, customize) as any
|
|
25
|
+
|
|
26
|
+
return context
|
|
27
|
+
}
|
package/src/exports.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
export { config } from '@owlmeans/server-context'
|
|
3
|
+
export { sservice } from '@owlmeans/server-config'
|
|
4
|
+
export { addWebService } from '@owlmeans/client-config'
|
|
5
|
+
export { service, toConfigRecord, PLUGINS } from '@owlmeans/config'
|
|
6
|
+
export { parent, filter, body, params, ModuleOutcome } from '@owlmeans/module'
|
|
7
|
+
export type { AbstractRequest as Request, AbstractResponse as Response } from '@owlmeans/module'
|
|
8
|
+
export { createListSchema, filterObject } from '@owlmeans/resource'
|
|
9
|
+
export type { ListResult } from '@owlmeans/resource'
|
|
10
|
+
export { AppType, BASE, Layer, assertContext } from '@owlmeans/context'
|
|
11
|
+
export { elevate, module, guard } from '@owlmeans/server-module'
|
|
12
|
+
export { elevate as celevate } from '@owlmeans/client-module'
|
|
13
|
+
export type { ServerModule as Module, RefedModuleHandler } from '@owlmeans/server-module'
|
|
14
|
+
export type { ClientModule } from '@owlmeans/client-module'
|
|
15
|
+
export { route as broute } from '@owlmeans/server-route'
|
|
16
|
+
export { handleRequest, handleBody, handleParams } from '@owlmeans/server-api'
|
|
17
|
+
export { route } from '@owlmeans/route'
|
|
18
|
+
export { DEFAULT_ALIAS as DAUTH_GUARD } from '@owlmeans/server-auth'
|
|
19
|
+
export { klusterize } from '@owlmeans/kluster'
|
|
20
|
+
export type { PluginConfig } from '@owlmeans/config'
|
|
21
|
+
export { GUARD_ED25519, BED255_CASHE_RESOURCE } from '@owlmeans/auth-common'
|
package/src/index.ts
ADDED
package/src/main.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import type { ServerModule } from '@owlmeans/server-module'
|
|
4
|
+
import type { CommonModule } from '@owlmeans/module'
|
|
5
|
+
import type { AppContext, AppConfig } from './types.js'
|
|
6
|
+
|
|
7
|
+
// @TODO Remove or refactor request types. We actually don't use them and this make
|
|
8
|
+
// a mess with <R
|
|
9
|
+
export const main = async <R, C extends AppConfig, T extends AppContext<C>>(
|
|
10
|
+
ctx: T, modules: (CommonModule | ServerModule<R>)[]
|
|
11
|
+
) => {
|
|
12
|
+
ctx.registerModules(modules)
|
|
13
|
+
await ctx.configure().init()
|
|
14
|
+
await ctx.getApiServer().listen()
|
|
15
|
+
}
|
package/src/modules.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ServerContext, ServerConfig } from '@owlmeans/server-context'
|
|
2
|
+
import type { AuthServiceAppend } from '@owlmeans/server-auth'
|
|
3
|
+
import type { KlusterConfig } from '@owlmeans/kluster'
|
|
4
|
+
import type { ServiceRoute } from '@owlmeans/server-route'
|
|
5
|
+
import type { ApiServerAppend } from '@owlmeans/server-api'
|
|
6
|
+
|
|
7
|
+
export interface AppConfig extends ServerConfig, KlusterConfig {
|
|
8
|
+
services: Record<string, ServiceRoute>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface AppContext<C extends AppConfig = AppConfig> extends ServerContext<C>,
|
|
12
|
+
AuthServiceAppend,
|
|
13
|
+
ApiServerAppend { }
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
"moduleResolution": "Bundler",
|
|
9
|
+
},
|
|
10
|
+
"exclude": [
|
|
11
|
+
"./dist/**/*",
|
|
12
|
+
"./build/**/*",
|
|
13
|
+
"./*.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/context.ts","./src/exports.ts","./src/index.ts","./src/main.ts","./src/modules.ts","./src/types.ts"],"version":"5.6.3"}
|