@fjell/express-router 4.4.2 → 4.4.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.
package/src/ItemRouter.ts CHANGED
@@ -11,36 +11,11 @@ import {
11
11
  } from "@fjell/core";
12
12
  import { NotFoundError, Operations } from "@fjell/lib";
13
13
  import deepmerge from "deepmerge";
14
- import { Request, RequestHandler, Response, Router } from "express";
14
+ import { Request, Response, Router } from "express";
15
15
  import LibLogger from "./logger";
16
16
 
17
17
  export type ItemRouterOptions = Record<string, never>;
18
18
 
19
- // TODO: body is in the request, it's not needed in the parameters
20
- export type ActionMethod = <
21
- S extends string,
22
- L1 extends string = never,
23
- L2 extends string = never,
24
- L3 extends string = never,
25
- L4 extends string = never,
26
- L5 extends string = never
27
- >(req: Request, res: Response, item: Item<S, L1, L2, L3, L4, L5>, params: any, body: any) =>
28
- Promise<Item<S, L1, L2, L3, L4, L5>>;
29
-
30
- // TODO: body is in the request, it's not needed in the parameters
31
- export type AllActionMethods = Array<RequestHandler>;
32
-
33
- // TODO: body is in the request, it's not needed in the parameters
34
- export type FacetMethod = <
35
- S extends string,
36
- L1 extends string = never,
37
- L2 extends string = never,
38
- L3 extends string = never,
39
- L4 extends string = never,
40
- L5 extends string = never
41
- >(req: Request, res: Response, item: Item<S, L1, L2, L3, L4, L5>, params: any) =>
42
- Promise<any>;
43
-
44
19
  export class ItemRouter<
45
20
  S extends string,
46
21
  L1 extends string = never,
@@ -55,8 +30,6 @@ export class ItemRouter<
55
30
  protected options: ItemRouterOptions;
56
31
  private childRouters: Record<string, Router> = {};
57
32
  private logger;
58
- private itemActions: Record<string, ActionMethod> | undefined;
59
- private itemFacets: Record<string, FacetMethod> | undefined;
60
33
 
61
34
  constructor(
62
35
  lib: Operations<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>,
@@ -102,19 +75,68 @@ export class ItemRouter<
102
75
  throw new Error('Method not implemented in an abstract router');
103
76
  }
104
77
 
