@owlmeans/route 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.
Files changed (3) hide show
  1. package/README.md +38 -524
  2. package/package.json +4 -3
  3. package/tsconfig.json +5 -9
package/README.md CHANGED
@@ -1,561 +1,75 @@
1
1
  # @owlmeans/route
2
2
 
3
- Cross-environment routing library for OwlMeans applications that provides structures for URLs, URIs, aliases, permissions, and validations.
3
+ Route model factory and type definitions for OwlMeans modules.
4
4
 
5
5
  ## Overview
6
6
 
7
- The `@owlmeans/route` module is a core component of the OwlMeans Common library suite that provides routing functionality as part of the OwlMeans Common Module approach (described in `@owlmeans/context`). This module is not self-sufficient and is designed to work within the OwlMeans Common Module ecosystem.
8
-
9
- ### Understanding "Modules" in OwlMeans Common Libraries
10
-
11
- The term "module" in the context of OwlMeans Common libraries refers not to a programmatic module but to a **URL unit** in the system. The OwlMeans Common libraries are intended for fullstack microservices and microclients development, where modules serve as a central registry for URL structures.
12
-
13
- Modules provide several key capabilities:
14
-
15
- - **URL Declaration and Nesting** - Define hierarchical URL structures that can be shared across services
16
- - **Context-Aware Transformation** - Transform module definitions into routes based on frontend or backend context
17
- - **Handler Attachment** - On the backend, attach handlers to routes; on the frontend, specify which components to render
18
- - **URL Generation** - Generate final URLs for navigation or API calls on both backend and frontend
19
- - **Centralized Registration** - Provide a single place where all possible routes are registered, allowing micro-applications and micro-services to seamlessly address different parts of the system
20
-
21
- This approach enables consistent URL management across distributed systems while maintaining flexibility for different deployment contexts.
22
-
23
- ### Key Features
24
-
25
- - **Routes** - Cross-environment structures consisting of URLs, URIs, aliases, permissions, and validations (POJO)
26
- - **Route Models** - Wrapper objects that add behavior to route POJOs with resolution capabilities
27
- - **Service Routes** - Routes that define service endpoints and configurations
28
- - **Resolution Logic** - Context-aware route resolution with parent-child relationships
29
- - **Helper Functions** - Utilities for creating, manipulating, and working with routes
30
-
31
- ## Core Concepts
32
-
33
- ### Route
34
- A route is a cross-environment structure that defines how to access a particular endpoint or resource. It includes:
35
- - **Alias** - Unique identifier for the route
36
- - **Path** - URL path pattern
37
- - **Parent** - Optional parent route for hierarchical structures
38
- - **Method** - HTTP method (GET, POST, PUT, PATCH)
39
- - **Protocol** - Communication protocol (HTTP, WebSocket)
40
- - **Security** - Whether the route requires secure connections
41
-
42
- ### Route Model
43
- A route model wraps a route POJO with additional behavior, particularly the ability to resolve the route within a given context.
44
-
45
- ### Service Route
46
- A service route is an object that describes the base URL of a service (host, port, and other connection details). It differs from a regular route object, which describes a specific URL within a service.
7
+ - `route()` creates a `CommonRouteModel` used as the first argument to `module()`
8
+ - `frontend()` / `backend()` / `socket()` helpers set the route's `AppType` and parent
9
+ - `RouteMethod` enum covers HTTP verbs; `RouteProtocols` covers `http`/`ws`
10
+ - This package is a dependency of `@owlmeans/module` — you rarely use it directly unless defining module-level routes
47
11
 
48
12
  ## Installation
49
13
 
