@fjell/express-router 4.4.74 → 4.4.76
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/dist/PItemRouter.d.ts.map +1 -1
- package/dist/PItemRouter.js +0 -24
- package/dist/PItemRouter.js.map +2 -2
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC5I,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAMpD,qBAAa,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;gBAErE,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAE,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAM;IAI1G,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAM/B,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,OAAO,GAAG,mBAmEhE;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"PItemRouter.d.ts","sourceRoot":"","sources":["../src/PItemRouter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,IAAI,EAA4B,MAAM,EAA2B,MAAM,aAAa,CAAC;AAC5I,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAiB,MAAM,YAAY,CAAC;AAMpD,qBAAa,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;gBAErE,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAE,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAM;IAI1G,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC;IAM/B,UAAU,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,OAAO,GAAG,mBAmEhE;IAEF,SAAS,CAAC,SAAS,GAAU,KAAK,OAAO,EAAE,KAAK,QAAQ,mBAyMtD;CAEH"}
|
package/dist/PItemRouter.js
CHANGED
|
@@ -40,10 +40,6 @@ class PItemRouter extends ItemRouter {
|
|
|
40
40
|
}
|
|
41
41
|
};
|
|
42
42
|
findItems = async (req, res) => {
|
|
43
|
-
console.log("=== FIND ITEMS CALLED ===");
|
|
44
|
-
console.log("Query:", JSON.stringify(req.query));
|
|
45
|
-
console.log("Path:", req.path);
|
|
46
|
-
console.log("Method:", req.method);
|
|
47
43
|
const libOperations = this.lib.operations;
|
|
48
44
|
this.logger.default("Finding Items", { query: req.query, params: req.params, locals: res.locals });
|
|
49
45
|
try {
|
|
@@ -52,10 +48,6 @@ class PItemRouter extends ItemRouter {
|
|
|
52
48
|
const finderParams = query["finderParams"];
|
|
53
49
|
const one = query["one"];
|
|
54
50
|
if (finder) {
|
|
55
|
-
console.log("=== FINDER REQUEST ===");
|
|
56
|
-
console.log("Finder:", finder);
|
|
57
|
-
console.log("Finder Params:", finderParams);
|
|
58
|
-
console.log("One:", one);
|
|
59
51
|
this.logger.default("Finding Items with Finder %s %j one:%s", finder, finderParams, one);
|
|
60
52
|
let parsedParams;
|
|
61
53
|
try {
|
|
@@ -85,18 +77,9 @@ class PItemRouter extends ItemRouter {
|
|
|
85
77
|
};
|
|
86
78
|
res.json(result);
|
|
87
79
|
} else {
|
|
88
|
-
console.log("=== CALLING libOperations.find ===");
|
|
89
|
-
console.log("Finder:", finder);
|
|
90
|
-
console.log("Parsed Params:", JSON.stringify(parsedParams));
|
|
91
|
-
console.log("Find Options:", JSON.stringify(findOptions));
|
|
92
80
|
let result;
|
|
93
81
|
try {
|
|
94
|
-
console.log("About to call libOperations.find...");
|
|
95
82
|
result = await libOperations.find(finder, parsedParams, [], findOptions);
|
|
96
|
-
console.log("libOperations.find SUCCESS - got result:", {
|
|
97
|
-
itemCount: result?.items?.length,
|
|
98
|
-
total: result?.metadata?.total
|
|
99
|
-
});
|
|
100
83
|
} catch (findError) {
|
|
101
84
|
console.error("=== ERROR IN libOperations.find ===");
|
|
102
85
|
console.error("Error:", findError);
|
|
@@ -113,12 +96,9 @@ class PItemRouter extends ItemRouter {
|
|
|
113
96
|
});
|
|
114
97
|
throw findError;
|
|
115
98
|
}
|
|
116
|
-
console.log("=== VALIDATING ITEMS ===");
|
|
117
|
-
console.log("Item count:", result.items?.length);
|
|
118
99
|
let validatedItems;
|
|
119
100
|
try {
|
|
120
101
|
validatedItems = validatePK(result.items, this.getPkType());
|
|
121
|
-
console.log("Validation SUCCESS - validated items:", validatedItems.length);
|
|
122
102
|
} catch (validationError) {
|
|
123
103
|
console.error("=== ERROR IN VALIDATION ===");
|
|
124
104
|
console.error("Validation Error:", validationError);
|
|
@@ -134,14 +114,10 @@ class PItemRouter extends ItemRouter {
|
|
|
134
114
|
});
|
|
135
115
|
throw validationError;
|
|
136
116
|
}
|
|
137
|
-
console.log("=== SENDING RESPONSE ===");
|
|
138
|
-
console.log("Items:", validatedItems.length);
|
|
139
|
-
console.log("Metadata:", JSON.stringify(result.metadata));
|
|
140
117
|
res.json({
|
|
141
118
|
items: validatedItems,
|
|
142
119
|
metadata: result.metadata
|
|
143
120
|
});
|
|
144
|
-
console.log("=== RESPONSE SENT ===");
|
|
145
121
|
}
|
|
146
122
|
} else {
|
|
147
123
|
const itemQuery = paramsToQuery(req.query);
|
package/dist/PItemRouter.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/PItemRouter.ts"],
|
|
4
|
-
"sourcesContent": ["import { AllOptions, FindOperationResult, FindOptions, Item, ItemQuery, paramsToQuery, PriKey, QueryParams, validatePK } from \"@fjell/core\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\n\ninterface ParsedQuery {\n [key: string]: undefined | string | string[] | ParsedQuery | ParsedQuery[];\n}\n\nexport class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {\n\n constructor(lib: Library<T, S>, keyType: S, options: ItemRouterOptions<S, never, never, never, never, never> = {}) {\n super(lib as any, keyType, options);\n }\n\n public getIk(res: Response): PriKey<S> {\n const pri = this.getPk(res) as PriKey<S>;\n return pri\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public createItem = async (req: Request, res: Response, next?: any) => {\n const libOperations = this.lib.operations;\n this.logger.default('Creating Item', { body: req.body, query: req.query, params: req.params, locals: res.locals });\n\n try {\n const itemToCreate = this.convertDates(req.body as Item<S>);\n let item = validatePK(await libOperations.create(itemToCreate), this.getPkType()) as Item<S>;\n item = await this.postCreateItem(item);\n this.logger.default('Created Item %j', item);\n res.status(201).json(item);\n } catch (error: any) {\n // Check for validation errors - check multiple patterns\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n\n // Log error details for debugging\n this.logger.error('Error in createItem', {\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n errorCode: error?.errorInfo?.code,\n originalErrorCode: originalError?.errorInfo?.code\n });\n const isValidationError =\n error.name === 'CreateValidationError' ||\n originalError?.name === 'CreateValidationError' ||\n error.name === 'ValidationError' ||\n originalError?.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n originalError?.name === 'SequelizeValidationError' ||\n error?.errorInfo?.code === 'VALIDATION_ERROR' ||\n originalError?.errorInfo?.code === 'VALIDATION_ERROR' ||\n (error.message && (\n error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation') ||\n error.message.includes('Required field') ||\n error.message.includes('Referenced item does not exist') ||\n error.message.includes('Foreign key constraint') ||\n error.message.includes('Operation failed') ||\n error.message.includes('preCreate') ||\n error.message.includes('preUpdate') ||\n error.message.includes('Create Validation Failed')\n )) ||\n (originalError?.message && (\n originalError.message.includes('validation') ||\n originalError.message.includes('required') ||\n originalError.message.includes('cannot be null') ||\n originalError.message.includes('notNull Violation') ||\n originalError.message.includes('Required field') ||\n originalError.message.includes('Referenced item does not exist') ||\n originalError.message.includes('Foreign key constraint') ||\n originalError.message.includes('preCreate') ||\n originalError.message.includes('preUpdate') ||\n originalError.message.includes('Create Validation Failed')\n ));\n\n if (isValidationError) {\n const errorMessage = originalError?.message || error.message || \"Validation failed\";\n res.status(400).json({ success: false, error: errorMessage });\n } else {\n res.status(500).json({ success: false, error: error.message || \"Internal server error\" });\n }\n }\n };\n\n protected findItems = async (req: Request, res: Response) => {\n console.log('=== FIND ITEMS CALLED ===');\n console.log('Query:', JSON.stringify(req.query));\n console.log('Path:', req.path);\n console.log('Method:', req.method);\n\n const libOperations = this.lib.operations;\n this.logger.default('Finding Items', { query: req.query, params: req.params, locals: res.locals });\n\n try {\n const query: ParsedQuery = req.query as unknown as ParsedQuery;\n const finder = query['finder'] as string;\n const finderParams = query['finderParams'] as string;\n const one = query['one'] as string;\n\n if (finder) {\n // If finder is defined? Call a finder.\n console.log('=== FINDER REQUEST ===');\n console.log('Finder:', finder);\n console.log('Finder Params:', finderParams);\n console.log('One:', one);\n this.logger.default('Finding Items with Finder %s %j one:%s', finder, finderParams, one);\n\n let parsedParams: any;\n try {\n parsedParams = finderParams ? JSON.parse(finderParams) : {};\n } catch (parseError: any) {\n res.status(400).json({\n error: 'Invalid JSON in finderParams',\n message: parseError.message\n });\n return;\n }\n\n // Parse pagination options from query parameters\n const findOptions: FindOptions | undefined =\n (req.query.limit || req.query.offset) ? {\n ...(req.query.limit && { limit: parseInt(req.query.limit as string, 10) }),\n ...(req.query.offset && { offset: parseInt(req.query.offset as string, 10) }),\n } : (void 0);\n\n if (one === 'true') {\n const item = await (this.lib as any).findOne(finder, parsedParams);\n // Wrap findOne result in FindOperationResult format\n const validatedItem = item ? (validatePK(item, this.getPkType()) as Item<S>) : null;\n const result: FindOperationResult<Item<S>> = {\n items: validatedItem ? [validatedItem] : [],\n metadata: {\n total: validatedItem ? 1 : 0,\n returned: validatedItem ? 1 : 0,\n offset: 0,\n hasMore: false\n }\n };\n res.json(result);\n } else {\n // Call find() with pagination options - it returns FindOperationResult\n console.log('=== CALLING libOperations.find ===');\n console.log('Finder:', finder);\n console.log('Parsed Params:', JSON.stringify(parsedParams));\n console.log('Find Options:', JSON.stringify(findOptions));\n\n let result: FindOperationResult<Item<S>>;\n try {\n console.log('About to call libOperations.find...');\n result = await libOperations.find(finder, parsedParams, [], findOptions);\n console.log('libOperations.find SUCCESS - got result:', {\n itemCount: result?.items?.length,\n total: result?.metadata?.total\n });\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 // Validate items - validatePK can handle arrays\n console.log('=== VALIDATING ITEMS ===');\n console.log('Item count:', result.items?.length);\n\n let validatedItems: Item<S>[];\n try {\n validatedItems = validatePK(result.items, this.getPkType()) as Item<S>[];\n console.log('Validation SUCCESS - validated items:', validatedItems.length);\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 console.log('=== SENDING RESPONSE ===');\n console.log('Items:', validatedItems.length);\n console.log('Metadata:', JSON.stringify(result.metadata));\n\n res.json({\n items: validatedItems,\n metadata: result.metadata\n });\n\n console.log('=== RESPONSE SENT ===');\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": "AAAA,SAAwE,eAAoC,kBAAkB;AAE9H,SAAS,kBAAqC;AAC9C,SAAkB,qBAAqB;AAMhC,MAAM,oBAAyD,WAAc;AAAA,EAElF,YAAY,KAAoB,SAAY,UAAmE,CAAC,GAAG;AACjH,UAAM,KAAY,SAAS,OAAO;AAAA,EACpC;AAAA,EAEO,MAAM,KAA0B;AACrC,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,WAAO;AAAA,EACT;AAAA;AAAA,EAGO,aAAa,OAAO,KAAc,KAAe,SAAe;AACrE,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,QAAQ,iBAAiB,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAO,CAAC;AAEjH,QAAI;AACF,YAAM,eAAe,KAAK,aAAa,IAAI,IAAe;AAC1D,UAAI,OAAO,WAAW,MAAM,cAAc,OAAO,YAAY,GAAG,KAAK,UAAU,CAAC;AAChF,aAAO,MAAM,KAAK,eAAe,IAAI;AACrC,WAAK,OAAO,QAAQ,mBAAmB,IAAI;AAC3C,UAAI,OAAO,GAAG,EAAE,KAAK,IAAI;AAAA,IAC3B,SAAS,OAAY;AAGnB,YAAM,gBAAgB,OAAO,SAAS;AAGtC,WAAK,OAAO,MAAM,uBAAuB;AAAA,QACvC;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,cAAc,OAAO;AAAA,QACrB,mBAAmB,eAAe;AAAA,QAClC,sBAAsB,eAAe;AAAA,QACrC,WAAW,OAAO,WAAW;AAAA,QAC7B,mBAAmB,eAAe,WAAW;AAAA,MAC/C,CAAC;AACD,YAAM,oBACJ,MAAM,SAAS,2BACf,eAAe,SAAS,2BACxB,MAAM,SAAS,qBACf,eAAe,SAAS,qBACxB,MAAM,SAAS,8BACf,eAAe,SAAS,8BACxB,OAAO,WAAW,SAAS,sBAC3B,eAAe,WAAW,SAAS,sBAClC,MAAM,YACL,MAAM,QAAQ,SAAS,YAAY,KACnC,MAAM,QAAQ,SAAS,UAAU,KACjC,MAAM,QAAQ,SAAS,gBAAgB,KACvC,MAAM,QAAQ,SAAS,mBAAmB,KAC1C,MAAM,QAAQ,SAAS,gBAAgB,KACvC,MAAM,QAAQ,SAAS,gCAAgC,KACvD,MAAM,QAAQ,SAAS,wBAAwB,KAC/C,MAAM,QAAQ,SAAS,kBAAkB,KACzC,MAAM,QAAQ,SAAS,WAAW,KAClC,MAAM,QAAQ,SAAS,WAAW,KAClC,MAAM,QAAQ,SAAS,0BAA0B,MAElD,eAAe,YACd,cAAc,QAAQ,SAAS,YAAY,KAC3C,cAAc,QAAQ,SAAS,UAAU,KACzC,cAAc,QAAQ,SAAS,gBAAgB,KAC/C,cAAc,QAAQ,SAAS,mBAAmB,KAClD,cAAc,QAAQ,SAAS,gBAAgB,KAC/C,cAAc,QAAQ,SAAS,gCAAgC,KAC/D,cAAc,QAAQ,SAAS,wBAAwB,KACvD,cAAc,QAAQ,SAAS,WAAW,KAC1C,cAAc,QAAQ,SAAS,WAAW,KAC1C,cAAc,QAAQ,SAAS,0BAA0B;AAG7D,UAAI,mBAAmB;AACrB,cAAM,eAAe,eAAe,WAAW,MAAM,WAAW;AAChE,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,OAAO,OAAO,aAAa,CAAC;AAAA,MAC9D,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,OAAO,OAAO,MAAM,WAAW,wBAAwB,CAAC;AAAA,MAC1F;AAAA,IACF;AAAA,EACF;AAAA,EAEU,YAAY,OAAO,KAAc,QAAkB;AAC3D,
|
|
4
|
+
"sourcesContent": ["import { AllOptions, FindOperationResult, FindOptions, Item, ItemQuery, paramsToQuery, PriKey, QueryParams, validatePK } from \"@fjell/core\";\nimport { Request, Response } from \"express\";\nimport { ItemRouter, ItemRouterOptions } from \"./ItemRouter.js\";\nimport { Library, NotFoundError } from \"@fjell/lib\";\n\ninterface ParsedQuery {\n [key: string]: undefined | string | string[] | ParsedQuery | ParsedQuery[];\n}\n\nexport class PItemRouter<T extends Item<S>, S extends string> extends ItemRouter<S> {\n\n constructor(lib: Library<T, S>, keyType: S, options: ItemRouterOptions<S, never, never, never, never, never> = {}) {\n super(lib as any, keyType, options);\n }\n\n public getIk(res: Response): PriKey<S> {\n const pri = this.getPk(res) as PriKey<S>;\n return pri\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public createItem = async (req: Request, res: Response, next?: any) => {\n const libOperations = this.lib.operations;\n this.logger.default('Creating Item', { body: req.body, query: req.query, params: req.params, locals: res.locals });\n\n try {\n const itemToCreate = this.convertDates(req.body as Item<S>);\n let item = validatePK(await libOperations.create(itemToCreate), this.getPkType()) as Item<S>;\n item = await this.postCreateItem(item);\n this.logger.default('Created Item %j', item);\n res.status(201).json(item);\n } catch (error: any) {\n // Check for validation errors - check multiple patterns\n // Also check error.cause since errors may be wrapped\n const originalError = error?.cause || error;\n\n // Log error details for debugging\n this.logger.error('Error in createItem', {\n error,\n errorName: error?.name,\n errorMessage: error?.message,\n originalErrorName: originalError?.name,\n originalErrorMessage: originalError?.message,\n errorCode: error?.errorInfo?.code,\n originalErrorCode: originalError?.errorInfo?.code\n });\n const isValidationError =\n error.name === 'CreateValidationError' ||\n originalError?.name === 'CreateValidationError' ||\n error.name === 'ValidationError' ||\n originalError?.name === 'ValidationError' ||\n error.name === 'SequelizeValidationError' ||\n originalError?.name === 'SequelizeValidationError' ||\n error?.errorInfo?.code === 'VALIDATION_ERROR' ||\n originalError?.errorInfo?.code === 'VALIDATION_ERROR' ||\n (error.message && (\n error.message.includes('validation') ||\n error.message.includes('required') ||\n error.message.includes('cannot be null') ||\n error.message.includes('notNull Violation') ||\n error.message.includes('Required field') ||\n error.message.includes('Referenced item does not exist') ||\n error.message.includes('Foreign key constraint') ||\n error.message.includes('Operation failed') ||\n error.message.includes('preCreate') ||\n error.message.includes('preUpdate') ||\n error.message.includes('Create Validation Failed')\n )) ||\n (originalError?.message && (\n originalError.message.includes('validation') ||\n originalError.message.includes('required') ||\n originalError.message.includes('cannot be null') ||\n originalError.message.includes('notNull Violation') ||\n originalError.message.includes('Required field') ||\n originalError.message.includes('Referenced item does not exist') ||\n originalError.message.includes('Foreign key constraint') ||\n originalError.message.includes('preCreate') ||\n originalError.message.includes('preUpdate') ||\n originalError.message.includes('Create Validation Failed')\n ));\n\n if (isValidationError) {\n const errorMessage = originalError?.message || error.message || \"Validation failed\";\n res.status(400).json({ success: false, error: errorMessage });\n } else {\n res.status(500).json({ success: false, error: error.message || \"Internal server error\" });\n }\n }\n };\n\n protected findItems = async (req: Request, res: Response) => {\n const libOperations = this.lib.operations;\n this.logger.default('Finding Items', { query: req.query, params: req.params, locals: res.locals });\n\n try {\n const query: ParsedQuery = req.query as unknown as ParsedQuery;\n const finder = query['finder'] as string;\n const finderParams = query['finderParams'] as string;\n const one = query['one'] as string;\n\n if (finder) {\n 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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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/express-router",
|
|
3
3
|
"description": "Express Router for Fjell",
|
|
4
|
-
"version": "4.4.
|
|
4
|
+
"version": "4.4.76",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"express",
|
|
7
7
|
"router",
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"docs:test": "cd docs && npm run test"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@fjell/core": "^4.4.
|
|
38
|
-
"@fjell/lib": "^4.4.
|
|
39
|
-
"@fjell/logging": "^4.4.
|
|
40
|
-
"@fjell/registry": "^4.4.
|
|
37
|
+
"@fjell/core": "^4.4.70",
|
|
38
|
+
"@fjell/lib": "^4.4.81",
|
|
39
|
+
"@fjell/logging": "^4.4.62",
|
|
40
|
+
"@fjell/registry": "^4.4.79",
|
|
41
41
|
"deepmerge": "^4.3.1",
|
|
42
42
|
"express": "^5.1.0"
|
|
43
43
|
},
|