@fjell/express-router 4.4.23 → 4.4.25
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 +205 -0
- package/dist/CItemRouter.d.ts +1 -1
- package/dist/CItemRouter.d.ts.map +1 -1
- package/dist/CItemRouter.js +23 -8
- package/dist/CItemRouter.js.map +2 -2
- package/dist/Instance.d.ts.map +1 -1
- package/dist/Instance.js.map +2 -2
- package/dist/InstanceFactory.d.ts.map +1 -1
- package/dist/InstanceFactory.js.map +2 -2
- package/dist/ItemRouter.d.ts +64 -3
- package/dist/ItemRouter.d.ts.map +1 -1
- package/dist/ItemRouter.js +111 -15
- package/dist/ItemRouter.js.map +2 -2
- package/dist/PItemRouter.d.ts +1 -1
- package/dist/PItemRouter.d.ts.map +1 -1
- package/dist/PItemRouter.js.map +2 -2
- package/dist/util/general.d.ts.map +1 -1
- package/dist/util/general.js.map +2 -2
- package/examples/README.md +47 -0
- package/examples/basic-router-example.ts +7 -6
- package/examples/full-application-example.ts +137 -12
- package/examples/nested-router-example.ts +154 -54
- package/examples/router-handlers-example.ts +394 -0
- package/package.json +3 -2
package/dist/ItemRouter.js
CHANGED
|
@@ -49,15 +49,31 @@ class ItemRouter {
|
|
|
49
49
|
const libOperations = this.lib.operations;
|
|
50
50
|
this.logger.debug("Posting All Action", { query: req?.query, params: req?.params, locals: res?.locals });
|
|
51
51
|
const allActionKey = req.path.substring(req.path.lastIndexOf("/") + 1);
|
|
52
|
+
if (this.options.allActions && this.options.allActions[allActionKey]) {
|
|
53
|
+
this.logger.debug("Using router-level all action handler", { allActionKey });
|
|
54
|
+
try {
|
|
55
|
+
const result = await this.options.allActions[allActionKey](
|
|
56
|
+
req.body,
|
|
57
|
+
this.getLKA(res),
|
|
58
|
+
{ req, res }
|
|
59
|
+
);
|
|
60
|
+
if (result != null) res.json(result);
|
|
61
|
+
return;
|
|
62
|
+
} catch (err) {
|
|
63
|
+
this.logger.error("Error in router-level all action", { message: err?.message, stack: err?.stack });
|
|
64
|
+
res.status(500).json(err);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
52
68
|
if (!libOptions.allActions) {
|
|
53
|
-
this.logger.error("
|
|
54
|
-
res.status(500).json({ error: "
|
|
69
|
+
this.logger.error("All Actions are not configured");
|
|
70
|
+
res.status(500).json({ error: "All Actions are not configured" });
|
|
55
71
|
return;
|
|
56
72
|
}
|
|
57
73
|
const allAction = libOptions.allActions[allActionKey];
|
|
58
74
|
if (!allAction) {
|
|
59
75
|
this.logger.error("All Action is not configured", { allActionKey });
|
|
60
|
-
res.status(500).json({ error: "
|
|
76
|
+
res.status(500).json({ error: "All Action is not configured" });
|
|
61
77
|
return;
|
|
62
78
|
}
|
|
63
79
|
try {
|
|
@@ -72,15 +88,31 @@ class ItemRouter {
|
|
|
72
88
|
const libOperations = this.lib.operations;
|
|
73
89
|
this.logger.debug("Getting All Facet", { query: req?.query, params: req?.params, locals: res?.locals });
|
|
74
90
|
const facetKey = req.path.substring(req.path.lastIndexOf("/") + 1);
|
|
91
|
+
if (this.options.allFacets && this.options.allFacets[facetKey]) {
|
|
92
|
+
this.logger.debug("Using router-level all facet handler", { facetKey });
|
|
93
|
+
try {
|
|
94
|
+
const result = await this.options.allFacets[facetKey](
|
|
95
|
+
req.query,
|
|
96
|
+
this.getLKA(res),
|
|
97
|
+
{ req, res }
|
|
98
|
+
);
|
|
99
|
+
if (result != null) res.json(result);
|
|
100
|
+
return;
|
|
101
|
+
} catch (err) {
|
|
102
|
+
this.logger.error("Error in router-level all facet", { message: err?.message, stack: err?.stack });
|
|
103
|
+
res.status(500).json(err);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
75
107
|
if (!libOptions.allFacets) {
|
|
76
|
-
this.logger.error("
|
|
77
|
-
res.status(500).json({ error: "
|
|
108
|
+
this.logger.error("All Facets are not configured");
|
|
109
|
+
res.status(500).json({ error: "All Facets are not configured" });
|
|
78
110
|
return;
|
|
79
111
|
}
|
|
80
112
|
const facet = libOptions.allFacets[facetKey];
|
|
81
113
|
if (!facet) {
|
|
82
|
-
this.logger.error("
|
|
83
|
-
res.status(500).json({ error: "
|
|
114
|
+
this.logger.error("All Facet is not configured", { facetKey });
|
|
115
|
+
res.status(500).json({ error: "All Facet is not configured" });
|
|
84
116
|
return;
|
|
85
117
|
}
|
|
86
118
|
try {
|
|
@@ -94,9 +126,25 @@ class ItemRouter {
|
|
|
94
126
|
postItemAction = async (req, res) => {
|
|
95
127
|
const libOptions = this.lib.options;
|
|
96
128
|
const libOperations = this.lib.operations;
|
|
97
|
-
this.logger.debug("
|
|
129
|
+
this.logger.debug("Posting Item Action", { query: req?.query, params: req?.params, locals: res?.locals });
|
|
98
130
|
const ik = this.getIk(res);
|
|
99
131
|
const actionKey = req.path.substring(req.path.lastIndexOf("/") + 1);
|
|
132
|
+
if (this.options.actions && this.options.actions[actionKey]) {
|
|
133
|
+
this.logger.debug("Using router-level action handler", { actionKey });
|
|
134
|
+
try {
|
|
135
|
+
const result = await this.options.actions[actionKey](
|
|
136
|
+
ik,
|
|
137
|
+
req.body,
|
|
138
|
+
{ req, res }
|
|
139
|
+
);
|
|
140
|
+
if (result != null) res.json(result);
|
|
141
|
+
return;
|
|
142
|
+
} catch (err) {
|
|
143
|
+
this.logger.error("Error in router-level action", { message: err?.message, stack: err?.stack });
|
|
144
|
+
res.status(500).json(err);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
100
148
|
if (!libOptions.actions) {
|
|
101
149
|
this.logger.error("Item Actions are not configured");
|
|
102
150
|
res.status(500).json({ error: "Item Actions are not configured" });
|
|
@@ -118,9 +166,25 @@ class ItemRouter {
|
|
|
118
166
|
getItemFacet = async (req, res) => {
|
|
119
167
|
const libOptions = this.lib.options;
|
|
120
168
|
const libOperations = this.lib.operations;
|
|
121
|
-
this.logger.debug("Getting Item", { query: req?.query, params: req?.params, locals: res?.locals });
|
|
169
|
+
this.logger.debug("Getting Item Facet", { query: req?.query, params: req?.params, locals: res?.locals });
|
|
122
170
|
const ik = this.getIk(res);
|
|
123
171
|
const facetKey = req.path.substring(req.path.lastIndexOf("/") + 1);
|
|
172
|
+
if (this.options.facets && this.options.facets[facetKey]) {
|
|
173
|
+
this.logger.debug("Using router-level facet handler", { facetKey });
|
|
174
|
+
try {
|
|
175
|
+
const result = await this.options.facets[facetKey](
|
|
176
|
+
ik,
|
|
177
|
+
req.query,
|
|
178
|
+
{ req, res }
|
|
179
|
+
);
|
|
180
|
+
if (result != null) res.json(result);
|
|
181
|
+
return;
|
|
182
|
+
} catch (err) {
|
|
183
|
+
this.logger.error("Error in router-level facet", { message: err?.message, stack: err?.stack });
|
|
184
|
+
res.status(500).json(err);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
124
188
|
if (!libOptions.facets) {
|
|
125
189
|
this.logger.error("Item Facets are not configured");
|
|
126
190
|
res.status(500).json({ error: "Item Facets are not configured" });
|
|
@@ -225,9 +289,25 @@ class ItemRouter {
|
|
|
225
289
|
const libOperations = this.lib.operations;
|
|
226
290
|
this.logger.debug("Deleting Item", { query: req.query, params: req.params, locals: res.locals });
|
|
227
291
|
const ik = this.getIk(res);
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
292
|
+
try {
|
|
293
|
+
const removedItem = await libOperations.remove(ik);
|
|
294
|
+
const item = validatePK(removedItem, this.getPkType());
|
|
295
|
+
res.json(item);
|
|
296
|
+
} catch (err) {
|
|
297
|
+
if (err instanceof NotFoundError) {
|
|
298
|
+
this.logger.error("Item Not Found for Delete", { ik, message: err?.message, stack: err?.stack });
|
|
299
|
+
res.status(404).json({
|
|
300
|
+
ik,
|
|
301
|
+
message: "Item Not Found"
|
|
302
|
+
});
|
|
303
|
+
} else {
|
|
304
|
+
this.logger.error("General Error in Delete", { ik, message: err?.message, stack: err?.stack });
|
|
305
|
+
res.status(500).json({
|
|
306
|
+
ik,
|
|
307
|
+
message: "General Error"
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
231
311
|
};
|
|
232
312
|
/* eslint-disable */
|
|
233
313
|
/* istanbul ignore next */
|
|
@@ -265,9 +345,25 @@ class ItemRouter {
|
|
|
265
345
|
{ body: req?.body, query: req?.query, params: req?.params, locals: res?.locals }
|
|
266
346
|
);
|
|
267
347
|
const ik = this.getIk(res);
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
348
|
+
try {
|
|
349
|
+
const itemToUpdate = this.convertDates(req.body);
|
|
350
|
+
const retItem = validatePK(await libOperations.update(ik, itemToUpdate), this.getPkType());
|
|
351
|
+
res.json(retItem);
|
|
352
|
+
} catch (err) {
|
|
353
|
+
if (err instanceof NotFoundError) {
|
|
354
|
+
this.logger.error("Item Not Found for Update", { ik, message: err?.message, stack: err?.stack });
|
|
355
|
+
res.status(404).json({
|
|
356
|
+
ik,
|
|
357
|
+
message: "Item Not Found"
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
this.logger.error("General Error in Update", { ik, message: err?.message, stack: err?.stack });
|
|
361
|
+
res.status(500).json({
|
|
362
|
+
ik,
|
|
363
|
+
message: "General Error"
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
271
367
|
};
|
|
272
368
|
convertDates = (item) => {
|
|
273
369
|
const events = item.events;
|
package/dist/ItemRouter.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/ItemRouter.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ComKey,\n cPK,\n Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\n\nexport type ItemRouterOptions = Record<string, never>;\n\nexport class ItemRouter<\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\n protected lib: Instance<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>;\n private keyType: S;\n protected options: ItemRouterOptions;\n private childRouters: Record<string, Router> = {};\n protected logger;\n\n constructor(\n lib: Instance<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>,\n keyType: S,\n options: ItemRouterOptions = {}\n ) {\n this.lib = lib;\n this.keyType = keyType;\n this.options = options;\n this.logger = LibLogger.get(\"ItemRouter\", keyType);\n }\n\n public getPkType = (): S => {\n return this.keyType;\n }\n\n protected getPkParam = (): string => {\n return `${this.getPkType()}Pk`;\n }\n\n protected getLk(res: Response): LocKey<S> {\n return { kt: this.keyType, lk: res.locals[this.getPkParam()] };\n }\n\n // this is meant to be consumed by children routers\n public getLKA(res: Response): LocKeyArray<S, L1, L2, L3, L4> {\n return [this.getLk(res)] as LocKeyArray<S, L1, L2, L3, L4>;\n }\n\n public getPk(res: Response): PriKey<S> {\n return cPK<S>(res.locals[this.getPkParam()], this.getPkType());\n }\n\n // Unless this is a contained router, the locations will always be an empty array.\n /* eslint-disable */\n protected getLocations(res: Response): LocKeyArray<L1, L2, L3, L4, L5> | [] {\n throw new Error('Method not implemented in an abstract router');\n }\n /* eslint-enable */\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected getIk(res: Response): PriKey<S> | ComKey<S, L1, L2, L3, L4, L5> {\n throw new Error('Method not implemented in an abstract router');\n }\n\n protected postAllAction = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Posting All Action', { query: req?.query, params: req?.params, locals: res?.locals });\n const allActionKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n if (!libOptions.allActions) {\n this.logger.error('Item Actions are not configured');\n res.status(500).json({ error: 'Item Actions are not configured' });\n return;\n }\n const allAction = libOptions.allActions[allActionKey];\n if (!allAction) {\n this.logger.error('All Action is not configured', { allActionKey });\n res.status(500).json({ error: 'Item Action is not configured' });\n return;\n }\n try {\n res.json(await libOperations.allAction(allActionKey, req.body));\n } catch (err: any) {\n this.logger.error('Error in All Action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected getAllFacet = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Getting All Facet', { query: req?.query, params: req?.params, locals: res?.locals });\n const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n if (!libOptions.allFacets) {\n this.logger.error('Item Facets are not configured');\n res.status(500).json({ error: 'Item Facets are not configured' });\n return;\n }\n const facet = libOptions.allFacets[facetKey];\n if (!facet) {\n this.logger.error('Item Facet is not configured', { facetKey });\n res.status(500).json({ error: 'Item Facet is not configured' });\n return;\n }\n try {\n const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n res.json(await libOperations.allFacet(facetKey, combinedQueryParams));\n } catch (err: any) {\n this.logger.error('Error in All Facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected postItemAction = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Getting Item', { query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n const actionKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n if (!libOptions.actions) {\n this.logger.error('Item Actions are not configured');\n res.status(500).json({ error: 'Item Actions are not configured' });\n return;\n }\n const action = libOptions.actions[actionKey];\n if (!action) {\n this.logger.error('Item Action is not configured', { actionKey });\n res.status(500).json({ error: 'Item Action is not configured' });\n return;\n }\n try {\n res.json(await libOperations.action(ik, actionKey, req.body));\n } catch (err: any) {\n this.logger.error('Error in Item Action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected getItemFacet = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Getting Item', { query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n if (!libOptions.facets) {\n this.logger.error('Item Facets are not configured');\n res.status(500).json({ error: 'Item Facets are not configured' });\n return;\n }\n const facet = libOptions.facets[facetKey];\n if (!facet) {\n this.logger.error('Item Facet is not configured', { facetKey });\n res.status(500).json({ error: 'Item Facet is not configured' });\n return;\n }\n try {\n const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n res.json(await libOperations.facet(ik, facetKey, combinedQueryParams));\n } catch (err: any) {\n this.logger.error('Error in Item Facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n private configure = (router: Router) => {\n const libOptions = this.lib.options;\n this.logger.debug('Configuring Router', { pkType: this.getPkType() });\n router.get('/', this.findItems);\n router.post('/', this.createItem);\n\n this.logger.default('All Actions supplied to Router', { allActions: libOptions.allActions });\n if (libOptions.allActions) {\n Object.keys(libOptions.allActions).forEach((actionKey) => {\n this.logger.debug('Configuring All Action %s', actionKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n router.post(`/${actionKey}`, this.postAllAction);\n });\n }\n\n this.logger.default('All Facets supplied to Router', { allFacets: libOptions.allFacets });\n if (libOptions.allFacets) {\n Object.keys(libOptions.allFacets).forEach((facetKey) => {\n this.logger.debug('Configuring All Facet %s', facetKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n router.get(`/${facetKey}`, this.getAllFacet);\n });\n }\n\n const itemRouter = Router();\n itemRouter.get('/', this.getItem);\n itemRouter.put('/', this.updateItem);\n itemRouter.delete('/', this.deleteItem);\n\n this.logger.default('Item Actions supplied to Router', { itemActions: libOptions.actions });\n if (libOptions.actions) {\n Object.keys(libOptions.actions).forEach((actionKey) => {\n this.logger.debug('Configuring Item Action %s', actionKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n itemRouter.post(`/${actionKey}`, this.postItemAction)\n });\n }\n\n this.logger.default('Item Facets supplied to Router', { itemFacets: libOptions.facets });\n if (libOptions.facets) {\n Object.keys(libOptions.facets).forEach((facetKey) => {\n this.logger.debug('Configuring Item Facet %s', facetKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n itemRouter.get(`/${facetKey}`, this.getItemFacet)\n });\n }\n\n this.logger.debug('Configuring Item Operations under PK Param %s', this.getPkParam());\n router.use(`/:${this.getPkParam()}`, this.validatePrimaryKeyValue, itemRouter);\n\n if (this.childRouters) {\n this.configureChildRouters(itemRouter, this.childRouters);\n }\n return router;\n }\n\n private validatePrimaryKeyValue = (req: Request, res: Response, next: any) => {\n const pkParamValue = req.params[this.getPkParam()];\n if (this.validatePKParam(pkParamValue)) {\n res.locals[this.getPkParam()] = pkParamValue;\n next();\n } else {\n this.logger.error('Invalid Primary Key', { pkParamValue, path: req?.originalUrl });\n res.status(500).json({ error: 'Invalid Primary Key', path: req?.originalUrl });\n }\n }\n\n private configureChildRouters = (router: Router, childRouters: Record<string, Router>) => {\n for (const path in childRouters) {\n this.logger.debug('Configuring Child Router at Path %s', path);\n\n router.use(`/${path}`, childRouters[path]);\n }\n return router;\n }\n\n public addChildRouter = (path: string, router: Router) => {\n this.childRouters[path] = router;\n }\n\n /* istanbul ignore next */\n public getRouter(): Router {\n const router = Router();\n this.configure(router);\n return router;\n }\n\n /* istanbul ignore next */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected createItem = async (req: Request, res: Response): Promise<void> => {\n throw new Error('Method not implemented in an abstract router');\n };\n\n // TODO: Probably a better way to do this, but this postCreate hook only needs the item.\n /* istanbul ignore next */\n public postCreateItem = async (item: Item<S, L1, L2, L3, L4, L5>): Promise<Item<S, L1, L2, L3, L4, L5>> => {\n this.logger.debug('Post Create Item', { item });\n return item;\n };\n\n protected deleteItem = async (req: Request, res: Response): Promise<void> => {\n const libOperations = this.lib.operations;\n\n this.logger.debug('Deleting Item', { query: req.query, params: req.params, locals: res.locals });\n const ik = this.getIk(res);\n const removedItem = await libOperations.remove(ik);\n const item = validatePK(removedItem, this.getPkType());\n res.json(item);\n };\n\n /* eslint-disable */\n /* istanbul ignore next */\n protected findItems = async (req: Request, res: Response): Promise<void> => {\n throw new Error('Method not implemented in an abstract router');\n };\n /* eslint-enable */\n\n protected getItem = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.debug('Getting Item', { query: req.query, params: req.params, locals: res.locals });\n const ik = this.getIk(res);\n try {\n // TODO: What error does validate PK throw, when can that fail?\n const item = validatePK(await libOperations.get(ik), this.getPkType());\n res.json(item);\n } catch (err: any) {\n if (err instanceof NotFoundError) {\n this.logger.error('Item Not Found', { ik, message: err?.message, stack: err?.stack });\n res.status(404).json({\n ik,\n message: \"Item Not Found\",\n });\n } else {\n this.logger.error('General Error', { ik, message: err?.message, stack: err?.stack });\n res.status(500).json({\n ik,\n message: \"General Error\",\n });\n }\n }\n }\n\n protected updateItem = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.debug('Updating Item',\n { body: req?.body, query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n const itemToUpdate = this.convertDates(req.body as Partial<Item<S, L1, L2, L3, L4, L5>>);\n const retItem = validatePK(await libOperations.update(ik, itemToUpdate), this.getPkType());\n res.json(retItem);\n };\n\n public convertDates = (item: Partial<Item<S, L1, L2, L3, L4, L5>>): Partial<Item<S, L1, L2, L3, L4, L5>> => {\n const events = item.events as Record<string, ItemEvent>;\n this.logger.debug('Converting Dates', { item });\n if (events) {\n Object.keys(events).forEach((key: string) => {\n Object.assign(events, {\n [key]: deepmerge(events[key], { at: events[key].at ? new Date(events[key].at) : null })\n });\n });\n }\n Object.assign(item, { events });\n return item;\n };\n\n // TODO: Maybe just simplify this and require that everything is a UUID?\n /**\n * This method might be an annoyance, but we need to capture a few cases where someone passes\n * a PK parameter that has an odd string in it.\n *\n * @param pkParamValue The value of the primary key parameter\n * @returns if the value is valid.\n */\n protected validatePKParam = (pkParamValue: string): boolean => {\n let validPkParam = true;\n if (pkParamValue.length <= 0) {\n this.logger.error('Primary Key is an Empty String', { pkParamValue });\n validPkParam = false;\n } else if (pkParamValue === 'undefined') {\n this.logger.error('Primary Key is the string \\'undefined\\'', { pkParamValue });\n validPkParam = false;\n }\n return validPkParam;\n }\n\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n ComKey,\n cPK,\n Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\n\n/**\n * Router-level action method signature - aligned with library ActionMethod pattern\n * Takes the resolved item key, action parameters, and HTTP context\n */\nexport interface RouterActionMethod<\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 (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n actionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level facet method signature - aligned with library FacetMethod pattern\n * Takes the resolved item key, facet parameters, and HTTP context\n */\nexport interface RouterFacetMethod<\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 (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n facetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all action method signature - aligned with library AllActionMethod pattern\n * Takes action parameters, optional locations, and HTTP context\n */\nexport interface RouterAllActionMethod<\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 (\n allActionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all facet method signature - aligned with library AllFacetMethod pattern\n * Takes facet parameters, optional locations, and HTTP context\n */\nexport interface RouterAllFacetMethod<\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 (\n allFacetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\nexport type ItemRouterOptions<\n S extends string = 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 /**\n * Handlers for item actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives resolved item key and parameters\n */\n actions?: Record<string, RouterActionMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for item facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives resolved item key and parameters\n */\n facets?: Record<string, RouterFacetMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives parameters and optional locations\n */\n allActions?: Record<string, RouterAllActionMethod<L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives parameters and optional locations\n */\n allFacets?: Record<string, RouterAllFacetMethod<L1, L2, L3, L4, L5>>;\n};\n\nexport class ItemRouter<\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\n protected lib: Instance<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>;\n private keyType: S;\n protected options: ItemRouterOptions<S, L1, L2, L3, L4, L5>;\n private childRouters: Record<string, Router> = {};\n protected logger;\n\n constructor(\n lib: Instance<Item<S, L1, L2, L3, L4, L5>, S, L1, L2, L3, L4, L5>,\n keyType: S,\n options: ItemRouterOptions<S, L1, L2, L3, L4, L5> = {}\n ) {\n this.lib = lib;\n this.keyType = keyType;\n this.options = options;\n this.logger = LibLogger.get(\"ItemRouter\", keyType);\n }\n\n public getPkType = (): S => {\n return this.keyType;\n }\n\n protected getPkParam = (): string => {\n return `${this.getPkType()}Pk`;\n }\n\n protected getLk(res: Response): LocKey<S> {\n return { kt: this.keyType, lk: res.locals[this.getPkParam()] };\n }\n\n // this is meant to be consumed by children routers\n public getLKA(res: Response): LocKeyArray<S, L1, L2, L3, L4> {\n return [this.getLk(res)] as LocKeyArray<S, L1, L2, L3, L4>;\n }\n\n public getPk(res: Response): PriKey<S> {\n return cPK<S>(res.locals[this.getPkParam()], this.getPkType());\n }\n\n // Unless this is a contained router, the locations will always be an empty array.\n /* eslint-disable */\n protected getLocations(res: Response): LocKeyArray<L1, L2, L3, L4, L5> | [] {\n throw new Error('Method not implemented in an abstract router');\n }\n /* eslint-enable */\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected getIk(res: Response): PriKey<S> | ComKey<S, L1, L2, L3, L4, L5> {\n throw new Error('Method not implemented in an abstract router');\n }\n\n protected postAllAction = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Posting All Action', { query: req?.query, params: req?.params, locals: res?.locals });\n const allActionKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n\n // Check for router-level handler first\n if (this.options.allActions && this.options.allActions[allActionKey]) {\n this.logger.debug('Using router-level all action handler', { allActionKey });\n try {\n const result = await this.options.allActions[allActionKey](\n req.body as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLKA(res) as LocKeyArray<L1, L2, L3, L4, L5> | [],\n { req, res }\n );\n if (result != null) res.json(result);\n return;\n } catch (err: any) {\n this.logger.error('Error in router-level all action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n return;\n }\n }\n\n // Fallback to library handler\n if (!libOptions.allActions) {\n this.logger.error('All Actions are not configured');\n res.status(500).json({ error: 'All Actions are not configured' });\n return;\n }\n const allAction = libOptions.allActions[allActionKey];\n if (!allAction) {\n this.logger.error('All Action is not configured', { allActionKey });\n res.status(500).json({ error: 'All Action is not configured' });\n return;\n }\n try {\n res.json(await libOperations.allAction(allActionKey, req.body));\n } catch (err: any) {\n this.logger.error('Error in All Action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected getAllFacet = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Getting All Facet', { query: req?.query, params: req?.params, locals: res?.locals });\n const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n\n // Check for router-level handler first\n if (this.options.allFacets && this.options.allFacets[facetKey]) {\n this.logger.debug('Using router-level all facet handler', { facetKey });\n try {\n const result = await this.options.allFacets[facetKey](\n req.query as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLKA(res) as LocKeyArray<L1, L2, L3, L4, L5> | [],\n { req, res }\n );\n if (result != null) res.json(result);\n return;\n } catch (err: any) {\n this.logger.error('Error in router-level all facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n return;\n }\n }\n\n // Fallback to library handler\n if (!libOptions.allFacets) {\n this.logger.error('All Facets are not configured');\n res.status(500).json({ error: 'All Facets are not configured' });\n return;\n }\n const facet = libOptions.allFacets[facetKey];\n if (!facet) {\n this.logger.error('All Facet is not configured', { facetKey });\n res.status(500).json({ error: 'All Facet is not configured' });\n return;\n }\n try {\n const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n res.json(await libOperations.allFacet(facetKey, combinedQueryParams));\n } catch (err: any) {\n this.logger.error('Error in All Facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected postItemAction = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Posting Item Action', { query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n const actionKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n\n // Check for router-level handler first\n if (this.options.actions && this.options.actions[actionKey]) {\n this.logger.debug('Using router-level action handler', { actionKey });\n try {\n const result = await this.options.actions[actionKey](\n ik,\n req.body as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n { req, res }\n );\n if (result != null) res.json(result);\n return;\n } catch (err: any) {\n this.logger.error('Error in router-level action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n return;\n }\n }\n\n // Fallback to library handler\n if (!libOptions.actions) {\n this.logger.error('Item Actions are not configured');\n res.status(500).json({ error: 'Item Actions are not configured' });\n return;\n }\n const action = libOptions.actions[actionKey];\n if (!action) {\n this.logger.error('Item Action is not configured', { actionKey });\n res.status(500).json({ error: 'Item Action is not configured' });\n return;\n }\n try {\n res.json(await libOperations.action(ik, actionKey, req.body));\n } catch (err: any) {\n this.logger.error('Error in Item Action', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n protected getItemFacet = async (req: Request, res: Response) => {\n const libOptions = this.lib.options;\n const libOperations = this.lib.operations;\n this.logger.debug('Getting Item Facet', { query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n const facetKey = req.path.substring(req.path.lastIndexOf('/') + 1);\n\n // Check for router-level handler first\n if (this.options.facets && this.options.facets[facetKey]) {\n this.logger.debug('Using router-level facet handler', { facetKey });\n try {\n const result = await this.options.facets[facetKey](\n ik,\n req.query as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n { req, res }\n );\n if (result != null) res.json(result);\n return;\n } catch (err: any) {\n this.logger.error('Error in router-level facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n return;\n }\n }\n\n // Fallback to library handler\n if (!libOptions.facets) {\n this.logger.error('Item Facets are not configured');\n res.status(500).json({ error: 'Item Facets are not configured' });\n return;\n }\n const facet = libOptions.facets[facetKey];\n if (!facet) {\n this.logger.error('Item Facet is not configured', { facetKey });\n res.status(500).json({ error: 'Item Facet is not configured' });\n return;\n }\n try {\n const combinedQueryParams = { ...req.query, ...req.params } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n res.json(await libOperations.facet(ik, facetKey, combinedQueryParams));\n } catch (err: any) {\n this.logger.error('Error in Item Facet', { message: err?.message, stack: err?.stack });\n res.status(500).json(err);\n }\n }\n\n private configure = (router: Router) => {\n const libOptions = this.lib.options;\n this.logger.debug('Configuring Router', { pkType: this.getPkType() });\n router.get('/', this.findItems);\n router.post('/', this.createItem);\n\n this.logger.default('All Actions supplied to Router', { allActions: libOptions.allActions });\n if (libOptions.allActions) {\n Object.keys(libOptions.allActions).forEach((actionKey) => {\n this.logger.debug('Configuring All Action %s', actionKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n router.post(`/${actionKey}`, this.postAllAction);\n });\n }\n\n this.logger.default('All Facets supplied to Router', { allFacets: libOptions.allFacets });\n if (libOptions.allFacets) {\n Object.keys(libOptions.allFacets).forEach((facetKey) => {\n this.logger.debug('Configuring All Facet %s', facetKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n router.get(`/${facetKey}`, this.getAllFacet);\n });\n }\n\n const itemRouter = Router();\n itemRouter.get('/', this.getItem);\n itemRouter.put('/', this.updateItem);\n itemRouter.delete('/', this.deleteItem);\n\n this.logger.default('Item Actions supplied to Router', { itemActions: libOptions.actions });\n if (libOptions.actions) {\n Object.keys(libOptions.actions).forEach((actionKey) => {\n this.logger.debug('Configuring Item Action %s', actionKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n itemRouter.post(`/${actionKey}`, this.postItemAction)\n });\n }\n\n this.logger.default('Item Facets supplied to Router', { itemFacets: libOptions.facets });\n if (libOptions.facets) {\n Object.keys(libOptions.facets).forEach((facetKey) => {\n this.logger.debug('Configuring Item Facet %s', facetKey);\n // TODO: Ok, this is a bit of a hack, but we need to customize the types of the request handlers\n itemRouter.get(`/${facetKey}`, this.getItemFacet)\n });\n }\n\n this.logger.debug('Configuring Item Operations under PK Param %s', this.getPkParam());\n router.use(`/:${this.getPkParam()}`, this.validatePrimaryKeyValue, itemRouter);\n\n if (this.childRouters) {\n this.configureChildRouters(itemRouter, this.childRouters);\n }\n return router;\n }\n\n private validatePrimaryKeyValue = (req: Request, res: Response, next: any) => {\n const pkParamValue = req.params[this.getPkParam()];\n if (this.validatePKParam(pkParamValue)) {\n res.locals[this.getPkParam()] = pkParamValue;\n next();\n } else {\n this.logger.error('Invalid Primary Key', { pkParamValue, path: req?.originalUrl });\n res.status(500).json({ error: 'Invalid Primary Key', path: req?.originalUrl });\n }\n }\n\n private configureChildRouters = (router: Router, childRouters: Record<string, Router>) => {\n for (const path in childRouters) {\n this.logger.debug('Configuring Child Router at Path %s', path);\n\n router.use(`/${path}`, childRouters[path]);\n }\n return router;\n }\n\n public addChildRouter = (path: string, router: Router) => {\n this.childRouters[path] = router;\n }\n\n /* istanbul ignore next */\n public getRouter(): Router {\n const router = Router();\n this.configure(router);\n return router;\n }\n\n /* istanbul ignore next */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected createItem = async (req: Request, res: Response): Promise<void> => {\n throw new Error('Method not implemented in an abstract router');\n };\n\n // TODO: Probably a better way to do this, but this postCreate hook only needs the item.\n /* istanbul ignore next */\n public postCreateItem = async (item: Item<S, L1, L2, L3, L4, L5>): Promise<Item<S, L1, L2, L3, L4, L5>> => {\n this.logger.debug('Post Create Item', { item });\n return item;\n };\n\n protected deleteItem = async (req: Request, res: Response): Promise<void> => {\n const libOperations = this.lib.operations;\n\n this.logger.debug('Deleting Item', { query: req.query, params: req.params, locals: res.locals });\n const ik = this.getIk(res);\n try {\n const removedItem = await libOperations.remove(ik);\n const item = validatePK(removedItem, this.getPkType());\n res.json(item);\n } catch (err: any) {\n if (err instanceof NotFoundError) {\n this.logger.error('Item Not Found for Delete', { ik, message: err?.message, stack: err?.stack });\n res.status(404).json({\n ik,\n message: \"Item Not Found\",\n });\n } else {\n this.logger.error('General Error in Delete', { ik, message: err?.message, stack: err?.stack });\n res.status(500).json({\n ik,\n message: \"General Error\",\n });\n }\n }\n };\n\n /* eslint-disable */\n /* istanbul ignore next */\n protected findItems = async (req: Request, res: Response): Promise<void> => {\n throw new Error('Method not implemented in an abstract router');\n };\n /* eslint-enable */\n\n protected getItem = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.debug('Getting Item', { query: req.query, params: req.params, locals: res.locals });\n const ik = this.getIk(res);\n try {\n // TODO: What error does validate PK throw, when can that fail?\n const item = validatePK(await libOperations.get(ik), this.getPkType());\n res.json(item);\n } catch (err: any) {\n if (err instanceof NotFoundError) {\n this.logger.error('Item Not Found', { ik, message: err?.message, stack: err?.stack });\n res.status(404).json({\n ik,\n message: \"Item Not Found\",\n });\n } else {\n this.logger.error('General Error', { ik, message: err?.message, stack: err?.stack });\n res.status(500).json({\n ik,\n message: \"General Error\",\n });\n }\n }\n }\n\n protected updateItem = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.debug('Updating Item',\n { body: req?.body, query: req?.query, params: req?.params, locals: res?.locals });\n const ik = this.getIk(res);\n try {\n const itemToUpdate = this.convertDates(req.body as Partial<Item<S, L1, L2, L3, L4, L5>>);\n const retItem = validatePK(await libOperations.update(ik, itemToUpdate), this.getPkType());\n res.json(retItem);\n } catch (err: any) {\n if (err instanceof NotFoundError) {\n this.logger.error('Item Not Found for Update', { ik, message: err?.message, stack: err?.stack });\n res.status(404).json({\n ik,\n message: \"Item Not Found\",\n });\n } else {\n this.logger.error('General Error in Update', { ik, message: err?.message, stack: err?.stack });\n res.status(500).json({\n ik,\n message: \"General Error\",\n });\n }\n }\n };\n\n public convertDates = (item: Partial<Item<S, L1, L2, L3, L4, L5>>): Partial<Item<S, L1, L2, L3, L4, L5>> => {\n const events = item.events as Record<string, ItemEvent>;\n this.logger.debug('Converting Dates', { item });\n if (events) {\n Object.keys(events).forEach((key: string) => {\n Object.assign(events, {\n [key]: deepmerge(events[key], { at: events[key].at ? new Date(events[key].at) : null })\n });\n });\n }\n Object.assign(item, { events });\n return item;\n };\n\n // TODO: Maybe just simplify this and require that everything is a UUID?\n /**\n * This method might be an annoyance, but we need to capture a few cases where someone passes\n * a PK parameter that has an odd string in it.\n *\n * @param pkParamValue The value of the primary key parameter\n * @returns if the value is valid.\n */\n protected validatePKParam = (pkParamValue: string): boolean => {\n let validPkParam = true;\n if (pkParamValue.length <= 0) {\n this.logger.error('Primary Key is an Empty String', { pkParamValue });\n validPkParam = false;\n } else if (pkParamValue === 'undefined') {\n this.logger.error('Primary Key is the string \\'undefined\\'', { pkParamValue });\n validPkParam = false;\n }\n return validPkParam;\n }\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/PItemRouter.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ItemRouter, ItemRouterOptions } from "./ItemRouter.js";
|
|
|
3
3
|
import { Instance } from "./Instance.js";
|
|
4
4
|
import { Request, Response } from "express";
|
|
5
5
|
export declare class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {
|
|
6
|
-
constructor(lib: Instance<T, S>, keyType: S, options?: ItemRouterOptions);
|
|
6
|
+
constructor(lib: Instance<T, S>, keyType: S, options?: ItemRouterOptions<S, never, never, never, never, never>);
|
|
7
7
|
getIk(res: Response): PriKey<S>;
|
|
8
8
|
createItem: (req: Request, res: Response) => Promise<void>;
|
|
9
9
|
protected findItems: (req: Request, res: Response) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM5C,qBAAa,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;gBAErE,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAE,
|
|
1
|
+
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAM5C,qBAAa,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;gBAErE,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAE,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAM;IAI3G,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAK/B,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAQpD;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA6BtD;CAEH"}
|
package/dist/PItemRouter.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/PItemRouter.ts"],
|
|
4
|
-
"sourcesContent": ["import { Item, ItemQuery, paramsToQuery, PriKey, QueryParams, validatePK } from \"@fjell/core\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Instance } from \"./Instance.js\";\nimport { Request, Response } from \"express\";\n\ninterface ParsedQuery {\n [key: string]: undefined | string | string[] | ParsedQuery | ParsedQuery[];\n}\n\nexport class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {\n\n constructor(lib: Instance<T, S>, keyType: S, options: ItemRouterOptions = {}) {\n super(lib as any, keyType, options);\n }\n\n public getIk(res: Response): PriKey<S> {\n const pri = this.getPk(res) as PriKey<S>;\n return pri\n }\n\n public 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>);\n let item = validatePK(await libOperations.create(itemToCreate), this.getPkType()) as Item<S>;\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 this.logger.default('Finding Items', { query: req.query, params: req.params, locals: res.locals });\n\n let items: Item<S>[] = [];\n\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 if (finder) {\n // If finder is defined? Call a finder.\n this.logger.default('Finding Items with Finder %s %j one:%s', finder, finderParams, one);\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, JSON.parse(finderParams));\n items = item ? [item] : [];\n } else {\n items = await libOperations.find(finder, JSON.parse(finderParams));\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 a query %j', itemQuery);\n items = await libOperations.all(itemQuery);\n }\n\n res.json(items.map((item: Item<S>) => validatePK(item, this.getPkType())));\n };\n\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAA0B,eAAoC,kBAAkB;AAChF,SAAS,kBAAqC;AAQvC,MAAM,oBAAyD,WAAc;AAAA,EAElF,YAAY,KAAqB,SAAY,
|
|
4
|
+
"sourcesContent": ["import { Item, ItemQuery, paramsToQuery, PriKey, QueryParams, validatePK } from \"@fjell/core\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Instance } from \"./Instance.js\";\nimport { Request, Response } from \"express\";\n\ninterface ParsedQuery {\n [key: string]: undefined | string | string[] | ParsedQuery | ParsedQuery[];\n}\n\nexport class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {\n\n constructor(lib: Instance<T, S>, keyType: S, options: ItemRouterOptions<S, never, never, never, never, never> = {}) {\n super(lib as any, keyType, options);\n }\n\n public getIk(res: Response): PriKey<S> {\n const pri = this.getPk(res) as PriKey<S>;\n return pri\n }\n\n public 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>);\n let item = validatePK(await libOperations.create(itemToCreate), this.getPkType()) as Item<S>;\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 this.logger.default('Finding Items', { query: req.query, params: req.params, locals: res.locals });\n\n let items: Item<S>[] = [];\n\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 if (finder) {\n // If finder is defined? Call a finder.\n this.logger.default('Finding Items with Finder %s %j one:%s', finder, finderParams, one);\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, JSON.parse(finderParams));\n items = item ? [item] : [];\n } else {\n items = await libOperations.find(finder, JSON.parse(finderParams));\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 a query %j', itemQuery);\n items = await libOperations.all(itemQuery);\n }\n\n res.json(items.map((item: Item<S>) => validatePK(item, this.getPkType())));\n };\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAA0B,eAAoC,kBAAkB;AAChF,SAAS,kBAAqC;AAQvC,MAAM,oBAAyD,WAAc;AAAA,EAElF,YAAY,KAAqB,SAAY,UAAmE,CAAC,GAAG;AAClH,UAAM,KAAY,SAAS,OAAO;AAAA,EACpC;AAAA,EAEO,MAAM,KAA0B;AACrC,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AAAA,EAEO,aAAa,OAAO,KAAc,QAAkB;AACzD,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,QAAQ,iBAAiB,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAO,CAAC;AACjH,UAAM,eAAe,KAAK,aAAa,IAAI,IAAe;AAC1D,QAAI,OAAO,WAAW,MAAM,cAAc,OAAO,YAAY,GAAG,KAAK,UAAU,CAAC;AAChF,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,SAAK,OAAO,QAAQ,iBAAiB,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAO,CAAC;AAEjG,QAAI,QAAmB,CAAC;AAExB,UAAM,QAAqB,IAAI;AAC/B,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,eAAe,MAAM,cAAc;AACzC,UAAM,MAAM,MAAM,KAAK;AAEvB,QAAI,QAAQ;AAEV,WAAK,OAAO,QAAQ,0CAA0C,QAAQ,cAAc,GAAG;AAEvF,UAAI,QAAQ,QAAQ;AAClB,cAAM,OAAO,MAAO,KAAK,IAAY,QAAQ,QAAQ,KAAK,MAAM,YAAY,CAAC;AAC7E,gBAAQ,OAAO,CAAC,IAAI,IAAI,CAAC;AAAA,MAC3B,OAAO;AACL,gBAAQ,MAAM,cAAc,KAAK,QAAQ,KAAK,MAAM,YAAY,CAAC;AAAA,MACnE;AAAA,IACF,OAAO;AAEL,YAAM,YAAuB,cAAc,IAAI,KAAoB;AACnE,WAAK,OAAO,QAAQ,iCAAiC,SAAS;AAC9D,cAAQ,MAAM,cAAc,IAAI,SAAS;AAAA,IAC3C;AAEA,QAAI,KAAK,MAAM,IAAI,CAAC,SAAkB,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC;AAAA,EAC3E;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/util/general.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/util/general.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,GAAI,KAAK,GAAG;;CAI7B,CAAA;AAGD,eAAO,MAAM,aAAa,GAAa,KAAK,GAAG,EAAE,UAAS,GAAG,CAAC,GAAG,CAAa,KAAG,MAuDhF,CAAC"}
|
package/dist/util/general.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/util/general.ts"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n}
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-unused-vars */\n\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n};\n"],
|
|
5
|
+
"mappings": "AAGO,MAAM,QAAQ,CAAC,QAAa;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,MAAS;AAAA,EACxD;AACF;AAGO,MAAM,gBAAgB,SAAU,KAAU,UAAoB,oBAAI,IAAI,GAAW;AACtF,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAoB,CAAC;AAGzB,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,QAAQ;AACjE,WAAO,KAAK;AAAA,WACL,OAAO,QAAQ;AACtB,WAAO,MAAM,MAAM;AAGrB,MAAI,eAAe,UAAU,QAAQ,IAAI,GAAG,GAAG;AAC7C,WAAO;AAAA,EACT,WAGS,MAAM,QAAQ,GAAG,GAAG;AAE3B,QAAI,IAAI,CAAC,MAAM;AACb,aAAO;AAAA,SACJ;AAEH,cAAQ,IAAI,GAAG;AACf,UAAI,QAAQ,SAAU,IAAI;AACxB,gBAAQ,KAAK,cAAc,IAAI,OAAO,CAAC;AAAA,MACzC,CAAC;AACD,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,EACF,WAES,eAAe,QAAQ;AAE9B,YAAQ,IAAI,GAAG;AAEf,cAAU,OAAO,KAAK,GAAG;AAEzB,YAAQ,QAAQ,SAAU,KAAK;AAC7B,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,YAAY,IAAI,GAAG;AAEzB,UAAI,qBAAqB,YAAY,cAAc;AACjD;AAAA,eACO,OAAO,cAAc;AAC5B,qBAAa,KAAK,SAAS,MAAM,YAAY,GAAG;AAAA,eACzC,OAAO,cAAc,aAAa,OAAO,cAAc,YAAY,cAAc;AACxF,qBAAa,KAAK,SAAS,SAAS;AAAA,eAE7B,qBAAqB,QAAQ;AACpC,qBAAa,KAAK,SAAS,cAAc,WAAW,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC;AACD,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/examples/README.md
CHANGED
|
@@ -34,6 +34,16 @@ Shows how fjell-express-router handles enterprise organizational data patterns w
|
|
|
34
34
|
|
|
35
35
|
Perfect for understanding how to build production-ready applications with fjell-express-router.
|
|
36
36
|
|
|
37
|
+
### 4. `router-handlers-example.ts` 🎯 **Router-Level Handler Precedence**
|
|
38
|
+
**Advanced router customization!** Demonstrates how to define custom handlers at the router level that take precedence over library-level handlers:
|
|
39
|
+
- **Router-level handlers**: Define custom actions, facets, allActions, and allFacets directly in router options
|
|
40
|
+
- **Handler precedence**: Router-level handlers are called first, with fallback to library handlers
|
|
41
|
+
- **Cross-system integration**: Perfect for aggregating data from multiple services or external APIs
|
|
42
|
+
- **Business logic separation**: Keep complex integrations at the router layer while maintaining library simplicity
|
|
43
|
+
- **Flexible architecture**: Supports both PItemRouter and CItemRouter with appropriate type safety
|
|
44
|
+
|
|
45
|
+
Ideal for scenarios requiring external service calls, data aggregation, or complex business logic that shouldn't be in the core library layer.
|
|
46
|
+
|
|
37
47
|
## Key Concepts Demonstrated
|
|
38
48
|
|
|
39
49
|
### Basic Router Setup (basic-router-example.ts)
|
|
@@ -170,6 +180,12 @@ npx tsx examples/full-application-example.ts
|
|
|
170
180
|
# Server runs on http://localhost:3003
|
|
171
181
|
```
|
|
172
182
|
|
|
183
|
+
**Router Handlers Example:**
|
|
184
|
+
```bash
|
|
185
|
+
npx tsx examples/router-handlers-example.ts
|
|
186
|
+
# Server runs on http://localhost:3004
|
|
187
|
+
```
|
|
188
|
+
|
|
173
189
|
## Testing the Examples
|
|
174
190
|
|
|
175
191
|
### Basic Router Example (Port 3001)
|
|
@@ -258,6 +274,37 @@ curl -X POST http://localhost:3003/api/customers \
|
|
|
258
274
|
}'
|
|
259
275
|
```
|
|
260
276
|
|
|
277
|
+
### Router Handlers Example (Port 3004)
|
|
278
|
+
```bash
|
|
279
|
+
# Test router-level user actions
|
|
280
|
+
curl -X POST http://localhost:3004/api/users/user-1/activate
|
|
281
|
+
curl -X POST http://localhost:3004/api/users/user-1/deactivate
|
|
282
|
+
|
|
283
|
+
# Test router-level user facets
|
|
284
|
+
curl http://localhost:3004/api/users/user-1/profile
|
|
285
|
+
curl http://localhost:3004/api/users/user-1/activity
|
|
286
|
+
|
|
287
|
+
# Test router-level all actions
|
|
288
|
+
curl -X POST http://localhost:3004/api/users/bulk-activate
|
|
289
|
+
curl -X POST http://localhost:3004/api/users/send-notifications
|
|
290
|
+
|
|
291
|
+
# Test router-level all facets
|
|
292
|
+
curl http://localhost:3004/api/users/statistics
|
|
293
|
+
curl http://localhost:3004/api/users/analytics
|
|
294
|
+
|
|
295
|
+
# Test router-level post actions (nested under users)
|
|
296
|
+
curl -X POST http://localhost:3004/api/users/user-1/posts/post-1/publish
|
|
297
|
+
curl -X POST http://localhost:3004/api/users/user-1/posts/post-1/archive
|
|
298
|
+
|
|
299
|
+
# Test router-level post facets
|
|
300
|
+
curl http://localhost:3004/api/users/user-1/posts/post-1/analytics
|
|
301
|
+
curl http://localhost:3004/api/users/user-1/posts/post-1/comments
|
|
302
|
+
|
|
303
|
+
# Test fallback to library handlers for undefined router handlers
|
|
304
|
+
curl -X POST http://localhost:3004/api/users/user-1/someOtherAction
|
|
305
|
+
curl http://localhost:3004/api/users/user-1/someOtherFacet
|
|
306
|
+
```
|
|
307
|
+
|
|
261
308
|
## Integration Patterns
|
|
262
309
|
|
|
263
310
|
### Mock Operations
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { Item, PriKey, UUID } from '@fjell/core';
|
|
15
|
+
import { NotFoundError } from '@fjell/lib';
|
|
15
16
|
import express, { Application } from 'express';
|
|
16
17
|
import { createRegistry, PItemRouter } from '../src';
|
|
17
18
|
|
|
18
19
|
// Define our data models
|
|
19
|
-
interface User extends Item<'user'> {
|
|
20
|
+
export interface User extends Item<'user'> {
|
|
20
21
|
id: string;
|
|
21
22
|
name: string;
|
|
22
23
|
email: string;
|
|
@@ -24,7 +25,7 @@ interface User extends Item<'user'> {
|
|
|
24
25
|
lastLogin?: Date;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
interface Task extends Item<'task'> {
|
|
28
|
+
export interface Task extends Item<'task'> {
|
|
28
29
|
id: string;
|
|
29
30
|
title: string;
|
|
30
31
|
description: string;
|
|
@@ -122,7 +123,7 @@ const createUserOperations = () => {
|
|
|
122
123
|
console.log(`🔍 UserOperations.get(${key.pk}) - Fetching user...`);
|
|
123
124
|
const user = mockUserStorage.get(String(key.pk));
|
|
124
125
|
if (!user) {
|
|
125
|
-
throw new
|
|
126
|
+
throw new NotFoundError('get', { kta: ['user', '', '', '', '', ''], scopes: [] }, key);
|
|
126
127
|
}
|
|
127
128
|
return user;
|
|
128
129
|
},
|
|
@@ -148,7 +149,7 @@ const createUserOperations = () => {
|
|
|
148
149
|
console.log(`🔄 UserOperations.update(${key.pk}) - Updating user...`);
|
|
149
150
|
const existing = mockUserStorage.get(String(key.pk));
|
|
150
151
|
if (!existing) {
|
|
151
|
-
throw new
|
|
152
|
+
throw new NotFoundError('update', { kta: ['user', '', '', '', '', ''], scopes: [] }, key);
|
|
152
153
|
}
|
|
153
154
|
const updated: User = {
|
|
154
155
|
...existing,
|
|
@@ -199,7 +200,7 @@ const createTaskOperations = () => {
|
|
|
199
200
|
console.log(`🔍 TaskOperations.get(${key.pk}) - Fetching task...`);
|
|
200
201
|
const task = mockTaskStorage.get(String(key.pk));
|
|
201
202
|
if (!task) {
|
|
202
|
-
throw new
|
|
203
|
+
throw new NotFoundError('get', { kta: ['task', '', '', '', '', ''], scopes: [] }, key);
|
|
203
204
|
}
|
|
204
205
|
return task;
|
|
205
206
|
},
|
|
@@ -225,7 +226,7 @@ const createTaskOperations = () => {
|
|
|
225
226
|
console.log(`🔄 TaskOperations.update(${key.pk}) - Updating task...`);
|
|
226
227
|
const existing = mockTaskStorage.get(String(key.pk));
|
|
227
228
|
if (!existing) {
|
|
228
|
-
throw new
|
|
229
|
+
throw new NotFoundError('update', { kta: ['task', '', '', '', '', ''], scopes: [] }, key);
|
|
229
230
|
}
|
|
230
231
|
const updated: Task = {
|
|
231
232
|
...existing,
|