50
14
  ```bash
51
- npm install @owlmeans/route
52
- ```
53
-
54
- ## API Reference
55
-
56
- ### Types
57
-
58
- #### CommonRoute
59
- Main route interface that extends BasicRoute with additional properties.
60
-
61
- ```typescript
62
- interface CommonRoute extends BasicRoute {
63
- alias: string // Unique identifier for the route
64
- path: string // URL path pattern
65
- parent?: string // Optional parent route alias
66
- default?: boolean // Whether this is a default route
67
- method?: RouteMethod // HTTP method
68
- protocol?: RouteProtocols // Communication protocol
69
- secure?: boolean // Whether secure connection is required
70
- }
71
- ```
72
-
73
- #### CommonServiceRoute
74
- Service route interface that describes the base URL of a service.
75
-
76
- ```typescript
77
- interface CommonServiceRoute extends BasicRoute {
78
- home?: string // Home path for the service
79
- service: string // Service identifier
80
- default?: boolean // Whether this is a default service
81
- }
82
- ```
83
-
84
- **Note:** A service route describes the base URL of a service (such as host and port), while a regular route describes a specific URL within that service.
85
-
86
- #### BasicRoute
87
- Base route interface with common properties.
88
-
89
- ```typescript
90
- interface BasicRoute {
91
- type: AppType // Application type (Backend/Frontend)
92
- service?: string // Service identifier
93
- host?: string // Host address
94
- port?: number // Port number
95
- base?: string // Base path
96
- resolved: boolean // Whether route is resolved
97
- }
98
- ```
99
-
100
- #### CommonRouteModel
101
- Route model that wraps a route with resolution capabilities.
102
-
103
- ```typescript
104
- interface CommonRouteModel {
105
- route: CommonRoute // The wrapped route
106
- resolve: <C extends BasicConfig, T extends BasicContext<C>>(context: T) => Promise<CommonRoute>
107
- }
108
- ```
109
-
110
- #### RouteOptions
111
- Partial CommonRoute options for route creation.
112
-
113
- ```typescript
114
- interface RouteOptions extends Partial<CommonRoute> {
115
- }
116
- ```
117
-
118
- ### Constants
119
-
120
- #### RouteMethod
121
- Enumeration of supported HTTP methods.
122
-
123
- ```typescript
124
- enum RouteMethod {
125
- GET = 'get',
126
- POST = 'post',
127
- PATCH = 'patch',
128
- PUT = 'put'
129
- }
130
- ```
131
-
132
- #### RouteProtocols
133
- Enumeration of supported communication protocols.
134
-
135
- ```typescript
136
- enum RouteProtocols {
137
- WEB = 'http',
138
- SOCKET = 'ws'
139
- }
140
- ```
141
-
142
- #### SEP
143
- Path separator constant.
144
-
145
- ```typescript
146
- const SEP = '/'
147
- ```
148
-
149
- #### PARAM
150
- Parameter prefix constant.
151
-
152
- ```typescript
153
- const PARAM = ':'
154
- ```
155
-
156
- ### Core Functions
157
-
158
- #### route(alias, path, opts?)
159
- Creates a route model from the given parameters.
160
-
161
- ```typescript
162
- const route: CreateRouteSignature<CommonRouteModel> = (alias, path, opts?) => CommonRouteModel
163
- ```
164
-
165
- **Parameters:**
166
- - `alias: string` - Unique identifier for the route
167
- - `path: string` - URL path pattern
168
- - `opts?: RouteOptions | string` - Route options or parent route alias
169
-
170
- **Returns:** `CommonRouteModel` - Route model with resolve capability
171
-
172
- **Example:**
173
- ```typescript
174
- const userRoute = route('user', '/api/users/:id', {
175
- method: RouteMethod.GET,
176
- protocol: RouteProtocols.WEB
177
- })
178
- ```
179
-
180
- #### createRoute(alias, path, opts?)
181
- Creates a route POJO without wrapping it in a model.
182
-
183
- ```typescript
184
- const createRoute: CreateRouteSignature<CommonRoute> = (alias, path, opts?) => CommonRoute
185
- ```
186
-
187
- **Parameters:**
188
- - `alias: string` - Unique identifier for the route
189
- - `path: string` - URL path pattern
190
- - `opts?: RouteOptions | string` - Route options or parent route alias
191
-
192
- **Returns:** `CommonRoute` - Route POJO
193
-
194
- **Example:**
195
- ```typescript
196
- const apiRoute = createRoute('api', '/api', {
197
- type: AppType.Backend,
198
- secure: true
199
- })
200
- ```
201
-
202
- #### makeRouteModel(route)
203
- Creates a route model from a route POJO.
204
-
205
- ```typescript
206
- const makeRouteModel = (route: CommonRoute): CommonRouteModel
207
- ```
208
-
209
- **Parameters:**
210
- - `route: CommonRoute` - Route POJO to wrap
211
-
212
- **Returns:** `CommonRouteModel` - Route model with resolve capability
213
-
214
- ### Helper Functions
215
-
216
- #### normalizePath(path)
217
- Normalizes a URL path by removing leading/trailing slashes and trimming whitespace.
218
-
219
- ```typescript
220
- const normalizePath = (path: string): string
15
+ bun add @owlmeans/route
221
16
  ```
