feathers-utils 10.0.0-rc.9 → 10.0.0

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.
Files changed (231) hide show
  1. package/dist/guards.mjs +1 -1
  2. package/dist/guards.mjs.map +1 -1
  3. package/dist/{hook-context-D16ztLk5.d.mts → hook-context-aHkq1h0N.d.mts} +3 -2
  4. package/dist/{traverse.hook-C2VIvQrn.mjs → hooks-DPFxxjBu.mjs} +115 -56
  5. package/dist/hooks-DPFxxjBu.mjs.map +1 -0
  6. package/dist/hooks.d.mts +45 -14
  7. package/dist/hooks.mjs +5 -9
  8. package/dist/{zip-data-result.util-Bjinzz8t.d.mts → index-CNrzxmWo.d.mts} +55 -8
  9. package/dist/index.d.mts +9 -10
  10. package/dist/index.mjs +8 -12
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/{infer-service-methods-DRcpjEXa.d.mts → infer-service-methods-D7zRVQeJ.d.mts} +2 -2
  13. package/dist/{internal.utils-C8LH1H55.mjs → internal.utils-BWQ25nOd.mjs} +2 -5
  14. package/dist/internal.utils-BWQ25nOd.mjs.map +1 -0
  15. package/dist/{mutate-result.util-BBqz9sPw.d.mts → mutate-result.util-BIeYlqqT.d.mts} +2 -2
  16. package/dist/{mutate-result.util-C8ZumXWd.mjs → mutate-result.util-CCBWix-G.mjs} +3 -7
  17. package/dist/{mutate-result.util-C8ZumXWd.mjs.map → mutate-result.util-CCBWix-G.mjs.map} +1 -1
  18. package/dist/{throw-if.hook-CiuUMtny.mjs → predicates-CT08opkD.mjs} +69 -78
  19. package/dist/predicates-CT08opkD.mjs.map +1 -0
  20. package/dist/predicates.d.mts +18 -42
  21. package/dist/predicates.mjs +2 -4
  22. package/dist/{resolve-CsbBZQE9.d.mts → resolve-CA7-EaTw.d.mts} +7 -7
  23. package/dist/{resolve-B-y8cmo6.mjs → resolve-Cx9osy8O.mjs} +4 -8
  24. package/dist/resolve-Cx9osy8O.mjs.map +1 -0
  25. package/dist/resolvers.d.mts +2 -2
  26. package/dist/resolvers.mjs +2 -12
  27. package/dist/resolvers.mjs.map +1 -1
  28. package/dist/{transform-result.hook-CTPT14PS.d.mts → transform-result.hook-BUwLePT2.d.mts} +4 -4
  29. package/dist/{transform-result.hook-BZ55kPq7.mjs → transform-result.hook-CevWK5TA.mjs} +3 -6
  30. package/dist/transform-result.hook-CevWK5TA.mjs.map +1 -0
  31. package/dist/transformers.d.mts +3 -3
  32. package/dist/transformers.mjs +4 -11
  33. package/dist/transformers.mjs.map +1 -1
  34. package/dist/{unless.hook-s-Efoy7S.d.mts → unless.hook-BYWO9hzO.d.mts} +6 -6
  35. package/dist/{zip-data-result.util-CVD17gWe.mjs → utils-1I_iPZkV.mjs} +25 -42
  36. package/dist/utils-1I_iPZkV.mjs.map +1 -0
  37. package/dist/utils.d.mts +3 -5
  38. package/dist/utils.mjs +4 -6
  39. package/package.json +42 -30
  40. package/src/hooks/check-multi/check-multi.hook.ts +10 -12
  41. package/src/hooks/check-required/check-required.hook.ts +5 -6
  42. package/src/hooks/create-related/create-related.hook.ts +5 -1
  43. package/src/hooks/disable-pagination/disable-pagination.hook.ts +5 -1
  44. package/src/hooks/disallow/disallow.hook.ts +1 -1
  45. package/src/hooks/iff/iff.hook.ts +5 -5
  46. package/src/hooks/iff-else/iff-else.hook.ts +20 -9
  47. package/src/hooks/index.ts +1 -0
  48. package/src/hooks/on-delete/on-delete.hook.ts +5 -1
  49. package/src/hooks/params-from-client/params-from-client.hook.ts +1 -0
  50. package/src/hooks/rate-limit/rate-limit.hook.ts +58 -0
  51. package/src/hooks/set-data/set-data.hook.ts +2 -0
  52. package/src/hooks/set-field/set-field.hook.ts +2 -1
  53. package/src/hooks/set-result/set-result.hook.ts +1 -1
  54. package/src/hooks/skippable/skippable.hook.ts +1 -0
  55. package/src/hooks/soft-delete/soft-delete.hook.ts +1 -1
  56. package/src/hooks/stashable/stashable.hook.ts +5 -6
  57. package/src/hooks/transform-data/transform-data.hook.ts +2 -2
  58. package/src/hooks/transform-result/transform-result.hook.ts +2 -2
  59. package/src/internal.utils.ts +1 -0
  60. package/src/predicates/and/and.predicate.ts +57 -0
  61. package/src/predicates/index.ts +2 -2
  62. package/src/predicates/is-context/is-context.predicate.ts +20 -27
  63. package/src/predicates/or/or.predicate.ts +60 -0
  64. package/src/resolvers/resolve/resolve.ts +4 -2
  65. package/src/resolvers/resolve-data/resolve-data.ts +3 -3
  66. package/src/resolvers/resolve-query/resolve-query.ts +6 -1
  67. package/src/resolvers/resolve-result/resolve-result.ts +3 -3
  68. package/src/utils/check-context/check-context.util.ts +89 -8
  69. package/dist/internal.utils-C8LH1H55.mjs.map +0 -1
  70. package/dist/resolve-B-y8cmo6.mjs.map +0 -1
  71. package/dist/throw-if.hook-CiuUMtny.mjs.map +0 -1
  72. package/dist/transform-result.hook-BZ55kPq7.mjs.map +0 -1
  73. package/dist/traverse.hook-C2VIvQrn.mjs.map +0 -1
  74. package/dist/zip-data-result.util-CVD17gWe.mjs.map +0 -1
  75. package/src/.DS_Store +0 -0
  76. package/src/guards/has-query/has-query.guard.md +0 -6
  77. package/src/hooks/.DS_Store +0 -0
  78. package/src/hooks/cache/cache.hook.md +0 -227
  79. package/src/hooks/cache/cache.hook.test.ts +0 -944
  80. package/src/hooks/check-multi/check-multi.hook.md +0 -10
  81. package/src/hooks/check-multi/check-multi.hook.test.ts +0 -173
  82. package/src/hooks/check-required/check-required.hook.md +0 -8
  83. package/src/hooks/check-required/check-required.hook.test.ts +0 -41
  84. package/src/hooks/create-related/create-related.hook.md +0 -8
  85. package/src/hooks/create-related/create-related.hook.test.ts +0 -405
  86. package/src/hooks/debug/debug.hook.md +0 -8
  87. package/src/hooks/debug/debug.hook.test.ts +0 -25
  88. package/src/hooks/disable-pagination/disable-pagination.hook.md +0 -8
  89. package/src/hooks/disable-pagination/disable-pagination.hook.test.ts +0 -61
  90. package/src/hooks/disallow/disallow.hook.md +0 -9
  91. package/src/hooks/disallow/disallow.hook.test.ts +0 -159
  92. package/src/hooks/iff/iff.hook.md +0 -19
  93. package/src/hooks/iff/iff.hook.test.ts +0 -469
  94. package/src/hooks/iff-else/iff-else.hook.md +0 -19
  95. package/src/hooks/iff-else/iff-else.hook.test.ts +0 -219
  96. package/src/hooks/on-delete/on-delete.hook.md +0 -32
  97. package/src/hooks/on-delete/on-delete.hook.test.ts +0 -918
  98. package/src/hooks/params-for-server/params-for-server.hook.md +0 -10
  99. package/src/hooks/params-for-server/params-for-server.hook.test.ts +0 -68
  100. package/src/hooks/params-from-client/params-from-client.hook.md +0 -10
  101. package/src/hooks/params-from-client/params-from-client.hook.test.ts +0 -54
  102. package/src/hooks/prevent-changes/prevent-changes.hook.md +0 -8
  103. package/src/hooks/prevent-changes/prevent-changes.hook.test.ts +0 -206
  104. package/src/hooks/set-data/set-data.hook.md +0 -8
  105. package/src/hooks/set-data/set-data.hook.test.ts +0 -390
  106. package/src/hooks/set-field/set-field.hook.md +0 -8
  107. package/src/hooks/set-field/set-field.hook.test.ts +0 -94
  108. package/src/hooks/set-result/set-result.hook.md +0 -8
  109. package/src/hooks/set-result/set-result.hook.test.ts +0 -417
  110. package/src/hooks/set-slug/set-slug.hook.md +0 -8
  111. package/src/hooks/set-slug/set-slug.hook.test.ts +0 -57
  112. package/src/hooks/skippable/skippable.hook.md +0 -20
  113. package/src/hooks/skippable/skippable.hook.test.ts +0 -124
  114. package/src/hooks/soft-delete/soft-delete.hook.md +0 -8
  115. package/src/hooks/soft-delete/soft-delete.hook.test.ts +0 -213
  116. package/src/hooks/stashable/stashable.hook.md +0 -8
  117. package/src/hooks/stashable/stashable.hook.test.ts +0 -255
  118. package/src/hooks/throw-if/throw-if.hook.md +0 -9
  119. package/src/hooks/throw-if/throw-if.hook.test.ts +0 -27
  120. package/src/hooks/throw-if-is-multi/throw-if-is-multi.hook.md +0 -10
  121. package/src/hooks/throw-if-is-multi/throw-if-is-multi.hook.test.ts +0 -148
  122. package/src/hooks/throw-if-is-provider/throw-if-is-provider.hook.md +0 -10
  123. package/src/hooks/throw-if-is-provider/throw-if-is-provider.hook.test.ts +0 -39
  124. package/src/hooks/transform-data/transform-data.hook.md +0 -49
  125. package/src/hooks/transform-data/transform-data.hook.test-d.ts +0 -104
  126. package/src/hooks/transform-data/transform-data.hook.test.ts +0 -115
  127. package/src/hooks/transform-query/transform-query.hook.md +0 -19
  128. package/src/hooks/transform-query/transform-query.hook.test.ts +0 -30
  129. package/src/hooks/transform-result/transform-result.hook.md +0 -41
  130. package/src/hooks/transform-result/transform-result.hook.test-d.ts +0 -104
  131. package/src/hooks/transform-result/transform-result.hook.test.ts +0 -248
  132. package/src/hooks/traverse/traverse.hook.md +0 -8
  133. package/src/hooks/traverse/traverse.hook.test.ts +0 -128
  134. package/src/hooks/unless/unless.hook.md +0 -13
  135. package/src/hooks/unless/unless.hook.test.ts +0 -450
  136. package/src/predicates/.DS_Store +0 -0
  137. package/src/predicates/every/every.predicate.md +0 -9
  138. package/src/predicates/every/every.predicate.test.ts +0 -186
  139. package/src/predicates/every/every.predicate.ts +0 -66
  140. package/src/predicates/is-context/is-context.predicate.md +0 -4
  141. package/src/predicates/is-context/is-context.predicate.test.ts +0 -64
  142. package/src/predicates/is-multi/is-multi.predicate.md +0 -4
  143. package/src/predicates/is-multi/is-multi.predicate.test.ts +0 -57
  144. package/src/predicates/is-paginated/is-paginated.predicate.md +0 -6
  145. package/src/predicates/is-paginated/is-paginated.predicate.test.ts +0 -72
  146. package/src/predicates/is-provider/is-provider.predicate.md +0 -4
  147. package/src/predicates/is-provider/is-provider.predicate.test.ts +0 -138
  148. package/src/predicates/not/not.predicate.md +0 -9
  149. package/src/predicates/not/not.predicate.test.ts +0 -124
  150. package/src/predicates/should-skip/should-skip.predicate.md +0 -7
  151. package/src/predicates/should-skip/should-skip.predicate.test.ts +0 -121
  152. package/src/predicates/some/some.predicate.md +0 -9
  153. package/src/predicates/some/some.predicate.test.ts +0 -66
  154. package/src/predicates/some/some.predicate.ts +0 -69
  155. package/src/resolvers/from-predicate/from-predicate.md +0 -27
  156. package/src/resolvers/from-predicate/from-predicate.test-d.ts +0 -33
  157. package/src/resolvers/from-predicate/from-predicate.test.ts +0 -52
  158. package/src/resolvers/helpers/defaults/defaults.md +0 -9
  159. package/src/resolvers/helpers/helpers.test-d.ts +0 -96
  160. package/src/resolvers/helpers/helpers.test.ts +0 -117
  161. package/src/resolvers/helpers/lowercase/lowercase.md +0 -9
  162. package/src/resolvers/helpers/omit/omit.md +0 -9
  163. package/src/resolvers/helpers/set-now/set-now.md +0 -9
  164. package/src/resolvers/helpers/trim/trim.md +0 -9
  165. package/src/resolvers/resolve/resolve.md +0 -19
  166. package/src/resolvers/resolve/resolve.test-d.ts +0 -63
  167. package/src/resolvers/resolve/resolve.test.ts +0 -130
  168. package/src/resolvers/resolve-data/resolve-data.md +0 -17
  169. package/src/resolvers/resolve-data/resolve-data.test-d.ts +0 -73
  170. package/src/resolvers/resolve-data/resolve-data.test.ts +0 -420
  171. package/src/resolvers/resolve-query/resolve-query.md +0 -17
  172. package/src/resolvers/resolve-query/resolve-query.test-d.ts +0 -50
  173. package/src/resolvers/resolve-query/resolve-query.test.ts +0 -230
  174. package/src/resolvers/resolve-result/resolve-result.md +0 -17
  175. package/src/resolvers/resolve-result/resolve-result.test-d.ts +0 -64
  176. package/src/resolvers/resolve-result/resolve-result.test.ts +0 -369
  177. package/src/transformers/defaults/defaults.transformer.md +0 -4
  178. package/src/transformers/defaults/defaults.transformer.test-d.ts +0 -79
  179. package/src/transformers/defaults/defaults.transformer.test.ts +0 -58
  180. package/src/transformers/lowercase/lowercase.transformer.md +0 -4
  181. package/src/transformers/lowercase/lowercase.transformer.test.ts +0 -40
  182. package/src/transformers/omit/omit.transformer.md +0 -4
  183. package/src/transformers/omit/omit.transformer.test.ts +0 -29
  184. package/src/transformers/parse-date/parse-date.transformer.md +0 -4
  185. package/src/transformers/parse-date/parse-date.transformer.test.ts +0 -41
  186. package/src/transformers/pick/pick.transformer.md +0 -4
  187. package/src/transformers/pick/pick.transformer.test.ts +0 -27
  188. package/src/transformers/set-now/set-now.transformer.md +0 -4
  189. package/src/transformers/set-now/set-now.transformer.test.ts +0 -28
  190. package/src/transformers/trim/trim.transformer.md +0 -4
  191. package/src/transformers/trim/trim.transformer.test.ts +0 -40
  192. package/src/utils/.DS_Store +0 -0
  193. package/src/utils/add-skip/add-skip.util.md +0 -6
  194. package/src/utils/add-skip/add-skip.util.test.ts +0 -29
  195. package/src/utils/add-to-query/add-to-query.util.md +0 -4
  196. package/src/utils/add-to-query/add-to-query.util.test.ts +0 -72
  197. package/src/utils/check-context/check-context.util.md +0 -4
  198. package/src/utils/check-context/check-context.util.test.ts +0 -107
  199. package/src/utils/chunk-find/chunk-find.util.md +0 -6
  200. package/src/utils/chunk-find/chunk-find.util.test.ts +0 -118
  201. package/src/utils/combine/combine.util.md +0 -8
  202. package/src/utils/combine/combine.util.test.ts +0 -158
  203. package/src/utils/context-to-json/context-to-json.util.md +0 -4
  204. package/src/utils/define-hooks/define-hooks.util.md +0 -27
  205. package/src/utils/define-hooks/define-hooks.util.test.ts +0 -27
  206. package/src/utils/get-data-is-array/get-data-is-array.util.md +0 -4
  207. package/src/utils/get-data-is-array/get-data-is-array.util.test.ts +0 -63
  208. package/src/utils/get-exposed-methods/get-exposed-methods.util.md +0 -4
  209. package/src/utils/get-exposed-methods/get-exposed-methods.util.test.ts +0 -47
  210. package/src/utils/get-paginate/get-paginate.util.md +0 -4
  211. package/src/utils/get-paginate/get-paginate.util.test.ts +0 -73
  212. package/src/utils/get-result-is-array/get-result-is-array.util.md +0 -4
  213. package/src/utils/get-result-is-array/get-result-is-array.util.test.ts +0 -187
  214. package/src/utils/iterate-find/iterate-find.util.md +0 -6
  215. package/src/utils/iterate-find/iterate-find.util.test.ts +0 -122
  216. package/src/utils/mutate-data/mutate-data.util.md +0 -8
  217. package/src/utils/mutate-result/mutate-result.util.md +0 -8
  218. package/src/utils/mutate-result/mutate-result.util.test.ts +0 -175
  219. package/src/utils/patch-batch/patch-batch.util.md +0 -4
  220. package/src/utils/patch-batch/patch-batch.util.test.ts +0 -41
  221. package/src/utils/skip-result/skip-result.util.md +0 -4
  222. package/src/utils/skip-result/skip-result.util.test.ts +0 -262
  223. package/src/utils/sort-query-properties/sort-query-properties.util.md +0 -4
  224. package/src/utils/sort-query-properties/sort-query-properties.util.test.ts +0 -93
  225. package/src/utils/to-paginated/to-paginated.util.md +0 -4
  226. package/src/utils/to-paginated/to-paginated.util.test.ts +0 -27
  227. package/src/utils/transform-params/transform-params.util.md +0 -4
  228. package/src/utils/walk-query/walk-query.util.md +0 -4
  229. package/src/utils/walk-query/walk-query.util.test.ts +0 -141
  230. package/src/utils/zip-data-result/zip-data-result.util.md +0 -4
  231. package/src/utils/zip-data-result/zip-data-result.util.test.ts +0 -180
