@fjell/express-router 4.4.69 → 4.4.71

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,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"}
1
+ {"version":3,"file":"CItemRouter.d.ts","sourceRoot":"","sources":["../src/CItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EACO,MAAM,EAAoC,IAAI,EAAqB,WAAW,EAC3F,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,mBA+FtD;CAEH"}
@@ -64,24 +64,32 @@ class CItemRouter extends ItemRouter {
64
64
  });
65
65
  return;
66
66
  }
67
- let items = [];
67
+ const findOptions = req.query.limit || req.query.offset ? {
68
+ ...req.query.limit && { limit: parseInt(req.query.limit, 10) },
69
+ ...req.query.offset && { offset: parseInt(req.query.offset, 10) }
70
+ } : void 0;
71
+ const locations = this.getLocations(res);
68
72
  if (one === "true") {
69
- const item = await this.lib.findOne(finder, parsedParams, this.getLocations(res));
70
- items = item ? [item] : [];
73
+ const item = await this.lib.findOne(finder, parsedParams, locations);
74
+ const validatedItem = item ? validatePK(item, this.getPkType()) : null;
75
+ const result = {
76
+ items: validatedItem ? [validatedItem] : [],
77
+ metadata: {
78
+ total: validatedItem ? 1 : 0,
79
+ returned: validatedItem ? 1 : 0,
80
+ offset: 0,
81
+ hasMore: false
82
+ }
83
+ };
84
+ res.json(result);
71
85
  } else {
72
- items = await libOperations.find(finder, parsedParams, this.getLocations(res));
86
+ const result = await libOperations.find(finder, parsedParams, locations, findOptions);
87
+ const validatedItems = validatePK(result.items, this.getPkType());
88
+ res.json({
89
+ items: validatedItems,
90
+ metadata: result.metadata
91
+ });
73
92
  }
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);
85
93
  } else {
86
94
  const itemQuery = paramsToQuery(req.query);
87
95
  const locations = this.getLocations(res);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/CItemRouter.ts"],
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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",
4
+ "sourcesContent": ["import {\n AllOptions, ComKey, FindOperationResult, FindOptions, 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 // Parse pagination options from query parameters\n const findOptions: FindOptions | undefined =\n (req.query.limit || req.query.offset) ? {\n ...(req.query.limit && { limit: parseInt(req.query.limit as string, 10) }),\n ...(req.query.offset && { offset: parseInt(req.query.offset as string, 10) }),\n } : (void 0);\n\n const locations = this.getLocations(res);\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, parsedParams, locations);\n // Wrap findOne result in FindOperationResult format\n const validatedItem = item ? (validatePK(item, this.getPkType()) as Item<S, L1, L2, L3, L4, L5>) : null;\n const result: FindOperationResult<Item<S, L1, L2, L3, L4, L5>> = {\n items: validatedItem ? [validatedItem] : [],\n metadata: {\n total: validatedItem ? 1 : 0,\n returned: validatedItem ? 1 : 0,\n offset: 0,\n hasMore: false\n }\n };\n res.json(result);\n } else {\n // Call find() with pagination options - it returns FindOperationResult\n const result = await libOperations.find(finder, parsedParams, locations, findOptions);\n \n // Validate items - validatePK can handle arrays\n const validatedItems = validatePK(result.items, this.getPkType()) as Item<S, L1, L2, L3, L4, L5>[];\n \n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\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 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": "AAAA;AAAA,EAC8F;AAAA,EAAoC;AAAA,OAC3H;AACP,SAAkB,qBAAqB;AAEvC,SAAS,kBAAqC;AAMvC,MAAM,oBAQH,WAAkC;AAAA,EAE1C,YACE,KACA,MACA,aACA,UAAoD,CAAC,GACrD;AACA,UAAM,KAAY,MAAM,SAAS,WAAW;AAAA,EAC9C;AAAA,EAEO,YAAqB;AAC1B,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA,EAEO,MAAM,KAA8C;AACzD,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,UAAM,MAAM,KAAK,aAAa,GAAG;AACjC,WAAO,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,EACvC;AAAA,EAEO,OAAO,KAA+C;AAM3D,QAAI,MAAuC,CAAC,KAAK,MAAM,GAAG,CAAC;AAC3D,UAAM,IAAI,OAAO,KAAK,YAAa,OAAO,GAAG,CAAoC;AACjF,WAAO;AAAA,EACT;AAAA,EAEO,aAAa,KAAgD;AAClE,WAAO,KAAK,YAAa,OAAO,GAAG;AAAA,EACrC;AAAA,EAEO,aAAa,OAAO,KAAc,QAAkB;AACzD,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,QAAQ,iBAAiB,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AAErH,QAAI;AACF,YAAM,eAAe,KAAK,aAAa,IAAI,IAAmC;AAC9E,UAAI,OAAO,WAAW,MAAM,cAAc;AAAA,QACxC;AAAA,QAAc,EAAE,WAAW,KAAK,aAAa,GAAG,EAAE;AAAA,MAAC,GAAG,KAAK,UAAU,CAAC;AACxE,aAAO,MAAM,KAAK,eAAe,IAAI;AACrC,WAAK,OAAO,QAAQ,mBAAmB,IAAI;AAC3C,UAAI,OAAO,GAAG,EAAE,KAAK,IAAI;AAAA,IAC3B,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC;AAElD,UAAI,MAAM,SAAS,2BAA2B,MAAM,SAAS,qBACzD,MAAM,SAAS,8BACd,MAAM,YAAY,MAAM,QAAQ,SAAS,YAAY,KACrD,MAAM,QAAQ,SAAS,UAAU,KACjC,MAAM,QAAQ,SAAS,gBAAgB,KACvC,MAAM,QAAQ,SAAS,mBAAmB,IAAK;AAClD,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,mBAAmB,CAAC;AAAA,MACtD,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,gBAAgB,CAAC;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAAA,EAEU,YAAY,OAAO,KAAc,QAAkB;AAC3D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,UAAM,QAAqB,IAAI;AAC/B,UAAM,SAAS,MAAM,QAAQ;AAC7B,UAAM,eAAe,MAAM,cAAc;AACzC,UAAM,MAAM,MAAM,KAAK;AAEvB,QAAI;AACF,UAAI,QAAQ;AAEV,aAAK,OAAO,QAAQ,6BAA6B,EAAE,QAAQ,cAAc,IAAI,CAAC;AAE9E,YAAI;AACJ,YAAI;AACF,yBAAe,eAAe,KAAK,MAAM,YAAY,IAAI,CAAC;AAAA,QAC5D,SAAS,YAAiB;AACxB,cAAI,OAAO,GAAG,EAAE,KAAK;AAAA,YACnB,OAAO;AAAA,YACP,SAAS,WAAW;AAAA,UACtB,CAAC;AACD;AAAA,QACF;AAGA,cAAM,cACH,IAAI,MAAM,SAAS,IAAI,MAAM,SAAU;AAAA,UACtC,GAAI,IAAI,MAAM,SAAS,EAAE,OAAO,SAAS,IAAI,MAAM,OAAiB,EAAE,EAAE;AAAA,UACxE,GAAI,IAAI,MAAM,UAAU,EAAE,QAAQ,SAAS,IAAI,MAAM,QAAkB,EAAE,EAAE;AAAA,QAC7E,IAAK;AAEP,cAAM,YAAY,KAAK,aAAa,GAAG;AAEvC,YAAI,QAAQ,QAAQ;AAClB,gBAAM,OAAO,MAAO,KAAK,IAAY,QAAQ,QAAQ,cAAc,SAAS;AAE5E,gBAAM,gBAAgB,OAAQ,WAAW,MAAM,KAAK,UAAU,CAAC,IAAoC;AACnG,gBAAM,SAA2D;AAAA,YAC/D,OAAO,gBAAgB,CAAC,aAAa,IAAI,CAAC;AAAA,YAC1C,UAAU;AAAA,cACR,OAAO,gBAAgB,IAAI;AAAA,cAC3B,UAAU,gBAAgB,IAAI;AAAA,cAC9B,QAAQ;AAAA,cACR,SAAS;AAAA,YACX;AAAA,UACF;AACA,cAAI,KAAK,MAAM;AAAA,QACjB,OAAO;AAEL,gBAAM,SAAS,MAAM,cAAc,KAAK,QAAQ,cAAc,WAAW,WAAW;AAGpF,gBAAM,iBAAiB,WAAW,OAAO,OAAO,KAAK,UAAU,CAAC;AAEhE,cAAI,KAAK;AAAA,YACP,OAAO;AAAA,YACP,UAAU,OAAO;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF,OAAO;AAEL,cAAM,YAAuB,cAAc,IAAI,KAAoB;AACnE,cAAM,YAAY,KAAK,aAAa,GAAG;AACvC,aAAK,OAAO,MAAM,gCAAgC,SAAS;AAC3D,aAAK,OAAO,MAAM,kCAAkC,SAAS;AAG7D,cAAM,aAAyB,CAAC;AAChC,YAAI,IAAI,MAAM,OAAO;AACnB,qBAAW,QAAQ,SAAS,IAAI,MAAM,OAAiB,EAAE;AAAA,QAC3D;AACA,YAAI,IAAI,MAAM,QAAQ;AACpB,qBAAW,SAAS,SAAS,IAAI,MAAM,QAAkB,EAAE;AAAA,QAC7D;AAGA,cAAM,SAAS,MAAM,cAAc,IAAI,WAAW,WAAW,UAAU;AACvE,aAAK,OAAO,MAAM,6BAA6B,OAAO,MAAM,MAAM;AAGlE,cAAM,iBAAiB,OAAO,MAAM,IAAI,CAAC,SAAsC,WAAW,MAAM,KAAK,UAAU,CAAC,CAAC;AAGjH,YAAI,KAAK;AAAA,UACP,OAAO;AAAA,UACP,UAAU,OAAO;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC;AACjD,UAAI,iBAAiB,iBAAiB,OAAO,SAAS,iBAAiB;AACrE,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,MAAM,WAAW,wBAAwB,CAAC;AAAA,MAC1E,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,MAAM,WAAW,wBAAwB,CAAC;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC5I,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,mBA4FtD;CAEH"}
@@ -59,24 +59,31 @@ class PItemRouter extends ItemRouter {
59
59
  });