222
17
 
223
- **Parameters:**
224
- - `path: string` - Path to normalize
18
+ ## Usage
225
19
 
226
- **Returns:** `string` - Normalized path
20
+ Define routes for modules (typically via `@owlmeans/server-app` re-exports):
227
21
 
228
- **Example:**
229
22
  ```typescript
230
- normalizePath('/api/users/') // Returns 'api/users'
231
- normalizePath(' /api/ ') // Returns 'api'
232
- ```
23
+ import { route, frontend, backend, socket, RouteMethod } from '@owlmeans/route'
24
+ import { module } from '@owlmeans/module'
233
25
 
234
- #### rtype(type, opts?)
235
- Creates route options with a specific application type.
26
+ // Backend REST route
27
+ const createRoute = module(
28
+ route('story-create', '/stories', backend('api', RouteMethod.POST))
29
+ )
236
30
 
237
- ```typescript
238
- const rtype = (type: AppType, opts?: RouteOptions | string): Partial<RouteOptions>
239
- ```
240
-
241
- **Parameters:**
242
- - `type: AppType` - Application type (Backend/Frontend)
243
- - `opts?: RouteOptions | string` - Additional options or parent route alias
31
+ // Frontend client route nested under parent
32
+ const storyRoute = module(
33
+ route('story-view', '/stories/:id', frontend('app'))
34
+ )
244
35
 
245
- **Returns:** `Partial<RouteOptions>` - Route options with type set
246
-
247
- #### backend(opts?, method?)
248
- Creates route options configured for backend routes.
249
-
250
- ```typescript
251
- const backend = (opts?: RouteOptions | string | null, method?: RouteOptions | RouteMethod): Partial<RouteOptions>
36
+ // WebSocket route
37
+ const wsRoute = module(
38
+ route('story-ws', '/stories/stream', socket('api'))
39
+ )
252
40
  ```
253
41
 
254
- **Parameters:**
255
- - `opts?: RouteOptions | string | null` - Route options or parent route alias
256
- - `method?: RouteOptions | RouteMethod` - HTTP method or additional options
42
+ ## API
257
43
 
258
- **Returns:** `Partial<RouteOptions>` - Backend route options
44
+ ### `route(alias, path, opts?): CommonRouteModel`
259
45
 
260
- **Example:**
261
- ```typescript
262
- const backendRoute = route('api', '/api', backend(null, RouteMethod.GET))
263
- ```
264
-
265
- #### frontend(opts?, def?)
266
- Creates route options configured for frontend routes.
267
-
268
- ```typescript
269
- const frontend = (opts?: RouteOptions | string | null, def?: RouteOptions | boolean): Partial<RouteOptions>
270
- ```
46
+ Creates a route model. `opts` can be a `RouteOptions` object or the result of `frontend()`, `backend()`, or `socket()`.
271
47
 
272
- **Parameters:**
273
- - `opts?: RouteOptions | string | null` - Route options or parent route alias
274
- - `def?: RouteOptions | boolean` - Default flag or additional options
48
+ ### `frontend(parent?, sticky?): Partial<RouteOptions>`
275
49
 
276
- **Returns:** `Partial<RouteOptions>` - Frontend route options
50
+ Returns options marking the route as frontend (`AppType.Frontend`), optionally with a parent alias.
277
51
 
278
- **Example:**
279
- ```typescript
280
- const frontendRoute = route('home', '/', frontend(null, true))
281
- ```
282
-
283
- #### service(service, opts?)
284
- Creates route options with a specific service identifier.
52
+ ### `backend(parent?, method?): Partial<RouteOptions>`
285
53
 