78
+ protected postAllAction = async (req: Request, res: Response) => {
79
+ this.logger.default('Posting All Action', { query: req?.query, params: req?.params, locals: res?.locals });
80
+ const allActionKey = req.path.substring(req.path.lastIndexOf('/') + 1);
81
+ if (!this.lib.allActions) {
82
+ this.logger.error('Item Actions are not configured');
83
+ res.status(500).json({ error: 'Item Actions are not configured' });
84
+ return;
85
+ }
86
+ const allAction = this.lib.allActions[allActionKey];
87
+ if (!allAction) {
88
+ this.logger.error('All Action is not configured', { allActionKey });
89
+ res.status(500).json({ error: 'Item Action is not configured' });
90
+ return;
91
+ }
92
+ try {
93
+ res.json(await this.lib.allAction(allActionKey, req.body));
94
+ } catch (err: any) {
95
+ this.logger.error('Error in All Action', { message: err?.message, stack: err?.stack });
96
+ res.status(500).json(err);
97
+ }
98
+ }
99
+
100
+ protected getAllFacet = async (req: Request, res: Response) => {
101
+ this.logger.default('Getting All Facet', { query: req?.query, params: req?.params, locals: res?.locals });
102
+ const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);
103
+ if (!this.lib.allFacets) {
104
+ this.logger.error('Item Facets are not configured');
105
+ res.status(500).json({ error: 'Item Facets are not configured' });
106
+ return;
107
+ }
108
+ const facet = this.lib.allFacets[facetKey];
109
+ if (!facet) {
110
+ this.logger.error('Item Facet is not configured', { facetKey });
111
+ res.status(500).json({ error: 'Item Facet is not configured' });
112
+ return;
113
+ }
114
+ try {
115
+ const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;
116
+ res.json(await this.lib.allFacet(facetKey, combinedQueryParams));
117
+ } catch (err: any) {
118
+ this.logger.error('Error in All Facet', { message: err?.message, stack: err?.stack });
119
+ res.status(500).json(err);
120
+ }
121
+ }
122
+
105
123
  protected postItemAction = async (req: Request, res: Response) => {
106
124
  this.logger.default('Getting Item', { query: req?.query, params: req?.params, locals: res?.locals });
107
125
  const ik = this.getIk(res);
108
126
  const actionKey = req.path.substring(req.path.lastIndexOf('/') + 1);
109
- if (!this.itemActions) {
127
+ if (!this.lib.actions) {
110
128
  this.logger.error('Item Actions are not configured');
111
129
  res.status(500).json({ error: 'Item Actions are not configured' });
112
130
  return;
113
131
  }
132
+ const action = this.lib.actions[actionKey];
133
+ if (!action) {
134
+ this.logger.error('Item Action is not configured', { actionKey });
135
+ res.status(500).json({ error: 'Item Action is not configured' });
136
+ return;
137
+ }
114
138
  try {
115
- const item =
116
- validatePK(await this.lib.get(ik), this.getPkType()) as Item<S, L1, L2, L3, L4, L5>;
117
- res.json(await this.itemActions[actionKey](req, res, item, req.params, req.body));
139
+ res.json(await this.lib.action(ik, actionKey, req.body));
118
140
  } catch (err: any) {
119
141
  this.logger.error('Error in Item Action', { message: err?.message, stack: err?.stack });
120
142
  res.status(500).json(err);
@@ -125,15 +147,20 @@ export class ItemRouter<
125
147
  this.logger.default('Getting Item', { query: req?.query, params: req?.params, locals: res?.locals });
126
148
  const ik = this.getIk(res);
127
149
  const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);
128
- if (!this.itemFacets) {
150
+ if (!this.lib.facets) {
129
151
  this.logger.error('Item Facets are not configured');
130
152
  res.status(500).json({ error: 'Item Facets are not configured' });
131
153
  return;
132
154
  }
155
+ const facet = this.lib.facets[facetKey];
156
+ if (!facet) {
157
+ this.logger.error('Item Facet is not configured', { facetKey });
158
+ res.status(500).json({ error: 'Item Facet is not configured' });
159
+ return;
160
+ }
133
161
  try {
134
- const item =
135
- validatePK(await this.lib.get(ik), this.getPkType()) as Item<S, L1, L2, L3, L4, L5>;
136
- await this.itemFacets[facetKey](req, res, item, req.params);
162
+ const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;
163
+ res.json(await this.lib.facet(ik, facetKey, combinedQueryParams));
137
164
  } catch (err: any) {
138
165
  this.logger.error('Error in Item Facet', { message: err?.message, stack: err?.stack });
139
166
  res.status(500).json(err);
@@ -145,13 +172,21 @@ export class ItemRouter<
145
172
  router.get('/', this.findItems);
146
173
  router.post('/', this.createItem);
147
174
 
148
- const allActions = this.configureAllActions();
149
- this.logger.debug('All Actions supplied to Router', { allActions });
150
- if (allActions) {
151
- Object.keys(allActions).forEach((actionKey) => {
175
+ this.logger.debug('All Actions supplied to Router', { allActions: this.lib.allActions });
176
+ if (this.lib.allActions) {
177
+ Object.keys(this.lib.allActions).forEach((actionKey) => {
152
178
  this.logger.default('Configuring All Action', { actionKey });
153
179
  // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers
154
- router.post(`/${actionKey}`, ...allActions[actionKey]);
180
+ router.post(`/${actionKey}`, this.postAllAction);
181
+ });
182
+ }
183
+
184
+ this.logger.debug('All Facets supplied to Router', { allFacets: this.lib.allFacets });
185
+ if (this.lib.allFacets) {
186
+ Object.keys(this.lib.allFacets).forEach((facetKey) => {
187
+ this.logger.default('Configuring All Facet', { facetKey });
188
+ // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers
189
+ router.get(`/${facetKey}`, this.getAllFacet);
155
190
  });
156
191
  }
157
192
 
@@ -160,20 +195,18 @@ export class ItemRouter<
160
195
  itemRouter.put('/', this.updateItem);
161
196
  itemRouter.delete('/', this.deleteItem);
162
197
 
163
- this.itemActions = this.configureItemActions();
164
- this.logger.debug('Item Actions supplied to Router', { itemActions: this.itemActions });
165
- if (this.itemActions) {
166
- Object.keys(this.itemActions).forEach((actionKey) => {
198
+ this.logger.debug('Item Actions supplied to Router', { itemActions: this.lib.actions });
199
+ if (this.lib.actions) {
200
+ Object.keys(this.lib.actions).forEach((actionKey) => {
167
201
  this.logger.default('Configuring Item Action', { actionKey });
168
202
  // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers
169
203
  itemRouter.post(`/${actionKey}`, this.postItemAction)
170
204
  });
171
205
  }
172
206
 
173
- this.itemFacets = this.configureItemFacets();
174
- this.logger.debug('Item Facets supplied to Router', { itemFacets: this.itemFacets });
175
- if (this.itemFacets) {
176
- Object.keys(this.itemFacets).forEach((facetKey) => {
207
+ this.logger.debug('Item Facets supplied to Router', { itemFacets: this.lib.facets });
208
+ if (this.lib.facets) {
209
+ Object.keys(this.lib.facets).forEach((facetKey) => {
177
210
  this.logger.default('Configuring Item Facet', { facetKey });
178
211
  // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers
179
212
  itemRouter.get(`/${facetKey}`, this.getItemFacet)
@@ -213,24 +246,6 @@ export class ItemRouter<
213
246
  this.childRouters[path] = router;
214
247
  }
215
248
 
216
- /* istanbul ignore next */
217
- protected configureItemActions(): Record<string, ActionMethod> {
218
- this.logger.debug('ARouter - No Item Actions Configured');
219
- return {};
220
- }
221
-
222
- /* istanbul ignore next */
223
- protected configureItemFacets(): Record<string, FacetMethod> {
224
- this.logger.debug('ARouter - No Item Facets Configured');
225
- return {};
226
- }
227
-
228
- /* istanbul ignore next */
229
- protected configureAllActions(): Record<string, AllActionMethods> {
230
- this.logger.debug('ARouter - No All Actions Configured');
231
- return {};
232
- }
233
-
234
249
  /* istanbul ignore next */
235
250
  public getRouter(): Router {
236
251
  const router = Router();
@@ -13,7 +13,7 @@ interface ParsedQuery {
13
13
  export class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {
14
14
 
15
15
  constructor(lib: Primary.Operations<T, S>, keyType: S, options: ItemRouterOptions = {}) {
16
- super(lib, keyType, options);
16
+ super(lib as any, keyType, options);
17
17
  }
18
18
 
19
19
  public getIk(res: Response): PriKey<S> {