60
60
  return;
61
61
  }
62
- let items = [];
62
+ const findOptions = req.query.limit || req.query.offset ? {
63
+ ...req.query.limit && { limit: parseInt(req.query.limit, 10) },
64
+ ...req.query.offset && { offset: parseInt(req.query.offset, 10) }
65
+ } : void 0;
63
66
  if (one === "true") {
64
67
  const item = await this.lib.findOne(finder, parsedParams);
65
- items = item ? [item] : [];
68
+ const validatedItem = item ? validatePK(item, this.getPkType()) : null;
69
+ const result = {
70
+ items: validatedItem ? [validatedItem] : [],
71
+ metadata: {
72
+ total: validatedItem ? 1 : 0,
73
+ returned: validatedItem ? 1 : 0,
74
+ offset: 0,
75
+ hasMore: false
76
+ }
77
+ };
78
+ res.json(result);
66
79
  } else {
67
- items = await libOperations.find(finder, parsedParams);
80
+ const result = await libOperations.find(finder, parsedParams, [], findOptions);
81
+ const validatedItems = validatePK(result.items, this.getPkType());
82
+ res.json({
83
+ items: validatedItems,
84
+ metadata: result.metadata
85
+ });
68
86
  }
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);
80
87
  } else {
81
88
  const itemQuery = paramsToQuery(req.query);
82
89
  this.logger.default("Finding Items with a query %j", itemQuery);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/PItemRouter.ts"],
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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",
4
+ "sourcesContent": ["import { AllOptions, FindOperationResult, FindOptions, 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 // Parse pagination options from query parameters\n const findOptions: FindOptions | undefined =\n (req.query.limit || req.query.offset) ? {\n ...(req.query.limit && { limit: parseInt(req.query.limit as string, 10) }),\n ...(req.query.offset && { offset: parseInt(req.query.offset as string, 10) }),\n } : (void 0);\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, parsedParams);\n // Wrap findOne result in FindOperationResult format\n const validatedItem = item ? (validatePK(item, this.getPkType()) as Item<S>) : null;\n const result: FindOperationResult<Item<S>> = {\n items: validatedItem ? [validatedItem] : [],\n metadata: {\n total: validatedItem ? 1 : 0,\n returned: validatedItem ? 1 : 0,\n offset: 0,\n hasMore: false\n }\n };\n res.json(result);\n } else {\n // Call find() with pagination options - it returns FindOperationResult\n const result = await libOperations.find(finder, parsedParams, [], findOptions);\n \n // Validate items - validatePK can handle arrays\n const validatedItems = validatePK(result.items, this.getPkType()) as Item<S>[];\n \n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\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 \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.69",
4
+ "version": "4.4.71",
5
5
  "keywords": [
6
6
  "express",
7
7
  "router",
@@ -34,10 +34,10 @@
34
34
  "docs:test": "cd docs && npm run test"
35
35
  },
36
36
  "dependencies": {
37
- "@fjell/core": "^4.4.64",
38
- "@fjell/lib": "^4.4.73",
37
+ "@fjell/core": "^4.4.66",
38
+ "@fjell/lib": "^4.4.75",
39
39
  "@fjell/logging": "^4.4.59",
40
- "@fjell/registry": "^4.4.70",
40
+ "@fjell/registry": "^4.4.72",
41
41
  "deepmerge": "^4.3.1",
42
42
  "express": "^5.1.0"
43
43
  },