286
- ```typescript
287
- const service = (service: string, opts?: Partial<RouteOptions>): Partial<RouteOptions>
288
- ```
54
+ Returns options marking the route as backend (`AppType.Backend`), optionally with a parent alias and `RouteMethod`.
289
55
 
290
- **Parameters:**
291
- - `service: string` - Service identifier
292
- - `opts?: Partial<RouteOptions>` - Additional route options
56
+ ### `socket(parent?): Partial<RouteOptions>`
293
57
 
294
- **Returns:** `Partial<RouteOptions>` - Route options with service set
58
+ Returns options for a WebSocket route with `RouteProtocols.SOCKET`.
295
59
 
296
- #### socket(opts?, secondary?)
297
- Creates route options configured for WebSocket routes.
60
+ ### `RouteMethod`
298
61
 
299
62
  ```typescript
300
- const socket = (opts?: RouteOptions | string | null, secondary?: RouteOptions): Partial<RouteOptions>
63
+ enum RouteMethod { GET, POST, PATCH, PUT, DELETE }
301
64
  ```
302
65
 
303
- **Parameters:**
304
- - `opts?: RouteOptions | string | null` - Route options or parent route alias
305
- - `secondary?: RouteOptions` - Additional options
306
-
307
- **Returns:** `Partial<RouteOptions>` - WebSocket route options
66
+ ### `RouteProtocols`
308
67
 
309
- **Example:**
310
68
  ```typescript
311
- const socketRoute = route('ws', '/socket', socket())
69
+ enum RouteProtocols { WEB = 'http', SOCKET = 'ws' }
312
70
  ```
313
71
 
