@fjell/express-router 4.4.56 → 4.4.58

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.
@@ -85,7 +85,7 @@ class ItemRouter {
85
85
  res.status(500).json({ error: "All Actions are not configured" });
86
86
  return;
87
87
  }
88
- const [result] = await libOperations.allAction(allActionKey, req.body, this.getLocations(res));
88
+ const result = await libOperations.allAction(allActionKey, req.body, this.getLocations(res));
89
89
  res.json(result);
90
90
  } catch (error) {
91
91
  this.logger.error("Error in postAllAction", { error });
@@ -151,7 +151,7 @@ class ItemRouter {
151
151
  res.status(500).json({ error: "Item Actions are not configured" });
152
152
  return;
153
153
  }
154
- const [result] = await libOperations.action(ik, actionKey, req.body);
154
+ const result = await libOperations.action(ik, actionKey, req.body);
155
155
  res.json(result);
156
156
  } catch (error) {
157
157
  this.logger.error("Error in postItemAction", { error });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/ItemRouter.ts"],
4
- "sourcesContent": ["import {\n ActionError,\n ComKey,\n cPK,\n Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { NextFunction, Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\nimport { createErrorHandler, ErrorHandlerOptions } from \"./errorHandler.js\";\n\n/**\n * Router-level action method signature - aligned with library ActionMethod pattern\n * Takes the resolved item key, action parameters, and HTTP context\n */\nexport interface RouterActionMethod<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n actionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level facet method signature - aligned with library FacetMethod pattern\n * Takes the resolved item key, facet parameters, and HTTP context\n */\nexport interface RouterFacetMethod<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n facetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all action method signature - aligned with library AllActionMethod pattern\n * Takes action parameters, optional locations, and HTTP context\n */\nexport interface RouterAllActionMethod<\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n allActionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all facet method signature - aligned with library AllFacetMethod pattern\n * Takes facet parameters, optional locations, and HTTP context\n */\nexport interface RouterAllFacetMethod<\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n allFacetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\nexport type ItemRouterOptions<\n S extends string = string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = {\n /**\n * Handlers for item actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives resolved item key and parameters\n */\n actions?: Record<string, RouterActionMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for item facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives resolved item key and parameters\n */\n facets?: Record<string, RouterFacetMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives parameters and optional locations\n */\n allActions?: Record<string, RouterAllActionMethod<L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives parameters and optional locations\n */\n allFacets?: Record<string, RouterAllFacetMethod<L1, L2, L3, L4, L5>>;\n\n /**\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', { 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', { 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', { 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', { 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 const libOptions = this.lib.options;\n this.logger.debug('Configuring Router', { pkType: this.getPkType() });\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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in deleteItem', { 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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in getItem', { 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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in updateItem', { 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": "AAAA;AAAA,EACE;AAAA,EAEA;AAAA,EAMA;AAAA,OACK;AACP,SAAS,qBAAqB;AAE9B,OAAO,eAAe;AACtB,SAA0C,cAAc;AACxD,OAAO,eAAe;AACtB,SAAS,0BAA+C;AAkHjD,MAAM,WAOX;AAAA,EAEU;AAAA,EACF;AAAA,EACE;AAAA,EACF,eAAuC,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EAEV,YACE,KACA,SACA,UAAoD,CAAC,GACrD,aACA;AACA,SAAK,MAAM;AACX,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,SAAS,UAAU,IAAI,cAAc,OAAO;AACjD,SAAK,eAAe,mBAAmB,QAAQ,YAAY;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKU,UAAU,IAAuE;AACzF,WAAO,CAAC,KAAc,KAAe,SAAuB;AAC1D,cAAQ,QAAQ,GAAG,KAAK,MAAM,KAAK,KAAK,IAAI,CAAC,EAAE,MAAM,IAAI;AAAA,IAC3D;AAAA,EACF;AAAA,EAEO,YAAY,MAAS;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,aAAa,MAAc;AACnC,WAAO,GAAG,KAAK,UAAU,CAAC;AAAA,EAC5B;AAAA,EAEU,MAAM,KAA0B;AACxC,UAAM,UAAU,KAAK,WAAW;AAChC,UAAM,UAAU,IAAI,OAAO,OAAO;AAClC,SAAK,OAAO,MAAM,wBAAwB;AAAA,MACxC,SAAS,KAAK;AAAA,MACd;AAAA,MACA;AAAA,MACA,WAAW,IAAI;AAAA,IACjB,CAAC;AACD,WAAO,EAAE,IAAI,KAAK,SAAS,IAAI,QAAQ;AAAA,EACzC;AAAA;AAAA,EAGO,OAAO,KAA+C;AAC3D,WAAO,CAAC,KAAK,MAAM,GAAG,CAAC;AAAA,EACzB;AAAA,EAEO,MAAM,KAA0B;AACrC,WAAO,IAAO,IAAI,OAAO,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGU,aAAa,KAAqD;AAC1E,WAAO,KAAK,cAAc,KAAK,YAAY,OAAO,GAAG,IAAuC,CAAC;AAAA,EAC/F;AAAA;AAAA,EAGU,MAAM,KAA0D;AACxE,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA,EAEU,gBAAgB,OAAO,KAAc,QAAkB;AAC/D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,MAAM,sBAAsB,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACvG,UAAM,eAAe,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,GAAG,IAAI,CAAC;AAErE,QAAI;AAEF,UAAI,KAAK,QAAQ,cAAc,KAAK,QAAQ,WAAW,YAAY,GAAG;AACpE,aAAK,OAAO,MAAM,yCAAyC,EAAE,aAAa,CAAC;AAC3E,cAAMA,UAAS,MAAM,KAAK,QAAQ,WAAW,YAAY;AAAA,UACvD,IAAI;AAAA,UACJ,KAAK,aAAa,GAAG;AAAA,UACrB,EAAE,KAAK,IAAI;AAAA,QACb;AACA,YAAIA,WAAU,MAAM;AAClB,cAAI,KAAKA,OAAM;AAAA,QACjB;AACA;AAAA,MACF;AAGA,UAAI,CAAC,cAAc,WAAW;AAC5B,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,iCAAiC,CAAC;AAChE;AAAA,MACF;AAGA,YAAM,CAAC,MAAM,IAAI,MAAM,cAAc,UAAU,cAAc,IAAI,MAAM,KAAK,aAAa,GAAG,CAAC;AAC7F,UAAI,KAAK,MAAM;AAAA,IACjB,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC;AAErD,WAAK,MAAM,SAAS,qBAAqB,MAAM,SAAS,SAAS,WAAW,MAAM,MAAM,SAAS;AAC/F,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,+BAA+B,CAAC;AAAA,MAChE,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEU,cAAc,OAAO,KAAc,QAAkB;AAC7D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,MAAM,qBAAqB,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACtG,UAAM,WAAW,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,GAAG,IAAI,CAAC;AAEjE,QAAI;AAEF,UAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,UAAU,QAAQ,GAAG;AAC9D,aAAK,OAAO,MAAM,wCAAwC,EAAE,SAAS,CAAC;AACtE,cAAMA,UAAS,MAAM,KAAK,QAAQ,UAAU,QAAQ;AAAA,UAClD,IAAI;AAAA,UACJ,KAAK,aAAa,GAAG;AAAA,UACrB,EAAE,KAAK,IAAI;AAAA,QACb;AACA,YAAIA,WAAU,MAAM;AAClB,cAAI,KAAKA,OAAM;AAAA,QACjB;AACA;AAAA,MACF;AAGA,UAAI,CAAC,cAAc,UAAU;AAC3B,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,gCAAgC,CAAC;AAC/D;AAAA,MACF;AAGA,YAAM,sBAAsB,EAAE,GAAI,IAAI,SAAS,CAAC,GAAI,GAAI,IAAI,UAAU,CAAC,EAAG;AAC1E,YAAM,SAAS,MAAM,cAAc,SAAS,UAAU,qBAAqB,KAAK,aAAa,GAAG,CAAC;AACjG,UAAI,KAAK,MAAM;AAAA,IACjB,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC;AAEnD,WAAK,MAAM,SAAS,qBAAqB,MAAM,SAAS,SAAS,WAAW,MAAM,MAAM,SAAS;AAC/F,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,8BAA8B,CAAC;AAAA,MAC/D,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEU,iBAAiB,OAAO,KAAc,QAAkB;AAChE,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,MAAM,uBAAuB,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACxG,UAAM,KAAK,KAAK,MAAM,GAAG;AACzB,UAAM,YAAY,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,GAAG,IAAI,CAAC;AAElE,QAAI;AAEF,UAAI,KAAK,QAAQ,WAAW,KAAK,QAAQ,QAAQ,SAAS,GAAG;AAC3D,aAAK,OAAO,MAAM,qCAAqC,EAAE,UAAU,CAAC;AACpE,cAAMA,UAAS,MAAM,KAAK,QAAQ,QAAQ,SAAS;AAAA,UACjD;AAAA,UACA,IAAI;AAAA,UACJ,EAAE,KAAK,IAAI;AAAA,QACb;AACA,YAAIA,WAAU,MAAM;AAClB,cAAI,KAAKA,OAAM;AAAA,QACjB;AACA;AAAA,MACF;AAGA,UAAI,CAAC,cAAc,QAAQ;AACzB,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,kCAAkC,CAAC;AACjE;AAAA,MACF;AAGA,YAAM,CAAC,MAAM,IAAI,MAAM,cAAc,OAAO,IAAI,WAAW,IAAI,IAAI;AACnE,UAAI,KAAK,MAAM;AAAA,IACjB,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC;AAEtD,WAAK,MAAM,SAAS,qBAAqB,MAAM,SAAS,SAAS,WAAW,MAAM,MAAM,SAAS;AAC/F,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,gCAAgC,CAAC;AAAA,MACjE,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEU,eAAe,OAAO,KAAc,QAAkB;AAC9D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,MAAM,sBAAsB,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO,CAAC;AACvG,UAAM,KAAK,KAAK,MAAM,GAAG;AACzB,UAAM,WAAW,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,GAAG,IAAI,CAAC;AAEjE,QAAI;AAEF,UAAI,KAAK,QAAQ,UAAU,KAAK,QAAQ,OAAO,QAAQ,GAAG;AACxD,aAAK,OAAO,MAAM,oCAAoC,EAAE,SAAS,CAAC;AAClE,cAAMA,UAAS,MAAM,KAAK,QAAQ,OAAO,QAAQ;AAAA,UAC/C;AAAA,UACA,IAAI;AAAA,UACJ,EAAE,KAAK,IAAI;AAAA,QACb;AACA,YAAIA,WAAU,MAAM;AAClB,cAAI,KAAKA,OAAM;AAAA,QACjB;AACA;AAAA,MACF;AAGA,UAAI,CAAC,cAAc,OAAO;AACxB,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,iCAAiC,CAAC;AAChE;AAAA,MACF;AAGA,YAAM,sBAAsB,EAAE,GAAI,IAAI,SAAS,CAAC,GAAI,GAAI,IAAI,UAAU,CAAC,EAAG;AAC1E,YAAM,SAAS,MAAM,cAAc,MAAM,IAAI,UAAU,mBAAmB;AAC1E,UAAI,KAAK,MAAM;AAAA,IACjB,SAAS,OAAY;AACnB,WAAK,OAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC;AAEpD,WAAK,MAAM,SAAS,qBAAqB,MAAM,SAAS,SAAS,WAAW,MAAM,MAAM,SAAS;AAC/F,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,+BAA+B,CAAC;AAAA,MAChE,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,YAAY,CAAC,WAAmB;AACtC,UAAM,aAAa,KAAK,IAAI;AAC5B,SAAK,OAAO,MAAM,sBAAsB,EAAE,QAAQ,KAAK,UAAU,EAAE,CAAC;AACpE,WAAO,IAAI,KAAK,KAAK,UAAU,KAAK,SAAS,CAAC;AAC9C,WAAO,KAAK,KAAK,KAAK,UAAU,KAAK,UAAU,CAAC;AAGhD,UAAM,uBAAuB,oBAAI,IAAY;AAC7C,UAAM,sBAAsB,oBAAI,IAAY;AAC5C,UAAM,wBAAwB,oBAAI,IAAY;AAC9C,UAAM,uBAAuB,oBAAI,IAAY;AAG7C,SAAK,OAAO,QAAQ,sBAAsB,EAAE,YAAY,KAAK,QAAQ,WAAW,CAAC;AACjF,QAAI,KAAK,QAAQ,YAAY;AAC3B,aAAO,KAAK,KAAK,QAAQ,UAAU,EAAE,QAAQ,CAAC,cAAc;AAC1D,aAAK,OAAO,MAAM,oCAAoC,SAAS;AAC/D,eAAO,KAAK,IAAI,SAAS,IAAI,KAAK,UAAU,KAAK,aAAa,CAAC;AAC/D,6BAAqB,IAAI,SAAS;AAAA,MACpC,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,uBAAuB,EAAE,YAAY,WAAW,WAAW,CAAC;AAChF,QAAI,WAAW,YAAY;AACzB,aAAO,KAAK,WAAW,UAAU,EAAE,QAAQ,CAAC,cAAc;AACxD,YAAI,qBAAqB,IAAI,SAAS,GAAG;AACvC,eAAK,OAAO,QAAQ,qEAAqE,EAAE,UAAU,CAAC;AAAA,QACxG,OAAO;AACL,eAAK,OAAO,MAAM,qCAAqC,SAAS;AAChE,iBAAO,KAAK,IAAI,SAAS,IAAI,KAAK,UAAU,KAAK,aAAa,CAAC;AAC/D,+BAAqB,IAAI,SAAS;AAAA,QACpC;AAAA,MACF,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,qBAAqB,EAAE,WAAW,KAAK,QAAQ,UAAU,CAAC;AAC9E,QAAI,KAAK,QAAQ,WAAW;AAC1B,aAAO,KAAK,KAAK,QAAQ,SAAS,EAAE,QAAQ,CAAC,aAAa;AACxD,aAAK,OAAO,MAAM,mCAAmC,QAAQ;AAC7D,eAAO,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU,KAAK,WAAW,CAAC;AAC3D,4BAAoB,IAAI,QAAQ;AAAA,MAClC,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,sBAAsB,EAAE,WAAW,WAAW,UAAU,CAAC;AAC7E,QAAI,WAAW,WAAW;AACxB,aAAO,KAAK,WAAW,SAAS,EAAE,QAAQ,CAAC,aAAa;AACtD,YAAI,oBAAoB,IAAI,QAAQ,GAAG;AACrC,eAAK,OAAO,QAAQ,oEAAoE,EAAE,SAAS,CAAC;AAAA,QACtG,OAAO;AACL,eAAK,OAAO,MAAM,oCAAoC,QAAQ;AAC9D,iBAAO,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU,KAAK,WAAW,CAAC;AAC3D,8BAAoB,IAAI,QAAQ;AAAA,QAClC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,aAAa,OAAO;AAC1B,eAAW,IAAI,KAAK,KAAK,UAAU,KAAK,OAAO,CAAC;AAChD,eAAW,IAAI,KAAK,KAAK,UAAU,KAAK,UAAU,CAAC;AACnD,eAAW,OAAO,KAAK,KAAK,UAAU,KAAK,UAAU,CAAC;AAGtD,SAAK,OAAO,QAAQ,uBAAuB,EAAE,aAAa,KAAK,QAAQ,QAAQ,CAAC;AAChF,QAAI,KAAK,QAAQ,SAAS;AACxB,aAAO,KAAK,KAAK,QAAQ,OAAO,EAAE,QAAQ,CAAC,cAAc;AACvD,aAAK,OAAO,MAAM,qCAAqC,SAAS;AAChE,mBAAW,KAAK,IAAI,SAAS,IAAI,KAAK,UAAU,KAAK,cAAc,CAAC;AACpE,8BAAsB,IAAI,SAAS;AAAA,MACrC,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,wBAAwB,EAAE,aAAa,WAAW,QAAQ,CAAC;AAC/E,QAAI,WAAW,SAAS;AACtB,aAAO,KAAK,WAAW,OAAO,EAAE,QAAQ,CAAC,cAAc;AACrD,YAAI,sBAAsB,IAAI,SAAS,GAAG;AACxC,eAAK,OAAO,QAAQ,sEAAsE,EAAE,UAAU,CAAC;AAAA,QACzG,OAAO;AACL,eAAK,OAAO,MAAM,sCAAsC,SAAS;AACjE,qBAAW,KAAK,IAAI,SAAS,IAAI,KAAK,UAAU,KAAK,cAAc,CAAC;AACpE,gCAAsB,IAAI,SAAS;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,sBAAsB,EAAE,YAAY,KAAK,QAAQ,OAAO,CAAC;AAC7E,QAAI,KAAK,QAAQ,QAAQ;AACvB,aAAO,KAAK,KAAK,QAAQ,MAAM,EAAE,QAAQ,CAAC,aAAa;AACrD,aAAK,OAAO,MAAM,oCAAoC,QAAQ;AAC9D,mBAAW,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU,KAAK,YAAY,CAAC;AAChE,6BAAqB,IAAI,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH;AAGA,SAAK,OAAO,QAAQ,uBAAuB,EAAE,YAAY,WAAW,OAAO,CAAC;AAC5E,QAAI,WAAW,QAAQ;AACrB,aAAO,KAAK,WAAW,MAAM,EAAE,QAAQ,CAAC,aAAa;AACnD,YAAI,qBAAqB,IAAI,QAAQ,GAAG;AACtC,eAAK,OAAO,QAAQ,qEAAqE,EAAE,SAAS,CAAC;AAAA,QACvG,OAAO;AACL,eAAK,OAAO,MAAM,qCAAqC,QAAQ;AAC/D,qBAAW,IAAI,IAAI,QAAQ,IAAI,KAAK,UAAU,KAAK,YAAY,CAAC;AAChE,+BAAqB,IAAI,QAAQ;AAAA,QACnC;AAAA,MACF,CAAC;AAAA,IACH;AAEA,SAAK,OAAO,MAAM,iDAAiD,KAAK,WAAW,CAAC;AACpF,WAAO,IAAI,KAAK,KAAK,WAAW,CAAC,IAAI,KAAK,yBAAyB,UAAU;AAE7E,QAAI,KAAK,cAAc;AACrB,WAAK,sBAAsB,YAAY,KAAK,YAAY;AAAA,IAC1D;AAGA,WAAO,IAAI,KAAK,YAAY;AAE5B,WAAO;AAAA,EACT;AAAA,EAEQ,0BAA0B,CAAC,KAAc,KAAe,SAAc;AAC5E,UAAM,eAAe,IAAI,OAAO,KAAK,WAAW,CAAC;AACjD,QAAI,KAAK,gBAAgB,YAAY,GAAG;AACtC,UAAI,OAAO,KAAK,WAAW,CAAC,IAAI;AAChC,WAAK;AAAA,IACP,OAAO;AACL,WAAK,OAAO,MAAM,uBAAuB,EAAE,cAAc,MAAM,KAAK,YAAY,CAAC;AACjF,UAAI,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,uBAAuB,MAAM,KAAK,YAAY,CAAC;AAAA,IAC/E;AAAA,EACF;AAAA,EAEQ,wBAAwB,CAAC,QAAgB,iBAAyC;AACxF,eAAW,QAAQ,cAAc;AAC/B,WAAK,OAAO,MAAM,uCAAuC,IAAI;AAE7D,aAAO,IAAI,IAAI,IAAI,IAAI,aAAa,IAAI,CAAC;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEO,iBAAiB,CAAC,MAAc,WAAmB;AACxD,SAAK,aAAa,IAAI,IAAI;AAAA,EAC5B;AAAA;AAAA,EAGO,YAAoB;AACzB,UAAM,SAAS,OAAO;AACtB,SAAK,UAAU,MAAM;AACrB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIU,aAAa,OAAO,KAAc,QAAiC;AAC3E,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA;AAAA;AAAA,EAIO,iBAAiB,OAAO,SAA4E;AACzG,SAAK,OAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC;AAC9C,WAAO;AAAA,EACT;AAAA,EAEU,aAAa,OAAO,KAAc,QAAiC;AAC3E,UAAM,gBAAgB,KAAK,IAAI;AAE/B,SAAK,OAAO,MAAM,iBAAiB,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAO,CAAC;AAC/F,UAAM,KAAK,KAAK,MAAM,GAAG;AAEzB,QAAI;AACF,YAAM,cAAc,MAAM,cAAc,OAAO,EAAE;AACjD,UAAI,aAAa;AACf,cAAM,OAAO,WAAW,aAAa,KAAK,UAAU,CAAC;AACrD,YAAI,KAAK,IAAI;AAAA,MACf,OAAO;AACL,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,MACvB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,iBAAkB,MAAc,SAAS,iBAAiB;AAC7E,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,iBAAiB,CAAC;AAAA,MACxD,OAAO;AACL,aAAK,OAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC;AAClD,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,gBAAgB,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA,EAIU,YAAY,OAAO,KAAc,QAAiC;AAC1E,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AAAA;AAAA,EAGU,UAAU,OAAO,KAAc,QAAkB;AACzD,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO,MAAM,gBAAgB,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,QAAQ,IAAI,OAAO,CAAC;AAC9F,UAAM,KAAK,KAAK,MAAM,GAAG;AAEzB,QAAI;AACF,YAAM,cAAc,MAAM,cAAc,IAAI,EAAE;AAC9C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,YAAY;AAAA,UACpB,MAAM;AAAA,UACN,SAAS,GAAG,KAAK,OAAO;AAAA,UACxB,WAAW;AAAA,YACT,MAAM;AAAA,YACN,MAAM;AAAA,YACN,QAAQ,EAAE,KAAK,GAAG;AAAA,UACpB;AAAA,UACA,SAAS;AAAA,YACP,UAAU,KAAK;AAAA,UACjB;AAAA,UACA,SAAS,EAAE,WAAW,MAAM;AAAA,UAC5B,WAAW;AAAA,YACT,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,OAAO,WAAW,aAAa,KAAK,UAAU,CAAC;AACrD,UAAI,KAAK,IAAI;AAAA,IACf,SAAS,OAAO;AACd,UAAI,iBAAiB,iBAAkB,MAAc,SAAS,iBAAiB;AAC7E,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,iBAAiB,CAAC;AAAA,MACxD,OAAO;AACL,aAAK,OAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC;AAC/C,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,gBAAgB,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEU,aAAa,OAAO,KAAc,QAAkB;AAC5D,UAAM,gBAAgB,KAAK,IAAI;AAC/B,SAAK,OAAO;AAAA,MAAM;AAAA,MAChB,EAAE,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,IAAC;AAClF,UAAM,KAAK,KAAK,MAAM,GAAG;AAEzB,QAAI;AACF,YAAM,eAAe,KAAK,aAAa,IAAI,IAA4C;AACvF,YAAM,UAAU,WAAW,MAAM,cAAc,OAAO,IAAI,YAAY,GAAG,KAAK,UAAU,CAAC;AACzF,UAAI,KAAK,OAAO;AAAA,IAClB,SAAS,OAAO;AACd,UAAI,iBAAiB,iBAAkB,MAAc,SAAS,iBAAiB;AAC7E,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,iBAAiB,CAAC;AAAA,MACxD,OAAO;AACL,aAAK,OAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC;AAClD,YAAI,OAAO,GAAG,EAAE,KAAK,EAAE,IAAI,SAAS,gBAAgB,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEO,eAAe,CAAC,SAAqF;AAC1G,SAAK,OAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC;AAC9C,UAAM,SAAS,KAAK;AACpB,QAAI,QAAQ;AACV,aAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,QAAgB;AAC3C,eAAO,OAAO,QAAQ;AAAA,UACpB,CAAC,GAAG,GAAG,UAAU,OAAO,GAAG,GAAG,EAAE,IAAI,OAAO,GAAG,EAAE,KAAK,IAAI,KAAK,OAAO,GAAG,EAAE,EAAE,IAAI,KAAK,CAAC;AAAA,QACxF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,WAAO,OAAO,MAAM,EAAE,OAAO,CAAC;AAC9B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUU,kBAAkB,CAAC,iBAAkC;AAC7D,QAAI,eAAe;AACnB,QAAI,aAAa,UAAU,GAAG;AAC5B,WAAK,OAAO,MAAM,kCAAkC,EAAE,aAAa,CAAC;AACpE,qBAAe;AAAA,IACjB,WAAW,iBAAiB,aAAa;AACvC,WAAK,OAAO,MAAM,yCAA2C,EAAE,aAAa,CAAC;AAC7E,qBAAe;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAEF;",
4
+ "sourcesContent": ["import {\n ActionError,\n ComKey,\n cPK,\n Item,\n ItemEvent,\n LocKey,\n LocKeyArray,\n PriKey,\n validatePK\n} from \"@fjell/core\";\nimport { NotFoundError } from \"@fjell/lib\";\nimport { Instance } from \"./Instance.js\";\nimport deepmerge from \"deepmerge\";\nimport { NextFunction, Request, Response, Router } from \"express\";\nimport LibLogger from \"./logger.js\";\nimport { createErrorHandler, ErrorHandlerOptions } from \"./errorHandler.js\";\n\n/**\n * Router-level action method signature - aligned with library ActionMethod pattern\n * Takes the resolved item key, action parameters, and HTTP context\n */\nexport interface RouterActionMethod<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n actionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level facet method signature - aligned with library FacetMethod pattern\n * Takes the resolved item key, facet parameters, and HTTP context\n */\nexport interface RouterFacetMethod<\n S extends string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n ik: PriKey<S> | ComKey<S, L1, L2, L3, L4, L5>,\n facetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all action method signature - aligned with library AllActionMethod pattern\n * Takes action parameters, optional locations, and HTTP context\n */\nexport interface RouterAllActionMethod<\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n allActionParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\n/**\n * Router-level all facet method signature - aligned with library AllFacetMethod pattern\n * Takes facet parameters, optional locations, and HTTP context\n */\nexport interface RouterAllFacetMethod<\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never,\n> {\n (\n allFacetParams: Record<string, string | number | boolean | Date | Array<string | number | boolean | Date>>,\n locations: LocKeyArray<L1, L2, L3, L4, L5> | [],\n context: { req: Request, res: Response }\n ): Promise<any>;\n}\n\nexport type ItemRouterOptions<\n S extends string = string,\n L1 extends string = never,\n L2 extends string = never,\n L3 extends string = never,\n L4 extends string = never,\n L5 extends string = never\n> = {\n /**\n * Handlers for item actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives resolved item key and parameters\n */\n actions?: Record<string, RouterActionMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for item facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives resolved item key and parameters\n */\n facets?: Record<string, RouterFacetMethod<S, L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all actions - aligned with library operation signatures\n * The key in the Record is the action name, method receives parameters and optional locations\n */\n allActions?: Record<string, RouterAllActionMethod<L1, L2, L3, L4, L5>>;\n\n /**\n * Handlers for all facets - aligned with library operation signatures\n * The key in the Record is the facet name, method receives parameters and optional locations\n */\n allFacets?: Record<string, RouterAllFacetMethod<L1, L2, L3, L4, L5>>;\n\n /**\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', { 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', { 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', { 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', { 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 const libOptions = this.lib.options;\n this.logger.debug('Configuring Router', { pkType: this.getPkType() });\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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in deleteItem', { 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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in getItem', { 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) {\n if (error instanceof NotFoundError || (error as any).name === 'NotFoundError') {\n res.status(404).json({ ik, message: \"Item Not Found\" });\n } else {\n this.logger.error('Error in updateItem', { 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,6 +1,6 @@
1
1
  const clean = (obj) => {
2
2
  return Object.fromEntries(
3
- Object.entries(obj).filter(([_, v]) => v !== void 0)
3
+ Object.entries(obj).filter(([, v]) => v !== void 0)
4
4
  );
5
5
  };
6
6
  const stringifyJSON = function(obj, visited = /* @__PURE__ */ new Set()) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/util/general.ts"],
4
- "sourcesContent": ["\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n // Remove array from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n // Remove object from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n};\n"],
5
- "mappings": "AAEO,MAAM,QAAQ,CAAC,QAAa;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,MAAS;AAAA,EACxD;AACF;AAGO,MAAM,gBAAgB,SAAU,KAAU,UAAoB,oBAAI,IAAI,GAAW;AACtF,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAoB,CAAC;AAGzB,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,QAAQ;AACjE,WAAO,KAAK;AAAA,WACL,OAAO,QAAQ;AACtB,WAAO,MAAM,MAAM;AAGrB,MAAI,eAAe,UAAU,QAAQ,IAAI,GAAG,GAAG;AAC7C,WAAO;AAAA,EACT,WAGS,MAAM,QAAQ,GAAG,GAAG;AAE3B,QAAI,IAAI,CAAC,MAAM;AACb,aAAO;AAAA,SACJ;AAEH,cAAQ,IAAI,GAAG;AACf,UAAI,QAAQ,SAAU,IAAI;AACxB,gBAAQ,KAAK,cAAc,IAAI,OAAO,CAAC;AAAA,MACzC,CAAC;AAED,cAAQ,OAAO,GAAG;AAClB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,EACF,WAES,eAAe,QAAQ;AAE9B,YAAQ,IAAI,GAAG;AAEf,cAAU,OAAO,KAAK,GAAG;AAEzB,YAAQ,QAAQ,SAAU,KAAK;AAC7B,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,YAAY,IAAI,GAAG;AAEzB,UAAI,qBAAqB,YAAY,cAAc;AACjD;AAAA,eACO,OAAO,cAAc;AAC5B,qBAAa,KAAK,SAAS,MAAM,YAAY,GAAG;AAAA,eACzC,OAAO,cAAc,aAAa,OAAO,cAAc,YAAY,cAAc;AACxF,qBAAa,KAAK,SAAS,SAAS;AAAA,eAE7B,qBAAqB,QAAQ;AACpC,qBAAa,KAAK,SAAS,cAAc,WAAW,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,YAAQ,OAAO,GAAG;AAClB,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["\n/* eslint-disable no-undefined */\nexport const clean = (obj: any) => {\n return Object.fromEntries(\n Object.entries(obj).filter(([, v]) => v !== undefined)\n );\n}\n\n//Recursive implementation of jSON.stringify;\nexport const stringifyJSON = function (obj: any, visited: Set<any> = new Set()): string {\n const arrOfKeyVals: string[] = [];\n const arrVals: string[] = [];\n let objKeys: string[] = [];\n\n /*********CHECK FOR PRIMITIVE TYPES**********/\n if (typeof obj === 'number' || typeof obj === 'boolean' || obj === null)\n return '' + obj;\n else if (typeof obj === 'string')\n return '\"' + obj + '\"';\n\n /*********DETECT CIRCULAR REFERENCES**********/\n if (obj instanceof Object && visited.has(obj)) {\n return '\"(circular)\"';\n }\n\n /*********CHECK FOR ARRAY**********/\n else if (Array.isArray(obj)) {\n //check for empty array\n if (obj[0] === undefined)\n return '[]';\n else {\n // Add array to visited before processing its elements\n visited.add(obj);\n obj.forEach(function (el) {\n arrVals.push(stringifyJSON(el, visited));\n });\n // Remove array from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '[' + arrVals + ']';\n }\n }\n /*********CHECK FOR OBJECT**********/\n else if (obj instanceof Object) {\n // Add object to visited before processing its properties\n visited.add(obj);\n //get object keys\n objKeys = Object.keys(obj);\n //set key output;\n objKeys.forEach(function (key) {\n const keyOut = '\"' + key + '\":';\n const keyValOut = obj[key];\n //skip functions and undefined properties\n if (keyValOut instanceof Function || keyValOut === undefined)\n return; // Skip this entry entirely instead of pushing an empty string\n else if (typeof keyValOut === 'string')\n arrOfKeyVals.push(keyOut + '\"' + keyValOut + '\"');\n else if (typeof keyValOut === 'boolean' || typeof keyValOut === 'number' || keyValOut === null)\n arrOfKeyVals.push(keyOut + keyValOut);\n //check for nested objects, call recursively until no more objects\n else if (keyValOut instanceof Object) {\n arrOfKeyVals.push(keyOut + stringifyJSON(keyValOut, visited));\n }\n });\n // Remove object from visited after processing to prevent memory leaks\n visited.delete(obj);\n return '{' + arrOfKeyVals + '}';\n }\n return '';\n};\n"],
5
+ "mappings": "AAEO,MAAM,QAAQ,CAAC,QAAa;AACjC,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS;AAAA,EACvD;AACF;AAGO,MAAM,gBAAgB,SAAU,KAAU,UAAoB,oBAAI,IAAI,GAAW;AACtF,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,UAAoB,CAAC;AAGzB,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,QAAQ;AACjE,WAAO,KAAK;AAAA,WACL,OAAO,QAAQ;AACtB,WAAO,MAAM,MAAM;AAGrB,MAAI,eAAe,UAAU,QAAQ,IAAI,GAAG,GAAG;AAC7C,WAAO;AAAA,EACT,WAGS,MAAM,QAAQ,GAAG,GAAG;AAE3B,QAAI,IAAI,CAAC,MAAM;AACb,aAAO;AAAA,SACJ;AAEH,cAAQ,IAAI,GAAG;AACf,UAAI,QAAQ,SAAU,IAAI;AACxB,gBAAQ,KAAK,cAAc,IAAI,OAAO,CAAC;AAAA,MACzC,CAAC;AAED,cAAQ,OAAO,GAAG;AAClB,aAAO,MAAM,UAAU;AAAA,IACzB;AAAA,EACF,WAES,eAAe,QAAQ;AAE9B,YAAQ,IAAI,GAAG;AAEf,cAAU,OAAO,KAAK,GAAG;AAEzB,YAAQ,QAAQ,SAAU,KAAK;AAC7B,YAAM,SAAS,MAAM,MAAM;AAC3B,YAAM,YAAY,IAAI,GAAG;AAEzB,UAAI,qBAAqB,YAAY,cAAc;AACjD;AAAA,eACO,OAAO,cAAc;AAC5B,qBAAa,KAAK,SAAS,MAAM,YAAY,GAAG;AAAA,eACzC,OAAO,cAAc,aAAa,OAAO,cAAc,YAAY,cAAc;AACxF,qBAAa,KAAK,SAAS,SAAS;AAAA,eAE7B,qBAAqB,QAAQ;AACpC,qBAAa,KAAK,SAAS,cAAc,WAAW,OAAO,CAAC;AAAA,MAC9D;AAAA,IACF,CAAC;AAED,YAAQ,OAAO,GAAG;AAClB,WAAO,MAAM,eAAe;AAAA,EAC9B;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "name": "@fjell/express-router",
3
- "version": "4.4.56",
4
- "license": "Apache-2.0",
3
+ "description": "Express Router for Fjell",
4
+ "version": "4.4.58",
5
5
  "keywords": [
6
6
  "express",
7
7
  "router",
8
8
  "fjell"
9
9
  ],
10
- "description": "Express Router for Fjell",
10
+ "license": "Apache-2.0",
11
11
  "engines": {
12
12
  "node": ">=21"
13
13
  },
14
- "main": "dist/index.js",
15
- "module": "dist/index.js",
14
+ "type": "module",
15
+ "main": "./dist/index.js",
16
+ "module": "./dist/index.js",
16
17
  "exports": {
17
18
  ".": {
18
19
  "types": "./dist/index.d.ts",
19
20
  "import": "./dist/index.js"
20
21
  }
21
22
  },
22
- "type": "module",
23
23
  "scripts": {
24
24
  "build": "npm run clean && node build.js",
25
25
  "dev": "nodemon --watch src --ext ts --exec 'npm run build'",
@@ -34,17 +34,17 @@
34
34
  "docs:test": "cd docs && npm run test"
35
35
  },
36
36
  "dependencies": {
37
- "@fjell/core": "^4.4.50",
38
- "@fjell/lib": "^4.4.58",
39
- "@fjell/logging": "^4.4.49",
40
- "@fjell/registry": "^4.4.52",
37
+ "@fjell/core": "^4.4.51",
38
+ "@fjell/lib": "^4.4.59",
39
+ "@fjell/logging": "^4.4.50",
40
+ "@fjell/registry": "^4.4.53",
41
41
  "deepmerge": "^4.3.1",
42
42
  "express": "^5.1.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@eslint/eslintrc": "^3.3.1",
46
46
  "@eslint/js": "^9.33.0",
47
- "@fjell/eslint-config": "^1.1.25",
47
+ "@fjell/eslint-config": "^1.1.28",
48
48
  "@tsconfig/recommended": "^1.0.10",
49
49
  "@types/express": "^5.0.3",
50
50
  "@types/node": "^24.2.1",
package/MIGRATION_v3.md DELETED
@@ -1,255 +0,0 @@
1
- # Migration Guide: v2.x to v3.0
2
-
3
- ## Overview
4
-
5
- Version 3.0 of `@fjell/express-router` adopts the standardized Operations interface from `@fjell/core`. This provides a unified interface across all Fjell packages and enables better type safety and cross-package compatibility.
6
-
7
- ## Breaking Changes
8
-
9
- ### Operations Interface
10
-
11
- The router now works directly with the `Operations` interface from `@fjell/core`, which is implemented by `@fjell/lib`, `@fjell/cache`, and other Fjell packages.
12
-
13
- **Good News**: This is a non-breaking change for most users since `@fjell/lib` already implements the core Operations interface.
14
-
15
- ## What You Need to Do
16
-
17
- ### Step 1: Update Dependencies
18
-
19
- Update to the latest versions of Fjell packages:
20
-
21
- ```bash
22
- npm install @fjell/core@latest @fjell/lib@latest @fjell/express-router@latest
23
- ```
24
-
25
- ### Step 2: Verify Your Code (Usually No Changes Needed)
26
-
27
- Your existing code should continue to work without modifications:
28
-
29
- ```typescript
30
- // This continues to work in v3.0
31
- import { PItemRouter, CItemRouter } from '@fjell/express-router';
32
- import { createLibrary } from '@fjell/lib';
33
- import { createRegistry } from '@fjell/registry';
34
-
35
- const registry = createRegistry();
36
- const library = createLibrary(
37
- registry,
38
- { keyType: 'user' },
39
- userOperations,
40
- userOptions
41
- );
42
-
43
- const userRouter = new PItemRouter(library, 'user');
44
- app.use('/api/users', userRouter.getRouter());
45
- ```
46
-
47
- ### Step 3: Optional - Use Type Imports from Core
48
-
49
- You can now import types directly from `@fjell/core` if needed:
50
-
51
- ```typescript
52
- import { Operations, OperationParams, AffectedKeys } from '@fjell/core';
53
- import type { Item } from '@fjell/core';
54
-
55
- // Your Operations implementation
56
- const myOperations: Operations<Item<'user'>, 'user'> = {
57
- // ... implementation
58
- };
59
- ```
60
-
61
- ## Benefits of v3.0
62
-
63
- ### 1. Unified Interface
64
-
65
- Works with any package that implements `@fjell/core` Operations:
66
-
67
- ```typescript
68
- import { PItemRouter } from '@fjell/express-router';
69
- import { createLibrary } from '@fjell/lib';
70
- import { createCache } from '@fjell/cache';
71
-
72
- // Works with @fjell/lib
73
- const library = createLibrary(registry, { keyType: 'user' }, ops, opts);
74
- const libRouter = new PItemRouter(library, 'user');
75
-
76
- // Works with @fjell/cache
77
- const cache = createCache(library);
78
- const cacheRouter = new PItemRouter(cache as any, 'user');
79
- ```
80
-
81
- ### 2. Better Type Safety
82
-
83
- Enhanced TypeScript support with explicit method types from core:
84
-
85
- ```typescript
86
- import type { GetMethod, CreateMethod } from '@fjell/core';
87
-
88
- // Core types are available for advanced use cases
89
- const getHandler: GetMethod<User, 'user'> = async (key) => {
90
- // Handler implementation
91
- };
92
- ```
93
-
94
- ### 3. Consistent API
95
-
96
- Same routing behavior across all Operations implementations:
97
-
98
- - `GET /items` → `operations.all()`
99
- - `GET /items/:id` → `operations.get(key)`
100
- - `POST /items` → `operations.create(item)`
101
- - `PUT /items/:id` → `operations.update(key, item)`
102
- - `DELETE /items/:id` → `operations.remove(key)`
103
- - `POST /items/:id/action` → `operations.action(key, action, params)`
104
- - `GET /items/:id/facet` → `operations.facet(key, facet, params)`
105
- - `POST /items/action` → `operations.allAction(action, params)`
106
- - `GET /items/facet` → `operations.allFacet(facet, params)`
107
-
108
- ### 4. Cross-Package Compatibility
109
-
110
- Works seamlessly with all Fjell packages:
111
-
112
- - `@fjell/lib` - Server-side operations
113
- - `@fjell/cache` - Caching layer
114
- - `@fjell/client-api` - HTTP client
115
- - `@fjell/providers` - React UI components
116
-
117
- ## What Hasn't Changed
118
-
119
- - Router creation API remains the same
120
- - Route configuration is identical
121
- - Router-level handlers work as before
122
- - Middleware integration unchanged
123
- - Error handling unchanged
124
- - All existing options and configurations continue to work
125
-
126
- ## Examples
127
-
128
- ### Basic Router (No Changes Required)
129
-
130
- ```typescript
131
- import express from 'express';
132
- import { PItemRouter } from '@fjell/express-router';
133
- import { createLibrary } from '@fjell/lib';
134
- import { createRegistry } from '@fjell/registry';
135
-
136
- const app = express();
137
- const registry = createRegistry();
138
-
139
- // Create library
140
- const userLibrary = createLibrary(
141
- registry,
142
- { keyType: 'user' },
143
- userOperations,
144
- userOptions
145
- );
146
-
147
- // Create router (same as v2.x)
148
- const userRouter = new PItemRouter(userLibrary, 'user');
149
- app.use('/api/users', userRouter.getRouter());
150
-
151
- app.listen(3000);
152
- ```
153
-
154
- ### Nested Routers (No Changes Required)
155
-
156
- ```typescript
157
- // Parent router
158
- const organizationRouter = new PItemRouter(orgLibrary, 'organization');
159
-
160
- // Child router
161
- const departmentRouter = new CItemRouter(
162
- deptLibrary,
163
- 'department',
164
- organizationRouter
165
- );
166
-
167
- // Mount routers (same as v2.x)
168
- app.use('/api/organizations', organizationRouter.getRouter());
169
- app.use(
170
- '/api/organizations/:organizationPk/departments',
171
- departmentRouter.getRouter()
172
- );
173
- ```
174
-
175
- ### Router-Level Handlers (No Changes Required)
176
-
177
- ```typescript
178
- const userRouter = new PItemRouter(userLibrary, 'user', {
179
- actions: {
180
- activate: async (ik, params, { req, res }) => {
181
- // Handler implementation (same as v2.x)
182
- const user = await userLibrary.operations.get(ik);
183
- await activateUser(user);
184
- res.json({ success: true });
185
- }
186
- },
187
- facets: {
188
- profile: async (ik, params, { req, res }) => {
189
- // Handler implementation (same as v2.x)
190
- const user = await userLibrary.operations.get(ik);
191
- const profile = await getProfile(user);
192
- res.json(profile);
193
- }
194
- }
195
- });
196
- ```
197
-
198
- ## Troubleshooting
199
-
200
- ### Type Errors
201
-
202
- If you encounter type errors after upgrading:
203
-
204
- 1. Ensure all Fjell packages are updated to their latest versions
205
- 2. Check that `@fjell/core` is installed
206
- 3. Clear your TypeScript cache: `rm -rf node_modules/.cache`
207
- 4. Rebuild: `npm run build`
208
-
209
- ### Import Errors
210
-
211
- If you have import errors:
212
-
213
- ```typescript
214
- // If this fails:
215
- import type { Operations } from '@fjell/express-router';
216
-
217
- // Use this instead:
218
- import type { Operations } from '@fjell/core';
219
- // or
220
- import type { Operations } from '@fjell/lib';
221
- ```
222
-
223
- ### Runtime Errors
224
-
225
- If your Operations object doesn't work with the router:
226
-
227
- 1. Verify it implements all required methods from `@fjell/core` Operations
228
- 2. Check that method signatures match the core interface
229
- 3. Ensure return types are correct (e.g., `action` and `allAction` return `[result, affectedKeys]`)
230
-
231
- ## Migration Checklist
232
-
233
- - [ ] Update `@fjell/core` to latest version
234
- - [ ] Update `@fjell/lib` to latest version
235
- - [ ] Update `@fjell/express-router` to v3.0+
236
- - [ ] Update other Fjell packages to latest versions
237
- - [ ] Run `npm install`
238
- - [ ] Run tests: `npm test`
239
- - [ ] Run build: `npm run build`
240
- - [ ] Verify application starts correctly
241
- - [ ] Test API endpoints work as expected
242
-
243
- ## Need Help?
244
-
245
- - **Documentation**: [README.md](./README.md)
246
- - **Examples**: [examples/](./examples/)
247
- - **Issues**: [GitHub Issues](https://github.com/getfjell/express-router/issues)
248
- - **Discussions**: [GitHub Discussions](https://github.com/getfjell/express-router/discussions)
249
-
250
- ## Summary
251
-
252
- Version 3.0 is a **seamless upgrade** for most users. The router now uses the standardized Operations interface from `@fjell/core`, providing better type safety and cross-package compatibility, but your existing code should continue to work without modifications.
253
-
254
- Simply update your dependencies and you're ready to go! 🎉
255
-
package/build.js DELETED
@@ -1,4 +0,0 @@
1
- import buildMultiFile from '@fjell/eslint-config/esbuild/multi-file';
2
-
3
- // Multi-file compilation - compiles each TypeScript file separately
4
- buildMultiFile();
@@ -1,44 +0,0 @@
1
- import { DocsConfig } from '@fjell/docs-template';
2
-
3
- const config: DocsConfig = {
4
- projectName: 'Fjell Express Router',
5
- basePath: '/express-router/',
6
- port: 3004,
7
- branding: {
8
- theme: 'express-router',
9
- tagline: 'Express Router for Fjell',
10
- backgroundImage: '/pano.png',
11
- github: 'https://github.com/getfjell/express-router',
12
- npm: 'https://www.npmjs.com/package/@fjell/express-router'
13
- },
14
- sections: [
15
- {
16
- id: 'overview',
17
- title: 'Getting Started',
18
- subtitle: 'Express Router for Fjell',
19
- file: '/README.md'
20
- },
21
- {
22
- id: 'examples',
23
- title: 'Examples',
24
- subtitle: 'Code examples & usage patterns',
25
- file: '/examples-README.md'
26
- }
27
- ],
28
- filesToCopy: [
29
- {
30
- source: '../README.md',
31
- destination: 'public/README.md'
32
- },
33
- {
34
- source: '../examples/README.md',
35
- destination: 'public/examples-README.md'
36
- }
37
- ],
38
- plugins: [],
39
- version: {
40
- source: 'package.json'
41
- }
42
- }
43
-
44
- export default config
package/docs/index.html DELETED
@@ -1,18 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8" />
6
- <link rel="icon" type="image/svg+xml" href="/fjell-icon.svg" />
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
- <title>Fjell Express Router - Express Router for Fjell</title>
9
- <meta name="description"
10
- content="Express Router for Fjell - A powerful Express.js router integration for the Fjell framework">
11
- </head>
12
-
13
- <body>
14
- <div id="root"></div>
15
- <script type="module" src="/src/main.tsx"></script>
16
- </body>
17
-
18
- </html>