@fjell/express-router 4.4.55 → 4.4.57

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.
@@ -1,394 +0,0 @@
1
-
2
- import { CItemRouter, createRegistry, PItemRouter } from '../src';
3
- import { ComKey, Item, PriKey } from '@fjell/core';
4
- import express from 'express';
5
- import { Request, Response } from 'express';
6
-
7
- // Define data models
8
- interface User extends Item<'user'> {
9
- id: string;
10
- name: string;
11
- email: string;
12
- role: 'admin' | 'user' | 'guest';
13
- }
14
-
15
- interface Post extends Item<'post', 'user'> {
16
- id: string;
17
- title: string;
18
- content: string;
19
- authorId: string;
20
- publishedAt?: Date;
21
- }
22
-
23
- // Mock operations for demonstration
24
- const userOperations = {
25
- create: async (item: User) => ({ ...item, id: `user_${Date.now()}` }),
26
- get: async (ik: PriKey<'user'>) => ({ id: ik.pk, name: 'John Doe', email: 'john@example.com', role: 'user' as const }),
27
- update: async (ik: PriKey<'user'>, item: Partial<User>) => ({ id: ik.pk, name: 'John Doe', email: 'john@example.com', role: 'user' as const, ...item }),
28
- remove: async (ik: PriKey<'user'>) => ({ id: ik.pk, name: 'John Doe', email: 'john@example.com', role: 'user' as const }),
29
- all: async () => [
30
- { id: 'user_1', name: 'John Doe', email: 'john@example.com', role: 'user' as const },
31
- { id: 'user_2', name: 'Jane Smith', email: 'jane@example.com', role: 'admin' as const }
32
- ],
33
- find: async () => [
34
- { id: 'user_1', name: 'John Doe', email: 'john@example.com', role: 'user' as const }
35
- ],
36
- action: async (ik: PriKey<'user'>, action: string, body: any) => ({ message: `Library action: ${action}`, userId: ik.pk, body }),
37
- facet: async (ik: PriKey<'user'>, facet: string, params: any) => ({ message: `Library facet: ${facet}`, userId: ik.pk, params }),
38
- allAction: async (action: string, body: any) => ({ message: `Library all action: ${action}`, body }),
39
- allFacet: async (facet: string, params: any) => ({ message: `Library all facet: ${facet}`, params })
40
- };
41
-
42
- const postOperations = {
43
- create: async (item: Post, _options: { locations: any[] }) => ({ ...item, id: `post_${Date.now()}` }),
44
- get: async (ik: ComKey<'post', 'user'>) => ({ id: ik.pk, title: 'Sample Post', content: 'Sample content', authorId: 'user_1' }),
45
- update: async (ik: ComKey<'post', 'user'>, item: Partial<Post>) => ({ id: ik.pk, title: 'Sample Post', content: 'Sample content', authorId: 'user_1', ...item }),
46
- remove: async (ik: ComKey<'post', 'user'>) => ({ id: ik.pk, title: 'Sample Post', content: 'Sample content', authorId: 'user_1' }),
47
- all: async (_query: any, _locations: any[]) => [
48
- { id: 'post_1', title: 'Sample Post 1', content: 'Sample content 1', authorId: 'user_1' },
49
- { id: 'post_2', title: 'Sample Post 2', content: 'Sample content 2', authorId: 'user_1' }
50
- ],
51
- find: async (_finder: string, _params: any, _locations: any[]) => [
52
- { id: 'post_1', title: 'Sample Post 1', content: 'Sample content 1', authorId: 'user_1' }
53
- ],
54
- action: async (ik: ComKey<'post', 'user'>, action: string, body: any) => ({ message: `Library action: ${action}`, postId: ik.pk, body }),
55
- facet: async (ik: ComKey<'post', 'user'>, facet: string, params: any) => ({ message: `Library facet: ${facet}`, postId: ik.pk, params }),
56
- allAction: async (action: string, body: any) => ({ message: `Library all action: ${action}`, body }),
57
- allFacet: async (facet: string, params: any) => ({ message: `Library all facet: ${facet}`, params })
58
- };
59
-
60
- // Create Express app and registry
61
- const app = express();
62
- app.use(express.json());
63
-
64
- const _registry = createRegistry();
65
-
66
- // Create instances
67
- const userInstance = {
68
- operations: userOperations,
69
- options: {
70
- actions: {
71
- activate: { description: 'Activate user account' },
72
- deactivate: { description: 'Deactivate user account' }
73
- },
74
- facets: {
75
- profile: { description: 'Get user profile' },
76
- stats: { description: 'Get user statistics' }
77
- },
78
- allActions: {
79
- bulkActivate: { description: 'Activate multiple users' },
80
- bulkDeactivate: { description: 'Deactivate multiple users' }
81
- },
82
- allFacets: {
83
- userStats: { description: 'Get overall user statistics' },
84
- userCount: { description: 'Get user count' }
85
- }
86
- }
87
- } as any;
88
-
89
- const postInstance = {
90
- operations: postOperations,
91
- options: {
92
- actions: {
93
- publish: { description: 'Publish post' },
94
- unpublish: { description: 'Unpublish post' }
95
- },
96
- facets: {
97
- analytics: { description: 'Get post analytics' },
98
- comments: { description: 'Get post comments' }
99
- },
100
- allActions: {
101
- bulkPublish: { description: 'Publish multiple posts' },
102
- bulkUnpublish: { description: 'Unpublish multiple posts' }
103
- },
104
- allFacets: {
105
- postStats: { description: 'Get overall post statistics' },
106
- postCount: { description: 'Get post count' }
107
- }
108
- }
109
- } as any;
110
-
111
- // Create routers with router-level handlers
112
- const userRouter = new PItemRouter(userInstance, 'user', {
113
- // Router-level action handlers - aligned with library operation signatures
114
- actions: {
115
- activate: async (ik: PriKey<'user'>, actionParams: any, _context: { req: Request, res: Response }) => {
116
- console.log('Router-level activate action called for user:', ik.pk);
117
- console.log('Action params:', actionParams);
118
- // Custom logic: send activation email, update status, etc.
119
- const result = {
120
- message: 'User activated via router handler',
121
- userId: ik.pk,
122
- timestamp: new Date().toISOString(),
123
- emailSent: true
124
- };
125
- return result;
126
- },
127
- deactivate: async (ik: PriKey<'user'>, actionParams: any, _context: { req: Request, res: Response }) => {
128
- console.log('Router-level deactivate action called for user:', ik.pk);
129
- console.log('Action params:', actionParams);
130
- // Custom logic: send deactivation notification, update status, etc.
131
- const result = {
132
- message: 'User deactivated via router handler',
133
- userId: ik.pk,
134
- timestamp: new Date().toISOString(),
135
- notificationSent: true
136
- };
137
- return result;
138
- }
139
- },
140
-
141
- // Router-level facet handlers - aligned with library operation signatures
142
- facets: {
143
- profile: async (ik: PriKey<'user'>, facetParams: any, _context: { req: Request, res: Response }) => {
144
- console.log('Router-level profile facet called for user:', ik.pk);
145
- console.log('Facet params:', facetParams);
146
- // Custom logic: aggregate data from multiple sources
147
- return {
148
- userId: ik.pk,
149
- basicInfo: { name: 'John Doe', email: 'john@example.com' },
150
- extendedInfo: { lastLogin: new Date(), preferences: { theme: 'dark' } },
151
- socialInfo: { followers: 150, following: 75 }
152
- };
153
- },
154
- stats: async (ik: PriKey<'user'>, facetParams: any, _context: { req: Request, res: Response }) => {
155
- console.log('Router-level stats facet called for user:', ik.pk);
156
- console.log('Facet params:', facetParams);
157
- // Custom logic: calculate statistics from multiple data sources
158
- return {
159
- userId: ik.pk,
160
- postsCount: 25,
161
- commentsCount: 150,
162
- likesReceived: 500,
163
- lastActivity: new Date()
164
- };
165
- }
166
- },
167
-
168
- // Router-level all action handlers - aligned with library operation signatures
169
- allActions: {
170
- bulkActivate: async (allActionParams: any, locations: any, _context: { req: Request, res: Response }) => {
171
- console.log('Router-level bulk activate action called');
172
- console.log('All action params:', allActionParams);
173
- console.log('Locations:', locations);
174
- // Custom logic: batch processing, external service integration
175
- const { userIds } = allActionParams;
176
- return {
177
- message: 'Bulk activation via router handler',
178
- processedUsers: userIds?.length || 0,
179
- timestamp: new Date().toISOString(),
180
- externalServiceCalled: true
181
- };
182
- },
183
- bulkDeactivate: async (allActionParams: any, locations: any, _context: { req: Request, res: Response }) => {
184
- console.log('Router-level bulk deactivate action called');
185
- console.log('All action params:', allActionParams);
186
- console.log('Locations:', locations);
187
- // Custom logic: batch processing, audit logging
188
- const { userIds } = allActionParams;
189
- return {
190
- message: 'Bulk deactivation via router handler',
191
- processedUsers: userIds?.length || 0,
192
- timestamp: new Date().toISOString(),
193
- auditLogged: true
194
- };
195
- }
196
- },
197
-
198
- // Router-level all facet handlers - aligned with library operation signatures
199
- allFacets: {
200
- userStats: async (allFacetParams: any, locations: any, _context: { req: Request, res: Response }) => {
201
- console.log('Router-level user stats facet called');
202
- console.log('All facet params:', allFacetParams);
203
- console.log('Locations:', locations);
204
- // Custom logic: aggregate statistics from multiple systems
205
- return {
206
- totalUsers: 1250,
207
- activeUsers: 890,
208
- newUsersThisMonth: 45,
209
- topRoles: { admin: 15, user: 1200, guest: 35 },
210
- systemHealth: 'excellent'
211
- };
212
- },
213
- userCount: async (_allFacetParams: any, _locations: any, _context: { req: Request, res: Response }) => {
214
- console.log('Router-level user count facet called');
215
- // Custom logic: real-time count from cache
216
- return {
217
- count: 1250,
218
- lastUpdated: new Date().toISOString(),
219
- source: 'cache'
220
- };
221
- }
222
- }
223
- } as any);
224
-
225
- const postRouter = new CItemRouter(postInstance, 'post', userRouter, {
226
- // Router-level action handlers for posts - aligned with library operation signatures
227
- actions: {
228
- publish: async (ik: ComKey<'post', 'user'>, actionParams: any, _context: { req: Request, res: Response }) => {
229
- console.log('Router-level publish action called for post:', ik.pk);
230
- console.log('Action params:', actionParams);
231
- // Custom logic: publish to social media, send notifications
232
- return {
233
- message: 'Post published via router handler',
234
- postId: ik.pk,
235
- authorId: ik.loc[0].lk,
236
- publishedAt: new Date().toISOString(),
237
- socialMediaPosted: true,
238
- notificationsSent: true
239
- };
240
- },
241
- unpublish: async (ik: ComKey<'post', 'user'>, actionParams: any, _context: { req: Request, res: Response }) => {
242
- console.log('Router-level unpublish action called for post:', ik.pk);
243
- console.log('Action params:', actionParams);
244
- // Custom logic: remove from social media, send notifications
245
- return {
246
- message: 'Post unpublished via router handler',
247
- postId: ik.pk,
248
- authorId: ik.loc[0].lk,
249
- unpublishedAt: new Date().toISOString(),
250
- socialMediaRemoved: true,
251
- notificationsSent: true
252
- };
253
- }
254
- },
255
-
256
- // Router-level facet handlers for posts - aligned with library operation signatures
257
- facets: {
258
- analytics: async (ik: ComKey<'post', 'user'>, facetParams: any, _context: { req: Request, res: Response }) => {
259
- console.log('Router-level analytics facet called for post:', ik.pk);
260
- console.log('Facet params:', facetParams);
261
- // Custom logic: aggregate analytics from multiple sources
262
- return {
263
- postId: ik.pk,
264
- views: 1250,
265
- likes: 89,
266
- shares: 23,
267
- comments: 15,
268
- engagementRate: 0.12,
269
- topReferrers: ['twitter.com', 'facebook.com', 'linkedin.com']
270
- };
271
- },
272
- comments: async (ik: ComKey<'post', 'user'>, facetParams: any, _context: { req: Request, res: Response }) => {
273
- console.log('Router-level comments facet called for post:', ik.pk);
274
- console.log('Facet params:', facetParams);
275
- // Custom logic: fetch comments from external service
276
- return {
277
- postId: ik.pk,
278
- comments: [
279
- { id: 'comment_1', text: 'Great post!', author: 'user_2', timestamp: new Date() },
280
- { id: 'comment_2', text: 'Very informative', author: 'user_3', timestamp: new Date() }
281
- ],
282
- totalComments: 2
283
- };
284
- }
285
- },
286
-
287
- // Router-level all action handlers for posts - aligned with library operation signatures
288
- allActions: {
289
- bulkPublish: async (allActionParams: any, locations: any, _context: { req: Request, res: Response }) => {
290
- console.log('Router-level bulk publish action called');
291
- console.log('All action params:', allActionParams);
292
- console.log('Locations:', locations);
293
- // Custom logic: batch publishing to multiple platforms
294
- const { postIds } = allActionParams;
295
- return {
296
- message: 'Bulk publish via router handler',
297
- processedPosts: postIds?.length || 0,
298
- timestamp: new Date().toISOString(),
299
- platformsUpdated: ['twitter', 'facebook', 'linkedin']
300
- };
301
- },
302
- bulkUnpublish: async (allActionParams: any, locations: any, _context: { req: Request, res: Response }) => {
303
- console.log('Router-level bulk unpublish action called');
304
- console.log('All action params:', allActionParams);
305
- console.log('Locations:', locations);
306
- // Custom logic: batch unpublishing from multiple platforms
307
- const { postIds } = allActionParams;
308
- return {
309
- message: 'Bulk unpublish via router handler',
310
- processedPosts: postIds?.length || 0,
311
- timestamp: new Date().toISOString(),
312
- platformsUpdated: ['twitter', 'facebook', 'linkedin']
313
- };
314
- }
315
- },
316
-
317
- // Router-level all facet handlers for posts - aligned with library operation signatures
318
- allFacets: {
319
- postStats: async (allFacetParams: any, locations: any, _context: { req: Request, res: Response }) => {
320
- console.log('Router-level post stats facet called');
321
- console.log('All facet params:', allFacetParams);
322
- console.log('Locations:', locations);
323
- // Custom logic: aggregate post statistics
324
- return {
325
- totalPosts: 450,
326
- publishedPosts: 380,
327
- draftPosts: 70,
328
- averageViews: 850,
329
- averageLikes: 45,
330
- topCategories: ['technology', 'business', 'lifestyle']
331
- };
332
- },
333
- postCount: async (allFacetParams: any, locations: any, _context: { req: Request, res: Response }) => {
334
- console.log('Router-level post count facet called');
335
- console.log('All facet params:', allFacetParams);
336
- console.log('Locations:', locations);
337
- // Custom logic: real-time count with filtering
338
- return {
339
- count: 450,
340
- published: 380,
341
- draft: 70,
342
- lastUpdated: new Date().toISOString(),
343
- source: 'database'
344
- };
345
- }
346
- }
347
- } as any);
348
-
349
- // Mount routers
350
- app.use('/api/users', userRouter.getRouter());
351
- app.use('/api/posts', postRouter.getRouter());
352
-
353
- // Example usage endpoints
354
- app.get('/examples', (req, res) => {
355
- res.json({
356
- message: 'Router Handlers Example',
357
- endpoints: {
358
- // User endpoints with router handlers
359
- 'POST /api/users/user_1/activate': 'Router-level activate action',
360
- 'POST /api/users/user_1/deactivate': 'Router-level deactivate action',
361
- 'GET /api/users/user_1/profile': 'Router-level profile facet',
362
- 'GET /api/users/user_1/stats': 'Router-level stats facet',
363
- 'POST /api/users/bulkActivate': 'Router-level bulk activate action',
364
- 'POST /api/users/bulkDeactivate': 'Router-level bulk deactivate action',
365
- 'GET /api/users/userStats': 'Router-level user stats facet',
366
- 'GET /api/users/userCount': 'Router-level user count facet',
367
-
368
- // Post endpoints with router handlers
369
- 'POST /api/posts/post_1/publish': 'Router-level publish action',
370
- 'POST /api/posts/post_1/unpublish': 'Router-level unpublish action',
371
- 'GET /api/posts/post_1/analytics': 'Router-level analytics facet',
372
- 'GET /api/posts/post_1/comments': 'Router-level comments facet',
373
- 'POST /api/posts/bulkPublish': 'Router-level bulk publish action',
374
- 'POST /api/posts/bulkUnpublish': 'Router-level bulk unpublish action',
375
- 'GET /api/posts/postStats': 'Router-level post stats facet',
376
- 'GET /api/posts/postCount': 'Router-level post count facet',
377
-
378
- // Library fallback endpoints (these will use library handlers)
379
- 'POST /api/users/user_1/someOtherAction': 'Library action (fallback)',
380
- 'GET /api/users/user_1/someOtherFacet': 'Library facet (fallback)',
381
- 'POST /api/users/someOtherAllAction': 'Library all action (fallback)',
382
- 'GET /api/users/someOtherAllFacet': 'Library all facet (fallback)'
383
- }
384
- });
385
- });
386
-
387
- // Start server
388
- const PORT = 3000;
389
- app.listen(PORT, () => {
390
- console.log(`Router Handlers Example server running on http://localhost:${PORT}`);
391
- console.log('Visit http://localhost:3000/examples for endpoint documentation');
392
- });
393
-
394
- export { app, userRouter, postRouter };
@@ -1,214 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- /**
3
- * Example: Router-Level Options with Name Collision Handling
4
- *
5
- * This example demonstrates how router-level actions, facets, allActions, and allFacets
6
- * take precedence over library-level options with the same names, and how collision
7
- * warnings are logged when there are conflicts.
8
- */
9
-
10
- import { ItemRouter, ItemRouterOptions } from "../src/ItemRouter.js";
11
- import { ComKey, Item, LocKeyArray, PriKey } from "@fjell/core";
12
- import { Request, Response } from "express";
13
-
14
- // Sample Item Types
15
- type User = Item<"user", "tenant">;
16
- type Tenant = Item<"tenant">;
17
-
18
- // Mock library instance with actions/facets that will collide with router options
19
- const mockLibWithConflicts = {
20
- operations: {
21
- get: async () => ({ key: { kt: "user", pk: "user-1" }, name: "John Doe" } as User),
22
- create: async () => ({ key: { kt: "user", pk: "user-2" }, name: "Jane Doe" } as User),
23
- update: async () => ({ key: { kt: "user", pk: "user-1" }, name: "John Updated" } as User),
24
- remove: async () => ({ key: { kt: "user", pk: "user-1" }, name: "John Doe" } as User),
25
- all: async () => [] as User[],
26
- find: async () => [] as User[],
27
- findOne: async () => null,
28
- action: async (ik: any, actionKey: string) => ({ source: "library", action: actionKey }),
29
- facet: async (ik: any, facetKey: string) => ({ source: "library", facet: facetKey }),
30
- allAction: async (actionKey: string) => ({ source: "library", allAction: actionKey }),
31
- allFacet: async (facetKey: string) => ({ source: "library", allFacet: facetKey })
32
- },
33
- options: {
34
- // These will collide with router-level options
35
- actions: {
36
- activate: async () => ({ source: "library", action: "activate" }),
37
- archive: async () => ({ source: "library", action: "archive" })
38
- },
39
- facets: {
40
- profile: async () => ({ source: "library", facet: "profile" }),
41
- settings: async () => ({ source: "library", facet: "settings" })
42
- },
43
- allActions: {
44
- bulkUpdate: async () => ({ source: "library", allAction: "bulkUpdate" }),
45
- export: async () => ({ source: "library", allAction: "export" })
46
- },
47
- allFacets: {
48
- analytics: async () => ({ source: "library", allFacet: "analytics" }),
49
- dashboard: async () => ({ source: "library", allFacet: "dashboard" })
50
- }
51
- }
52
- };
53
-
54
- class UserRouter extends ItemRouter<"user", "tenant"> {
55
- protected getIk(res: Response): ComKey<"user", "tenant"> {
56
- return {
57
- kt: "user",
58
- pk: res.locals.userPk,
59
- loc: [{ kt: "tenant", lk: res.locals.tenantId || "tenant-1" }]
60
- };
61
- }
62
-
63
- protected getLocations(res: Response): LocKeyArray<"tenant"> {
64
- return [{ kt: "tenant", lk: res.locals.tenantId || "tenant-1" }];
65
- }
66
-
67
- public createItem = async (req: Request, res: Response): Promise<void> => {
68
- const newUser: User = {
69
- key: { kt: "user", pk: "user-new", loc: this.getLocations(res) },
70
- name: req.body.name || "New User",
71
- email: req.body.email || "new@example.com",
72
- events: {
73
- created: { at: new Date() },
74
- updated: { at: new Date() },
75
- deleted: { at: null }
76
- }
77
- };
78
- res.json(newUser);
79
- };
80
-
81
- public findItems = async (req: Request, res: Response): Promise<void> => {
82
- const users: User[] = [
83
- {
84
- key: { kt: "user", pk: "user-1", loc: this.getLocations(res) },
85
- name: "John Doe",
86
- email: "john@example.com",
87
- events: {
88
- created: { at: new Date() },
89
- updated: { at: new Date() },
90
- deleted: { at: null }
91
- }
92
- }
93
- ];
94
- res.json(users);
95
- };
96
- }
97
-
98
- /**
99
- * Router-level options that will take precedence over library options
100
- * Notice some of these have the same names as the library options
101
- */
102
- const routerOptions: ItemRouterOptions<"user", "tenant"> = {
103
- // These will override library actions with same names
104
- actions: {
105
- activate: async (ik, params, { req, res }) => {
106
- console.log("🚀 Router-level activate action called!");
107
- return { source: "router", action: "activate", ik, params };
108
- },
109
- archive: async (ik, params, { req, res }) => {
110
- console.log("📦 Router-level archive action called!");
111
- return { source: "router", action: "archive", ik, params };
112
- },
113
- // This one is unique to router
114
- resetPassword: async (ik, params, { req, res }) => {
115
- console.log("🔑 Router-level resetPassword action called!");
116
- return { source: "router", action: "resetPassword", ik, params };
117
- }
118
- },
119
-
120
- // These will override library facets with same names
121
- facets: {
122
- profile: async (ik, params, { req, res }) => {
123
- console.log("👤 Router-level profile facet called!");
124
- return { source: "router", facet: "profile", ik, params };
125
- },
126
- settings: async (ik, params, { req, res }) => {
127
- console.log("⚙️ Router-level settings facet called!");
128
- return { source: "router", facet: "settings", ik, params };
129
- },
130
- // This one is unique to router
131
- permissions: async (ik, params, { req, res }) => {
132
- console.log("🔒 Router-level permissions facet called!");
133
- return { source: "router", facet: "permissions", ik, params };
134
- }
135
- },
136
-
137
- // These will override library allActions with same names
138
- allActions: {
139
- bulkUpdate: async (params, locations, { req, res }) => {
140
- console.log("📝 Router-level bulkUpdate allAction called!");
141
- return { source: "router", allAction: "bulkUpdate", params, locations };
142
- },
143
- export: async (params, locations, { req, res }) => {
144
- console.log("📤 Router-level export allAction called!");
145
- return { source: "router", allAction: "export", params, locations };
146
- },
147
- // This one is unique to router
148
- backup: async (params, locations, { req, res }) => {
149
- console.log("💾 Router-level backup allAction called!");
150
- return { source: "router", allAction: "backup", params, locations };
151
- }
152
- },
153
-
154
- // These will override library allFacets with same names
155
- allFacets: {
156
- analytics: async (params, locations, { req, res }) => {
157
- console.log("📊 Router-level analytics allFacet called!");
158
- return { source: "router", allFacet: "analytics", params, locations };
159
- },
160
- dashboard: async (params, locations, { req, res }) => {
161
- console.log("📈 Router-level dashboard allFacet called!");
162
- return { source: "router", allFacet: "dashboard", params, locations };
163
- },
164
- // This one is unique to router
165
- reports: async (params, locations, { req, res }) => {
166
- console.log("📋 Router-level reports allFacet called!");
167
- return { source: "router", allFacet: "reports", params, locations };
168
- }
169
- }
170
- };
171
-
172
- export function createRouterWithCollisions() {
173
- console.log("🎭 Creating UserRouter with router-level options that collide with library options...");
174
- console.log("⚠️ Watch for collision warnings in the logs!");
175
-
176
- // Create router with options that will collide with library options
177
- const userRouter = new UserRouter(mockLibWithConflicts as any, "user", routerOptions);
178
-
179
- console.log("✅ Router created successfully!");
180
- console.log("📋 Available endpoints with precedence:");
181
- console.log(" Actions (router overrides library):");
182
- console.log(" ✅ POST /users/:userPk/activate (Router-level handler)");
183
- console.log(" ✅ POST /users/:userPk/archive (Router-level handler)");
184
- console.log(" 🆕 POST /users/:userPk/resetPassword (Router-only)");
185
- console.log(" Facets (router overrides library):");
186
- console.log(" ✅ GET /users/:userPk/profile (Router-level handler)");
187
- console.log(" ✅ GET /users/:userPk/settings (Router-level handler)");
188
- console.log(" 🆕 GET /users/:userPk/permissions (Router-only)");
189
- console.log(" All Actions (router overrides library):");
190
- console.log(" ✅ POST /users/bulkUpdate (Router-level handler)");
191
- console.log(" ✅ POST /users/export (Router-level handler)");
192
- console.log(" 🆕 POST /users/backup (Router-only)");
193
- console.log(" All Facets (router overrides library):");
194
- console.log(" ✅ GET /users/analytics (Router-level handler)");
195
- console.log(" ✅ GET /users/dashboard (Router-level handler)");
196
- console.log(" 🆕 GET /users/reports (Router-only)");
197
-
198
- return {
199
- userRouter,
200
- expressRouter: userRouter.getRouter()
201
- };
202
- }
203
-
204
- // Example usage
205
- if (import.meta.url === `file://${process.argv[1]}`) {
206
- console.log("🚀 Starting Router Options Collision Example...");
207
- console.log("=".repeat(60));
208
-
209
- const { userRouter, expressRouter } = createRouterWithCollisions();
210
-
211
- console.log("=".repeat(60));
212
- console.log("✅ Example complete! Check the logs above for collision warnings.");
213
- console.log("💡 Router-level handlers take precedence over library handlers with the same names.");
214
- }
package/vitest.config.ts DELETED
@@ -1,39 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- setupFiles: ['./tests/setup.ts'],
6
- include: [
7
- 'tests/**/*.test.ts',
8
- 'tests/**/*.spec.ts',
9
- ],
10
- coverage: {
11
- provider: 'v8',
12
- reporter: ['text', 'html', 'lcov'],
13
- reportsDirectory: './coverage',
14
- include: [
15
- 'src/**/*.ts',
16
- 'examples/**/*.ts',
17
- ],
18
- exclude: [
19
- 'node_modules/',
20
- 'tests/',
21
- 'src/index.ts',
22
- 'dist/**/*.ts',
23
- 'dist/**/*.js',
24
- 'esbuild.config.js',
25
- 'vitest.config.ts',
26
- 'eslint.config.mjs',
27
- ],
28
- thresholds: {
29
- global: {
30
- branches: 72,
31
- functions: 100,
32
- lines: 98,
33
- statements: 98,
34
- },
35
- },
36
- },
37
- environment: 'node',
38
- },
39
- });