314
- ### Utility Functions
315
-
316
- #### resolve(route)
317
- Creates a route resolution function that resolves the route within a given context.
318
-
319
- ```typescript
320
- const resolve = <C extends Config, T extends BasicContext<C>>(route: CommonRoute) => (context: T) => Promise<CommonRoute>
321
- ```
322
-
323
- **Parameters:**
324
- - `route: CommonRoute` - Route to resolve
325
-
326
- **Returns:** `(context: T) => Promise<CommonRoute>` - Resolution function
327
-
328
- **Features:**
329
- - Resolves parent routes recursively
330
- - Handles service route resolution
331
- - Manages path concatenation
332
- - Applies security settings
333
- - Detects circular dependencies
334
-
335
- #### getParentRoute(context, route)
336
- Retrieves and resolves the parent route for a given route.
337
-
338
- ```typescript
339
- const getParentRoute = async <C extends Config, T extends BasicContext<C>>(context: T, route: CommonRoute): Promise<CommonRoute | null>
340
- ```
341
-
342
- **Parameters:**
343
- - `context: T` - Application context
344
- - `route: CommonRoute` - Route to find parent for
345
-
346
- **Returns:** `Promise<CommonRoute | null>` - Parent route or null if no parent
347
-
348
- #### overrideParams(route, overrides, filter?)
349
- Overrides route parameters with provided values.
350
-
351
- ```typescript
352
- const overrideParams = (route: CommonRoute, overrides?: Partial<CommonRoute>, filter?: string[]) => void
353
- ```
354
-
355
- **Parameters:**
356
- - `route: CommonRoute` - Route to modify
357
- - `overrides?: Partial<CommonRoute>` - Parameters to override
358
- - `filter?: string[]` - Optional filter for which parameters to override
359
-
360
- #### prependBase(route)
361
- Prepends the base path to a route's path.
362
-
363
- ```typescript
364
- const prependBase = (route: CommonRoute) => string
365
- ```
366
-
367
- **Parameters:**
368
- - `route: CommonRoute` - Route to process
369
-
370
- **Returns:** `string` - Path with base prepended
371
-
372
- #### isServiceRoute(obj)
373
- Type guard to check if an object is a service route.
374
-
375
- ```typescript
376
- const isServiceRoute = (obj?: Object): obj is CommonServiceRoute
377
- ```
378
-
379
- **Parameters:**
380
- - `obj?: Object` - Object to check
381
-
382
- **Returns:** `boolean` - True if object is a service route
383
-
384
- #### isServiceRouteResolved(route)
385
- Type guard to check if a service route is resolved.
386
-
387
- ```typescript
388
- const isServiceRouteResolved = (route: CommonServiceRoute): route is ResolvedServiceRoute
389
- ```
390
-
391
- **Parameters:**
392
- - `route: CommonServiceRoute` - Service route to check
393
-
394
- **Returns:** `boolean` - True if service route is resolved
395
-
396
- ## Usage Examples
397
-
398
- ### Basic Route Creation
399
-
400
- ```typescript
401
- import { route, RouteMethod, RouteProtocols } from '@owlmeans/route'
402
-
403
- // Create a simple API route
404
- const userRoute = route('user', '/api/users/:id', {
405
- method: RouteMethod.GET,
406
- protocol: RouteProtocols.WEB
407
- })
408
-
409
- // Create a nested route with parent
410
- const userProfileRoute = route('userProfile', '/profile', 'user')
411
- ```
412
-
413
- ### Backend Route Configuration
414
-
415
- ```typescript
416
- import { route, backend, RouteMethod } from '@owlmeans/route'
417
-
418
- // Create a backend API route
419
- const apiRoute = route('api', '/api', backend())
420
-
421
- // Create a POST endpoint
422
- const createUserRoute = route('createUser', '/users', backend('api', RouteMethod.POST))
423
- ```
424
-
425
- ### Frontend Route Configuration
426
-
427
- ```typescript
428
- import { route, frontend } from '@owlmeans/route'
429
-
430
- // Create a default frontend route
431
- const homeRoute = route('home', '/', frontend(null, true))
432
-
433
- // Create a nested frontend route
434
- const aboutRoute = route('about', '/about', frontend())
435
- ```
436
-
437
- ### WebSocket Route Configuration
438
-
439
- ```typescript
440
- import { route, socket } from '@owlmeans/route'
441
-
442
- // Create a WebSocket route
443
- const chatRoute = route('chat', '/chat', socket())
444
- ```
445
-
446
- ### Route Resolution
447
-
448
- ```typescript
449
- import { route, backend } from '@owlmeans/route'
450
-
451
- // Create a route that needs resolution
452
- const apiRoute = route('api', '/api', backend())
453
-
454
- // Resolve the route with context
455
- const resolvedRoute = await apiRoute.resolve(context)
456
- console.log(resolvedRoute.host) // Resolved host
457
- console.log(resolvedRoute.port) // Resolved port
458
- ```
459
-
460
- ### Service Route Usage
461
-
462
- ```typescript
463
- import { route, service, backend } from '@owlmeans/route'
464
-
465
- // Create a route with service configuration
466
- const userServiceRoute = route('userService', '/users', {
467
- ...backend(),
468
- ...service('user-service')
469
- })
470
- ```
471
-
472
- ## Client-Side Usage
473
-
474
- For client-side applications, consider using the `@owlmeans/client-route` package which extends this module with additional client-specific functionality:
475
-
476
- ```typescript
477
- import { route as baseRoute } from '@owlmeans/route'
478
- import { route as clientRoute } from '@owlmeans/client-route'
479
-
480
- // Create a base route
481
- const userRoute = baseRoute('user', '/users/:id')
482
-
483
- // Wrap with client functionality
484
- const clientUserRoute = clientRoute(userRoute)
485
-
486
- // Access client-specific features
487
- console.log(clientUserRoute.route.partialPath) // '/users/:id'
488
- ```
489
-
490
- The `@owlmeans/client-route` package provides:
491
- - **Partial Path Preservation** - Maintains original path patterns for client-side processing
492
- - **Parameter Extraction** - Utilities for extracting route parameters
493
- - **Promise-based Resolution** - Enhanced resolution tracking for client applications
494
-
495
- See the `@owlmeans/client-route` documentation for complete client-side routing capabilities.
496
-
497
- ## Integration with OwlMeans Context
498
-
499
- The route module is part of the OwlMeans Common Module approach and integrates seamlessly with the OwlMeans context system (see `@owlmeans/context` for more details on the Common Module approach). This module is not self-sufficient and requires the context system to function properly.
500
-
501
- ### Working with Modules and Routes
502
-
503
- In the OwlMeans ecosystem, modules define URL structures that can be transformed into routes based on the deployment context. Here's how they work together:
504
-
505
- ```typescript
506
- import { route, backend } from '@owlmeans/route'
507
- import { BasicContext } from '@owlmeans/context'
508
-
509
- // Define a module with route structure
510
- const apiModule = {
511
- _module: true,
512
- route: route('api', '/api', backend()),
513
-
514
- // Nested routes within the module
515
- users: route('users', '/users', 'api'),
516
- posts: route('posts', '/posts', 'api'),
517
-
518
- // Resolution logic
519
- resolve: async (context) => {
520
- await apiModule.route.resolve(context)
521
- await apiModule.users.resolve(context)
522
- await apiModule.posts.resolve(context)
523
- }
524
- }
525
-
526
- // Use the module in different contexts
527
- const resolvedRoute = await apiModule.route.resolve(context)
528
-
529
- // Generate URLs for navigation or API calls
530
- const userApiUrl = await apiModule.users.resolve(backendContext) // Backend API URL
531
- const userPageUrl = await apiModule.users.resolve(frontendContext) // Frontend page URL
532
- ```
533
-
534
- ### Module-Based Architecture Benefits
535
-
536
- - **Centralized Route Definition** - All routes are defined in modules and shared across services
537
- - **Context-Aware Resolution** - Same route definitions work for both frontend and backend
538
- - **Consistent URL Generation** - URLs are generated consistently across the entire system
539
- - **Service Integration** - Modules can span multiple microservices while maintaining coherent routing
540
-
541
- ## Error Handling
542
-
543
- The module provides comprehensive error handling:
544
-
545
- - **SyntaxError** - Thrown for configuration errors, missing services, or circular dependencies
546
- - **Type Guards** - Used to ensure type safety when working with service routes
547
- - **Validation** - Route parameters are validated during resolution
548
-
549
- ## Best Practices
550
-
551
- 1. **Use Aliases** - Always provide meaningful aliases for routes
552
- 2. **Hierarchical Structure** - Organize routes in a parent-child hierarchy when appropriate
553
- 3. **Service Configuration** - Configure services properly in the context for route resolution
554
- 4. **Security** - Set appropriate security flags for routes
555
- 5. **Type Safety** - Use TypeScript interfaces and type guards for better development experience
556
-
557
- ## Related Modules
72
+ ## Related Packages
558
73
 