package/dist/guards.mjs CHANGED
@@ -25,7 +25,7 @@
25
25
  function hasQuery(params) {
26
26
  return !!params.query;
27
27
  }
28
-
29
28
  //#endregion
30
29
  export { hasQuery };
30
+
31
31
  //# sourceMappingURL=guards.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.mjs","names":[],"sources":["../src/guards/has-query/has-query.guard.ts"],"sourcesContent":["import type { Params } from '@feathersjs/feathers'\nimport type { RequiredQuery } from '../../utility-types/required-query.js'\n\n/**\n * Type guard to check if the `query` property of `Params` is present and non-nullable.\n *\n * @param params - The `Params` object to check.\n * @returns `true` if `params.query` is present and non-nullable, otherwise `false`.\n *\n * @see https://utils.feathersjs.com/guards/has-query.html\n *\n * @example\n * ```ts\n * import { hasQuery } from 'feathers-utils/guards'\n *\n * function example(params: Params) {\n * // `params.query` is optional and can be undefined at this point\n * if (!hasQuery(params)) {\n * return;\n * }\n *\n * // TypeScript now knows that params.query is present and non-nullable\n * // You can safely access params.query here without additional checks\n * }\n * ```\n */\nexport function hasQuery<P extends Params>(\n params: P,\n): params is RequiredQuery<P> {\n return !!params.query\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,SACd,QAC4B;AAC5B,QAAO,CAAC,CAAC,OAAO"}
