@fjell/express-router 4.4.82 → 4.4.83

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/LICENSE CHANGED
@@ -187,7 +187,7 @@
187
187
  same "printed page" as the copyright notice for easier
188
188
  identification within third-party archives.
189
189
 
190
- Copyright 2025 Fjell Project
190
+ Copyright 2026 Tim O'Brien
191
191
 
192
192
  Licensed under the Apache License, Version 2.0 (the "License");
193
193
  you may not use this file except in compliance with the License.
@@ -1 +1 @@
1
- {"version":3,"file":"CItemRouter.d.ts","sourceRoot":"","sources":["../src/CItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EACO,MAAM,EAAoC,IAAI,EAAqB,WAAW,EAC3F,MAAM,cAAc,CAAC;AAGtB,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;AAyEhE,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,mBAgDpD;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA+FtD;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,cAAc,CAAC;AAGtB,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;AAyEhE,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,mBAgDpD;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA4GtD;CAEH"}
@@ -121,6 +121,16 @@ class CItemRouter extends ItemRouter {
121
121
  const finderParams = query["finderParams"];
122
122
  const one = query["one"];
123
123
  try {
124
+ const parsePaginationParam = (value) => {
125
+ if (typeof value !== "string" || value.trim().length === 0) {
126
+ return void 0;
127
+ }
128
+ const parsed = parseInt(value, 10);
129
+ if (Number.isNaN(parsed) || parsed < 0) {
130
+ return void 0;
131
+ }
132
+ return parsed;
133
+ };
124
134
  if (finder) {
125
135
  this.logger.default("Finding Items with Finder", { finder, finderParams, one });
126
136
  let parsedParams;
@@ -134,8 +144,8 @@ class CItemRouter extends ItemRouter {
134
144
  return;
135
145
  }
136
146
  const findOptions = req.query.limit || req.query.offset ? {
137
- ...req.query.limit && { limit: parseInt(req.query.limit, 10) },
138
- ...req.query.offset && { offset: parseInt(req.query.offset, 10) }
147
+ ...parsePaginationParam(req.query.limit) !== void 0 && { limit: parsePaginationParam(req.query.limit) },
148
+ ...parsePaginationParam(req.query.offset) !== void 0 && { offset: parsePaginationParam(req.query.offset) }
139
149
  } : void 0;
140
150
  const locations = this.getLocations(res);
141
151
  if (one === "true") {
@@ -165,11 +175,13 @@ class CItemRouter extends ItemRouter {
165
175
  this.logger.debug("Finding Items with Query: %j", itemQuery);
166
176
  this.logger.debug("Location keys being passed: %j", locations);
167
177
  const allOptions = {};
168
- if (req.query.limit) {
169
- allOptions.limit = parseInt(req.query.limit, 10);
178
+ const parsedLimit = parsePaginationParam(req.query.limit);
179
+ if (parsedLimit !== void 0) {
180
+ allOptions.limit = parsedLimit;
170
181
  }
171
- if (req.query.offset) {
172
- allOptions.offset = parseInt(req.query.offset, 10);
182
+ const parsedOffset = parsePaginationParam(req.query.offset);
183
+ if (parsedOffset !== void 0) {
184
+ allOptions.offset = parsedOffset;
173
185
  }
174
186
  const result = await libOperations.all(itemQuery, locations, allOptions);
175
187
  this.logger.debug("Found %d Items with Query", result.items.length);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/CItemRouter.ts"],
4
- "sourcesContent": ["import {\n AllOptions, ComKey, FindOperationResult, FindOptions, Item, ItemQuery, LocKey, LocKeyArray, PriKey, QueryParams\n} from \"@fjell/types\";\nimport { paramsToQuery } from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\n\n/**\n * Extract serializable error details from Error objects\n *\n * Error objects have non-enumerable properties that don't serialize to JSON.\n * This function explicitly extracts all meaningful details into a plain object.\n */\nfunction extractErrorDetails(error: any): Record<string, any> {\n if (!error) {\n return { type: 'unknown_error' };\n }\n\n const details: Record<string, any> = {};\n\n // Standard JavaScript Error properties\n if (typeof error.message === 'string') {\n details.message = error.message;\n }\n if (typeof error.name === 'string') {\n details.name = error.name;\n }\n if (typeof error.code === 'string' || typeof error.code === 'number') {\n details.code = error.code;\n }\n if (typeof error.stack === 'string') {\n details.stack = error.stack;\n }\n\n // Database-specific error properties (PostgreSQL/Sequelize)\n if (typeof error.constraint === 'string') {\n details.constraint = error.constraint;\n }\n if (typeof error.detail === 'string') {\n details.detail = error.detail;\n }\n if (typeof error.table === 'string') {\n details.table = error.table;\n }\n if (typeof error.column === 'string') {\n details.column = error.column;\n }\n\n // Sequelize validation errors\n if (error.errors && Array.isArray(error.errors)) {\n details.validationErrors = error.errors.map((e: any) => {\n const errorDetail: any = {\n message: e.message,\n type: e.type,\n path: e.path\n };\n if (e.value !== null && e.value !== void 0) {\n errorDetail.value = String(e.value).substring(0, 100);\n }\n return errorDetail;\n });\n }\n\n // HTTP status\n if (typeof error.status === 'number') {\n details.status = error.status;\n }\n if (typeof error.statusCode === 'number') {\n details.statusCode = error.statusCode;\n }\n\n return details;\n}\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 // Log structured error details for agentic debugging\n this.logger.error('Error in createItem endpoint', {\n component: 'CItemRouter',\n operation: 'createItem',\n endpoint: req.path,\n method: req.method,\n itemType: this.getPkType(),\n requestBody: JSON.stringify(req.body),\n locations: JSON.stringify(this.getLocations(res)),\n errorType: error?.constructor?.name || typeof error,\n errorName: error?.name,\n errorMessage: error?.message,\n errorCode: error?.errorInfo?.code || error?.code,\n validationErrors: error?.errorInfo?.details?.fieldErrors,\n suggestion: 'Check request body validation, required fields, parent locations, unique constraints, and data types',\n stack: error?.stack\n });\n\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({\n message: \"Validation Error\",\n details: error?.errorInfo?.details?.fieldErrors || error?.message\n });\n } else {\n res.status(500).json({\n message: \"General Error\",\n error: error?.message\n });\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', extractErrorDetails(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, PriKey, QueryParams\n} from \"@fjell/types\";\nimport { paramsToQuery } from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\n\n/**\n * Extract serializable error details from Error objects\n *\n * Error objects have non-enumerable properties that don't serialize to JSON.\n * This function explicitly extracts all meaningful details into a plain object.\n */\nfunction extractErrorDetails(error: any): Record<string, any> {\n if (!error) {\n return { type: 'unknown_error' };\n }\n\n const details: Record<string, any> = {};\n\n // Standard JavaScript Error properties\n if (typeof error.message === 'string') {\n details.message = error.message;\n }\n if (typeof error.name === 'string') {\n details.name = error.name;\n }\n if (typeof error.code === 'string' || typeof error.code === 'number') {\n details.code = error.code;\n }\n if (typeof error.stack === 'string') {\n details.stack = error.stack;\n }\n\n // Database-specific error properties (PostgreSQL/Sequelize)\n if (typeof error.constraint === 'string') {\n details.constraint = error.constraint;\n }\n if (typeof error.detail === 'string') {\n details.detail = error.detail;\n }\n if (typeof error.table === 'string') {\n details.table = error.table;\n }\n if (typeof error.column === 'string') {\n details.column = error.column;\n }\n\n // Sequelize validation errors\n if (error.errors && Array.isArray(error.errors)) {\n details.validationErrors = error.errors.map((e: any) => {\n const errorDetail: any = {\n message: e.message,\n type: e.type,\n path: e.path\n };\n if (e.value !== null && e.value !== void 0) {\n errorDetail.value = String(e.value).substring(0, 100);\n }\n return errorDetail;\n });\n }\n\n // HTTP status\n if (typeof error.status === 'number') {\n details.status = error.status;\n }\n if (typeof error.statusCode === 'number') {\n details.statusCode = error.statusCode;\n }\n\n return details;\n}\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 // Log structured error details for agentic debugging\n this.logger.error('Error in createItem endpoint', {\n component: 'CItemRouter',\n operation: 'createItem',\n endpoint: req.path,\n method: req.method,\n itemType: this.getPkType(),\n requestBody: JSON.stringify(req.body),\n locations: JSON.stringify(this.getLocations(res)),\n errorType: error?.constructor?.name || typeof error,\n errorName: error?.name,\n errorMessage: error?.message,\n errorCode: error?.errorInfo?.code || error?.code,\n validationErrors: error?.errorInfo?.details?.fieldErrors,\n suggestion: 'Check request body validation, required fields, parent locations, unique constraints, and data types',\n stack: error?.stack\n });\n\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({\n message: \"Validation Error\",\n details: error?.errorInfo?.details?.fieldErrors || error?.message\n });\n } else {\n res.status(500).json({\n message: \"General Error\",\n error: error?.message\n });\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 const parsePaginationParam = (value: unknown): number | undefined => {\n if (typeof value !== 'string' || value.trim().length === 0) {\n return void 0;\n }\n const parsed = parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed < 0) {\n return void 0;\n }\n return parsed;\n };\n\n if (finder) {\n // If finder is defined? Call a finder.\n this.logger.default('Finding Items with Finder', { finder, finderParams, one });\n\n 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 ...(parsePaginationParam(req.query.limit) !== void 0 && { limit: parsePaginationParam(req.query.limit) }),\n ...(parsePaginationParam(req.query.offset) !== void 0 && { offset: parsePaginationParam(req.query.offset) }),\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 const parsedLimit = parsePaginationParam(req.query.limit);\n if (parsedLimit !== void 0) {\n allOptions.limit = parsedLimit;\n }\n const parsedOffset = parsePaginationParam(req.query.offset);\n if (parsedOffset !== void 0) {\n allOptions.offset = parsedOffset;\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', extractErrorDetails(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":"ItemRouter.d.ts","sourceRoot":"","sources":["../src/ItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,IAAI,EAEJ,MAAM,EACN,WAAW,EACX,MAAM,EACP,MAAM,cAAc,CAAC;AAOtB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAsB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAqE5E;;;GAGG;AACH,MAAM,WAAW,kBAAkB,CACjC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK;IAEzB,CACE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAC7C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,EACxG,OAAO,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK;IAEzB,CACE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAC7C,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,EACvG,OAAO,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CACpC,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK;IAEzB,CACE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,EAC3G,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAC/C,OAAO,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB,CACnC,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK;IAEzB,CACE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,EAC1G,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,EAC/C,OAAO,EAAE;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,GACvC,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,MAAM,GAAG,MAAM,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,IACvB;IACF;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAEpE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAElE;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAEvE;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAErE;;OAEG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC,CAAC;AAEF,qBAAa,UAAU,CACrB,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK;IAGzB,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,OAAO,CAAC,OAAO,CAAI;IACnB,SAAS,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,YAAY,CAA8B;IAClD,SAAS,CAAC,MAAM,kCAAC;IACjB,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC9D,SAAS,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;gBAG1F,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACjE,OAAO,EAAE,CAAC,EACV,OAAO,GAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAM,EACtD,WAAW,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC;IAUrD;;OAEG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,IAC/E,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY;IAKlD,SAAS,QAAO,CAAC,CAEvB;IAED,SAAS,CAAC,UAAU,QAAO,MAAM,CAEhC;IAED,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAalC,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAIrD,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAKtC,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE;IAK3E,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAIzE,SAAS,CAAC,aAAa,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAsC3D;IAED,SAAS,CAAC,WAAW,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAuCzD;IAED,SAAS,CAAC,cAAc,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAuC5D;IAED,SAAS,CAAC,YAAY,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAwC1D;IAED,OAAO,CAAC,SAAS,CAiIhB;IAED,OAAO,CAAC,uBAAuB,CAS9B;IAED,OAAO,CAAC,qBAAqB,CAO5B;IAEM,cAAc,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,UAEpD;IAGM,SAAS,IAAI,MAAM;IAQ1B,SAAS,CAAC,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;IAIK,cAAc,GAAU,MAAM,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAGrG;IAEF,SAAS,CAAC,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CA6CvE;IAIF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;IAGF,SAAS,CAAC,OAAO,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA2DrD;IAED,SAAS,CAAC,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBA0CvD;IAEK,YAAY,GAAI,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAYtG;IAGF;;;;;;OAMG;IACH,SAAS,CAAC,eAAe,GAAI,cAAc,MAAM,KAAG,OAAO,CAU1D;CAEF"}
1
+ {"version":3,"file":"ItemRouter.d.ts","sourceRoot":"","sources":["../src/ItemRouter.ts"],"names":[],"mappings":"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"}
@@ -128,6 +128,8 @@ class ItemRouter {
128
128
  );
129
129
  if (result2 != null) {
130
130
  res.json(result2);
131
+ } else {
132
+ res.status(204).send();
131
133
  }
132
134
  return;
133
135
  }
@@ -160,6 +162,8 @@ class ItemRouter {
160
162
  );
161
163
  if (result2 != null) {
162
164
  res.json(result2);
165
+ } else {
166
+ res.status(204).send();
163
167
  }
164
168
  return;
165
169
  }
@@ -194,6 +198,8 @@ class ItemRouter {
194
198
  );
195
199
  if (result2 != null) {
196
200
  res.json(result2);
201
+ } else {
202
+ res.status(204).send();
197
203
  }
198
204
  return;
199
205
  }
@@ -227,6 +233,8 @@ class ItemRouter {
227
233
  );
228
234
  if (result2 != null) {
229
235
  res.json(result2);
236
+ } else {
237
+ res.status(204).send();
230
238
  }
231
239
  return;
232
240
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/ItemRouter.ts"],
4
- "sourcesContent": ["import {\n ComKey,\n Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n} from \"@fjell/types\";\nimport {\n ActionError,\n cPK,\n} from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { NextFunction, Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\nimport { createErrorHandler, ErrorHandlerOptions } from \"./errorHandler.js\";\n\n/**\n * Extract serializable error details from Error objects\n *\n * Error objects have non-enumerable properties that don't serialize to JSON.\n * This function explicitly extracts all meaningful details into a plain object.\n */\nfunction extractErrorDetails(error: any): Record<string, any> {\n if (!error) {\n return { type: 'unknown_error' };\n }\n\n const details: Record<string, any> = {};\n\n // Standard JavaScript Error properties\n if (typeof error.message === 'string') {\n details.message = error.message;\n }\n if (typeof error.name === 'string') {\n details.name = error.name;\n }\n if (typeof error.code === 'string' || typeof error.code === 'number') {\n details.code = error.code;\n }\n if (typeof error.stack === 'string') {\n details.stack = error.stack;\n }\n\n // Database-specific error properties (PostgreSQL/Sequelize)\n if (typeof error.constraint === 'string') {\n details.constraint = error.constraint;\n }\n if (typeof error.detail === 'string') {\n details.detail = error.detail;\n }\n if (typeof error.table === 'string') {\n details.table = error.table;\n }\n if (typeof error.column === 'string') {\n details.column = error.column;\n }\n\n // Sequelize validation errors\n if (error.errors && Array.isArray(error.errors)) {\n details.validationErrors = error.errors.map((e: any) => {\n const errorDetail: any = {\n message: e.message,\n type: e.type,\n path: e.path\n };\n if (e.value !== null && e.value !== void 0) {\n errorDetail.value = String(e.value).substring(0, 100);\n }\n return errorDetail;\n });\n }\n\n // HTTP status\n if (typeof error.status === 'number') {\n details.status = error.status;\n }\n if (typeof error.statusCode === 'number') {\n details.statusCode = error.statusCode;\n }\n\n return details;\n}\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 /**\n * Error handler configuration\n */\n errorHandler?: ErrorHandlerOptions;\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 protected parentRoute?: ItemRouter<L1, L2, L3, L4, L5, never>;\n protected errorHandler: (err: any, req: Request, res: Response, next: NextFunction) => void;\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 parentRoute?: ItemRouter<L1, L2, L3, L4, L5, never>\n ) {\n this.lib = lib;\n this.keyType = keyType;\n this.options = options;\n this.parentRoute = parentRoute;\n this.logger = LibLogger.get(\"ItemRouter\", keyType);\n this.errorHandler = createErrorHandler(options.errorHandler);\n }\n\n /**\n * Wrap async route handlers to catch errors and pass to error handler\n */\n protected wrapAsync(fn: (req: Request, res: Response, next: NextFunction) => Promise<any>) {\n return (req: Request, res: Response, next: NextFunction) => {\n Promise.resolve(fn.call(this, req, res, next)).catch(next);\n };\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 const pkParam = this.getPkParam();\n const lkValue = res.locals[pkParam];\n this.logger.debug('Getting location key', {\n keyType: this.keyType,\n pkParam: pkParam,\n lkValue: lkValue,\n allLocals: res.locals\n });\n return { kt: this.keyType, lk: lkValue };\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 protected getLocations(res: Response): LocKeyArray<L1, L2, L3, L4, L5> | [] {\n return this.parentRoute ? this.parentRoute.getLKA(res) as LocKeyArray<L1, L2, L3, L4, L5> : [];\n }\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 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 try {\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 const result = await this.options.allActions[allActionKey](\n req.body as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLocations(res),\n { req, res }\n );\n if (result != null) {\n res.json(result);\n }\n return;\n }\n\n // Check if allAction operation exists\n if (!libOperations.allAction) {\n res.status(500).json({ error: 'All Actions are not configured' });\n return;\n }\n\n // Fallback to library handler\n const result = await libOperations.allAction(allActionKey, req.body, this.getLocations(res));\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in postAllAction', extractErrorDetails(error));\n // Check if it's a validation error or action not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'All Action is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected getAllFacet = async (req: Request, res: Response) => {\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 try {\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 const result = await this.options.allFacets[facetKey](\n req.query as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLocations(res),\n { req, res }\n );\n if (result != null) {\n res.json(result);\n }\n return;\n }\n\n // Check if allFacet operation exists\n if (!libOperations.allFacet) {\n res.status(500).json({ error: 'All Facets are not configured' });\n return;\n }\n\n // Fallback to library handler\n const combinedQueryParams = { ...(req.query || {}), ...(req.params || {}) } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n const result = await libOperations.allFacet(facetKey, combinedQueryParams, this.getLocations(res));\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in getAllFacet', extractErrorDetails(error));\n // Check if it's a validation error or facet not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'All Facet is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected postItemAction = async (req: Request, res: Response) => {\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 try {\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 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) {\n res.json(result);\n }\n return;\n }\n\n // Check if actions operation exists\n if (!libOperations.action) {\n res.status(500).json({ error: 'Item Actions are not configured' });\n return;\n }\n\n // Fallback to library handler\n const result = await libOperations.action(ik, actionKey, req.body);\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in postItemAction', extractErrorDetails(error));\n // Check if it's a validation error or action not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'Item Action is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected getItemFacet = async (req: Request, res: Response) => {\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 try {\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 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) {\n res.json(result);\n }\n return;\n }\n\n // Check if facets operation exists\n if (!libOperations.facet) {\n res.status(500).json({ error: 'Item Facets are not configured' });\n return;\n }\n\n // Fallback to library handler\n const combinedQueryParams = { ...(req.query || {}), ...(req.params || {}) } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n const result = await libOperations.facet(ik, facetKey, combinedQueryParams);\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in getItemFacet', extractErrorDetails(error));\n // Check if it's a validation error or facet not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'Item Facet is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n private configure = (router: Router) => {\n if (!this.lib) {\n this.logger.error('Library is undefined in configure');\n throw new Error('Library is required for router configuration');\n }\n // Ensure options exists - library should have options but handle case where it doesn't\n const libOptions = (this.lib as any).options || {};\n this.logger.debug('Configuring Router', { pkType: this.getPkType(), hasOptions: !!libOptions });\n router.get('/', this.wrapAsync(this.findItems));\n router.post('/', this.wrapAsync(this.createItem));\n\n // Track registered routes to detect collisions\n const registeredAllActions = new Set<string>();\n const registeredAllFacets = new Set<string>();\n const registeredItemActions = new Set<string>();\n const registeredItemFacets = new Set<string>();\n\n // Configure router-level allActions first (highest precedence)\n this.logger.default('Router All Actions', { allActions: this.options.allActions });\n if (this.options.allActions) {\n Object.keys(this.options.allActions).forEach((actionKey) => {\n this.logger.debug('Configuring Router All Action %s', actionKey);\n router.post(`/${actionKey}`, this.wrapAsync(this.postAllAction));\n registeredAllActions.add(actionKey);\n });\n }\n\n // Configure library allActions, warn on conflicts\n this.logger.default('Library All Actions', { allActions: libOptions.allActions });\n if (libOptions.allActions) {\n Object.keys(libOptions.allActions).forEach((actionKey) => {\n if (registeredAllActions.has(actionKey)) {\n this.logger.warning('All Action name collision - router-level handler takes precedence', { actionKey });\n } else {\n this.logger.debug('Configuring Library All Action %s', actionKey);\n router.post(`/${actionKey}`, this.wrapAsync(this.postAllAction));\n registeredAllActions.add(actionKey);\n }\n });\n }\n\n // Configure router-level allFacets first (highest precedence)\n this.logger.default('Router All Facets', { allFacets: this.options.allFacets });\n if (this.options.allFacets) {\n Object.keys(this.options.allFacets).forEach((facetKey) => {\n this.logger.debug('Configuring Router All Facet %s', facetKey);\n router.get(`/${facetKey}`, this.wrapAsync(this.getAllFacet));\n registeredAllFacets.add(facetKey);\n });\n }\n\n // Configure library allFacets, warn on conflicts\n this.logger.default('Library All Facets', { allFacets: libOptions.allFacets });\n if (libOptions.allFacets) {\n Object.keys(libOptions.allFacets).forEach((facetKey) => {\n if (registeredAllFacets.has(facetKey)) {\n this.logger.warning('All Facet name collision - router-level handler takes precedence', { facetKey });\n } else {\n this.logger.debug('Configuring Library All Facet %s', facetKey);\n router.get(`/${facetKey}`, this.wrapAsync(this.getAllFacet));\n registeredAllFacets.add(facetKey);\n }\n });\n }\n\n const itemRouter = Router();\n itemRouter.get('/', this.wrapAsync(this.getItem));\n itemRouter.put('/', this.wrapAsync(this.updateItem));\n itemRouter.delete('/', this.wrapAsync(this.deleteItem));\n\n // Configure router-level item actions first (highest precedence)\n this.logger.default('Router Item Actions', { itemActions: this.options.actions });\n if (this.options.actions) {\n Object.keys(this.options.actions).forEach((actionKey) => {\n this.logger.debug('Configuring Router Item Action %s', actionKey);\n itemRouter.post(`/${actionKey}`, this.wrapAsync(this.postItemAction));\n registeredItemActions.add(actionKey);\n });\n }\n\n // Configure library item actions, warn on conflicts\n this.logger.default('Library Item Actions', { itemActions: libOptions.actions });\n if (libOptions.actions) {\n Object.keys(libOptions.actions).forEach((actionKey) => {\n if (registeredItemActions.has(actionKey)) {\n this.logger.warning('Item Action name collision - router-level handler takes precedence', { actionKey });\n } else {\n this.logger.debug('Configuring Library Item Action %s', actionKey);\n itemRouter.post(`/${actionKey}`, this.wrapAsync(this.postItemAction));\n registeredItemActions.add(actionKey);\n }\n });\n }\n\n // Configure router-level item facets first (highest precedence)\n this.logger.default('Router Item Facets', { itemFacets: this.options.facets });\n if (this.options.facets) {\n Object.keys(this.options.facets).forEach((facetKey) => {\n this.logger.debug('Configuring Router Item Facet %s', facetKey);\n itemRouter.get(`/${facetKey}`, this.wrapAsync(this.getItemFacet));\n registeredItemFacets.add(facetKey);\n });\n }\n\n // Configure library item facets, warn on conflicts\n this.logger.default('Library Item Facets', { itemFacets: libOptions.facets });\n if (libOptions.facets) {\n Object.keys(libOptions.facets).forEach((facetKey) => {\n if (registeredItemFacets.has(facetKey)) {\n this.logger.warning('Item Facet name collision - router-level handler takes precedence', { facetKey });\n } else {\n this.logger.debug('Configuring Library Item Facet %s', facetKey);\n itemRouter.get(`/${facetKey}`, this.wrapAsync(this.getItemFacet));\n registeredItemFacets.add(facetKey);\n }\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\n // Apply error handler as last middleware\n router.use(this.errorHandler);\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(400).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\n try {\n const removedItem = await libOperations.remove(ik);\n if (removedItem) {\n const item = validatePK(removedItem, this.getPkType());\n res.json(item);\n } else {\n res.status(204).send();\n }\n } catch (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in deleteItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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\n try {\n const fetchedItem = await libOperations.get(ik);\n if (!fetchedItem) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: `${this.keyType} not found`,\n operation: {\n type: 'get',\n name: 'get',\n params: { key: ik }\n },\n context: {\n itemType: this.keyType\n },\n details: { retryable: false },\n technical: {\n timestamp: new Date().toISOString()\n }\n });\n }\n\n const item = validatePK(fetchedItem, this.getPkType());\n res.json(item);\n } catch (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in getItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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\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 (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.includes('Update Failed') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in updateItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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 this.logger.debug('Converting Dates', { item });\n const events = item.events as Record<string, ItemEvent> | undefined;\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 Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n} from \"@fjell/types\";\nimport {\n ActionError,\n cPK,\n} from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { NextFunction, Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\nimport { createErrorHandler, ErrorHandlerOptions } from \"./errorHandler.js\";\n\n/**\n * Extract serializable error details from Error objects\n *\n * Error objects have non-enumerable properties that don't serialize to JSON.\n * This function explicitly extracts all meaningful details into a plain object.\n */\nfunction extractErrorDetails(error: any): Record<string, any> {\n if (!error) {\n return { type: 'unknown_error' };\n }\n\n const details: Record<string, any> = {};\n\n // Standard JavaScript Error properties\n if (typeof error.message === 'string') {\n details.message = error.message;\n }\n if (typeof error.name === 'string') {\n details.name = error.name;\n }\n if (typeof error.code === 'string' || typeof error.code === 'number') {\n details.code = error.code;\n }\n if (typeof error.stack === 'string') {\n details.stack = error.stack;\n }\n\n // Database-specific error properties (PostgreSQL/Sequelize)\n if (typeof error.constraint === 'string') {\n details.constraint = error.constraint;\n }\n if (typeof error.detail === 'string') {\n details.detail = error.detail;\n }\n if (typeof error.table === 'string') {\n details.table = error.table;\n }\n if (typeof error.column === 'string') {\n details.column = error.column;\n }\n\n // Sequelize validation errors\n if (error.errors && Array.isArray(error.errors)) {\n details.validationErrors = error.errors.map((e: any) => {\n const errorDetail: any = {\n message: e.message,\n type: e.type,\n path: e.path\n };\n if (e.value !== null && e.value !== void 0) {\n errorDetail.value = String(e.value).substring(0, 100);\n }\n return errorDetail;\n });\n }\n\n // HTTP status\n if (typeof error.status === 'number') {\n details.status = error.status;\n }\n if (typeof error.statusCode === 'number') {\n details.statusCode = error.statusCode;\n }\n\n return details;\n}\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 /**\n * Error handler configuration\n */\n errorHandler?: ErrorHandlerOptions;\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 protected parentRoute?: ItemRouter<L1, L2, L3, L4, L5, never>;\n protected errorHandler: (err: any, req: Request, res: Response, next: NextFunction) => void;\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 parentRoute?: ItemRouter<L1, L2, L3, L4, L5, never>\n ) {\n this.lib = lib;\n this.keyType = keyType;\n this.options = options;\n this.parentRoute = parentRoute;\n this.logger = LibLogger.get(\"ItemRouter\", keyType);\n this.errorHandler = createErrorHandler(options.errorHandler);\n }\n\n /**\n * Wrap async route handlers to catch errors and pass to error handler\n */\n protected wrapAsync(fn: (req: Request, res: Response, next: NextFunction) => Promise<any>) {\n return (req: Request, res: Response, next: NextFunction) => {\n Promise.resolve(fn.call(this, req, res, next)).catch(next);\n };\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 const pkParam = this.getPkParam();\n const lkValue = res.locals[pkParam];\n this.logger.debug('Getting location key', {\n keyType: this.keyType,\n pkParam: pkParam,\n lkValue: lkValue,\n allLocals: res.locals\n });\n return { kt: this.keyType, lk: lkValue };\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 protected getLocations(res: Response): LocKeyArray<L1, L2, L3, L4, L5> | [] {\n return this.parentRoute ? this.parentRoute.getLKA(res) as LocKeyArray<L1, L2, L3, L4, L5> : [];\n }\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 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 try {\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 const result = await this.options.allActions[allActionKey](\n req.body as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLocations(res),\n { req, res }\n );\n if (result != null) {\n res.json(result);\n } else {\n res.status(204).send();\n }\n return;\n }\n\n // Check if allAction operation exists\n if (!libOperations.allAction) {\n res.status(500).json({ error: 'All Actions are not configured' });\n return;\n }\n\n // Fallback to library handler\n const result = await libOperations.allAction(allActionKey, req.body, this.getLocations(res));\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in postAllAction', extractErrorDetails(error));\n // Check if it's a validation error or action not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'All Action is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected getAllFacet = async (req: Request, res: Response) => {\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 try {\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 const result = await this.options.allFacets[facetKey](\n req.query as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n this.getLocations(res),\n { req, res }\n );\n if (result != null) {\n res.json(result);\n } else {\n res.status(204).send();\n }\n return;\n }\n\n // Check if allFacet operation exists\n if (!libOperations.allFacet) {\n res.status(500).json({ error: 'All Facets are not configured' });\n return;\n }\n\n // Fallback to library handler\n const combinedQueryParams = { ...(req.query || {}), ...(req.params || {}) } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n const result = await libOperations.allFacet(facetKey, combinedQueryParams, this.getLocations(res));\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in getAllFacet', extractErrorDetails(error));\n // Check if it's a validation error or facet not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'All Facet is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected postItemAction = async (req: Request, res: Response) => {\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 try {\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 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) {\n res.json(result);\n } else {\n res.status(204).send();\n }\n return;\n }\n\n // Check if actions operation exists\n if (!libOperations.action) {\n res.status(500).json({ error: 'Item Actions are not configured' });\n return;\n }\n\n // Fallback to library handler\n const result = await libOperations.action(ik, actionKey, req.body);\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in postItemAction', extractErrorDetails(error));\n // Check if it's a validation error or action not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'Item Action is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n protected getItemFacet = async (req: Request, res: Response) => {\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 try {\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 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) {\n res.json(result);\n } else {\n res.status(204).send();\n }\n return;\n }\n\n // Check if facets operation exists\n if (!libOperations.facet) {\n res.status(500).json({ error: 'Item Facets are not configured' });\n return;\n }\n\n // Fallback to library handler\n const combinedQueryParams = { ...(req.query || {}), ...(req.params || {}) } as Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>;\n const result = await libOperations.facet(ik, facetKey, combinedQueryParams);\n res.json(result);\n } catch (error: any) {\n this.logger.error('Error in getItemFacet', extractErrorDetails(error));\n // Check if it's a validation error or facet not found error\n if ((error.name === 'ValidationError' || error.message?.includes('not found')) && error.message) {\n res.status(500).json({ error: 'Item Facet is not configured' });\n } else {\n res.status(500).json(error);\n }\n }\n }\n\n private configure = (router: Router) => {\n if (!this.lib) {\n this.logger.error('Library is undefined in configure');\n throw new Error('Library is required for router configuration');\n }\n // Ensure options exists - library should have options but handle case where it doesn't\n const libOptions = (this.lib as any).options || {};\n this.logger.debug('Configuring Router', { pkType: this.getPkType(), hasOptions: !!libOptions });\n router.get('/', this.wrapAsync(this.findItems));\n router.post('/', this.wrapAsync(this.createItem));\n\n // Track registered routes to detect collisions\n const registeredAllActions = new Set<string>();\n const registeredAllFacets = new Set<string>();\n const registeredItemActions = new Set<string>();\n const registeredItemFacets = new Set<string>();\n\n // Configure router-level allActions first (highest precedence)\n this.logger.default('Router All Actions', { allActions: this.options.allActions });\n if (this.options.allActions) {\n Object.keys(this.options.allActions).forEach((actionKey) => {\n this.logger.debug('Configuring Router All Action %s', actionKey);\n router.post(`/${actionKey}`, this.wrapAsync(this.postAllAction));\n registeredAllActions.add(actionKey);\n });\n }\n\n // Configure library allActions, warn on conflicts\n this.logger.default('Library All Actions', { allActions: libOptions.allActions });\n if (libOptions.allActions) {\n Object.keys(libOptions.allActions).forEach((actionKey) => {\n if (registeredAllActions.has(actionKey)) {\n this.logger.warning('All Action name collision - router-level handler takes precedence', { actionKey });\n } else {\n this.logger.debug('Configuring Library All Action %s', actionKey);\n router.post(`/${actionKey}`, this.wrapAsync(this.postAllAction));\n registeredAllActions.add(actionKey);\n }\n });\n }\n\n // Configure router-level allFacets first (highest precedence)\n this.logger.default('Router All Facets', { allFacets: this.options.allFacets });\n if (this.options.allFacets) {\n Object.keys(this.options.allFacets).forEach((facetKey) => {\n this.logger.debug('Configuring Router All Facet %s', facetKey);\n router.get(`/${facetKey}`, this.wrapAsync(this.getAllFacet));\n registeredAllFacets.add(facetKey);\n });\n }\n\n // Configure library allFacets, warn on conflicts\n this.logger.default('Library All Facets', { allFacets: libOptions.allFacets });\n if (libOptions.allFacets) {\n Object.keys(libOptions.allFacets).forEach((facetKey) => {\n if (registeredAllFacets.has(facetKey)) {\n this.logger.warning('All Facet name collision - router-level handler takes precedence', { facetKey });\n } else {\n this.logger.debug('Configuring Library All Facet %s', facetKey);\n router.get(`/${facetKey}`, this.wrapAsync(this.getAllFacet));\n registeredAllFacets.add(facetKey);\n }\n });\n }\n\n const itemRouter = Router();\n itemRouter.get('/', this.wrapAsync(this.getItem));\n itemRouter.put('/', this.wrapAsync(this.updateItem));\n itemRouter.delete('/', this.wrapAsync(this.deleteItem));\n\n // Configure router-level item actions first (highest precedence)\n this.logger.default('Router Item Actions', { itemActions: this.options.actions });\n if (this.options.actions) {\n Object.keys(this.options.actions).forEach((actionKey) => {\n this.logger.debug('Configuring Router Item Action %s', actionKey);\n itemRouter.post(`/${actionKey}`, this.wrapAsync(this.postItemAction));\n registeredItemActions.add(actionKey);\n });\n }\n\n // Configure library item actions, warn on conflicts\n this.logger.default('Library Item Actions', { itemActions: libOptions.actions });\n if (libOptions.actions) {\n Object.keys(libOptions.actions).forEach((actionKey) => {\n if (registeredItemActions.has(actionKey)) {\n this.logger.warning('Item Action name collision - router-level handler takes precedence', { actionKey });\n } else {\n this.logger.debug('Configuring Library Item Action %s', actionKey);\n itemRouter.post(`/${actionKey}`, this.wrapAsync(this.postItemAction));\n registeredItemActions.add(actionKey);\n }\n });\n }\n\n // Configure router-level item facets first (highest precedence)\n this.logger.default('Router Item Facets', { itemFacets: this.options.facets });\n if (this.options.facets) {\n Object.keys(this.options.facets).forEach((facetKey) => {\n this.logger.debug('Configuring Router Item Facet %s', facetKey);\n itemRouter.get(`/${facetKey}`, this.wrapAsync(this.getItemFacet));\n registeredItemFacets.add(facetKey);\n });\n }\n\n // Configure library item facets, warn on conflicts\n this.logger.default('Library Item Facets', { itemFacets: libOptions.facets });\n if (libOptions.facets) {\n Object.keys(libOptions.facets).forEach((facetKey) => {\n if (registeredItemFacets.has(facetKey)) {\n this.logger.warning('Item Facet name collision - router-level handler takes precedence', { facetKey });\n } else {\n this.logger.debug('Configuring Library Item Facet %s', facetKey);\n itemRouter.get(`/${facetKey}`, this.wrapAsync(this.getItemFacet));\n registeredItemFacets.add(facetKey);\n }\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\n // Apply error handler as last middleware\n router.use(this.errorHandler);\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(400).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\n try {\n const removedItem = await libOperations.remove(ik);\n if (removedItem) {\n const item = validatePK(removedItem, this.getPkType());\n res.json(item);\n } else {\n res.status(204).send();\n }\n } catch (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in deleteItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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\n try {\n const fetchedItem = await libOperations.get(ik);\n if (!fetchedItem) {\n throw new ActionError({\n code: 'NOT_FOUND',\n message: `${this.keyType} not found`,\n operation: {\n type: 'get',\n name: 'get',\n params: { key: ik }\n },\n context: {\n itemType: this.keyType\n },\n details: { retryable: false },\n technical: {\n timestamp: new Date().toISOString()\n }\n });\n }\n\n const item = validatePK(fetchedItem, this.getPkType());\n res.json(item);\n } catch (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in getItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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\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 (error: any) {\n // Check for NotFoundError from various packages\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n const isNotFound =\n error instanceof NotFoundError ||\n originalError instanceof NotFoundError ||\n error?.name === 'NotFoundError' ||\n originalError?.name === 'NotFoundError' ||\n error?.errorInfo?.code === 'NOT_FOUND' ||\n originalError?.errorInfo?.code === 'NOT_FOUND' ||\n (error?.message && (\n error.message.includes('not found') ||\n error.message.includes('Cannot remove') ||\n error.message.includes('Cannot update') ||\n error.message.includes('Update Failed') ||\n error.message.toLowerCase().includes('not found')\n )) ||\n (originalError?.message && (\n originalError.message.includes('not found') ||\n originalError.message.includes('Cannot remove') ||\n originalError.message.includes('Cannot update') ||\n originalError.message.toLowerCase().includes('not found')\n ));\n\n if (isNotFound) {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in updateItem', extractErrorDetails(error));\n res.status(500).json({ ik, message: \"General Error\" });\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 this.logger.debug('Converting Dates', { item });\n const events = item.events as Record<string, ItemEvent> | undefined;\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": ["result"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,IAAI,EAAa,MAAM,EAAe,MAAM,cAAc,CAAC;AAGlH,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,mBA4EhE;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAyMtD;CAEH"}
1
+ {"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,IAAI,EAAa,MAAM,EAAe,MAAM,cAAc,CAAC;AAGlH,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,mBA4EhE;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAsNtD;CAEH"}
@@ -53,6 +53,16 @@ class PItemRouter extends ItemRouter {
53
53
  const libOperations = this.lib.operations;
54
54
  this.logger.default("Finding Items", { query: req.query, params: req.params, locals: res.locals });
55
55
  try {
56
+ const parsePaginationParam = (value) => {
57
+ if (typeof value !== "string" || value.trim().length === 0) {
58
+ return void 0;
59
+ }
60
+ const parsed = parseInt(value, 10);
61
+ if (Number.isNaN(parsed) || parsed < 0) {
62
+ return void 0;
63
+ }
64
+ return parsed;
65
+ };
56
66
  const query = req.query;
57
67
  const finder = query["finder"];
58
68
  const finderParams = query["finderParams"];
@@ -70,8 +80,8 @@ class PItemRouter extends ItemRouter {
70
80
  return;
71
81
  }
72
82
  const findOptions = req.query.limit || req.query.offset ? {
73
- ...req.query.limit && { limit: parseInt(req.query.limit, 10) },
74
- ...req.query.offset && { offset: parseInt(req.query.offset, 10) }
83
+ ...parsePaginationParam(req.query.limit) !== void 0 && { limit: parsePaginationParam(req.query.limit) },
84
+ ...parsePaginationParam(req.query.offset) !== void 0 && { offset: parsePaginationParam(req.query.offset) }
75
85
  } : void 0;
76
86
  if (one === "true") {
77
87
  const item = await this.lib.findOne(finder, parsedParams);
@@ -133,11 +143,13 @@ class PItemRouter extends ItemRouter {
133
143
  const itemQuery = paramsToQuery(req.query);
134
144
  this.logger.default("Finding Items with a query %j", itemQuery);
135
145
  const allOptions = {};
136
- if (req.query.limit) {
137
- allOptions.limit = parseInt(req.query.limit, 10);
146
+ const parsedLimit = parsePaginationParam(req.query.limit);
147
+ if (parsedLimit !== void 0) {
148
+ allOptions.limit = parsedLimit;
138
149
  }
139
- if (req.query.offset) {
140
- allOptions.offset = parseInt(req.query.offset, 10);
150
+ const parsedOffset = parsePaginationParam(req.query.offset);
151
+ if (parsedOffset !== void 0) {
152
+ allOptions.offset = parsedOffset;
141
153
  }
142
154
  const result = await libOperations.all(itemQuery, [], allOptions);
143
155
  const validatedItems = result.items.map((item) => validatePK(item, this.getPkType()));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/PItemRouter.ts"],
4
- "sourcesContent": ["import { AllOptions, FindOperationResult, FindOptions, Item, ItemQuery, PriKey, QueryParams } from \"@fjell/types\";\nimport { paramsToQuery } from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\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 structured error details for agentic debugging\n this.logger.error('Error in createItem endpoint', {\n component: 'PItemRouter',\n operation: 'createItem',\n endpoint: req.path,\n method: req.method,\n itemType: this.getPkType(),\n requestBody: JSON.stringify(req.body),\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n errorCode: error?.errorInfo?.code || error?.code,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n originalErrorCode: originalError?.errorInfo?.code || originalError?.code,\n validationErrors: error?.errorInfo?.details?.fieldErrors || originalError?.errorInfo?.details?.fieldErrors,\n suggestion: 'Check request body validation, required fields, unique constraints, and data types',\n stack: error?.stack\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 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\n let result: FindOperationResult<Item<S>>;\n try {\n result = await libOperations.find(finder, parsedParams, [], findOptions);\n } catch (findError: any) {\n console.error('=== ERROR IN libOperations.find ===');\n console.error('Error:', findError);\n console.error('Error Message:', findError?.message);\n console.error('Error Stack:', findError?.stack);\n this.logger.error('Error calling libOperations.find', {\n finder,\n parsedParams,\n findOptions,\n errorMessage: findError?.message,\n errorName: findError?.name,\n errorStack: findError?.stack,\n errorCause: findError?.cause\n });\n throw findError;\n }\n\n let validatedItems: Item<S>[];\n try {\n validatedItems = validatePK(result.items, this.getPkType()) as Item<S>[];\n } catch (validationError: any) {\n console.error('=== ERROR IN VALIDATION ===');\n console.error('Validation Error:', validationError);\n console.error('Error Message:', validationError?.message);\n console.error('Error Stack:', validationError?.stack);\n this.logger.error('Error validating items from find result', {\n finder,\n itemCount: result.items?.length,\n firstItem: result.items?.[0],\n errorMessage: validationError?.message,\n errorName: validationError?.name,\n errorStack: validationError?.stack\n });\n throw validationError;\n }\n\n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\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 // Enhanced error logging to capture the actual error details\n const originalError = error?.cause || error;\n const errorMessage = error?.message || originalError?.message || String(error) || 'Internal server error';\n // Extract all error properties that can be serialized\n const errorProps: Record<string, any> = {};\n if (error) {\n Object.getOwnPropertyNames(error).forEach(key => {\n try {\n const value = (error as any)[key];\n // Only include serializable values\n if (typeof value !== 'function' && typeof value !== 'object') {\n errorProps[key] = value;\n } else if (key === 'stack' || key === 'message' || key === 'cause') {\n errorProps[key] = value;\n }\n } catch {\n // Skip properties that can't be accessed\n }\n });\n }\n\n const errorDetails = {\n errorMessage,\n errorName: error?.name || originalError?.name,\n errorCode: error?.code || originalError?.code,\n errorStack: error?.stack || originalError?.stack,\n errorString: String(error),\n errorType: error?.constructor?.name,\n errorProps,\n errorCause: error?.cause ? {\n message: error.cause?.message,\n name: error.cause?.name,\n stack: error.cause?.stack\n } : void 0,\n finder: (req.query as any)?.finder,\n finderParams: (req.query as any)?.finderParams,\n requestPath: req.path,\n requestMethod: req.method\n };\n\n // Log with multiple levels to ensure we see it\n // Serialize error properly - errors don't serialize well, so log each property separately\n console.error('=== ERROR IN findItems ===');\n console.error('Error object:', error);\n console.error('Error message:', errorMessage);\n console.error('Error name:', error?.name);\n console.error('Error code:', error?.code);\n console.error('Error stack:', error?.stack);\n console.error('Error cause:', error?.cause);\n console.error('Error string:', String(error));\n console.error('Full error details:', JSON.stringify(errorDetails, null, 2));\n console.error('=== END ERROR ===\\n\\n');\n\n // Log to structured logger with serializable data only (don't pass errorDetails directly)\n this.logger.error('Error in findItems', {\n errorMessage,\n errorName: errorDetails.errorName,\n errorCode: errorDetails.errorCode,\n errorStack: errorDetails.errorStack,\n errorType: errorDetails.errorType,\n errorProps: errorDetails.errorProps,\n errorCause: errorDetails.errorCause,\n finder: errorDetails.finder,\n finderParams: errorDetails.finderParams,\n requestPath: errorDetails.requestPath,\n requestMethod: errorDetails.requestMethod\n });\n\n if (error instanceof NotFoundError || error?.name === 'NotFoundError') {\n res.status(404).json({ error: errorMessage });\n } else {\n // Include more details in development, but keep it generic in production\n const isDevelopment = process.env.NODE_ENV === 'development';\n res.status(500).json({\n error: errorMessage,\n ...(isDevelopment && {\n details: errorDetails.errorName,\n stack: errorDetails.errorStack\n })\n });\n }\n }\n };\n\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { AllOptions, FindOperationResult, FindOptions, Item, ItemQuery, PriKey, QueryParams } from \"@fjell/types\";\nimport { paramsToQuery } from \"@fjell/core\";\nimport { validatePK } from \"@fjell/validation\";\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 structured error details for agentic debugging\n this.logger.error('Error in createItem endpoint', {\n component: 'PItemRouter',\n operation: 'createItem',\n endpoint: req.path,\n method: req.method,\n itemType: this.getPkType(),\n requestBody: JSON.stringify(req.body),\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n errorCode: error?.errorInfo?.code || error?.code,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n originalErrorCode: originalError?.errorInfo?.code || originalError?.code,\n validationErrors: error?.errorInfo?.details?.fieldErrors || originalError?.errorInfo?.details?.fieldErrors,\n suggestion: 'Check request body validation, required fields, unique constraints, and data types',\n stack: error?.stack\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 parsePaginationParam = (value: unknown): number | undefined => {\n if (typeof value !== 'string' || value.trim().length === 0) {\n return void 0;\n }\n const parsed = parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed < 0) {\n return void 0;\n }\n return parsed;\n };\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 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 ...(parsePaginationParam(req.query.limit) !== void 0 && { limit: parsePaginationParam(req.query.limit) }),\n ...(parsePaginationParam(req.query.offset) !== void 0 && { offset: parsePaginationParam(req.query.offset) }),\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\n let result: FindOperationResult<Item<S>>;\n try {\n result = await libOperations.find(finder, parsedParams, [], findOptions);\n } catch (findError: any) {\n console.error('=== ERROR IN libOperations.find ===');\n console.error('Error:', findError);\n console.error('Error Message:', findError?.message);\n console.error('Error Stack:', findError?.stack);\n this.logger.error('Error calling libOperations.find', {\n finder,\n parsedParams,\n findOptions,\n errorMessage: findError?.message,\n errorName: findError?.name,\n errorStack: findError?.stack,\n errorCause: findError?.cause\n });\n throw findError;\n }\n\n let validatedItems: Item<S>[];\n try {\n validatedItems = validatePK(result.items, this.getPkType()) as Item<S>[];\n } catch (validationError: any) {\n console.error('=== ERROR IN VALIDATION ===');\n console.error('Validation Error:', validationError);\n console.error('Error Message:', validationError?.message);\n console.error('Error Stack:', validationError?.stack);\n this.logger.error('Error validating items from find result', {\n finder,\n itemCount: result.items?.length,\n firstItem: result.items?.[0],\n errorMessage: validationError?.message,\n errorName: validationError?.name,\n errorStack: validationError?.stack\n });\n throw validationError;\n }\n\n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\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 const parsedLimit = parsePaginationParam(req.query.limit);\n if (parsedLimit !== void 0) {\n allOptions.limit = parsedLimit;\n }\n const parsedOffset = parsePaginationParam(req.query.offset);\n if (parsedOffset !== void 0) {\n allOptions.offset = parsedOffset;\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 // Enhanced error logging to capture the actual error details\n const originalError = error?.cause || error;\n const errorMessage = error?.message || originalError?.message || String(error) || 'Internal server error';\n // Extract all error properties that can be serialized\n const errorProps: Record<string, any> = {};\n if (error) {\n Object.getOwnPropertyNames(error).forEach(key => {\n try {\n const value = (error as any)[key];\n // Only include serializable values\n if (typeof value !== 'function' && typeof value !== 'object') {\n errorProps[key] = value;\n } else if (key === 'stack' || key === 'message' || key === 'cause') {\n errorProps[key] = value;\n }\n } catch {\n // Skip properties that can't be accessed\n }\n });\n }\n\n const errorDetails = {\n errorMessage,\n errorName: error?.name || originalError?.name,\n errorCode: error?.code || originalError?.code,\n errorStack: error?.stack || originalError?.stack,\n errorString: String(error),\n errorType: error?.constructor?.name,\n errorProps,\n errorCause: error?.cause ? {\n message: error.cause?.message,\n name: error.cause?.name,\n stack: error.cause?.stack\n } : void 0,\n finder: (req.query as any)?.finder,\n finderParams: (req.query as any)?.finderParams,\n requestPath: req.path,\n requestMethod: req.method\n };\n\n // Log with multiple levels to ensure we see it\n // Serialize error properly - errors don't serialize well, so log each property separately\n console.error('=== ERROR IN findItems ===');\n console.error('Error object:', error);\n console.error('Error message:', errorMessage);\n console.error('Error name:', error?.name);\n console.error('Error code:', error?.code);\n console.error('Error stack:', error?.stack);\n console.error('Error cause:', error?.cause);\n console.error('Error string:', String(error));\n console.error('Full error details:', JSON.stringify(errorDetails, null, 2));\n console.error('=== END ERROR ===\\n\\n');\n\n // Log to structured logger with serializable data only (don't pass errorDetails directly)\n this.logger.error('Error in findItems', {\n errorMessage,\n errorName: errorDetails.errorName,\n errorCode: errorDetails.errorCode,\n errorStack: errorDetails.errorStack,\n errorType: errorDetails.errorType,\n errorProps: errorDetails.errorProps,\n errorCause: errorDetails.errorCause,\n finder: errorDetails.finder,\n finderParams: errorDetails.finderParams,\n requestPath: errorDetails.requestPath,\n requestMethod: errorDetails.requestMethod\n });\n\n if (error instanceof NotFoundError || error?.name === 'NotFoundError') {\n res.status(404).json({ error: errorMessage });\n } else {\n // Include more details in development, but keep it generic in production\n const isDevelopment = process.env.NODE_ENV === 'development';\n res.status(500).json({\n error: errorMessage,\n ...(isDevelopment && {\n details: errorDetails.errorName,\n stack: errorDetails.errorStack\n })\n });\n }\n }\n };\n\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/guide/index.md ADDED
@@ -0,0 +1,30 @@
1
+ # @fjell/express-router - Agentic Guide
2
+
3
+ ## Purpose
4
+
5
+ Express routing layer for exposing Fjell operations over HTTP.
6
+
7
+ This guide is optimized for AI-assisted code generation and integration workflows.
8
+
9
+ ## Documentation
10
+
11
+ - **[Usage Guide](./usage.md)** - API-oriented usage patterns and model-safe examples
12
+ - **[Integration Guide](./integration.md)** - Architecture placement, composition rules, and implementation guidance
13
+
14
+ ## Key Capabilities
15
+
16
+ - Provides routers for generic, primary, and contained item APIs
17
+ - Includes standard error handler and app creation helpers
18
+ - Bridges library operations to HTTP endpoints with typed contracts
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @fjell/express-router
24
+ ```
25
+
26
+ ## Public API Highlights
27
+
28
+ - `ItemRouter`, `PItemRouter`, and `CItemRouter` exports
29
+ - `createApp`, `errorHandler`, and route types
30
+ - Instance and registry helpers for composing route dependencies
@@ -0,0 +1,32 @@
1
+ # Integration Guide
2
+
3
+ Guide for integrating `@fjell/express-router` into larger Fjell-based systems.
4
+
5
+ ## Where It Fits
6
+
7
+ Express routing layer for exposing Fjell operations over HTTP.
8
+
9
+ ## Recommended Integration Pattern
10
+
11
+ - Keep router-layer validation and auth explicit before invoking operations
12
+ - Use shared Fjell HTTP error mapping so client and server semantics stay aligned
13
+ - Register routers with dependency-injected operations for testability
14
+
15
+ ## System Composition Checklist
16
+
17
+ - Define package boundaries: schema/types, transport, operations, adapters, and UI.
18
+ - Keep contracts stable by sharing @fjell/types interfaces where applicable.
19
+ - Centralize retries/timeouts/logging around infrastructure-facing operations.
20
+ - Validate inputs at API boundaries before invoking persistence or provider layers.
21
+ - Add contract and integration tests for every generated workflow.
22
+
23
+ ## Cross-Library Pairings
24
+
25
+ - Pair with @fjell/types for shared contracts.
26
+ - Pair with @fjell/validation for input and schema checks.
27
+ - Pair with @fjell/logging for observability in integration flows.
28
+ - Pair with storage/router/provider packages based on your runtime architecture.
29
+
30
+ ## Integration Example Shape
31
+
32
+ Use this package behind an application service layer that exposes stable domain methods. Generated code should call those service methods, not raw infrastructure primitives, unless your architecture intentionally keeps infrastructure at the edge.
package/guide/usage.md ADDED
@@ -0,0 +1,41 @@
1
+ # Usage Guide
2
+
3
+ Comprehensive usage guidance for `@fjell/express-router`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @fjell/express-router
9
+ ```
10
+
11
+ ## API Highlights
12
+
13
+ - `ItemRouter`, `PItemRouter`, and `CItemRouter` exports
14
+ - `createApp`, `errorHandler`, and route types
15
+ - Instance and registry helpers for composing route dependencies
16
+
17
+ ## Quick Example
18
+
19
+ ```ts
20
+ import { createApp, PItemRouter, errorHandler } from "@fjell/express-router";
21
+
22
+ const app = createApp();
23
+ app.use("/api/widgets", PItemRouter({ operations }));
24
+ app.use(errorHandler());
25
+
26
+ app.listen(3000);
27
+ ```
28
+
29
+ ## Model Consumption Rules
30
+
31
+ 1. Import from the package root (`@fjell/express-router`) instead of deep-internal paths unless explicitly documented.
32
+ 2. Keep usage aligned with exported public symbols listed in this guide.
33
+ 3. Prefer explicit typing at package boundaries so generated code remains robust during upgrades.
34
+ 4. Keep error handling deterministic and map infrastructure failures into domain-level errors.
35
+ 5. Co-locate integration wrappers in your app so model-generated code has one canonical entry point.
36
+
37
+ ## Best Practices
38
+
39
+ - Keep examples and abstractions consistent with existing Fjell package conventions.
40
+ - Favor composable wrappers over one-off inline integration logic.
41
+ - Add targeted tests around generated integration code paths.
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.82",
4
+ "version": "4.4.83",
5
5
  "keywords": [
6
6
  "express",
7
7
  "router",
@@ -34,18 +34,18 @@
34
34
  "docs:test": "cd docs && npm run test"
35
35
  },
36
36
  "dependencies": {
37
- "@fjell/core": "^4.4.77",
38
- "@fjell/lib": "^4.4.88",
39
- "@fjell/logging": "^4.4.67",
40
- "@fjell/registry": "^4.4.84",
41
- "@fjell/validation": "^4.4.4",
37
+ "@fjell/core": "^4.4.79",
38
+ "@fjell/lib": "^4.4.89",
39
+ "@fjell/logging": "^4.4.72",
40
+ "@fjell/registry": "^4.4.86",
41
+ "@fjell/validation": "^4.4.6",
42
42
  "deepmerge": "^4.3.1",
43
43
  "express": "^5.1.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@eslint/eslintrc": "^3.3.1",
47
47
  "@eslint/js": "^9.38.0",
48
- "@fjell/common-config": "^1.1.37",
48
+ "@fjell/common-config": "^1.1.38",
49
49
  "@tsconfig/recommended": "^1.0.10",
50
50
  "@types/express": "^5.0.3",
51
51
  "@types/node": "^24.9.1",