@fjell/express-router 4.4.67 → 4.4.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CItemRouter.d.ts","sourceRoot":"","sources":["../src/CItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"CItemRouter.d.ts","sourceRoot":"","sources":["../src/CItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAC2B,MAAM,EAAE,IAAI,EAAqB,WAAW,EAC7E,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAMhE,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;gBAGvC,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACtC,IAAI,EAAE,CAAC,EACP,WAAW,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAClD,OAAO,GAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAM;IAKjD,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;IAI5D,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAyBpD;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAgFtD;CAEH"}
|
package/dist/CItemRouter.js
CHANGED
|
@@ -52,7 +52,6 @@ class CItemRouter extends ItemRouter {
|
|
|
52
52
|
const finderParams = query["finderParams"];
|
|
53
53
|
const one = query["one"];
|
|
54
54
|
try {
|
|
55
|
-
let items = [];
|
|
56
55
|
if (finder) {
|
|
57
56
|
this.logger.default("Finding Items with Finder", { finder, finderParams, one });
|
|
58
57
|
let parsedParams;
|
|
@@ -65,22 +64,44 @@ class CItemRouter extends ItemRouter {
|
|
|
65
64
|
});
|
|
66
65
|
return;
|
|
67
66
|
}
|
|
67
|
+
let items = [];
|
|
68
68
|
if (one === "true") {
|
|
69
69
|
const item = await this.lib.findOne(finder, parsedParams, this.getLocations(res));
|
|
70
70
|
items = item ? [item] : [];
|
|
71
71
|
} else {
|
|
72
72
|
items = await libOperations.find(finder, parsedParams, this.getLocations(res));
|
|
73
73
|
}
|
|
74
|
+
const validatedItems = items.map((item) => validatePK(item, this.getPkType()));
|
|
75
|
+
const result = {
|
|
76
|
+
items: validatedItems,
|
|
77
|
+
metadata: {
|
|
78
|
+
total: validatedItems.length,
|
|
79
|
+
returned: validatedItems.length,
|
|
80
|
+
offset: 0,
|
|
81
|
+
hasMore: false
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
res.json(result);
|
|
74
85
|
} else {
|
|
75
86
|
const itemQuery = paramsToQuery(req.query);
|
|
76
87
|
const locations = this.getLocations(res);
|
|
77
88
|
this.logger.debug("Finding Items with Query: %j", itemQuery);
|
|
78
89
|
this.logger.debug("Location keys being passed: %j", locations);
|
|
79
|
-
|
|
80
|
-
|
|
90
|
+
const allOptions = {};
|
|
91
|
+
if (req.query.limit) {
|
|
92
|
+
allOptions.limit = parseInt(req.query.limit, 10);
|
|
93
|
+
}
|
|
94
|
+
if (req.query.offset) {
|
|
95
|
+
allOptions.offset = parseInt(req.query.offset, 10);
|
|
96
|
+
}
|
|
97
|
+
const result = await libOperations.all(itemQuery, locations, allOptions);
|
|
98
|
+
this.logger.debug("Found %d Items with Query", result.items.length);
|
|
99
|
+
const validatedItems = result.items.map((item) => validatePK(item, this.getPkType()));
|
|
100
|
+
res.json({
|
|
101
|
+
items: validatedItems,
|
|
102
|
+
metadata: result.metadata
|
|
103
|
+
});
|
|
81
104
|
}
|
|
82
|
-
const validatedItems = items.map((item) => validatePK(item, this.getPkType()));
|
|
83
|
-
res.json(validatedItems);
|
|
84
105
|
} catch (error) {
|
|
85
106
|
this.logger.error("Error in findItems", { error });
|
|
86
107
|
if (error instanceof NotFoundError || error?.name === "NotFoundError") {
|
package/dist/CItemRouter.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/CItemRouter.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n ComKey, Item, ItemQuery, LocKey, LocKeyArray, paramsToQuery, PriKey, QueryParams, validatePK\n} from \"@fjell/core\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\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 constructor(\n lib: Library<T, S, L1, L2, L3, L4, L5>,\n type: S,\n parentRoute: ItemRouter<L1, L2, L3, L4, L5, never>,\n options: ItemRouterOptions<S, L1, L2, L3, L4, L5> = {},\n ) {\n super(lib as any, type, options, 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 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 \n try {\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.status(201).json(item);\n } catch (error: any) {\n this.logger.error('Error in createItem', { error });\n // Check for validation errors\n if (error.name === 'CreateValidationError' || error.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n (error.message && (error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation')))) {\n res.status(400).json({ message: \"Validation Error\" });\n } else {\n res.status(500).json({ message: \"General Error\" });\n }\n }\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 try {\n
|
|
5
|
-
"mappings": "AAAA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n AllOperationResult, AllOptions, ComKey, Item, ItemQuery, LocKey, LocKeyArray, paramsToQuery, PriKey, QueryParams, validatePK\n} from \"@fjell/core\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\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 constructor(\n lib: Library<T, S, L1, L2, L3, L4, L5>,\n type: S,\n parentRoute: ItemRouter<L1, L2, L3, L4, L5, never>,\n options: ItemRouterOptions<S, L1, L2, L3, L4, L5> = {},\n ) {\n super(lib as any, type, options, 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 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 \n try {\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.status(201).json(item);\n } catch (error: any) {\n this.logger.error('Error in createItem', { error });\n // Check for validation errors\n if (error.name === 'CreateValidationError' || error.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n (error.message && (error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation')))) {\n res.status(400).json({ message: \"Validation Error\" });\n } else {\n res.status(500).json({ message: \"General Error\" });\n }\n }\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 try {\n if (finder) {\n // If finder is defined? Call a finder.\n this.logger.default('Finding Items with Finder', { finder, finderParams, one });\n\n let parsedParams: any;\n try {\n parsedParams = finderParams ? JSON.parse(finderParams) : {};\n } catch (parseError: any) {\n res.status(400).json({\n error: 'Invalid JSON in finderParams',\n message: parseError.message\n });\n return;\n }\n\n let items: Item<S, L1, L2, L3, L4, L5>[] = [];\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, parsedParams, this.getLocations(res));\n items = item ? [item] : [];\n } else {\n items = await libOperations.find(finder, parsedParams, this.getLocations(res));\n }\n\n // For finder queries, wrap in AllOperationResult format for consistency\n const validatedItems = items.map((item: Item<S, L1, L2, L3, L4, L5>) => validatePK(item, this.getPkType()));\n const result: AllOperationResult<Item<S, L1, L2, L3, L4, L5>> = {\n items: validatedItems,\n metadata: {\n total: validatedItems.length,\n returned: validatedItems.length,\n offset: 0,\n hasMore: false\n }\n };\n res.json(result);\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 const locations = this.getLocations(res);\n this.logger.debug('Finding Items with Query: %j', itemQuery);\n this.logger.debug('Location keys being passed: %j', locations);\n \n // Parse pagination options from query params\n const allOptions: AllOptions = {};\n if (req.query.limit) {\n allOptions.limit = parseInt(req.query.limit as string, 10);\n }\n if (req.query.offset) {\n allOptions.offset = parseInt(req.query.offset as string, 10);\n }\n \n // libOperations.all() now returns AllOperationResult<V>\n const result = await libOperations.all(itemQuery, locations, allOptions);\n this.logger.debug('Found %d Items with Query', result.items.length);\n\n // Validate PKs on returned items\n const validatedItems = result.items.map((item: Item<S, L1, L2, L3, L4, L5>) => validatePK(item, this.getPkType()));\n \n // Return full AllOperationResult structure with validated items\n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\n }\n } catch (error: any) {\n this.logger.error('Error in findItems', { error });\n if (error instanceof NotFoundError || error?.name === 'NotFoundError') {\n res.status(404).json({ error: error.message || 'Parent item not found' });\n } else {\n res.status(500).json({ error: error.message || 'Internal server error' });\n }\n }\n };\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC9H,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAMpD,qBAAa,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;gBAErE,GAAG,EAAE,OAAO,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;IAI1G,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAM/B,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,OAAO,GAAG,mBAmEhE;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA+EtD;CAEH"}
|
package/dist/PItemRouter.js
CHANGED
|
@@ -43,7 +43,6 @@ class PItemRouter extends ItemRouter {
|
|
|
43
43
|
const libOperations = this.lib.operations;
|
|
44
44
|
this.logger.default("Finding Items", { query: req.query, params: req.params, locals: res.locals });
|
|
45
45
|
try {
|
|
46
|
-
let items = [];
|
|
47
46
|
const query = req.query;
|
|
48
47
|
const finder = query["finder"];
|
|
49
48
|
const finderParams = query["finderParams"];
|
|
@@ -60,19 +59,41 @@ class PItemRouter extends ItemRouter {
|
|
|
60
59
|
});
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
62
|
+
let items = [];
|
|
63
63
|
if (one === "true") {
|
|
64
64
|
const item = await this.lib.findOne(finder, parsedParams);
|
|
65
65
|
items = item ? [item] : [];
|
|
66
66
|
} else {
|
|
67
67
|
items = await libOperations.find(finder, parsedParams);
|
|
68
68
|
}
|
|
69
|
+
const validatedItems = items.map((item) => validatePK(item, this.getPkType()));
|
|
70
|
+
const result = {
|
|
71
|
+
items: validatedItems,
|
|
72
|
+
metadata: {
|
|
73
|
+
total: validatedItems.length,
|
|
74
|
+
returned: validatedItems.length,
|
|
75
|
+
offset: 0,
|
|
76
|
+
hasMore: false
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
res.json(result);
|
|
69
80
|
} else {
|
|
70
81
|
const itemQuery = paramsToQuery(req.query);
|
|
71
82
|
this.logger.default("Finding Items with a query %j", itemQuery);
|
|
72
|
-
|
|
83
|
+
const allOptions = {};
|
|
84
|
+
if (req.query.limit) {
|
|
85
|
+
allOptions.limit = parseInt(req.query.limit, 10);
|
|
86
|
+
}
|
|
87
|
+
if (req.query.offset) {
|
|
88
|
+
allOptions.offset = parseInt(req.query.offset, 10);
|
|
89
|
+
}
|
|
90
|
+
const result = await libOperations.all(itemQuery, [], allOptions);
|
|
91
|
+
const validatedItems = result.items.map((item) => validatePK(item, this.getPkType()));
|
|
92
|
+
res.json({
|
|
93
|
+
items: validatedItems,
|
|
94
|
+
metadata: result.metadata
|
|
95
|
+
});
|
|
73
96
|
}
|
|
74
|
-
const validatedItems = items.map((item) => validatePK(item, this.getPkType()));
|
|
75
|
-
res.json(validatedItems);
|
|
76
97
|
} catch (error) {
|
|
77
98
|
this.logger.error("Error in findItems", { error });
|
|
78
99
|
if (error instanceof NotFoundError || error?.name === "NotFoundError") {
|
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 { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\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: Library<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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public createItem = async (req: Request, res: Response, next?: any) => {\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\n try {\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.status(201).json(item);\n } catch (error: any) {\n // Check for validation errors - check multiple patterns\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n \n // Log error details for debugging\n this.logger.error('Error in createItem', {\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n errorCode: error?.errorInfo?.code,\n originalErrorCode: originalError?.errorInfo?.code\n });\n const isValidationError =\n error.name === 'CreateValidationError' ||\n originalError?.name === 'CreateValidationError' ||\n error.name === 'ValidationError' ||\n originalError?.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n originalError?.name === 'SequelizeValidationError' ||\n error?.errorInfo?.code === 'VALIDATION_ERROR' ||\n originalError?.errorInfo?.code === 'VALIDATION_ERROR' ||\n (error.message && (\n error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation') ||\n error.message.includes('Required field') ||\n error.message.includes('Referenced item does not exist') ||\n error.message.includes('Foreign key constraint') ||\n error.message.includes('Operation failed') ||\n error.message.includes('preCreate') ||\n error.message.includes('preUpdate') ||\n error.message.includes('Create Validation Failed')\n )) ||\n (originalError?.message && (\n originalError.message.includes('validation') ||\n originalError.message.includes('required') ||\n originalError.message.includes('cannot be null') ||\n originalError.message.includes('notNull Violation') ||\n originalError.message.includes('Required field') ||\n originalError.message.includes('Referenced item does not exist') ||\n originalError.message.includes('Foreign key constraint') ||\n originalError.message.includes('preCreate') ||\n originalError.message.includes('preUpdate') ||\n originalError.message.includes('Create Validation Failed')\n ));\n \n if (isValidationError) {\n const errorMessage = originalError?.message || error.message || \"Validation failed\";\n res.status(400).json({ success: false, error: errorMessage });\n } else {\n res.status(500).json({ success: false, error: error.message || \"Internal server error\" });\n }\n }\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 try {\n
|
|
5
|
-
"mappings": "AAAA,
|
|
4
|
+
"sourcesContent": ["import { AllOperationResult, AllOptions, Item, ItemQuery, paramsToQuery, PriKey, QueryParams, validatePK } from \"@fjell/core\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\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: Library<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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public createItem = async (req: Request, res: Response, next?: any) => {\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\n try {\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.status(201).json(item);\n } catch (error: any) {\n // Check for validation errors - check multiple patterns\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n \n // Log error details for debugging\n this.logger.error('Error in createItem', {\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n errorCode: error?.errorInfo?.code,\n originalErrorCode: originalError?.errorInfo?.code\n });\n const isValidationError =\n error.name === 'CreateValidationError' ||\n originalError?.name === 'CreateValidationError' ||\n error.name === 'ValidationError' ||\n originalError?.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n originalError?.name === 'SequelizeValidationError' ||\n error?.errorInfo?.code === 'VALIDATION_ERROR' ||\n originalError?.errorInfo?.code === 'VALIDATION_ERROR' ||\n (error.message && (\n error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation') ||\n error.message.includes('Required field') ||\n error.message.includes('Referenced item does not exist') ||\n error.message.includes('Foreign key constraint') ||\n error.message.includes('Operation failed') ||\n error.message.includes('preCreate') ||\n error.message.includes('preUpdate') ||\n error.message.includes('Create Validation Failed')\n )) ||\n (originalError?.message && (\n originalError.message.includes('validation') ||\n originalError.message.includes('required') ||\n originalError.message.includes('cannot be null') ||\n originalError.message.includes('notNull Violation') ||\n originalError.message.includes('Required field') ||\n originalError.message.includes('Referenced item does not exist') ||\n originalError.message.includes('Foreign key constraint') ||\n originalError.message.includes('preCreate') ||\n originalError.message.includes('preUpdate') ||\n originalError.message.includes('Create Validation Failed')\n ));\n \n if (isValidationError) {\n const errorMessage = originalError?.message || error.message || \"Validation failed\";\n res.status(400).json({ success: false, error: errorMessage });\n } else {\n res.status(500).json({ success: false, error: error.message || \"Internal server error\" });\n }\n }\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 try {\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 let parsedParams: any;\n try {\n parsedParams = finderParams ? JSON.parse(finderParams) : {};\n } catch (parseError: any) {\n res.status(400).json({\n error: 'Invalid JSON in finderParams',\n message: parseError.message\n });\n return;\n }\n\n let items: Item<S>[] = [];\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, parsedParams);\n items = item ? [item] : [];\n } else {\n items = await libOperations.find(finder, parsedParams);\n }\n\n // For finder queries, wrap in AllOperationResult format for consistency\n const validatedItems = items.map((item: Item<S>) => validatePK(item, this.getPkType()));\n const result: AllOperationResult<Item<S>> = {\n items: validatedItems,\n metadata: {\n total: validatedItems.length,\n returned: validatedItems.length,\n offset: 0,\n hasMore: false\n }\n };\n res.json(result);\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 \n // Parse pagination options from query params\n const allOptions: AllOptions = {};\n if (req.query.limit) {\n allOptions.limit = parseInt(req.query.limit as string, 10);\n }\n if (req.query.offset) {\n allOptions.offset = parseInt(req.query.offset as string, 10);\n }\n \n // libOperations.all() now returns AllOperationResult<V>\n const result = await libOperations.all(itemQuery, [], allOptions);\n \n // Validate PKs on returned items\n const validatedItems = result.items.map((item: Item<S>) => validatePK(item, this.getPkType()));\n \n // Return full AllOperationResult structure with validated items\n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\n }\n } catch (error: any) {\n this.logger.error('Error in findItems', { error });\n if (error instanceof NotFoundError || error?.name === 'NotFoundError') {\n res.status(404).json({ error: error.message || 'Item not found' });\n } else {\n res.status(500).json({ error: error.message || 'Internal server error' });\n }\n }\n };\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/express-router",
|
|
3
3
|
"description": "Express Router for Fjell",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.69",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"express",
|
|
7
7
|
"router",
|
|
@@ -34,17 +34,17 @@
|
|
|
34
34
|
"docs:test": "cd docs && npm run test"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@fjell/core": "^4.4.
|
|
38
|
-
"@fjell/lib": "^4.4.
|
|
39
|
-
"@fjell/logging": "^4.4.
|
|
40
|
-
"@fjell/registry": "^4.4.
|
|
37
|
+
"@fjell/core": "^4.4.64",
|
|
38
|
+
"@fjell/lib": "^4.4.73",
|
|
39
|
+
"@fjell/logging": "^4.4.59",
|
|
40
|
+
"@fjell/registry": "^4.4.70",
|
|
41
41
|
"deepmerge": "^4.3.1",
|
|
42
42
|
"express": "^5.1.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@eslint/eslintrc": "^3.3.1",
|
|
46
46
|
"@eslint/js": "^9.38.0",
|
|
47
|
-
"@fjell/common-config": "^1.1.
|
|
47
|
+
"@fjell/common-config": "^1.1.31",
|
|
48
48
|
"@tsconfig/recommended": "^1.0.10",
|
|
49
49
|
"@types/express": "^5.0.3",
|
|
50
50
|
"@types/node": "^24.9.1",
|