@fjell/express-router 4.4.12 → 4.4.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +332 -0
- package/build.js +4 -0
- package/dist/CItemRouter.d.ts +5 -4
- package/dist/CItemRouter.d.ts.map +1 -0
- package/dist/CItemRouter.js +63 -92
- package/dist/CItemRouter.js.map +7 -1
- package/dist/Instance.d.ts +5 -4
- package/dist/Instance.d.ts.map +1 -0
- package/dist/Instance.js +12 -22
- package/dist/Instance.js.map +7 -1
- package/dist/InstanceFactory.d.ts +5 -4
- package/dist/InstanceFactory.d.ts.map +1 -0
- package/dist/InstanceFactory.js +10 -18
- package/dist/InstanceFactory.js.map +7 -1
- package/dist/ItemRouter.d.ts +5 -4
- package/dist/ItemRouter.d.ts.map +1 -0
- package/dist/ItemRouter.js +290 -405
- package/dist/ItemRouter.js.map +7 -1
- package/dist/PItemRouter.d.ts +5 -4
- package/dist/PItemRouter.d.ts.map +1 -0
- package/dist/PItemRouter.js +43 -67
- package/dist/PItemRouter.js.map +7 -1
- package/dist/Registry.d.ts +1 -0
- package/dist/Registry.d.ts.map +1 -0
- package/dist/Registry.js +22 -27
- package/dist/Registry.js.map +7 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -6
- package/dist/index.js.map +7 -1
- package/dist/logger.d.ts +2 -1
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +6 -5
- package/dist/logger.js.map +7 -1
- package/dist/util/general.d.ts +1 -0
- package/dist/util/general.d.ts.map +1 -0
- package/dist/util/general.js +50 -0
- package/dist/util/general.js.map +7 -0
- package/docs/docs.config.ts +44 -0
- package/docs/index.html +18 -0
- package/docs/package.json +34 -0
- package/docs/public/README.md +332 -0
- package/docs/public/examples-README.md +339 -0
- package/docs/public/fjell-icon.svg +1 -0
- package/docs/public/pano.png +0 -0
- package/docs/src/index.css +21 -0
- package/docs/src/main.tsx +12 -0
- package/docs/src/test/setup.ts +1 -0
- package/docs/src/types.d.ts +4 -0
- package/docs/tsconfig.node.json +6 -0
- package/package.json +21 -19
- package/vitest.config.ts +45 -0
- package/dist/CItemRouter.cjs +0 -100
- package/dist/CItemRouter.cjs.map +0 -1
- package/dist/Instance.cjs +0 -31
- package/dist/Instance.cjs.map +0 -1
- package/dist/InstanceFactory.cjs +0 -25
- package/dist/InstanceFactory.cjs.map +0 -1
- package/dist/ItemRouter.cjs +0 -427
- package/dist/ItemRouter.cjs.map +0 -1
- package/dist/PItemRouter.cjs +0 -75
- package/dist/PItemRouter.cjs.map +0 -1
- package/dist/Registry.cjs +0 -36
- package/dist/Registry.cjs.map +0 -1
- package/dist/index.cjs +0 -657
- package/dist/index.cjs.map +0 -1
- package/dist/logger.cjs +0 -10
- package/dist/logger.cjs.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Fjell Express Router
|
|
2
|
+
|
|
3
|
+
**Express Router for Fjell** - Automatic REST API generation with hierarchical data management for Express.js applications.
|
|
4
|
+
|
|
5
|
+
Fjell Express Router provides a powerful abstraction layer for creating Express.js REST APIs that automatically handle CRUD operations for complex, hierarchical data models. Built on the Fjell framework, it enables rapid development of enterprise-grade APIs with built-in support for nested resources, business logic integration, and type-safe operations.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Automatic CRUD Routes**: Generate complete REST endpoints with minimal configuration
|
|
10
|
+
- **Hierarchical Data Support**: Handle complex nested relationships with parent-child routing
|
|
11
|
+
- **Type-Safe Operations**: Full TypeScript support with generic type constraints
|
|
12
|
+
- **Flexible Business Logic**: Easy integration of custom business rules and validations
|
|
13
|
+
- **Express.js Integration**: Seamless mounting as Express middleware with full compatibility
|
|
14
|
+
- **Built-in Error Handling**: Comprehensive error responses with proper HTTP status codes
|
|
15
|
+
- **Extensible Architecture**: Support for custom actions, facets, and middleware
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @fjell/express-router
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or with pnpm:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @fjell/express-router
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { PItemRouter, createRegistry } from '@fjell/express-router';
|
|
33
|
+
import { Item } from '@fjell/core';
|
|
34
|
+
import express from 'express';
|
|
35
|
+
|
|
36
|
+
// Define your data model
|
|
37
|
+
interface User extends Item<'user'> {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
email: string;
|
|
41
|
+
role: 'admin' | 'user' | 'guest';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Create Express app and registry
|
|
45
|
+
const app = express();
|
|
46
|
+
const registry = createRegistry();
|
|
47
|
+
|
|
48
|
+
// Create instance and router
|
|
49
|
+
const userInstance = registry.getInstance(
|
|
50
|
+
'user',
|
|
51
|
+
userOperations, // Your business logic implementation
|
|
52
|
+
userOptions // Configuration options
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const userRouter = new PItemRouter(userInstance, 'user');
|
|
56
|
+
|
|
57
|
+
// Mount router - automatically creates CRUD endpoints
|
|
58
|
+
app.use('/api/users', userRouter.getRouter());
|
|
59
|
+
|
|
60
|
+
// Start server
|
|
61
|
+
app.listen(3000, () => {
|
|
62
|
+
console.log('Server running on http://localhost:3000');
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This automatically creates the following endpoints:
|
|
67
|
+
|
|
68
|
+
- `GET /api/users` - List all users
|
|
69
|
+
- `GET /api/users/:userPk` - Get specific user
|
|
70
|
+
- `POST /api/users` - Create new user
|
|
71
|
+
- `PUT /api/users/:userPk` - Update user
|
|
72
|
+
- `DELETE /api/users/:userPk` - Delete user
|
|
73
|
+
|
|
74
|
+
## Core Concepts
|
|
75
|
+
|
|
76
|
+
### Router Types
|
|
77
|
+
|
|
78
|
+
**PItemRouter** - For primary entities that exist independently:
|
|
79
|
+
```typescript
|
|
80
|
+
const userRouter = new PItemRouter(userInstance, 'user');
|
|
81
|
+
const productRouter = new PItemRouter(productInstance, 'product');
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**CItemRouter** - For child entities that belong to parent entities:
|
|
85
|
+
```typescript
|
|
86
|
+
const orderRouter = new PItemRouter(orderInstance, 'order');
|
|
87
|
+
const orderItemRouter = new CItemRouter(orderItemInstance, 'orderItem', orderRouter);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Hierarchical Routing
|
|
91
|
+
|
|
92
|
+
Create nested routes for complex relationships:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Organization -> Department -> Employee hierarchy
|
|
96
|
+
const orgRouter = new PItemRouter(orgInstance, 'organization');
|
|
97
|
+
const deptRouter = new CItemRouter(deptInstance, 'department', orgRouter);
|
|
98
|
+
const empRouter = new CItemRouter(empInstance, 'employee', deptRouter);
|
|
99
|
+
|
|
100
|
+
// Mount hierarchical routes
|
|
101
|
+
app.use('/api/organizations', orgRouter.getRouter());
|
|
102
|
+
app.use('/api/organizations/:organizationPk/departments', deptRouter.getRouter());
|
|
103
|
+
app.use('/api/organizations/:organizationPk/departments/:departmentPk/employees', empRouter.getRouter());
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This creates endpoints like:
|
|
107
|
+
- `GET /api/organizations/org-1/departments/dept-1/employees`
|
|
108
|
+
- `POST /api/organizations/org-1/departments/dept-1/employees`
|
|
109
|
+
- `GET /api/organizations/org-1/departments/dept-1/employees/emp-1`
|
|
110
|
+
|
|
111
|
+
## Advanced Usage
|
|
112
|
+
|
|
113
|
+
### Custom Business Logic
|
|
114
|
+
|
|
115
|
+
Add custom routes alongside automatic CRUD operations:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const router = userRouter.getRouter();
|
|
119
|
+
|
|
120
|
+
// Add custom business logic routes
|
|
121
|
+
router.get('/analytics', async (req, res) => {
|
|
122
|
+
const analytics = await userInstance.operations.getAnalytics();
|
|
123
|
+
res.json(analytics);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
router.post('/:userPk/activate', async (req, res) => {
|
|
127
|
+
const userPk = req.params.userPk;
|
|
128
|
+
const user = await userInstance.operations.activate(userPk);
|
|
129
|
+
res.json(user);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
app.use('/api/users', router);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Middleware Integration
|
|
136
|
+
|
|
137
|
+
Add Express middleware for authentication, validation, and more:
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { authenticate, authorize, validateRequest } from './middleware';
|
|
141
|
+
|
|
142
|
+
// Global middleware
|
|
143
|
+
app.use(express.json());
|
|
144
|
+
app.use(authenticate);
|
|
145
|
+
|
|
146
|
+
// Router-specific middleware
|
|
147
|
+
const protectedRouter = userRouter.getRouter();
|
|
148
|
+
protectedRouter.use(authorize(['admin', 'user']));
|
|
149
|
+
protectedRouter.use('/sensitive-endpoint', validateRequest);
|
|
150
|
+
|
|
151
|
+
app.use('/api/users', protectedRouter);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Error Handling
|
|
155
|
+
|
|
156
|
+
Built-in error handling with proper HTTP status codes:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// Automatic error responses for common scenarios:
|
|
160
|
+
// 404 - Entity not found
|
|
161
|
+
// 400 - Invalid request data
|
|
162
|
+
// 500 - Internal server errors
|
|
163
|
+
|
|
164
|
+
// Custom error handling
|
|
165
|
+
app.use((err, req, res, next) => {
|
|
166
|
+
console.error('API Error:', err);
|
|
167
|
+
res.status(err.status || 500).json({
|
|
168
|
+
error: err.message || 'Internal Server Error',
|
|
169
|
+
...(process.env.NODE_ENV === 'development' && { stack: err.stack })
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Data Model Requirements
|
|
175
|
+
|
|
176
|
+
Your data models must extend the Fjell `Item` interface:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { Item, UUID } from '@fjell/core';
|
|
180
|
+
|
|
181
|
+
interface User extends Item<'user'> {
|
|
182
|
+
id: string;
|
|
183
|
+
name: string;
|
|
184
|
+
email: string;
|
|
185
|
+
// ... other properties
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
interface Order extends Item<'order'> {
|
|
189
|
+
id: string;
|
|
190
|
+
customerId: string;
|
|
191
|
+
total: number;
|
|
192
|
+
// ... other properties
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
interface OrderItem extends Item<'orderItem', 'order'> {
|
|
196
|
+
id: string;
|
|
197
|
+
productId: string;
|
|
198
|
+
quantity: number;
|
|
199
|
+
price: number;
|
|
200
|
+
// ... other properties
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Configuration
|
|
205
|
+
|
|
206
|
+
Configure your instances with business operations and options:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
const userInstance = registry.getInstance(
|
|
210
|
+
'user',
|
|
211
|
+
{
|
|
212
|
+
// Business operations implementation
|
|
213
|
+
create: async (item) => { /* create logic */ },
|
|
214
|
+
get: async (pk) => { /* get logic */ },
|
|
215
|
+
update: async (pk, updates) => { /* update logic */ },
|
|
216
|
+
delete: async (pk) => { /* delete logic */ },
|
|
217
|
+
list: async (query) => { /* list logic */ },
|
|
218
|
+
// ... other operations
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
// Configuration options
|
|
222
|
+
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
223
|
+
validation: { /* validation rules */ },
|
|
224
|
+
facets: { /* custom facets */ },
|
|
225
|
+
actions: { /* custom actions */ },
|
|
226
|
+
// ... other options
|
|
227
|
+
}
|
|
228
|
+
);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Examples
|
|
232
|
+
|
|
233
|
+
This package includes comprehensive examples in the `examples/` directory:
|
|
234
|
+
|
|
235
|
+
- **`basic-router-example.ts`** - Start here for fundamental usage patterns
|
|
236
|
+
- **`nested-router-example.ts`** - Hierarchical data management with organizations/departments/employees
|
|
237
|
+
- **`full-application-example.ts`** - Production-ready e-commerce application
|
|
238
|
+
|
|
239
|
+
Run examples:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Basic example
|
|
243
|
+
npx tsx examples/basic-router-example.ts
|
|
244
|
+
|
|
245
|
+
# Nested routing example
|
|
246
|
+
npx tsx examples/nested-router-example.ts
|
|
247
|
+
|
|
248
|
+
# Full application example
|
|
249
|
+
npx tsx examples/full-application-example.ts
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## API Reference
|
|
253
|
+
|
|
254
|
+
### PItemRouter<T, S>
|
|
255
|
+
|
|
256
|
+
Primary item router for top-level entities.
|
|
257
|
+
|
|
258
|
+
**Constructor**
|
|
259
|
+
```typescript
|
|
260
|
+
new PItemRouter<T, S>(instance: Instance<T, S>, keyType: S, options?: ItemRouterOptions)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Methods**
|
|
264
|
+
- `getRouter(): Router` - Get Express router instance
|
|
265
|
+
- `getPkType(): S` - Get primary key type
|
|
266
|
+
- `createItem(req, res)` - Handle POST requests
|
|
267
|
+
- `getItem(req, res)` - Handle GET requests for single items
|
|
268
|
+
- `updateItem(req, res)` - Handle PUT requests
|
|
269
|
+
- `deleteItem(req, res)` - Handle DELETE requests
|
|
270
|
+
|
|
271
|
+
### CItemRouter<T, S, L1, ...>
|
|
272
|
+
|
|
273
|
+
Child item router for nested entities.
|
|
274
|
+
|
|
275
|
+
**Constructor**
|
|
276
|
+
```typescript
|
|
277
|
+
new CItemRouter<T, S, L1>(
|
|
278
|
+
instance: Instance<T, S, L1>,
|
|
279
|
+
keyType: S,
|
|
280
|
+
parentRouter: ItemRouter<L1>,
|
|
281
|
+
options?: ItemRouterOptions
|
|
282
|
+
)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Inherits all methods from `ItemRouter` with additional parent-child relationship handling.
|
|
286
|
+
|
|
287
|
+
### createRegistry()
|
|
288
|
+
|
|
289
|
+
Factory function to create a new registry instance for managing multiple routers.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
const registry = createRegistry();
|
|
293
|
+
const instance = registry.getInstance(keyType, operations, options);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Requirements
|
|
297
|
+
|
|
298
|
+
- Node.js >= 21
|
|
299
|
+
- TypeScript >= 5.0
|
|
300
|
+
- Express.js >= 5.0
|
|
301
|
+
|
|
302
|
+
## Dependencies
|
|
303
|
+
|
|
304
|
+
- `@fjell/core` - Core Fjell framework types and utilities
|
|
305
|
+
- `@fjell/lib` - Fjell library components
|
|
306
|
+
- `@fjell/logging` - Structured logging for Fjell applications
|
|
307
|
+
- `@fjell/registry` - Registry management for Fjell instances
|
|
308
|
+
- `express` - Express.js web framework
|
|
309
|
+
- `deepmerge` - Deep object merging utility
|
|
310
|
+
|
|
311
|
+
## Contributing
|
|
312
|
+
|
|
313
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
|
|
314
|
+
|
|
315
|
+
1. Fork the repository
|
|
316
|
+
2. Create a feature branch
|
|
317
|
+
3. Make your changes with tests
|
|
318
|
+
4. Ensure all tests pass
|
|
319
|
+
5. Submit a pull request
|
|
320
|
+
|
|
321
|
+
## License
|
|
322
|
+
|
|
323
|
+
Licensed under the Apache License 2.0. See the LICENSE file for details.
|
|
324
|
+
|
|
325
|
+
## Support
|
|
326
|
+
|
|
327
|
+
- **Documentation**: [Full documentation and guides](./docs/)
|
|
328
|
+
- **Examples**: [Comprehensive examples](./examples/)
|
|
329
|
+
- **Issues**: [GitHub Issues](https://github.com/getfjell/express-router/issues)
|
|
330
|
+
- **Discussions**: [GitHub Discussions](https://github.com/getfjell/express-router/discussions)
|
|
331
|
+
|
|
332
|
+
Built with care by the Fjell team.
|
package/build.js
ADDED
package/dist/CItemRouter.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ComKey, Item, LocKeyArray } from
|
|
2
|
-
import { Request, Response } from
|
|
3
|
-
import { ItemRouter, ItemRouterOptions } from
|
|
4
|
-
import { Instance } from
|
|
1
|
+
import { ComKey, Item, LocKeyArray } from "@fjell/core";
|
|
2
|
+
import { Request, Response } from "express";
|
|
3
|
+
import { ItemRouter, ItemRouterOptions } from "@/ItemRouter";
|
|
4
|
+
import { Instance } from "./Instance";
|
|
5
5
|
export declare class CItemRouter<T extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never> extends ItemRouter<S, L1, L2, L3, L4, L5> {
|
|
6
6
|
private parentRoute;
|
|
7
7
|
constructor(lib: Instance<T, S, L1, L2, L3, L4, L5>, type: S, parentRoute: ItemRouter<L1, L2, L3, L4, L5, never>, options?: ItemRouterOptions);
|
|
@@ -12,3 +12,4 @@ export declare class CItemRouter<T extends Item<S, L1, L2, L3, L4, L5>, S extend
|
|
|
12
12
|
protected createItem: (req: Request, res: Response) => Promise<void>;
|
|
13
13
|
protected findItems: (req: Request, res: Response) => Promise<void>;
|
|
14
14
|
}
|
|
15
|
+
//# sourceMappingURL=CItemRouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CItemRouter.d.ts","sourceRoot":"","sources":["../src/CItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAAE,IAAI,EAAqB,WAAW,EAC7C,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAMtC,qBAAa,WAAW,CACtB,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACrC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,EACjB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,CACzB,SAAQ,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAEzC,OAAO,CAAC,WAAW,CAAwC;gBAGzD,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACvC,IAAI,EAAE,CAAC,EACP,WAAW,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAClD,OAAO,GAAE,iBAAsB;IAM1B,SAAS,IAAI,OAAO;IAIpB,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAMnD,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAWrD,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAInE,SAAS,CAAC,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBASvD;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA4BtD;CAEH"}
|
package/dist/CItemRouter.js
CHANGED
|
@@ -1,96 +1,67 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Object.defineProperty(obj, key, {
|
|
7
|
-
value: value,
|
|
8
|
-
enumerable: true,
|
|
9
|
-
configurable: true,
|
|
10
|
-
writable: true
|
|
11
|
-
});
|
|
12
|
-
} else {
|
|
13
|
-
obj[key] = value;
|
|
14
|
-
}
|
|
15
|
-
return obj;
|
|
16
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
paramsToQuery,
|
|
3
|
+
validatePK
|
|
4
|
+
} from "@fjell/core";
|
|
5
|
+
import { ItemRouter } from "@/ItemRouter";
|
|
17
6
|
class CItemRouter extends ItemRouter {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
finderParams,
|
|
72
|
-
one
|
|
73
|
-
});
|
|
74
|
-
if (one === 'true') {
|
|
75
|
-
const item = await this.lib.findOne(finder, JSON.parse(finderParams), this.getLocations(res));
|
|
76
|
-
items = item ? [
|
|
77
|
-
item
|
|
78
|
-
] : [];
|
|
79
|
-
} else {
|
|
80
|
-
items = await libOperations.find(finder, JSON.parse(finderParams), this.getLocations(res));
|
|
81
|
-
}
|
|
82
|
-
} else {
|
|
83
|
-
// TODO: This is once of the more important places to perform some validaation and feedback
|
|
84
|
-
const itemQuery = paramsToQuery(req.query);
|
|
85
|
-
this.logger.default('Finding Items with Query: %j', itemQuery);
|
|
86
|
-
items = await libOperations.all(itemQuery, this.getLocations(res));
|
|
87
|
-
this.logger.default('Found %d Items with Query', items.length);
|
|
88
|
-
}
|
|
89
|
-
res.json(items.map((item)=>validatePK(item, this.getPkType())));
|
|
90
|
-
});
|
|
91
|
-
this.parentRoute = parentRoute;
|
|
7
|
+
parentRoute;
|
|
8
|
+
constructor(lib, type, parentRoute, options = {}) {
|
|
9
|
+
super(lib, type, options);
|
|
10
|
+
this.parentRoute = parentRoute;
|
|
11
|
+
}
|
|
12
|
+
hasParent() {
|
|
13
|
+
return !!this.parentRoute;
|
|
14
|
+
}
|
|
15
|
+
getIk(res) {
|
|
16
|
+
const pri = this.getPk(res);
|
|
17
|
+
const loc = this.getLocations(res);
|
|
18
|
+
return { kt: pri.kt, pk: pri.pk, loc };
|
|
19
|
+
}
|
|
20
|
+
getLKA(res) {
|
|
21
|
+
let lka = [this.getLk(res)];
|
|
22
|
+
lka = lka.concat(this.parentRoute.getLKA(res));
|
|
23
|
+
return lka;
|
|
24
|
+
}
|
|
25
|
+
getLocations(res) {
|
|
26
|
+
return this.parentRoute.getLKA(res);
|
|
27
|
+
}
|
|
28
|
+
createItem = async (req, res) => {
|
|
29
|
+
const libOperations = this.lib.operations;
|
|
30
|
+
this.logger.default("Creating Item", { body: req?.body, query: req?.query, params: req?.params, locals: res?.locals });
|
|
31
|
+
const itemToCreate = this.convertDates(req.body);
|
|
32
|
+
let item = validatePK(await libOperations.create(
|
|
33
|
+
itemToCreate,
|
|
34
|
+
{ locations: this.getLocations(res) }
|
|
35
|
+
), this.getPkType());
|
|
36
|
+
item = await this.postCreateItem(item);
|
|
37
|
+
this.logger.default("Created Item %j", item);
|
|
38
|
+
res.json(item);
|
|
39
|
+
};
|
|
40
|
+
findItems = async (req, res) => {
|
|
41
|
+
const libOperations = this.lib.operations;
|
|
42
|
+
const query = req.query;
|
|
43
|
+
const finder = query["finder"];
|
|
44
|
+
const finderParams = query["finderParams"];
|
|
45
|
+
const one = query["one"];
|
|
46
|
+
let items = [];
|
|
47
|
+
if (finder) {
|
|
48
|
+
this.logger.default("Finding Items with Finder", { finder, finderParams, one });
|
|
49
|
+
if (one === "true") {
|
|
50
|
+
const item = await this.lib.findOne(finder, JSON.parse(finderParams), this.getLocations(res));
|
|
51
|
+
items = item ? [item] : [];
|
|
52
|
+
} else {
|
|
53
|
+
items = await libOperations.find(finder, JSON.parse(finderParams), this.getLocations(res));
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
const itemQuery = paramsToQuery(req.query);
|
|
57
|
+
this.logger.default("Finding Items with Query: %j", itemQuery);
|
|
58
|
+
items = await libOperations.all(itemQuery, this.getLocations(res));
|
|
59
|
+
this.logger.default("Found %d Items with Query", items.length);
|
|
92
60
|
}
|
|
61
|
+
res.json(items.map((item) => validatePK(item, this.getPkType())));
|
|
62
|
+
};
|
|
93
63
|
}
|
|
94
|
-
|
|
95
|
-
|
|
64
|
+
export {
|
|
65
|
+
CItemRouter
|
|
66
|
+
};
|
|
96
67
|
//# sourceMappingURL=CItemRouter.js.map
|
package/dist/CItemRouter.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/CItemRouter.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n ComKey, Item, ItemQuery, LocKey, LocKeyArray, paramsToQuery, PriKey, QueryParams, validatePK\n} from \"@fjell/core\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"@/ItemRouter\";\nimport { Instance } from \"./Instance\";\n\ninterface ParsedQuery {\n [key: string]: undefined | string | string[] | ParsedQuery | ParsedQuery[];\n}\n\nexport class CItemRouter<\n T extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends ItemRouter<S, L1, L2, L3, L4, L5> {\n\n private parentRoute: ItemRouter<L1, L2, L3, L4, L5, never>;\n\n constructor(\n lib: Instance<T, S, L1, L2, L3, L4, L5>,\n type: S,\n parentRoute: ItemRouter<L1, L2, L3, L4, L5, never>,\n options: ItemRouterOptions = {},\n ) {\n super(lib as any, type, options);\n this.parentRoute = parentRoute;\n }\n\n public hasParent(): boolean {\n return !!this.parentRoute;\n }\n\n public getIk(res: Response): ComKey<S, L1, L2, L3, L4, L5> {\n const pri = this.getPk(res) as PriKey<S>;\n const loc = this.getLocations(res) as LocKeyArray<L1, L2, L3, L4, L5>;\n return { kt: pri.kt, pk: pri.pk, loc }\n }\n\n public getLKA(res: Response): LocKeyArray<S, L1, L2, L3, L4> {\n /**\n * A location key array is passed to a child router to provide contextfor the items it will\n * be working with. It is always a concatenation of \"My LKA\" + \"Parent LKA\" which will\n * bubble all the way up to the root Primary.\n */\n let lka: LocKey<S | L1 | L2 | L3 | L4>[] = [this.getLk(res)];\n lka = lka.concat(this.parentRoute.getLKA(res) as LocKey<S | L1 | L2 | L3 | L4>[]);\n return lka as LocKeyArray<S, L1, L2, L3, L4>;\n }\n\n public getLocations(res: Response): LocKeyArray<L1, L2, L3, L4, L5> {\n return this.parentRoute.getLKA(res) as LocKeyArray<L1, L2, L3, L4, L5>;\n }\n\n protected createItem = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.default('Creating Item', { body: req?.body, query: req?.query, params: req?.params, locals: res?.locals });\n const itemToCreate = this.convertDates(req.body as Item<S, L1, L2, L3, L4, L5>);\n let item = validatePK(await libOperations.create(\n itemToCreate, { locations: this.getLocations(res) }), this.getPkType()) as Item<S, L1, L2, L3, L4, L5>;\n item = await this.postCreateItem(item);\n this.logger.default('Created Item %j', item);\n res.json(item);\n };\n\n protected findItems = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n const query: ParsedQuery = req.query as unknown as ParsedQuery;\n const finder = query['finder'] as string;\n const finderParams = query['finderParams'] as string;\n const one = query['one'] as string;\n\n let items: Item<S, L1, L2, L3, L4, L5>[] = [];\n\n if (finder) {\n // If finder is defined? Call a finder.\n this.logger.default('Finding Items with Finder', { finder, finderParams, one });\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, JSON.parse(finderParams), this.getLocations(res));\n items = item ? [item] : [];\n } else {\n items = await libOperations.find(finder, JSON.parse(finderParams), this.getLocations(res));\n }\n } else {\n // TODO: This is once of the more important places to perform some validaation and feedback\n const itemQuery: ItemQuery = paramsToQuery(req.query as QueryParams);\n this.logger.default('Finding Items with Query: %j', itemQuery);\n items = await libOperations.all(itemQuery, this.getLocations(res));\n this.logger.default('Found %d Items with Query', items.length);\n }\n\n res.json(items.map((item: Item<S, L1, L2, L3, L4, L5>) => validatePK(item, this.getPkType())));\n };\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EACgD;AAAA,EAAoC;AAAA,OAC7E;AAEP,SAAS,kBAAqC;AAOvC,MAAM,oBAQH,WAAkC;AAAA,EAElC;AAAA,EAER,YACE,KACA,MACA,aACA,UAA6B,CAAC,GAC9B;AACA,UAAM,KAAY,MAAM,OAAO;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEO,YAAqB;AAC1B,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA,EAEO,MAAM,KAA8C;AACzD,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,WAAO,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,EACvC;AAAA,EAEO,OAAO,KAA+C;AAM3D,QAAI,MAAuC,CAAC,KAAK,MAAM,GAAG,CAAC;AAC3D,UAAM,IAAI,OAAO,KAAK,YAAY,OAAO,GAAG,CAAoC;AAChF,WAAO;AAAA,EACT;AAAA,EAEO,aAAa,KAAgD;AAClE,WAAO,KAAK,YAAY,OAAO,GAAG;AAAA,EACpC;AAAA,EAEU,aAAa,OAAO,KAAc,QAAkB;AAC5D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,QAAQ,iBAAiB,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACrH,UAAM,eAAe,KAAK,aAAa,IAAI,IAAmC;AAC9E,QAAI,OAAO,WAAW,MAAM,cAAc;AAAA,MACxC;AAAA,MAAc,EAAE,WAAW,KAAK,aAAa,GAAG,EAAE;AAAA,IAAC,GAAG,KAAK,UAAU,CAAC;AACxE,WAAO,MAAM,KAAK,eAAe,IAAI;AACrC,SAAK,OAAO,QAAQ,mBAAmB,IAAI;AAC3C,QAAI,KAAK,IAAI;AAAA,EACf;AAAA,EAEU,YAAY,OAAO,KAAc,QAAkB;AAC3D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,UAAM,QAAqB,IAAI;AAC/B,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,eAAe,MAAM,cAAc;AACzC,UAAM,MAAM,MAAM,KAAK;AAEvB,QAAI,QAAuC,CAAC;AAE5C,QAAI,QAAQ;AAEV,WAAK,OAAO,QAAQ,6BAA6B,EAAE,QAAQ,cAAc,IAAI,CAAC;AAE9E,UAAI,QAAQ,QAAQ;AAClB,cAAM,OAAO,MAAO,KAAK,IAAY,QAAQ,QAAQ,KAAK,MAAM,YAAY,GAAG,KAAK,aAAa,GAAG,CAAC;AACrG,gBAAQ,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,MAC3B,OAAO;AACL,gBAAQ,MAAM,cAAc,KAAK,QAAQ,KAAK,MAAM,YAAY,GAAG,KAAK,aAAa,GAAG,CAAC;AAAA,MAC3F;AAAA,IACF,OAAO;AAEL,YAAM,YAAuB,cAAc,IAAI,KAAoB;AACnE,WAAK,OAAO,QAAQ,gCAAgC,SAAS;AAC7D,cAAQ,MAAM,cAAc,IAAI,WAAW,KAAK,aAAa,GAAG,CAAC;AACjE,WAAK,OAAO,QAAQ,6BAA6B,MAAM,MAAM;AAAA,IAC/D;AAEA,QAAI,KAAK,MAAM,IAAI,CAAC,SAAsC,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;AAAA,EAC/F;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/Instance.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Item } from
|
|
2
|
-
import { Instance as BaseInstance, Coordinate, Registry } from
|
|
3
|
-
import { Operations, Options } from
|
|
4
|
-
import { ItemRouter } from
|
|
1
|
+
import { Item } from "@fjell/core";
|
|
2
|
+
import { Instance as BaseInstance, Coordinate, Registry } from "@fjell/registry";
|
|
3
|
+
import { Operations, Options } from "@fjell/lib";
|
|
4
|
+
import { ItemRouter } from "./ItemRouter";
|
|
5
5
|
/**
|
|
6
6
|
* The Express Router Instance interface represents a router model instance that extends the base Instance
|
|
7
7
|
* from @fjell/registry and adds express router operations for handling HTTP requests.
|
|
@@ -27,3 +27,4 @@ export interface Instance<V extends Item<S, L1, L2, L3, L4, L5>, S extends strin
|
|
|
27
27
|
}
|
|
28
28
|
export declare const createInstance: <V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(registry: Registry, coordinate: Coordinate<S, L1, L2, L3, L4, L5>, router: ItemRouter<S, L1, L2, L3, L4, L5>, operations: Operations<V, S, L1, L2, L3, L4, L5>, options?: Options<V, S, L1, L2, L3, L4, L5>) => Instance<V, S, L1, L2, L3, L4, L5>;
|
|
29
29
|
export declare const isInstance: (instance: any) => instance is Instance<any, any, any, any, any, any, any>;
|
|
30
|
+
//# sourceMappingURL=Instance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Instance.d.ts","sourceRoot":"","sources":["../src/Instance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,UAAU,EAAwC,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACvH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,QAAQ,CACvB,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACrC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,CACzB,SAAQ,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAC3C,yEAAyE;IACzE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1C,sFAAsF;IACtF,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACjD,uFAAuF;IACvF,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3C,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,GACzB,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACrC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EAEvB,UAAU,QAAQ,EAClB,YAAY,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAC7C,QAAQ,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACzC,YAAY,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAChD,UAAU,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAC1C,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAIrC,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,UAAU,GAAG,KAAG,QAAQ,IAAI,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAQhG,CAAA"}
|
package/dist/Instance.js
CHANGED
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
import LibLogger from
|
|
2
|
-
import { createInstance as
|
|
3
|
-
|
|
1
|
+
import LibLogger from "./logger";
|
|
2
|
+
import { createInstance as createBaseInstance } from "@fjell/registry";
|
|
4
3
|
const logger = LibLogger.get("Instance");
|
|
5
|
-
const createInstance = (registry, coordinate, router, operations, options)=>{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
registry,
|
|
10
|
-
operations,
|
|
11
|
-
options
|
|
12
|
-
});
|
|
13
|
-
const baseInstance = createInstance$1(registry, coordinate);
|
|
14
|
-
return {
|
|
15
|
-
...baseInstance,
|
|
16
|
-
router,
|
|
17
|
-
operations,
|
|
18
|
-
options: options || {}
|
|
19
|
-
};
|
|
4
|
+
const createInstance = (registry, coordinate, router, operations, options) => {
|
|
5
|
+
logger.debug("createInstance", { coordinate, router, registry, operations, options });
|
|
6
|
+
const baseInstance = createBaseInstance(registry, coordinate);
|
|
7
|
+
return { ...baseInstance, router, operations, options: options || {} };
|
|
20
8
|
};
|
|
21
|
-
const isInstance = (instance)=>{
|
|
22
|
-
|
|
9
|
+
const isInstance = (instance) => {
|
|
10
|
+
return instance != null && typeof instance === "object" && instance.coordinate != null && instance.router != null && instance.registry != null && instance.operations != null && instance.options != null;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
createInstance,
|
|
14
|
+
isInstance
|
|
23
15
|
};
|
|
24
|
-
|
|
25
|
-
export { createInstance, isInstance };
|
|
26
16
|
//# sourceMappingURL=Instance.js.map
|
package/dist/Instance.js.map
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/Instance.ts"],
|
|
4
|
+
"sourcesContent": ["import LibLogger from \"./logger\";\nimport { Item } from \"@fjell/core\";\nimport { Instance as BaseInstance, Coordinate, createInstance as createBaseInstance, Registry } from \"@fjell/registry\";\nimport { Operations, Options } from \"@fjell/lib\";\nimport { ItemRouter } from \"./ItemRouter\";\n\nconst logger = LibLogger.get(\"Instance\");\n\n/**\n * The Express Router Instance interface represents a router model instance that extends the base Instance\n * from @fjell/registry and adds express router operations for handling HTTP requests.\n *\n * The interface extends the base Instance (which provides coordinate and registry) with:\n * - router: Provides methods for routing HTTP requests and handling CRUD operations\n * - operations: Provides methods for interacting with the data model (get, find, all, etc.)\n * - options: Provides hooks, validators, finders, actions, and facets\n *\n * @template V - The type of the data model item, extending Item\n * @template S - The string literal type representing the model's key type\n * @template L1-L5 - Optional string literal types for location hierarchy levels\n */\nexport interface Instance<\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> extends BaseInstance<S, L1, L2, L3, L4, L5> {\n /** The router object that provides methods for handling HTTP requests */\n router: ItemRouter<S, L1, L2, L3, L4, L5>;\n /** The operations object that provides methods for interacting with the data model */\n operations: Operations<V, S, L1, L2, L3, L4, L5>;\n /** The options object that provides hooks, validators, finders, actions, and facets */\n options: Options<V, S, L1, L2, L3, L4, L5>;\n /** The data model item type (for type safety) */\n readonly itemType?: V;\n}\n\nexport const createInstance = <\n V extends Item<S, L1, L2, L3, L4, L5>,\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n>(\n registry: Registry,\n coordinate: Coordinate<S, L1, L2, L3, L4, L5>,\n router: ItemRouter<S, L1, L2, L3, L4, L5>,\n operations: Operations<V, S, L1, L2, L3, L4, L5>,\n options?: Options<V, S, L1, L2, L3, L4, L5>,\n ): Instance<V, S, L1, L2, L3, L4, L5> => {\n logger.debug(\"createInstance\", { coordinate, router, registry, operations, options });\n const baseInstance = createBaseInstance(registry, coordinate);\n return { ...baseInstance, router, operations, options: options || {} as Options<V, S, L1, L2, L3, L4, L5> };\n}\n\nexport const isInstance = (instance: any): instance is Instance<any, any, any, any, any, any, any> => {\n return instance != null &&\n typeof instance === 'object' &&\n instance.coordinate != null &&\n instance.router != null &&\n instance.registry != null &&\n instance.operations != null &&\n instance.options != null;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,OAAO,eAAe;AAEtB,SAA+C,kBAAkB,0BAAoC;AAIrG,MAAM,SAAS,UAAU,IAAI,UAAU;AAkChC,MAAM,iBAAiB,CAS1B,UACA,YACA,QACA,YACA,YACuC;AACzC,SAAO,MAAM,kBAAkB,EAAE,YAAY,QAAQ,UAAU,YAAY,QAAQ,CAAC;AACpF,QAAM,eAAe,mBAAmB,UAAU,UAAU;AAC5D,SAAO,EAAE,GAAG,cAAc,QAAQ,YAAY,SAAS,WAAW,CAAC,EAAuC;AAC5G;AAEO,MAAM,aAAa,CAAC,aAA2E;AACpG,SAAO,YAAY,QACjB,OAAO,aAAa,YACpB,SAAS,cAAc,QACvB,SAAS,UAAU,QACnB,SAAS,YAAY,QACrB,SAAS,cAAc,QACvB,SAAS,WAAW;AACxB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|