1
+ {"version":3,"file":"guards.mjs","names":[],"sources":["../src/guards/has-query/has-query.guard.ts"],"sourcesContent":["import type { Params } from '@feathersjs/feathers'\nimport type { RequiredQuery } from '../../utility-types/required-query.js'\n\n/**\n * Type guard to check if the `query` property of `Params` is present and non-nullable.\n *\n * @param params - The `Params` object to check.\n * @returns `true` if `params.query` is present and non-nullable, otherwise `false`.\n *\n * @see https://utils.feathersjs.com/guards/has-query.html\n *\n * @example\n * ```ts\n * import { hasQuery } from 'feathers-utils/guards'\n *\n * function example(params: Params) {\n * // `params.query` is optional and can be undefined at this point\n * if (!hasQuery(params)) {\n * return;\n * }\n *\n * // TypeScript now knows that params.query is present and non-nullable\n * // You can safely access params.query here without additional checks\n * }\n * ```\n */\nexport function hasQuery<P extends Params>(\n params: P,\n): params is RequiredQuery<P> {\n return !!params.query\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,SACd,QAC4B;CAC5B,OAAO,CAAC,CAAC,OAAO"}
@@ -2,6 +2,7 @@ import { HookContext, NextFunction, Paginated, Params } from "@feathersjs/feathe
2
2
 
3
3
  //#region src/internal.utils.d.ts
4
4
  type MaybeArray<T> = T | readonly T[];
5
+ type UnpackMaybeArray<T> = T extends readonly (infer E)[] ? E : T;
5
6
  type Promisable<T> = T | Promise<T>;
6
7
  type KeyOf<T> = Extract<keyof T, string>;
7
8
  type UnwrapArray<T> = T extends Array<infer U> ? U : T;
@@ -46,5 +47,5 @@ type UnwrapPaginatedOrArray<T> = T extends Paginated<infer D> ? D : T extends an
46
47
  type ResultSingleHookContext<H extends HookContext> = UnwrapPaginatedOrArray<NonNullable<H['result']>>;
47
48
  type DataSingleHookContext<H extends HookContext> = UnwrapArray<NonNullable<H['data']>>;
48
49
  //#endregion
49
- export { Promisable as A, hookTypes as C, KeyOfOrDotNotation as D, KeyOf as E, MaybeArray as O, TransportName as S, AnyFallback as T, PredicateItemWithContext as _, ContextFunction as a, TransformerFn as b, DefaultsInput as c, HookFunction as d, HookType$1 as f, PredicateFn as g, PredicateContextSync as h, UnwrapPaginatedOrArray as i, UnwrapArray as j, NeverFallback as k, DispatchOption as l, PredicateContextAsync as m, ResultSingleHookContext as n, ContextFunctionAsync as o, MethodName as p, UnwrapPaginated as r, ContextFunctionSync as s, DataSingleHookContext as t, FieldKey as u, StringFieldKey as v, methodNames as w, TransformerInputFn as x, TransformParamsFn as y };
50
- //# sourceMappingURL=hook-context-D16ztLk5.d.mts.map
50
+ export { Promisable as A, hookTypes as C, KeyOfOrDotNotation as D, KeyOf as E, UnwrapArray as M, MaybeArray as O, TransportName as S, AnyFallback as T, PredicateItemWithContext as _, ContextFunction as a, TransformerFn as b, DefaultsInput as c, HookFunction as d, HookType$1 as f, PredicateFn as g, PredicateContextSync as h, UnwrapPaginatedOrArray as i, UnpackMaybeArray as j, NeverFallback as k, DispatchOption as l, PredicateContextAsync as m, ResultSingleHookContext as n, ContextFunctionAsync as o, MethodName as p, UnwrapPaginated as r, ContextFunctionSync as s, DataSingleHookContext as t, FieldKey as u, StringFieldKey as v, methodNames as w, TransformerInputFn as x, TransformParamsFn as y };
51
+ //# sourceMappingURL=hook-context-aHkq1h0N.d.mts.map
@@ -1,18 +1,18 @@
1
- import { f as isMulti, l as isProvider, m as every, t as throwIf } from "./throw-if.hook-CiuUMtny.mjs";
2
- import { d as checkContext, f as addToQuery, h as sortQueryProperties, r as transformParams, u as contextToJson } from "./zip-data-result.util-CVD17gWe.mjs";
3
- import { a as traverse$1, i as isPromise, r as toArray, t as early } from "./internal.utils-C8LH1H55.mjs";
4
- import { i as getDataIsArray, r as getResultIsArray } from "./mutate-result.util-C8ZumXWd.mjs";
5
- import { r as transformData } from "./transform-result.hook-BZ55kPq7.mjs";
1
+ import { g as every, p as isMulti, t as throwIf, u as isProvider } from "./predicates-CT08opkD.mjs";
2
+ import { d as checkContext, f as addToQuery, h as sortQueryProperties, r as transformParams, u as contextToJson } from "./utils-1I_iPZkV.mjs";
3
+ import { a as traverse$1, i as isPromise, r as toArray, t as early } from "./internal.utils-BWQ25nOd.mjs";
4
+ import { i as getDataIsArray, r as getResultIsArray } from "./mutate-result.util-CCBWix-G.mjs";
5
+ import { r as transformData } from "./transform-result.hook-CevWK5TA.mjs";
6
+ import "./resolve-Cx9osy8O.mjs";
6
7
  import isObject from "lodash/isObject.js";
7
8
  import { copy } from "fast-copy";
8
- import { BadRequest, Forbidden, MethodNotAllowed } from "@feathersjs/errors";
9
+ import { BadRequest, Forbidden, MethodNotAllowed, TooManyRequests } from "@feathersjs/errors";
9
10
  import _get from "lodash/get.js";
10
11
  import _has from "lodash/has.js";
11
12
  import _omit from "lodash/omit.js";
12
13
  import _set from "lodash/set.js";
13
14
  import _setWith from "lodash/setWith.js";
14
15
  import _clone from "lodash/clone.js";
15
-
16
16
  //#region src/hooks/cache/cache-utils.ts
17
17
  const stableStringify = (obj) => {
18
18
  if (obj.query) obj = {
@@ -28,7 +28,6 @@ const stableStringify = (obj) => {
28
28
  return value;
29
29
  });
30
30
  };
31
-
32
31
  //#endregion
33
32
  //#region src/hooks/cache/cache.hook.ts
34
33
  /**
@@ -175,7 +174,6 @@ var ContextCacheMap = class {
175
174
  return context;
176
175
  }
177
176
  };
178
-
179
177
  //#endregion
180
178
  //#region src/hooks/check-multi/check-multi.hook.ts
181
179
  /**
@@ -197,13 +195,13 @@ var ContextCacheMap = class {
197
195
  function checkMulti(options) {
198
196
  return (context, next) => {
199
197
  const { service, method } = context;
200
- if (!service.allowsMulti || !isMulti(context) || method === "find") return context;
201
- if (!service.allowsMulti(method)) throw options?.error ? options.error(context) : new MethodNotAllowed(`Can not ${method} multiple entries`);
202
- if (next) return next();
203
- return context;
198
+ if (!service.allowsMulti || !isMulti(context) || method === "find" || service.allowsMulti(method)) {
199
+ if (next) return next();
200
+ return context;
201
+ }
202
+ throw options?.error ? options.error(context) : new MethodNotAllowed(`Can not ${method} multiple entries`);
204
203
  };
205
204
  }
206
-
207
205
  //#endregion
208
206
  //#region src/hooks/check-required/check-required.hook.ts
209
207
  /**
@@ -225,11 +223,15 @@ function checkMulti(options) {
225
223
  function checkRequired(fieldNames) {
226
224
  const fieldNamesArray = toArray(fieldNames);
227
225
  return (context, next) => {
228
- checkContext(context, ["before", "around"], [
229
- "create",
230
- "update",
231
- "patch"
232
- ], "checkRequired");
226
+ checkContext(context, {
227
+ type: ["before", "around"],
228
+ method: [
229
+ "create",
230
+ "update",
231
+ "patch"
232
+ ],
233
+ label: "checkRequired"
234
+ });
233
235
  const { data } = getDataIsArray(context);
234
236
  for (let i = 0; i < data.length; i++) {
235
237
  const item = data[i];
@@ -243,7 +245,6 @@ function checkRequired(fieldNames) {
243
245
  if (next) return next();
244
246
  };
245
247
  }
246
-
247
248
  //#endregion
248
249
  //#region src/hooks/create-related/create-related.hook.ts
249
250
  /**
@@ -266,7 +267,11 @@ function checkRequired(fieldNames) {
266
267
  */
267
268
  function createRelated(options) {
268
269
  return async (context, next) => {
269
- checkContext(context, ["after", "around"], ["create"], "createRelated");
270
+ checkContext(context, {
271
+ type: ["after", "around"],
272
+ method: ["create"],
273
+ label: "createRelated"
274
+ });
270
275
  if (next) await next();
271
276
  const { result } = getResultIsArray(context);
272
277
  const entries = Array.isArray(options) ? options : [options];
@@ -279,7 +284,6 @@ function createRelated(options) {
279
284
  }));
280
285
  };
281
286
  }
282
-
283
287
  //#endregion
284
288
  //#region src/hooks/debug/debug.hook.ts
285
289
  /**
@@ -315,7 +319,6 @@ const debug = (msg, ...fieldNames) => async (context, next) => {
315
319
  });
316
320
  if (context.error) console.log("error", context.error);
317
321
  };
318
-
319
322
  //#endregion
320
323
  //#region src/hooks/disable-pagination/disable-pagination.hook.ts
321
324
  /**
@@ -336,7 +339,11 @@ const debug = (msg, ...fieldNames) => async (context, next) => {
336
339
  * @see https://utils.feathersjs.com/hooks/disable-pagination.html
337
340
  */