559
- - **@owlmeans/context** - Provides the context system for route resolution
560
- - **@owlmeans/client-route** - Client-side route implementations and extensions with additional functionality like partial path preservation and parameter extraction
561
- - **@owlmeans/server-route** - Server-side route implementations
74
+ - [`@owlmeans/module`](../module) — `module()` takes a `CommonRouteModel` as first argument
75
+ - [`@owlmeans/server-app`](../server-app) — re-exports `route` as `broute` (backend) alongside `route`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/route",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,11 +28,12 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@owlmeans/context": "^0.1.2"
31
+ "@owlmeans/context": "^0.1.4"
32
32
  },
33
33
  "devDependencies": {
34
+ "@owlmeans/dep-config": "workspace:*",
34
35
  "nodemon": "^3.1.11",
35
- "typescript": "^5.8.3"
36
+ "typescript": "^6.0.2"
36
37
  },
37
38
  "publishConfig": {
38
39
  "access": "public"
package/tsconfig.json CHANGED
@@ -1,14 +1,10 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json",
3
+ "@owlmeans/dep-config/tsconfig.base.json"
4
4
  ],
5
5
  "compilerOptions": {
6
- "rootDir": "./src/", /* Specify the root folder within your source files. */
7
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
6
+ "rootDir": "./src/",
7
+ "outDir": "./build/"
8
8
  },
9
- "exclude": [
10
- "./dist/**/*",
11
- "./build/**/*",
12
- "./*.ts"
13
- ]
14
- }
9
+ "exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
10
+ }