338
341
  const disablePagination = () => (context, next) => {
339
- checkContext(context, ["before", "around"], ["find"], "disablePagination");
342
+ checkContext(context, {
343
+ type: ["before", "around"],
344
+ method: ["find"],
345
+ label: "disablePagination"
346
+ });
340
347
  const $limit = context.params?.query?.$limit;
341
348
  if ($limit === "-1" || $limit === -1) {
342
349
  context.params.paginate = false;
@@ -345,7 +352,6 @@ const disablePagination = () => (context, next) => {
345
352
  if (next) return next();
346
353
  return context;
347
354
  };
348
-
349
355
  //#endregion
350
356
  //#region src/hooks/disallow/disallow.hook.ts
351
357
  /**
@@ -371,17 +377,20 @@ const disallow = (transports) => {
371
377
  const transportsArr = toArray(transports);
372
378
  return (context, next) => {
373
379
  if (!transports) throw new MethodNotAllowed("Method not allowed");
374
- if (isProvider(...transportsArr)(context)) throw new MethodNotAllowed(`Provider '${context.params.provider}' can not call '${context.method}'. (disallow)`);
380
+ if (isProvider(...transportsArr)(context)) throw new MethodNotAllowed(`Provider '${context.params.provider}' can not call '${context.method}' on '${context.path}'. (disallow)`);
375
381
  if (next) return next().then(() => context);
376
382
  };
377
383
  };
378
-
379
384
  //#endregion
380
385
  //#region src/hooks/on-delete/on-delete.hook.ts
381
386
  const onDelete = (options) => {
382
387
  const optionsMulti = Array.isArray(options) ? options : [options];
383
388
  return async (context, next) => {
384
- checkContext(context, ["after", "around"], "remove", "onDelete");
389
+ checkContext(context, {
390
+ type: ["after", "around"],
391
+ method: "remove",
392
+ label: "onDelete"
393
+ });
385
394
  if (next) await next();
386
395
  const { result } = getResultIsArray(context);
387
396
  if (!result.length) return;
@@ -408,11 +417,9 @@ const onDelete = (options) => {
408
417
  if (promises.length) await Promise.all(promises);
409
418
  };
410
419
  };
411
-
412
420
  //#endregion
413
421
  //#region src/hooks/params-for-server/params-for-from-shared.ts
414
422
  const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = "_$client";
415
-
416
423
  //#endregion
417
424
  //#region src/hooks/params-for-server/params-for-server.hook.ts
418
425
  /**
@@ -454,7 +461,6 @@ const paramsForServer = (whitelist, options) => {
454
461
  return context;
455
462
  };
456
463
  };
457
-
458
464
  //#endregion
459
465
  //#region src/hooks/params-from-client/params-from-client.hook.ts
460
466
  /**
@@ -478,7 +484,10 @@ const paramsFromClient = (whitelist, options) => {
478
484
  const whitelistArr = toArray(whitelist);
479
485
  const { keyToHide = FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } = options || {};
480
486
  return (context, next) => {
481
- if (!context.params?.query?.[keyToHide] || typeof context.params.query[keyToHide] !== "object") return context;
487
+ if (!context.params?.query?.[keyToHide] || typeof context.params.query[keyToHide] !== "object") {
488
+ if (next) return next();
489
+ return context;
490
+ }
482
491
  const params = {
483
492
  ...context.params,
484
493
  query: {
@@ -499,7 +508,6 @@ const paramsFromClient = (whitelist, options) => {
499
508
  return context;
500
509
  };
501
510
  };
502
-
503
511
  //#endregion
504
512
  //#region src/hooks/prevent-changes/prevent-changes.hook.ts
505
513
  /**
@@ -531,7 +539,47 @@ const preventChanges = (fieldNames, options) => {
531
539
  return item;
532
540
  });
533
541
  };
534
-
542
+ //#endregion
543
+ //#region src/hooks/rate-limit/rate-limit.hook.ts
544
+ /**
545
+ * Rate limits service method calls using `rate-limiter-flexible`.
546
+ * You provide a pre-configured `RateLimiterAbstract` instance
547
+ * (Memory, Redis, Mongo, etc.) and the hook consumes points per request.
548
+ *
549
+ * @example
550
+ * ```ts
551
+ * import { rateLimit } from 'feathers-utils/hooks'
552
+ * import { RateLimiterMemory } from 'rate-limiter-flexible'
553
+ *
554
+ * const rateLimiter = new RateLimiterMemory({ points: 10, duration: 1 })
555
+ *
556
+ * app.service('users').hooks({
557
+ * before: { find: [rateLimit(rateLimiter)] }
558
+ * })
559
+ * ```
560
+ *
561
+ * @see https://utils.feathersjs.com/hooks/rate-limit.html
562
+ */
563
+ const rateLimit = (rateLimiter, options) => {
564
+ const key = options?.key ?? ((context) => context.path);
565
+ const points = options?.points ?? (() => 1);
566
+ return async (context, next) => {
567
+ checkContext(context, {
568
+ type: ["before", "around"],
569
+ label: "rateLimit"
570
+ });
571
+ const resolvedKey = await key(context);
572
+ const resolvedPoints = await points(context);
573
+ try {
574
+ const res = await rateLimiter.consume(resolvedKey, resolvedPoints);
575
+ context.params.rateLimit = res;
576
+ } catch (res) {
577
+ context.params.rateLimit = res;
578
+ throw new TooManyRequests("Too many requests", { rateLimitRes: res });
579
+ }
580
+ if (next) return await next();
581
+ };
582
+ };
535
583
  //#endregion
536
584
  //#region src/hooks/set-data/set-data.hook.ts
537
585
  /**
@@ -556,8 +604,14 @@ function setData(from, to, options) {
556
604
  const { data } = getDataIsArray(context);
557
605
  const contextJson = contextToJson(context);
558
606
  if (!_has(contextJson, from)) {
559
- if (!context.params?.provider || allowUndefined === true) return context;
560
- if (!overwrite && data.every((item) => _has(item, to))) return context;
607
+ if (!context.params?.provider || allowUndefined === true) {
608
+ if (next) return next();
609
+ return context;
610
+ }
611
+ if (!overwrite && data.every((item) => _has(item, to))) {
612
+ if (next) return next();
613
+ return context;
614
+ }
561
615
  throw options?.error ? options.error(context, from) : new Forbidden(`Expected field ${from.toString()} not available`);
562
616
  }
563
617
  const val = _get(contextJson, from);
@@ -570,7 +624,6 @@ function setData(from, to, options) {
570
624
  return context;
571
625
  };
572
626
  }
573
-
574
627
  //#endregion
575
628
  //#region src/hooks/set-field/set-field.hook.ts
576
629
  /**
@@ -591,17 +644,22 @@ function setData(from, to, options) {
591
644
  */
592
645
  const setField = ({ as, from, allowUndefined = false, error }) => (context, next) => {
593
646
  const { params } = context;
594
- checkContext(context, ["before", "around"], null, "setField");
647
+ checkContext(context, {
648
+ type: ["before", "around"],
649
+ label: "setField"
650
+ });
595
651
  const value = _get(context, from);
596
652
  if (value === void 0) {
597
- if (!params.provider || allowUndefined) return context;
653
+ if (!params.provider || allowUndefined) {
654
+ if (next) return next();
655
+ return context;
656
+ }
598
657
  throw error ? error(context, from) : new Forbidden(`Expected field ${as} not available`);
599
658
  }
600
659
  context = _setWith(context, as, value, _clone);
601
660
  if (next) return next();
602
661
  return context;
603
662
  };
604
-
605
663
  //#endregion
606
664
  //#region src/hooks/set-result/set-result.hook.ts
607
665
  /**
@@ -646,11 +704,10 @@ function setResult(from, to, options) {
646
704
  return forResultOrDispatch(context, !!options?.dispatch);
647
705
  };
648
706
  return (context, next) => {
649
- if (next) next().then(() => fn(context));
707
+ if (next) return next().then(() => fn(context));
650
708
  return fn(context);
651
709
  };
652
710
  }
653
-
654
711
  //#endregion
655
712
  //#region src/hooks/set-slug/set-slug.hook.ts
656
713
  /**
@@ -680,7 +737,6 @@ const setSlug = (slug, fieldName) => {
680
737
  return context;
681
738
  };
682
739
  };
683
-
684
740
  //#endregion
685
741
  //#region src/hooks/soft-delete/soft-delete.hook.ts
686
742
  /**
@@ -704,7 +760,10 @@ const setSlug = (slug, fieldName) => {
704
760
  const softDelete = (options) => {
705
761
  if (!options?.deletedQuery || !options?.removeData) throw new Error("You must provide `deletedQuery` and `removeData` options to the softDelete hook.");
706
762
  return async (context, next) => {
707
- checkContext(context, ["before", "around"], null, "softDelete");
763
+ checkContext(context, {
764
+ type: ["before", "around"],
765
+ label: "softDelete"
766
+ });
708
767
  const { disableSoftDeleteKey = "disableSoftDelete" } = options;
709
768
  if (context.params[disableSoftDeleteKey]) return early(context, next);
710
769
  const { deletedQuery, removeData } = options;
@@ -730,7 +789,6 @@ const getValue = (value, ...args) => {
730
789
  if (typeof value === "function") return value(...args);
731
790
  return value;
732
791
  };
733
-
734
792
  //#endregion
735
793
  //#region src/hooks/stashable/stashable.hook.ts
736
794
  const defaultStashFunc = (context) => {
@@ -770,18 +828,21 @@ function stashable(options) {
770
828
  if (next) return next();
771
829
  return context;
772
830
  }
773
- checkContext(context, ["before", "around"], [
774
- "update",
775
- "patch",
776
- "remove"
777
- ], "stashable");
831
+ checkContext(context, {
832
+ type: ["before", "around"],
833
+ method: [
834
+ "update",
835
+ "patch",
836
+ "remove"
837
+ ],
838
+ label: "stashable"
839
+ });
778
840
  const promise = stashFunc(context).catch(() => void 0);
779
841
  context.params[propName] = () => promise;
780
842
  if (next) return next();
781
843
  return context;
782
844
  });
783
845
  }
784
-
785
846
  //#endregion
786
847
  //#region src/hooks/throw-if-is-multi/throw-if-is-multi.hook.ts
787
848
  const defaultError$1 = (context) => new BadRequest(`Cannot perform multi operation on method '${context.method}'`);
@@ -802,7 +863,6 @@ const defaultError$1 = (context) => new BadRequest(`Cannot perform multi operati
802
863
  * @see https://utils.feathersjs.com/hooks/throw-if-is-multi.html
803
864
  */
804
865
  const throwIfIsMulti = (options) => throwIf(every(every(isMulti, (context) => context.method !== "find"), options?.filter), { error: options?.error ?? defaultError$1 });
805
-
806
866
  //#endregion
807
867
  //#region src/hooks/throw-if-is-provider/throw-if-is-provider.hook.ts
808
868
  const defaultError = (context) => new MethodNotAllowed(`Provider '${context.params.provider}' can not call '${context.method}'.`);
@@ -825,7 +885,6 @@ const defaultError = (context) => new MethodNotAllowed(`Provider '${context.para
825
885
  const throwIfIsProvider = (transports, options) => {
826
886
  return throwIf(every(isProvider(...toArray(transports)), options?.filter), { error: options?.error ?? defaultError });
827
887
  };
828
-
829
888
  //#endregion
830
889
  //#region src/hooks/traverse/traverse.hook.ts
831
890
  /**
@@ -851,7 +910,7 @@ const traverse = ({ transformer, getObject }) => (context, next) => {
851
910
  if (next) return next();
852
911
  return context;
853
912
  };
854
-
855
913
  //#endregion
856
- export { createRelated as _, softDelete as a, cache as b, setField as c, paramsFromClient as d, paramsForServer as f, debug as g, disablePagination as h, stashable as i, setData as l, disallow as m, throwIfIsProvider as n, setSlug as o, onDelete as p, throwIfIsMulti as r, setResult as s, traverse as t, preventChanges as u, checkRequired as v, checkMulti as y };
857
- //# sourceMappingURL=traverse.hook-C2VIvQrn.mjs.map
914
+ export { debug as _, softDelete as a, checkMulti as b, setField as c, preventChanges as d, paramsFromClient as f, disablePagination as g, disallow as h, stashable as i, setData as l, onDelete as m, throwIfIsProvider as n, setSlug as o, paramsForServer as p, throwIfIsMulti as r, setResult as s, traverse as t, rateLimit as u, createRelated as v, cache as x, checkRequired as y };
915
+
916
+ //# sourceMappingURL=hooks-DPFxxjBu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-DPFxxjBu.mjs","names":["defaultError"],"sources":["../src/hooks/cache/cache-utils.ts","../src/hooks/cache/cache.hook.ts","../src/hooks/check-multi/check-multi.hook.ts","../src/hooks/check-required/check-required.hook.ts","../src/hooks/create-related/create-related.hook.ts","../src/hooks/debug/debug.hook.ts","../src/hooks/disable-pagination/disable-pagination.hook.ts","../src/hooks/disallow/disallow.hook.ts","../src/hooks/on-delete/on-delete.hook.ts","../src/hooks/params-for-server/params-for-from-shared.ts","../src/hooks/params-for-server/params-for-server.hook.ts","../src/hooks/params-from-client/params-from-client.hook.ts","../src/hooks/prevent-changes/prevent-changes.hook.ts","../src/hooks/rate-limit/rate-limit.hook.ts","../src/hooks/set-data/set-data.hook.ts","../src/hooks/set-field/set-field.hook.ts","../src/hooks/set-result/set-result.hook.ts","../src/hooks/set-slug/set-slug.hook.ts","../src/hooks/soft-delete/soft-delete.hook.ts","../src/hooks/stashable/stashable.hook.ts","../src/hooks/throw-if-is-multi/throw-if-is-multi.hook.ts","../src/hooks/throw-if-is-provider/throw-if-is-provider.hook.ts","../src/hooks/traverse/traverse.hook.ts"],"sourcesContent":["import isObject from 'lodash/isObject.js'\nimport { sortQueryProperties } from '../../utils/sort-query-properties/sort-query-properties.util.js'\n\nexport { sortQueryProperties }\n\nexport const stableStringify = (obj: Record<string, any>) => {\n if (obj.query) {\n obj = { ...obj, query: sortQueryProperties(obj.query) }\n }\n\n return JSON.stringify(obj, (key, value) => {\n if (typeof value === 'function') {\n throw new Error('Cannot stringify non JSON value')\n }\n\n if (isObject(value)) {\n return Object.keys(value)\n .sort()\n .reduce(\n (result, key) => {\n result[key] = (value as any)[key]\n return result\n },\n {} as Record<string, any>,\n )\n }\n\n return value\n })\n}\n","import type { HookContext, NextFunction, Params } from '@feathersjs/feathers'\nimport { stableStringify } from './cache-utils.js'\nimport { copy } from 'fast-copy'\nimport type { Promisable } from '../../internal.utils.js'\n\ntype Cache = {\n get: (key: string) => Promisable<any>\n set: (key: string, value: any) => Promisable<any>\n delete: (key: string) => Promisable<any>\n clear: () => any\n keys: () => IterableIterator<string>\n}\n\nexport type CacheEvent =\n | { type: 'hit'; method: string; key: string }\n | { type: 'miss'; method: string; key: string }\n | { type: 'set'; method: string; key: string }\n | { type: 'invalidate'; method: string; key: string }\n | { type: 'clear'; method: string }\n\nexport type CacheOptions = {\n /**\n * The cache implementation to use. It should implement the methods `get`, `set`, `delete`, `clear`, and `keys`.\n * This can be a Map, Redis client, or any other cache implementation.\n *\n * Use 'lru-cache' for an LRU cache implementation.\n */\n map: Cache\n /**\n * The id field to use for caching. Defaults to `service.options.id` and if not found, then 'id'.\n */\n id?: string\n /**\n * params are stringified for the key-value cache.\n * There are params properties you don't want to include in the cache key.\n * You can use this function to transform the params before they are stringified.\n */\n transformParams: (params: Params) => Params\n /**\n * Custom serialization function for converting params into a cache key string.\n * By default, uses `stableStringify` which sorts object keys and normalizes\n * query operator arrays (`$or`, `$and`, `$in`, etc.) for order-independent caching.\n *\n * Override this to use a custom serialization strategy.\n *\n * @example\n * ```ts\n * cache({\n * map: new Map(),\n * transformParams: (params) => ({ query: params.query }),\n * serialize: (params) => JSON.stringify(params),\n * })\n * ```\n */\n serialize?: (params: Params) => string\n /**\n * Optional logger callback for cache events (hit, miss, set, invalidate, clear).\n * Useful for debugging and monitoring cache behavior.\n *\n * @example\n * ```ts\n * cache({\n * map: new Map(),\n * transformParams: (params) => ({ query: params.query }),\n * logger: (event) => console.log(`cache ${event.type}`, event),\n * })\n * ```\n */\n logger?: (event: CacheEvent) => void\n}\n\n/**\n * Caches `get` and `find` results based on `params`. On mutating methods (`create`, `update`,\n * `patch`, `remove`), affected cache entries are automatically invalidated.\n * Works as a `before`, `after`, or `around` hook.\n *\n * @example\n * ```ts\n * import { cache } from 'feathers-utils/hooks'\n *\n * const myCache = new Map()\n *\n * app.service('users').hooks({\n * around: {\n * all: [cache({ map: myCache, transformParams: (params) => ({ query: params.query }) })]\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/cache.html\n */\nexport const cache = <H extends HookContext = HookContext>(\n options: CacheOptions,\n) => {\n const cacheMap = new ContextCacheMap(options)\n return async (context: H, next?: NextFunction) => {\n if (context.type === 'before') {\n return await cacheBefore(context, cacheMap)\n }\n if (context.type === 'after') {\n return await cacheAfter(context, cacheMap)\n }\n\n if (context.type === 'around' && next) {\n await cacheBefore(context, cacheMap)\n await next()\n await cacheAfter(context, cacheMap)\n return\n }\n }\n}\n\nconst cacheBefore = async (context: HookContext, cacheMap: ContextCacheMap) => {\n if (context.method === 'get' || context.method === 'find') {\n const value = await cacheMap.get(context)\n if (value) {\n context.result = value\n }\n }\n\n return context\n}\n\nconst cacheAfter = async (context: HookContext, cacheMap: ContextCacheMap) => {\n if (context.method === 'get' || context.method === 'find') {\n await cacheMap.set(context)\n } else {\n await cacheMap.clear(context)\n }\n\n return context\n}\n\nclass ContextCacheMap {\n map: Cache\n private delimiter = ':'\n private options: CacheOptions\n private log: ((event: CacheEvent) => void) | undefined\n private serialize: (params: Params) => string\n\n constructor(options: CacheOptions) {\n this.map = options.map\n this.options = options\n this.log = options.logger\n this.serialize = options.serialize ?? stableStringify\n }\n\n private stringifyCacheKey(context: HookContext) {\n if (context.method !== 'get' && context.method !== 'find') {\n throw new Error(\n `Cache can only be used with 'get' or 'find' methods, not '${context.method}'`,\n )\n }\n\n const stringifiedParams = this.serialize(\n this.options.transformParams(context.params ?? {}),\n )\n\n return `${context.id ?? 'null'}${this.delimiter}${stringifiedParams}`\n }\n\n private getCachedId(key: string) {\n const index = key.indexOf(this.delimiter)\n if (index === -1) {\n throw new Error(\n `Cache key '${key}' does not contain a delimiter '${this.delimiter}'`,\n )\n }\n return key.substring(0, index)\n }\n\n private getId(item: Record<string, any>, context: HookContext) {\n const idField = context.service.options?.id || this.options.id || 'id'\n const id = item[idField]\n return id && id.toString ? id.toString() : id\n }\n\n /**\n * Called before get() and find()\n *\n * returns a cached result for the given context if it exists.\n */\n async get(context: HookContext) {\n const key = this.stringifyCacheKey(context)\n const result = this.map.get(key)\n if (result) {\n this.log?.({ type: 'hit', method: context.method, key })\n return copy(result) // Use copy to avoid mutation of the original result\n }\n this.log?.({ type: 'miss', method: context.method, key })\n }\n\n /**\n * Called after get() and find()\n *\n * Caches the result for the given context.\n */\n async set(context: HookContext) {\n const key = this.stringifyCacheKey(context)\n this.log?.({ type: 'set', method: context.method, key })\n return this.map.set(key, copy(context.result)) // Use copy to avoid mutation of the original result\n }\n\n // Called after create(), update(), patch(), and remove()\n async clear<H extends HookContext>(context: H): Promise<H> {\n const results = Array.isArray(context.result)\n ? context.result\n : [context.result]\n\n const promises: Promise<any>[] = []\n\n const itemIds = results\n .map((item: any) => this.getId(item, context))\n .filter(Boolean)\n\n // If no itemIds are found, clear the entire cache to avoid stale data\n if (!itemIds.length) {\n this.log?.({ type: 'clear', method: context.method })\n await this.map.clear()\n return context\n }\n\n for (const key of this.map.keys()) {\n const cachedId = this.getCachedId(key)\n if (cachedId === 'null') {\n // This is a cached `find` request. Any create/patch/update/del\n // could affect the results of this query so it should be deleted\n this.log?.({ type: 'invalidate', method: context.method, key })\n promises.push(this.map.delete(key))\n continue\n }\n\n // This is a cached `get` request\n\n if (context.method === 'create') {\n // If this is a create, we don't need to delete any cached get requests\n continue\n }\n\n for (const itemId of itemIds) {\n if (cachedId === itemId) {\n // If the cached id matches the item id, delete the cached get\n this.log?.({ type: 'invalidate', method: context.method, key })\n promises.push(this.map.delete(key))\n }\n }\n }\n\n await Promise.all(promises)\n\n return context\n }\n}\n","import type { FeathersError } from '@feathersjs/errors'\nimport { MethodNotAllowed } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { isMulti } from '../../predicates/index.js'\n\nexport type CheckMultiOptions = {\n /**\n * Customize the error that is thrown if the service does not allow multi operations.\n *\n * If not provided, throws a `MethodNotAllowed` error with a message indicating the operation.\n */\n error?: (context: HookContext) => FeathersError\n}\n\n/**\n * Checks if the `multi` option is enabled for the current method and throws a\n * `MethodNotAllowed` error if multi operations are not permitted.\n * Useful to guard against accidental bulk `create`, `patch`, or `remove` calls.\n *\n * @example\n * ```ts\n * import { checkMulti } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { create: [checkMulti()] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/check-multi.html\n */\nexport function checkMulti<H extends HookContext = HookContext>(\n options?: CheckMultiOptions,\n) {\n return (context: H, next?: NextFunction) => {\n const { service, method } = context\n if (\n !service.allowsMulti ||\n !isMulti(context) ||\n method === 'find' ||\n service.allowsMulti(method)\n ) {\n if (next) return next()\n return context\n }\n\n throw options?.error\n ? options.error(context)\n : new MethodNotAllowed(`Can not ${method} multiple entries`)\n }\n}\n","import _get from 'lodash/get.js'\nimport _has from 'lodash/has.js'\nimport { BadRequest } from '@feathersjs/errors'\n\nimport { checkContext, getDataIsArray } from '../../utils/index.js'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\n\n/**\n * Validates that the specified fields exist on `context.data` and are not falsy.\n * Numeric `0` and boolean `false` are treated as valid values.\n * Throws a `BadRequest` error if any required field is missing or null.\n *\n * @example\n * ```ts\n * import { checkRequired } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { create: [checkRequired(['email', 'password'])] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/check-required.html\n */\nexport function checkRequired<H extends HookContext = HookContext>(\n fieldNames: MaybeArray<string>,\n) {\n const fieldNamesArray = toArray(fieldNames)\n return (context: H, next?: NextFunction) => {\n checkContext(context, {\n type: ['before', 'around'],\n method: ['create', 'update', 'patch'],\n label: 'checkRequired',\n })\n\n const { data } = getDataIsArray(context)\n\n for (let i = 0; i < data.length; i++) {\n const item = data[i]\n\n for (let j = 0; j < fieldNamesArray.length; j++) {\n const name = fieldNamesArray[j]\n\n if (!_has(item, name)) {\n throw new BadRequest(`Field ${name} does not exist. (required)`)\n }\n\n const value = _get(item, name)\n\n if (!value && value !== 0 && value !== false) {\n throw new BadRequest(`Field ${name} is null. (required)`)\n }\n }\n }\n\n if (next) return next()\n }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext, getResultIsArray } from '../../utils/index.js'\nimport type { MaybeArray, Promisable } from '../../internal.utils.js'\nimport type { InferCreateDataSingle } from '../../utility-types/infer-service-methods.js'\nimport type { ResultSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport interface CreateRelatedOptions<\n H extends HookContext = HookContext,\n Services extends H['app']['services'] = H['app']['services'],\n S extends keyof Services = keyof Services,\n> {\n service: S\n /**\n * Is relevant when the current context result is an array.\n *\n * If true, will create multiple related records in a single call to the related service's create method.\n * If false or not provided, will create related records one by one.\n *\n * @default false\n */\n multi?: boolean\n /**\n * A function that returns the data to be created in the related service.\n *\n * Receives the current item from the context result and the full hook context as arguments.\n * Can return a single data object, an array of data objects, or a promise that resolves to either.\n *\n * If the function returns undefined, no related record will be created for that item.\n */\n data: (\n item: ResultSingleHookContext<H>,\n context: H,\n ) => Promisable<MaybeArray<InferCreateDataSingle<Services[S]>> | undefined>\n}\n\n/**\n * Creates related records in other services after a successful `create` call.\n * For each result item, a `data` function produces the record to create in the target service.\n * Supports creating records one-by-one or in a single multi-create when `multi: true`.\n *\n * @example\n * ```ts\n * import { createRelated } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * after: {\n * create: [createRelated({ service: 'profiles', data: (user) => ({ userId: user.id }) })]\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/create-related.html\n */\nexport function createRelated<H extends HookContext = HookContext>(\n options: MaybeArray<CreateRelatedOptions<H>>,\n) {\n return async (context: H, next?: NextFunction) => {\n checkContext(context, {\n type: ['after', 'around'],\n method: ['create'],\n label: 'createRelated',\n })\n\n if (next) {\n await next()\n }\n\n const { result } = getResultIsArray(context)\n\n const entries = Array.isArray(options) ? options : [options]\n\n await Promise.all(\n entries.map(async (entry) => {\n const { data, service, multi } = entry\n\n const dataToCreate = (\n await Promise.all(result.map(async (item) => data(item, context)))\n )\n .flat()\n .filter((x) => !!x)\n\n if (!dataToCreate || dataToCreate.length <= 0) {\n return context\n }\n\n if (multi || dataToCreate.length === 1) {\n await context.app\n .service(service as string)\n .create(\n dataToCreate.length === 1\n ? (dataToCreate[0] as any)\n : (dataToCreate as any),\n )\n } else {\n await Promise.all(\n dataToCreate.map(async (item) =>\n context.app.service(service as string).create(item as any),\n ),\n )\n }\n }),\n )\n }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\n\n/**\n * Logs the current hook context to the console for debugging purposes.\n * Displays timestamp, service path, method, type, id, data, query, result, and\n * any additional param fields you specify.\n *\n * @example\n * ```ts\n * import { debug } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { find: [debug('before find', 'user')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/debug.html\n */\nexport const debug =\n <H extends HookContext = HookContext>(msg: string, ...fieldNames: string[]) =>\n async (context: H, next?: NextFunction) => {\n if (next) {\n await next()\n }\n\n // display timestamp\n const now = new Date()\n console.log(\n `${now.getFullYear()}-${\n now.getMonth() + 1\n }-${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`,\n )\n\n if (msg) {\n console.log(msg)\n }\n\n // display service, method & type of hook (before/after/error)\n console.log(\n `${context.type} service('${context.path}').${context.method}()`,\n )\n\n // display id for get, patch, update & remove\n if (!['find', 'create'].includes(context.method) && 'id' in context) {\n console.log('id:', context.id)\n }\n\n if (context.data) {\n console.log('data:', context.data)\n }\n\n if (context.params?.query) {\n console.log('query:', context.params.query)\n }\n\n if (context.result) {\n console.log('result:', context.result)\n }\n\n // display additional params\n const params = context.params || {}\n console.log('params props:', Object.keys(params).sort())\n\n fieldNames.forEach((name) => {\n console.log(`params.${name}:`, params[name])\n })\n\n if (context.error) {\n console.log('error', context.error)\n }\n }\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext } from '../../utils/index.js'\n\n/**\n * Disables pagination when `query.$limit` is `-1` or `'-1'`.\n * Removes the `$limit` from the query and sets `params.paginate = false`.\n * Must be used as a `before` or `around` hook on the `find` method.\n *\n * @example\n * ```ts\n * import { disablePagination } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { find: [disablePagination()] }\n * })\n * // Then call: app.service('users').find({ query: { $limit: -1 } })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/disable-pagination.html\n */\nexport const disablePagination =\n <H extends HookContext = HookContext>() =>\n (context: H, next?: NextFunction) => {\n checkContext(context, {\n type: ['before', 'around'],\n method: ['find'],\n label: 'disablePagination',\n })\n const $limit = context.params?.query?.$limit\n\n if ($limit === '-1' || $limit === -1) {\n context.params.paginate = false\n delete context.params.query.$limit\n }\n\n if (next) return next()\n\n return context\n }\n","import { MethodNotAllowed } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { TransportName } from '../../types.js'\nimport { isProvider } from '../../predicates/index.js'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\n\n/**\n * Prevents access to a service method completely or for specific transports.\n * When called without arguments, the method is blocked for all callers.\n * When called with transport names, only those transports are blocked.\n *\n * @example\n * ```ts\n * import { disallow } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: {\n * remove: [disallow('external')], // block external access\n * update: [disallow()], // block completely\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/disallow.html\n */\nexport const disallow = <H extends HookContext = HookContext>(\n transports?: MaybeArray<TransportName>,\n) => {\n const transportsArr = toArray(transports)\n return (context: H, next?: NextFunction) => {\n if (!transports) {\n throw new MethodNotAllowed('Method not allowed')\n }\n\n if (isProvider(...(transportsArr as TransportName[]))(context)) {\n throw new MethodNotAllowed(\n `Provider '${context.params.provider}' can not call '${context.method}' on '${context.path}'. (disallow)`,\n )\n }\n\n if (next) return next().then(() => context)\n }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext, getResultIsArray } from '../../utils/index.js'\nimport type { MaybeArray, NeverFallback } from '../../internal.utils.js'\nimport type {\n InferFindParams,\n InferGetResult,\n} from '../../utility-types/infer-service-methods.js'\nimport type { ResultSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type OnDeleteAction = 'cascade' | 'set null'\n\nexport interface OnDeleteOptions<\n H extends HookContext = HookContext,\n S extends keyof H['app']['services'] = keyof H['app']['services'],\n> {\n /**\n * The related service where related items should be manipulated\n */\n service: S\n /**\n * The propertyKey in the related service\n */\n keyThere: NeverFallback<keyof InferGetResult<H['app']['services'][S]>, string>\n /**\n * The propertyKey in the current service.\n */\n keyHere: keyof ResultSingleHookContext<H>\n /**\n * The action to perform on the related items.\n *\n * - `cascade`: remove related items\n * - `set null`: set the related property to null\n */\n onDelete: OnDeleteAction\n /**\n * Additional query to merge into the service call.\n * Typed based on the related service's query type.\n */\n query?: InferFindParams<H['app']['services'][S]>['query']\n /**\n * If true, the hook will wait for the service to finish before continuing\n *\n * @default false\n */\n blocking?: boolean\n}\n\n/**\n * Manipulates related items when a record is deleted, similar to SQL foreign key actions.\n * Supports `'cascade'` (remove related records) and `'set null'` (nullify the foreign key).\n * Unlike database-level cascades, this hook triggers service events and hooks for related items.\n *\n * @example\n * ```ts\n * import { onDelete } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * after: {\n * remove: [onDelete({ service: 'posts', keyHere: 'id', keyThere: 'userId', onDelete: 'cascade' })]\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/on-delete.html\n */\ntype OnDeleteOptionsDistributed<H extends HookContext> = {\n [S in keyof H['app']['services'] & string]: OnDeleteOptions<H, S>\n}[keyof H['app']['services'] & string]\n\nexport const onDelete = <H extends HookContext = HookContext>(\n options: MaybeArray<OnDeleteOptionsDistributed<H>>,\n) => {\n const optionsMulti = Array.isArray(options) ? options : [options]\n\n return async (context: H, next?: NextFunction) => {\n checkContext(context, {\n type: ['after', 'around'],\n method: 'remove',\n label: 'onDelete',\n })\n\n if (next) {\n await next()\n }\n\n const { result } = getResultIsArray(context)\n\n if (!result.length) {\n return\n }\n\n const promises: Promise<any>[] = []\n\n optionsMulti.forEach(\n async ({ keyHere, keyThere, onDelete, service, blocking, query }) => {\n let ids = result.map((x) => x[keyHere]).filter((x) => !!x)\n ids = [...new Set(ids)]\n\n if (!ids || ids.length <= 0) {\n return context\n }\n\n const params = {\n query: {\n ...query,\n ...(ids.length === 1\n ? { [keyThere]: ids[0] }\n : { [keyThere]: { $in: ids } }),\n },\n paginate: false,\n }\n\n let promise: Promise<any> | undefined = undefined\n\n if (onDelete === 'cascade') {\n promise = context.app.service(service as string).remove(null, params)\n } else if (onDelete === 'set null') {\n const data = { [keyThere]: null }\n promise = context.app\n .service(service as string)\n .patch(null, data, params)\n }\n\n if (promise && blocking) {\n promises.push(promise)\n }\n },\n )\n\n if (promises.length) {\n await Promise.all(promises)\n }\n\n return\n }\n}\n","export const FROM_CLIENT_FOR_SERVER_DEFAULT_KEY = '_$client' as const\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from './params-for-from-shared.js'\n\nexport type ParamsForServerOptions = {\n /**\n * @default '_$client'\n */\n keyToHide?: string\n}\n\n/**\n * Client-side hook that moves whitelisted `params` properties into `query._$client`\n * so they survive the client-to-server transport. The server only receives `query`\n * from params — use `paramsFromClient` on the server to restore them.\n *\n * @example\n * ```ts\n * import { paramsForServer } from 'feathers-utils/hooks'\n *\n * // Client-side\n * app.service('users').hooks({\n * before: { all: [paramsForServer('populateParams')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/params-for-server.html\n */\nexport const paramsForServer = (\n whitelist: MaybeArray<string>,\n options?: ParamsForServerOptions,\n) => {\n const whitelistArr = toArray(whitelist)\n\n const { keyToHide = FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } = options || {}\n\n return <H extends HookContext>(context: H, next?: NextFunction) => {\n // clone params on demand\n let clonedParams: any\n\n Object.keys(context.params).forEach((key) => {\n if (key === 'query') {\n return\n }\n\n if (whitelistArr.includes(key)) {\n if (!clonedParams) {\n clonedParams = {\n ...context.params,\n query: {\n ...context.params.query,\n },\n }\n }\n\n if (!clonedParams.query[keyToHide]) {\n clonedParams.query[keyToHide] = {}\n }\n\n clonedParams.query[keyToHide][key] = clonedParams[key]\n delete clonedParams[key]\n }\n })\n\n if (clonedParams) {\n context.params = clonedParams\n }\n\n if (next) {\n return next()\n }\n\n return context\n }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport { FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } from '../params-for-server/params-for-from-shared.js'\n\nexport type paramsFromClientOptions = {\n /**\n * @default '_$client'\n */\n keyToHide?: string\n}\n\n/**\n * Server-side hook that extracts whitelisted properties from `query._$client` back\n * into `context.params`. This is the counterpart to `paramsForServer`, which encodes\n * params on the client side for transport.\n *\n * @example\n * ```ts\n * import { paramsFromClient } from 'feathers-utils/hooks'\n *\n * // Server-side\n * app.service('users').hooks({\n * before: { all: [paramsFromClient('populateParams')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/params-from-client.html\n */\nexport const paramsFromClient = (\n whitelist: MaybeArray<string>,\n options?: paramsFromClientOptions,\n) => {\n const whitelistArr = toArray(whitelist)\n const { keyToHide = FROM_CLIENT_FOR_SERVER_DEFAULT_KEY } = options || {}\n return (context: HookContext, next?: NextFunction) => {\n if (\n !context.params?.query?.[keyToHide] ||\n typeof context.params.query[keyToHide] !== 'object'\n ) {\n if (next) return next()\n return context\n }\n\n const params = {\n ...context.params,\n query: {\n ...context.params.query,\n [keyToHide]: {\n ...context.params.query[keyToHide],\n },\n },\n }\n\n const client = params.query[keyToHide]\n\n whitelistArr.forEach((key) => {\n if (key in client) {\n params[key] = client[key]\n delete client[key]\n }\n })\n\n if (Object.keys(client).length === 0) {\n delete params.query[keyToHide]\n }\n\n context.params = params\n\n if (next) {\n return next()\n }\n\n return context\n }\n}\n","import _has from 'lodash/has.js'\nimport _omit from 'lodash/omit.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { BadRequest } from '@feathersjs/errors'\nimport { transformData } from '../transform-data/transform-data.hook.js'\nimport type { KeyOfOrDotNotation, MaybeArray } from '../../internal.utils.js'\nimport { toArray } from '../../internal.utils.js'\nimport type { HookContext } from '@feathersjs/feathers'\nimport type { DataSingleHookContext } from '../../utility-types/hook-context.js'\n\nexport type PreventChangesOptions<D, Keys extends KeyOfOrDotNotation<D>> = {\n /**\n * Customize the error that is thrown if the service tries to patch a field that is not allowed.\n *\n * If not provided, throws a `BadRequest` error with a message indicating the field that is not allowed.\n */\n error?: boolean | ((item: D, name: Keys) => FeathersError)\n}\n\n/**\n * Prevents `patch` calls from modifying certain fields. By default, the protected\n * fields are silently removed from `context.data`. When `error` is set, a `BadRequest`\n * is thrown if any protected field is present.\n *\n * Supports dot.notation for nested fields.\n *\n * @example\n * ```ts\n * import { preventChanges } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { patch: [preventChanges(['email', 'role'], { error: true })] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/prevent-changes.html\n */\nexport const preventChanges = <\n H extends HookContext = HookContext,\n D extends DataSingleHookContext<H> = DataSingleHookContext<H>,\n Keys extends KeyOfOrDotNotation<D> = KeyOfOrDotNotation<D>,\n>(\n fieldNames: MaybeArray<Keys>,\n options?: PreventChangesOptions<D, Keys>,\n) => {\n const fieldNamesArr = toArray(fieldNames)\n\n return transformData<H>((item) => {\n if (options?.error) {\n for (let i = 0; i < fieldNamesArr.length; i++) {\n const name = fieldNamesArr[i]\n\n if (_has(item, name)) {\n const error =\n typeof options.error === 'function'\n ? options.error(item as D, name)\n : new BadRequest(\n `Field ${String(name)} may not be patched. (preventChanges)`,\n )\n\n throw error\n }\n }\n } else {\n return _omit(item, fieldNamesArr)\n }\n\n return item\n })\n}\n","import { TooManyRequests } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { RateLimiterAbstract, RateLimiterRes } from 'rate-limiter-flexible'\nimport { checkContext } from '../../utils/index.js'\nimport type { Promisable } from '../../internal.utils.js'\n\nexport type RateLimitOptions<H extends HookContext = HookContext> = {\n /** Generate the rate-limiting key. Defaults to `context.path`. */\n key?: (context: H) => Promisable<string>\n /** Number of points to consume per request. Defaults to `1`. */\n points?: (context: H) => Promisable<number>\n}\n\n/**\n * Rate limits service method calls using `rate-limiter-flexible`.\n * You provide a pre-configured `RateLimiterAbstract` instance\n * (Memory, Redis, Mongo, etc.) and the hook consumes points per request.\n *\n * @example\n * ```ts\n * import { rateLimit } from 'feathers-utils/hooks'\n * import { RateLimiterMemory } from 'rate-limiter-flexible'\n *\n * const rateLimiter = new RateLimiterMemory({ points: 10, duration: 1 })\n *\n * app.service('users').hooks({\n * before: { find: [rateLimit(rateLimiter)] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/rate-limit.html\n */\nexport const rateLimit = <H extends HookContext = HookContext>(\n rateLimiter: RateLimiterAbstract,\n options?: RateLimitOptions<H>,\n) => {\n const key = options?.key ?? ((context: HookContext) => context.path)\n const points = options?.points ?? (() => 1)\n\n return async (context: H, next?: NextFunction) => {\n checkContext(context, { type: ['before', 'around'], label: 'rateLimit' })\n\n const resolvedKey = await key(context)\n const resolvedPoints = await points(context)\n\n try {\n const res = await rateLimiter.consume(resolvedKey, resolvedPoints)\n context.params.rateLimit = res\n } catch (res) {\n context.params.rateLimit = res as RateLimiterRes\n throw new TooManyRequests('Too many requests', {\n rateLimitRes: res as RateLimiterRes,\n })\n }\n\n if (next) return await next()\n }\n}\n","import _get from 'lodash/get.js'\nimport _set from 'lodash/set.js'\nimport _has from 'lodash/has.js'\n\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\n\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { PropertyPath } from 'lodash'\nimport { contextToJson } from '../../utils/context-to-json/context-to-json.util.js'\nimport { getDataIsArray } from '../../utils/index.js'\nimport type { PredicateItemWithContext } from '../../types.js'\n\nexport interface HookSetDataOptions {\n /**\n * Wether to throw if the context[from] is undefined.\n *\n * @default false\n */\n allowUndefined?: boolean\n /**\n * @default true\n */\n overwrite?: boolean | PredicateItemWithContext\n /**\n * Customize the error that is thrown if the context[from] is not available.\n * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n */\n error?: (context: HookContext, from: PropertyPath) => FeathersError\n}\n\n/**\n * Sets a property on each item in `context.data` from another property on the hook context.\n * Supports dot-notation paths for both source and target. Throws a `Forbidden` error\n * if the source field is missing (unless `allowUndefined` is `true`).\n *\n * @example\n * ```ts\n * import { setData } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n * before: { create: [setData('params.user.id', 'userId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-data.html\n */\nexport function setData<H extends HookContext = HookContext>(\n /**\n * The property path of the context to set the value from. 'dot.notation' is supported.\n *\n * If the property does not exist, the hook will throw an error unless `allowUndefined` is set to true.\n * If the property exists, it will be set to the value of the `to` property path of the data item.\n *\n * @example 'params.user.id'\n */\n from: PropertyPath,\n /**\n * The property path of the data item to set the value to. 'dot.notation' is supported.\n *\n * If the property does not exist, it will be created.\n * If the property exists, it will be overwritten unless `overwrite` is set to false.\n *\n * @example 'userId'\n */\n to: PropertyPath,\n options?: HookSetDataOptions,\n) {\n const { allowUndefined = false, overwrite = true } = options ?? {}\n\n return (context: H, next?: NextFunction) => {\n const { data } = getDataIsArray(context)\n\n const contextJson = contextToJson(context)\n\n if (!_has(contextJson, from)) {\n if (!context.params?.provider || allowUndefined === true) {\n if (next) return next()\n return context\n }\n\n if (\n !overwrite &&\n data.every((item: Record<string, unknown>) => _has(item, to))\n ) {\n if (next) return next()\n return context\n }\n\n throw options?.error\n ? options.error(context, from)\n : new Forbidden(`Expected field ${from.toString()} not available`)\n }\n\n const val = _get(contextJson, from)\n\n for (let i = 0, len = data.length; i < len; i++) {\n const item: Record<string, unknown> = data[i]\n\n const currentOverwrite =\n typeof overwrite === 'function' ? overwrite(item, context) : overwrite\n\n if (!currentOverwrite && _has(item, to)) {\n continue\n }\n\n _set(item, to, val)\n }\n\n if (next) {\n return next()\n }\n\n return context\n }\n}\n","import _get from 'lodash/get.js'\nimport _setWith from 'lodash/setWith.js'\nimport _clone from 'lodash/clone.js'\nimport { checkContext } from '../../utils/index.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\n\nexport interface SetFieldOptions {\n as: string\n from: string\n /**\n * If set to `true`, allows the field to be undefined.\n * If the field is not available and this is `true`, the hook will not throw an error.\n *\n * If set to `false`, the hook will throw an error if the field is not available.\n *\n * @default false\n */\n allowUndefined?: boolean\n /**\n * Customize the error that is thrown if the field is not available.\n *\n * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n */\n error?: (context: HookContext, from: string) => FeathersError\n}\n\n/**\n * Sets a field on the hook context (e.g. `params.query`) based on the value of another\n * context field (e.g. `params.user.id`). Useful for scoping queries to the authenticated user.\n * Throws a `Forbidden` error if the source field is missing (unless `allowUndefined` is `true`).\n *\n * @example\n * ```ts\n * import { setField } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n * before: { all: [setField({ from: 'params.user.id', as: 'params.query.userId' })] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-field.html\n */\nexport const setField =\n <H extends HookContext = HookContext>({\n as,\n from,\n allowUndefined = false,\n error,\n }: SetFieldOptions) =>\n (context: H, next?: NextFunction) => {\n const { params } = context\n\n checkContext(context, { type: ['before', 'around'], label: 'setField' })\n\n const value = _get(context, from)\n\n if (value === undefined) {\n if (!params.provider || allowUndefined) {\n if (next) return next()\n return context\n }\n\n throw error\n ? error(context, from)\n : new Forbidden(`Expected field ${as} not available`)\n }\n\n context = _setWith(context, as, value, _clone)\n\n if (next) return next()\n\n return context\n }\n","import _get from 'lodash/get.js'\nimport _set from 'lodash/set.js'\nimport _has from 'lodash/has.js'\n\nimport type { FeathersError } from '@feathersjs/errors'\nimport { Forbidden } from '@feathersjs/errors'\n\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport type { PropertyPath } from 'lodash'\nimport { contextToJson } from '../../utils/context-to-json/context-to-json.util.js'\nimport { getResultIsArray } from '../../utils/index.js'\nimport type { DispatchOption, PredicateItemWithContext } from '../../types.js'\n\nexport interface SetResultOptions {\n /**\n * Wether to throw if the context[from] is undefined.\n *\n * @default false\n */\n allowUndefined?: boolean\n /**\n * @default true\n */\n overwrite?: boolean | PredicateItemWithContext\n /**\n * Customize the error that is thrown if the context[from] is not available.\n * If not provided, throws a `Forbidden` error with a message indicating the missing field.\n */\n error?: (context: HookContext, from: PropertyPath) => FeathersError\n dispatch?: DispatchOption\n}\n\n/**\n * Sets a property on each item in `context.result` from another property on the hook context.\n * Supports dot-notation paths for both source and target, and can optionally\n * operate on `context.dispatch` as well.\n *\n * @example\n * ```ts\n * import { setResult } from 'feathers-utils/hooks'\n *\n * app.service('posts').hooks({\n * after: { all: [setResult('params.user.id', 'currentUserId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-result.html\n */\nexport function setResult<H extends HookContext = HookContext>(\n /**\n * The property path of the context to set the value from. 'dot.notation' is supported.\n *\n * If the property does not exist, the hook will throw an error unless `allowUndefined` is set to true.\n * If the property exists, it will be set to the value of the `to` property path of the data item.\n *\n * @example 'params.user.id'\n */\n from: PropertyPath,\n /**\n * The property path of the data item to set the value to. 'dot.notation' is supported.\n *\n * If the property does not exist, it will be created.\n * If the property exists, it will be overwritten unless `overwrite` is set to false.\n *\n * @example 'userId'\n */\n to: PropertyPath,\n options?: SetResultOptions,\n) {\n const { allowUndefined = false, overwrite = true } = options ?? {}\n\n const forResultOrDispatch = (context: H, dispatch: boolean) => {\n const { result } = getResultIsArray(context, { dispatch })\n\n const contextJson = contextToJson(context)\n\n if (!_has(contextJson, from)) {\n if (!context.params?.provider || allowUndefined === true) {\n return context\n }\n\n if (\n !overwrite &&\n result.every((item: Record<string, unknown>) => _has(item, to))\n ) {\n return context\n }\n\n throw options?.error\n ? options.error(context, from)\n : new Forbidden(`Expected field ${from.toString()} not available`)\n }\n\n const val = _get(contextJson, from)\n\n for (let i = 0; i < result.length; i++) {\n const item: Record<string, unknown> = result[i]\n\n const currentOverwrite =\n typeof overwrite === 'function' ? overwrite(item, context) : overwrite\n\n if (!currentOverwrite && _has(item, to)) {\n continue\n }\n\n _set(item, to, val)\n }\n\n return context\n }\n\n const fn = (context: H) => {\n if (options?.dispatch === 'both') {\n forResultOrDispatch(context, true)\n return forResultOrDispatch(context, false)\n }\n\n return forResultOrDispatch(context, !!options?.dispatch)\n }\n\n return (context: H, next?: NextFunction) => {\n if (next) {\n return next().then(() => fn(context))\n }\n\n return fn(context)\n }\n}\n","import _set from 'lodash/set.js'\nimport type { HookContext, NextFunction } from '@feathersjs/feathers'\n\n/**\n * Extracts URL route parameters (slugs) and sets them on `params.query`.\n * For example, given a route `/stores/:storeId`, this hook copies the resolved\n * `storeId` value from `params.route` into the query. Only applies to the `rest` provider.\n *\n * @example\n * ```ts\n * import { setSlug } from 'feathers-utils/hooks'\n *\n * app.service('stores/:storeId/products').hooks({\n * before: { all: [setSlug('storeId')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/set-slug.html\n */\nexport const setSlug = <H extends HookContext = HookContext>(\n slug: string,\n fieldName?: string,\n) => {\n if (typeof fieldName !== 'string') {\n fieldName = `query.${slug}`\n }\n\n return (context: H, next?: NextFunction) => {\n if (context.params && context.params.provider === 'rest') {\n const value = context.params.route[slug]\n if (typeof value === 'string' && value[0] !== ':') {\n _set(context.params, fieldName, value)\n }\n }\n\n if (next) return next()\n\n return context\n }\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { addToQuery, checkContext } from '../../utils/index.js'\nimport type { TransformParamsFn } from '../../types.js'\nimport { transformParams } from '../../utils/transform-params/transform-params.util.js'\nimport { early, type Promisable } from '../../internal.utils.js'\nimport { isPromise } from '../../common/index.js'\n\nexport type SoftDeleteOptionFunction<H extends HookContext = HookContext> = (\n context?: H,\n) => Promisable<{ [key: string]: any }>\n\nexport interface SoftDeleteOptions<H extends HookContext = HookContext> {\n /**\n * @example { deletedAt: null }\n */\n deletedQuery: { [key: string]: any } | SoftDeleteOptionFunction<H>\n /**\n * @example { deletedAt: new Date() }\n */\n removeData: { [key: string]: any } | SoftDeleteOptionFunction<H>\n /**\n * Transform the params before calling the service method. E.g. remove 'params.provider' or add custom params.\n */\n transformParams?: TransformParamsFn\n\n /**\n * Key in `params` to disable the soft delete functionality.\n *\n * @default 'disableSoftDelete'\n */\n disableSoftDeleteKey?: string\n\n /**\n * `softDelete` uses `._patch()` internally to mark items as deleted.\n *\n * If you set this option to `true`, it will use the `.patch()` method with hooks instead.\n */\n usePatchWithHooks?: boolean\n}\n\n/**\n * Marks items as deleted instead of physically removing them. On `remove`, the hook\n * patches the record with `removeData` (e.g. `{ deletedAt: new Date() }`). On all other\n * methods, it appends `deletedQuery` (e.g. `{ deletedAt: null }`) to filter out soft-deleted items.\n *\n * @example\n * ```ts\n * import { softDelete } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * around: {\n * all: [softDelete({ deletedQuery: { deletedAt: null }, removeData: { deletedAt: new Date() } })]\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/soft-delete.html\n */\nexport const softDelete = <H extends HookContext = HookContext>(\n options: SoftDeleteOptions<H>,\n) => {\n if (!options?.deletedQuery || !options?.removeData) {\n throw new Error(\n 'You must provide `deletedQuery` and `removeData` options to the softDelete hook.',\n )\n }\n\n return async (context: H, next?: NextFunction) => {\n checkContext(context, { type: ['before', 'around'], label: 'softDelete' })\n\n const { disableSoftDeleteKey = 'disableSoftDelete' } = options\n\n if (context.params[disableSoftDeleteKey]) {\n return early(context, next)\n }\n\n const { deletedQuery, removeData } = options\n\n let deleteQuery = getValue(deletedQuery, context)\n if (isPromise(deleteQuery)) {\n deleteQuery = await deleteQuery\n }\n\n const query = addToQuery(context.params.query, deleteQuery)\n\n const params = transformParams(\n {\n ...context.params,\n query,\n },\n options.transformParams,\n )\n\n context.params = params\n\n if (context.method === 'remove') {\n let data = getValue(removeData, context)\n if (isPromise(data)) {\n data = await data\n }\n const method = options.usePatchWithHooks ? 'patch' : '_patch'\n const result = await context.service[method](context.id, data, params)\n\n context.result = result\n }\n\n if (next) {\n return await next()\n }\n\n return context\n }\n}\n\nconst getValue = (value: any, ...args: any[]) => {\n if (typeof value === 'function') {\n return value(...args)\n }\n return value\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { checkContext } from '../../utils/index.js'\n\nexport type StashableOptions = {\n /** The property name on `context.params` to store the stash function. @default 'stashed' */\n propName?: string\n /** Custom function to fetch the pre-mutation state. Defaults to `service.get` or `service.find`. */\n stashFunc?: (context: HookContext) => Promise<any>\n}\n\nconst defaultStashFunc = (context: HookContext) => {\n const isMulti = context.id == null\n\n const params = {\n ...context.params,\n _stashable: true,\n ...(isMulti ? { paginate: false } : {}),\n }\n\n return isMulti\n ? context.service.find(params)\n : context.service.get(context.id, params)\n}\n\n/**\n * Stashes the pre-mutation state of a record into `context.params`.\n * Eagerly starts the fetch but exposes a memoized function — calling it\n * multiple times only hits the database once.\n * Use in `before` hooks on `update`, `patch`, or `remove` methods.\n *\n * @example\n * ```ts\n * import { stashable } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { patch: [stashable()] }\n * })\n *\n * // In a later hook (before or after):\n * const before = await context.params.stashed()\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/stashable.html\n */\nexport function stashable<H extends HookContext = HookContext>(\n options?: StashableOptions,\n): {\n (context: H, next: NextFunction): Promise<void>\n (context: H): H\n} {\n const propName = options?.propName ?? 'stashed'\n const stashFunc = options?.stashFunc ?? defaultStashFunc\n\n return ((context: H, next?: NextFunction) => {\n if (context.params._stashable) {\n if (next) return next()\n return context\n }\n\n checkContext(context, {\n type: ['before', 'around'],\n method: ['update', 'patch', 'remove'],\n label: 'stashable',\n })\n\n const promise = stashFunc(context).catch(() => undefined)\n\n context.params[propName] = () => promise\n\n if (next) return next()\n return context\n }) as any\n}\n","import type { HookContext } from '@feathersjs/feathers'\nimport type { PredicateFn } from '../../types.js'\nimport { BadRequest, type FeathersError } from '@feathersjs/errors'\nimport { every, isMulti } from '../../predicates/index.js'\nimport { throwIf } from '../throw-if/throw-if.hook.js'\n\nexport type ThrowIfIsMultiOptions = {\n /**\n * A predicate function to filter the contexts that should be checked for multi operations.\n * If provided, only contexts that pass this predicate will be checked for multi operations.\n */\n filter?: PredicateFn\n /**\n * Customize the error that is thrown if the context is multi and the service does not allow it.\n * If not provided, throws a `BadRequest` error.\n */\n error?: (context: HookContext) => FeathersError\n}\n\nconst defaultError = (context: HookContext) =>\n new BadRequest(`Cannot perform multi operation on method '${context.method}'`)\n\n/**\n * Throws a `BadRequest` error when the current operation is a multi operation\n * (array data on `create`, or `id === null` on `patch`/`remove`).\n * Useful to prevent bulk operations on services that should only handle single items.\n *\n * @example\n * ```ts\n * import { throwIfIsMulti } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * before: { all: [throwIfIsMulti()] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/throw-if-is-multi.html\n */\nexport const throwIfIsMulti = <H extends HookContext = HookContext>(\n options?: ThrowIfIsMultiOptions,\n) =>\n throwIf<H>(\n every(\n every(isMulti, (context) => context.method !== 'find'),\n options?.filter,\n ),\n {\n error: options?.error ?? defaultError,\n },\n )\n","import type { HookContext } from '@feathersjs/feathers'\nimport type { PredicateFn, TransportName } from '../../types.js'\nimport { throwIf } from '../throw-if/throw-if.hook.js'\nimport { every, isProvider } from '../../predicates/index.js'\nimport type { FeathersError } from '@feathersjs/errors'\nimport { MethodNotAllowed } from '@feathersjs/errors'\nimport { toArray } from '../../internal.utils.js'\n\nconst defaultError = (context: HookContext) =>\n new MethodNotAllowed(\n `Provider '${context.params.provider}' can not call '${context.method}'.`,\n )\n\nexport type ThrowIfIsIsProviderOptions = {\n filter?: PredicateFn\n /**\n * Customize the error that is thrown if the context is a provider and the service does not allow it.\n * If not provided, throws a `MethodNotAllowed` error.\n */\n error?: (context: HookContext) => FeathersError\n}\n\n/**\n * Throws a `MethodNotAllowed` error when the request comes from one of the specified transports.\n * Combines `throwIf` with the `isProvider` predicate for a convenient one-liner.\n * Use this to restrict methods to server-only or specific transport types.\n *\n * @example\n * ```ts\n * import { throwIfIsProvider } from 'feathers-utils/hooks'\n *\n * app.service('internal').hooks({\n * before: { all: [throwIfIsProvider('external')] }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/throw-if-is-provider.html\n */\nexport const throwIfIsProvider = <H extends HookContext = HookContext>(\n transports: TransportName | TransportName[],\n options?: ThrowIfIsIsProviderOptions,\n) => {\n const disallowTransports = toArray(transports)\n\n return throwIf<H>(\n every(isProvider(...(disallowTransports as any)), options?.filter),\n {\n error: options?.error ?? defaultError,\n },\n )\n}\n","import type { HookContext, NextFunction } from '@feathersjs/feathers'\nimport { traverse as _traverse } from '../../common/index.js'\n\nexport type TraverseOptions = {\n transformer: (transformContext: any) => any\n getObject: (\n context: HookContext,\n ) => Record<string, any> | Record<string, any>[]\n}\n\n/**\n * Recursively walks and transforms fields in record(s) using `neotraverse`.\n * The `getObject` function extracts the target from the context, and `transformer`\n * is called for every node during traversal --- ideal for deep, structural transformations.\n *\n * @example\n * ```ts\n * import { traverse } from 'feathers-utils/hooks'\n *\n * app.service('users').hooks({\n * after: {\n * all: [traverse({ getObject: (ctx) => ctx.result, transformer: function () { if (this.key === 'password') this.remove() } })]\n * }\n * })\n * ```\n *\n * @see https://utils.feathersjs.com/hooks/traverse.html\n */\nexport const traverse =\n <H extends HookContext = HookContext>({\n transformer,\n getObject,\n }: TraverseOptions) =>\n (context: H, next?: NextFunction) => {\n _traverse(getObject(context), transformer)\n\n if (next) {\n return next()\n }\n\n return context\n }\n"],"mappings":"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"}