@classytic/arc 2.1.2 → 2.1.3

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 (261) hide show
  1. package/dist/{EventTransport-BD2U0BTc.d.mts → EventTransport-BkUDYZEb.d.mts} +1 -2
  2. package/dist/HookSystem-BsGV-j2l.mjs +1 -2
  3. package/dist/{ResourceRegistry-DsN4KJjV.mjs → ResourceRegistry-7Ic20ZMw.mjs} +1 -2
  4. package/dist/adapters/index.d.mts +4 -4
  5. package/dist/audit/index.d.mts +5 -6
  6. package/dist/audit/index.mjs +2 -3
  7. package/dist/audit/mongodb.d.mts +4 -4
  8. package/dist/audit/mongodb.mjs +1 -1
  9. package/dist/{audited-C3T5DTUx.mjs → audited-CGdLiSlE.mjs} +1 -2
  10. package/dist/auth/index.d.mts +6 -7
  11. package/dist/auth/index.mjs +10 -16
  12. package/dist/auth/redis-session.d.mts +2 -3
  13. package/dist/auth/redis-session.mjs +1 -2
  14. package/dist/{betterAuthOpenApi-BrHKeSAx.mjs → betterAuthOpenApi-DjWDddNc.mjs} +2 -3
  15. package/dist/cache/index.d.mts +3 -4
  16. package/dist/cache/index.mjs +4 -5
  17. package/dist/{caching-Bl28lYsR.mjs → caching-GSDJcA6-.mjs} +1 -2
  18. package/dist/{circuitBreaker-DeY4FCjs.mjs → circuitBreaker-DYhWBW_D.mjs} +1 -2
  19. package/dist/cli/commands/describe.d.mts +1 -2
  20. package/dist/cli/commands/describe.mjs +1 -2
  21. package/dist/cli/commands/docs.d.mts +1 -2
  22. package/dist/cli/commands/docs.mjs +3 -4
  23. package/dist/cli/commands/generate.d.mts +1 -2
  24. package/dist/cli/commands/generate.mjs +2 -3
  25. package/dist/cli/commands/init.d.mts +1 -2
  26. package/dist/cli/commands/init.mjs +6 -7
  27. package/dist/cli/commands/introspect.d.mts +1 -2
  28. package/dist/cli/commands/introspect.mjs +2 -3
  29. package/dist/cli/index.d.mts +1 -2
  30. package/dist/cli/index.mjs +1 -2
  31. package/dist/constants-DdXFXQtN.mjs +1 -2
  32. package/dist/core/index.d.mts +4 -4
  33. package/dist/core/index.mjs +1 -1
  34. package/dist/{createApp-CUgNqegw.mjs → createApp-D2D5XXaV.mjs} +9 -10
  35. package/dist/{defineResource-k0_BDn8v.mjs → defineResource-PXzSJ15_.mjs} +11 -11
  36. package/dist/discovery/index.d.mts +1 -2
  37. package/dist/discovery/index.mjs +1 -2
  38. package/dist/docs/index.d.mts +5 -6
  39. package/dist/docs/index.mjs +5 -4
  40. package/dist/{elevation-B_2dRLVP.d.mts → elevation-DGo5shaX.d.mts} +1 -2
  41. package/dist/{elevation-BRy3yFWT.mjs → elevation-DSTbVvYj.mjs} +4 -4
  42. package/dist/{errorHandler-C1okiriz.mjs → errorHandler-C3GY3_ow.mjs} +2 -3
  43. package/dist/{errorHandler-BbcgBmIH.d.mts → errorHandler-CW3OOeYq.d.mts} +2 -3
  44. package/dist/{errors-ChKiFz62.d.mts → errors-DAWRdiYP.d.mts} +1 -2
  45. package/dist/{errors-B9bZok84.mjs → errors-DBANPbGr.mjs} +1 -2
  46. package/dist/{eventPlugin-DGR_B2on.mjs → eventPlugin-BEOvaDqo.mjs} +2 -3
  47. package/dist/{eventPlugin-CTrLH3mt.d.mts → eventPlugin-H6wDDjGO.d.mts} +2 -3
  48. package/dist/events/index.d.mts +4 -5
  49. package/dist/events/index.mjs +2 -3
  50. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  51. package/dist/events/transports/redis-stream-entry.mjs +1 -2
  52. package/dist/events/transports/redis.d.mts +2 -3
  53. package/dist/events/transports/redis.mjs +1 -2
  54. package/dist/{externalPaths-DlINfKbP.d.mts → externalPaths-SyPF2tgK.d.mts} +1 -2
  55. package/dist/factory/index.d.mts +8 -9
  56. package/dist/factory/index.mjs +1 -1
  57. package/dist/{fastifyAdapter-BkrGrlFi.d.mts → fastifyAdapter-C8DlE0YH.d.mts} +4 -5
  58. package/dist/{fields-DyaDVX4J.d.mts → fields-Bi_AVKSo.d.mts} +2 -3
  59. package/dist/{fields-iagOozy0.mjs → fields-CTd_CrKr.mjs} +2 -3
  60. package/dist/hooks/index.d.mts +3 -3
  61. package/dist/idempotency/index.d.mts +4 -5
  62. package/dist/idempotency/index.mjs +1 -2
  63. package/dist/idempotency/mongodb.d.mts +1 -1
  64. package/dist/idempotency/mongodb.mjs +1 -2
  65. package/dist/idempotency/redis.d.mts +1 -1
  66. package/dist/idempotency/redis.mjs +1 -2
  67. package/dist/index.d.mts +9 -10
  68. package/dist/index.mjs +7 -8
  69. package/dist/integrations/event-gateway.d.mts +2 -3
  70. package/dist/integrations/event-gateway.mjs +2 -3
  71. package/dist/integrations/jobs.d.mts +1 -2
  72. package/dist/integrations/jobs.mjs +1 -2
  73. package/dist/integrations/streamline.d.mts +1 -2
  74. package/dist/integrations/streamline.mjs +1 -2
  75. package/dist/integrations/websocket.d.mts +1 -2
  76. package/dist/integrations/websocket.mjs +1 -2
  77. package/dist/{interface-B01JvPVc.d.mts → interface-CSNjltAc.d.mts} +1 -2
  78. package/dist/{interface-CZe8IkMf.d.mts → interface-DTbsvIWe.d.mts} +1 -2
  79. package/dist/{interface-Ch8HU9uM.d.mts → interface-e9XfSsUV.d.mts} +3 -4
  80. package/dist/{introspectionPlugin-rFdO8ZUa.mjs → introspectionPlugin-B3JkrjwU.mjs} +1 -2
  81. package/dist/{keys-BqNejWup.mjs → keys-DhqDRxv3.mjs} +1 -2
  82. package/dist/{logger-Df2O2WsW.mjs → logger-ByrvQWZO.mjs} +1 -2
  83. package/dist/{memory-cQgelFOj.mjs → memory-B2v7KrCB.mjs} +1 -2
  84. package/dist/migrations/index.d.mts +1 -2
  85. package/dist/migrations/index.mjs +1 -2
  86. package/dist/{mongodb-CGzRbfAK.d.mts → mongodb-ClykrfGo.d.mts} +2 -3
  87. package/dist/{mongodb-BfJVlUJH.mjs → mongodb-DNKEExbf.mjs} +1 -2
  88. package/dist/{mongodb-JN-9JA7K.d.mts → mongodb-Dg8O_gvd.d.mts} +2 -3
  89. package/dist/{openapi-G3Cw7XuM.mjs → openapi-9nB_kiuR.mjs} +5 -4
  90. package/dist/org/index.d.mts +4 -5
  91. package/dist/org/index.mjs +1 -2
  92. package/dist/org/types.d.mts +1 -2
  93. package/dist/permissions/index.d.mts +5 -6
  94. package/dist/permissions/index.mjs +7 -7
  95. package/dist/plugins/index.d.mts +7 -8
  96. package/dist/plugins/index.mjs +7 -8
  97. package/dist/plugins/response-cache.d.mts +1 -2
  98. package/dist/plugins/response-cache.mjs +2 -3
  99. package/dist/plugins/tracing-entry.d.mts +1 -1
  100. package/dist/plugins/tracing-entry.mjs +1 -2
  101. package/dist/{pluralize-CEweyOEm.mjs → pluralize-CM-jZg7p.mjs} +1 -2
  102. package/dist/policies/index.d.mts +4 -5
  103. package/dist/policies/index.mjs +1 -2
  104. package/dist/presets/index.d.mts +4 -5
  105. package/dist/presets/index.mjs +2 -3
  106. package/dist/presets/multiTenant.d.mts +4 -5
  107. package/dist/presets/multiTenant.mjs +1 -2
  108. package/dist/{presets-DzSMwlKj.d.mts → presets-BTeYbw7h.d.mts} +2 -3
  109. package/dist/{presets-BITljm96.mjs → presets-CeFtfDR8.mjs} +1 -2
  110. package/dist/{prisma-Dg9GoVdj.d.mts → prisma-C3iornoK.d.mts} +2 -3
  111. package/dist/prisma-DJbMt3yf.mjs +1 -2
  112. package/dist/{queryCachePlugin-DMBnp2Q0.mjs → queryCachePlugin-B6R0d4av.mjs} +4 -5
  113. package/dist/{queryCachePlugin-7THaI5mt.d.mts → queryCachePlugin-Q6SYuHZ6.d.mts} +2 -3
  114. package/dist/{redis-D-JAeLtm.d.mts → redis-UwjEp8Ea.d.mts} +2 -3
  115. package/dist/{redis-stream-Bdh_vUU8.d.mts → redis-stream-CBg0upHI.d.mts} +2 -3
  116. package/dist/registry/index.d.mts +4 -5
  117. package/dist/registry/index.mjs +2 -2
  118. package/dist/{requestContext-QQD6ROJc.mjs → requestContext-xi6OKBL-.mjs} +1 -2
  119. package/dist/{schemaConverter-BwrmWroW.mjs → schemaConverter-Dtg0Kt9T.mjs} +1 -2
  120. package/dist/schemas/index.d.mts +1 -2
  121. package/dist/schemas/index.mjs +1 -2
  122. package/dist/scope/index.d.mts +2 -3
  123. package/dist/scope/index.mjs +2 -3
  124. package/dist/{sessionManager-jPKLbHE0.d.mts → sessionManager-D_iEHjQl.d.mts} +1 -2
  125. package/dist/{sse-B3c3_yZp.mjs → sse-DkqQ1uxb.mjs} +2 -3
  126. package/dist/testing/index.d.mts +8 -9
  127. package/dist/testing/index.mjs +3 -4
  128. package/dist/{tracing-Cc7vVQPp.d.mts → tracing-8CEbhF0w.d.mts} +1 -2
  129. package/dist/{typeGuards-DhMNLuvU.mjs → typeGuards-DwxA1t_L.mjs} +1 -2
  130. package/dist/types/index.d.mts +6 -7
  131. package/dist/types/index.mjs +1 -2
  132. package/dist/{types-CIgB7UUl.d.mts → types-B0dhNrnd.d.mts} +9 -10
  133. package/dist/types-Beqn1Un7.mjs +1 -2
  134. package/dist/types-DelU6kln.mjs +25 -0
  135. package/dist/{types-aYB4V7uN.d.mts → types-RLkFVgaw.d.mts} +18 -4
  136. package/dist/utils/index.d.mts +5 -6
  137. package/dist/utils/index.mjs +4 -4
  138. package/package.json +1 -1
  139. package/dist/EventTransport-BD2U0BTc.d.mts.map +0 -1
  140. package/dist/HookSystem-BsGV-j2l.mjs.map +0 -1
  141. package/dist/ResourceRegistry-DsN4KJjV.mjs.map +0 -1
  142. package/dist/audit/index.d.mts.map +0 -1
  143. package/dist/audit/index.mjs.map +0 -1
  144. package/dist/audited-C3T5DTUx.mjs.map +0 -1
  145. package/dist/auth/index.d.mts.map +0 -1
  146. package/dist/auth/index.mjs.map +0 -1
  147. package/dist/auth/redis-session.d.mts.map +0 -1
  148. package/dist/auth/redis-session.mjs.map +0 -1
  149. package/dist/betterAuthOpenApi-BrHKeSAx.mjs.map +0 -1
  150. package/dist/cache/index.d.mts.map +0 -1
  151. package/dist/cache/index.mjs.map +0 -1
  152. package/dist/caching-Bl28lYsR.mjs.map +0 -1
  153. package/dist/circuitBreaker-DeY4FCjs.mjs.map +0 -1
  154. package/dist/cli/commands/describe.d.mts.map +0 -1
  155. package/dist/cli/commands/describe.mjs.map +0 -1
  156. package/dist/cli/commands/docs.d.mts.map +0 -1
  157. package/dist/cli/commands/docs.mjs.map +0 -1
  158. package/dist/cli/commands/generate.d.mts.map +0 -1
  159. package/dist/cli/commands/generate.mjs.map +0 -1
  160. package/dist/cli/commands/init.d.mts.map +0 -1
  161. package/dist/cli/commands/init.mjs.map +0 -1
  162. package/dist/cli/commands/introspect.d.mts.map +0 -1
  163. package/dist/cli/commands/introspect.mjs.map +0 -1
  164. package/dist/cli/index.d.mts.map +0 -1
  165. package/dist/cli/index.mjs.map +0 -1
  166. package/dist/constants-DdXFXQtN.mjs.map +0 -1
  167. package/dist/createApp-CUgNqegw.mjs.map +0 -1
  168. package/dist/defineResource-k0_BDn8v.mjs.map +0 -1
  169. package/dist/discovery/index.d.mts.map +0 -1
  170. package/dist/discovery/index.mjs.map +0 -1
  171. package/dist/docs/index.d.mts.map +0 -1
  172. package/dist/docs/index.mjs.map +0 -1
  173. package/dist/elevation-BRy3yFWT.mjs.map +0 -1
  174. package/dist/elevation-B_2dRLVP.d.mts.map +0 -1
  175. package/dist/errorHandler-BbcgBmIH.d.mts.map +0 -1
  176. package/dist/errorHandler-C1okiriz.mjs.map +0 -1
  177. package/dist/errors-B9bZok84.mjs.map +0 -1
  178. package/dist/errors-ChKiFz62.d.mts.map +0 -1
  179. package/dist/eventPlugin-CTrLH3mt.d.mts.map +0 -1
  180. package/dist/eventPlugin-DGR_B2on.mjs.map +0 -1
  181. package/dist/events/index.d.mts.map +0 -1
  182. package/dist/events/index.mjs.map +0 -1
  183. package/dist/events/transports/redis-stream-entry.mjs.map +0 -1
  184. package/dist/events/transports/redis.d.mts.map +0 -1
  185. package/dist/events/transports/redis.mjs.map +0 -1
  186. package/dist/externalPaths-DlINfKbP.d.mts.map +0 -1
  187. package/dist/factory/index.d.mts.map +0 -1
  188. package/dist/fastifyAdapter-BkrGrlFi.d.mts.map +0 -1
  189. package/dist/fields-DyaDVX4J.d.mts.map +0 -1
  190. package/dist/fields-iagOozy0.mjs.map +0 -1
  191. package/dist/idempotency/index.d.mts.map +0 -1
  192. package/dist/idempotency/index.mjs.map +0 -1
  193. package/dist/idempotency/mongodb.mjs.map +0 -1
  194. package/dist/idempotency/redis.mjs.map +0 -1
  195. package/dist/index.d.mts.map +0 -1
  196. package/dist/index.mjs.map +0 -1
  197. package/dist/integrations/event-gateway.d.mts.map +0 -1
  198. package/dist/integrations/event-gateway.mjs.map +0 -1
  199. package/dist/integrations/jobs.d.mts.map +0 -1
  200. package/dist/integrations/jobs.mjs.map +0 -1
  201. package/dist/integrations/streamline.d.mts.map +0 -1
  202. package/dist/integrations/streamline.mjs.map +0 -1
  203. package/dist/integrations/websocket.d.mts.map +0 -1
  204. package/dist/integrations/websocket.mjs.map +0 -1
  205. package/dist/interface-B01JvPVc.d.mts.map +0 -1
  206. package/dist/interface-CZe8IkMf.d.mts.map +0 -1
  207. package/dist/interface-Ch8HU9uM.d.mts.map +0 -1
  208. package/dist/introspectionPlugin-rFdO8ZUa.mjs.map +0 -1
  209. package/dist/keys-BqNejWup.mjs.map +0 -1
  210. package/dist/logger-Df2O2WsW.mjs.map +0 -1
  211. package/dist/memory-cQgelFOj.mjs.map +0 -1
  212. package/dist/migrations/index.d.mts.map +0 -1
  213. package/dist/migrations/index.mjs.map +0 -1
  214. package/dist/mongodb-BfJVlUJH.mjs.map +0 -1
  215. package/dist/mongodb-CGzRbfAK.d.mts.map +0 -1
  216. package/dist/mongodb-JN-9JA7K.d.mts.map +0 -1
  217. package/dist/openapi-G3Cw7XuM.mjs.map +0 -1
  218. package/dist/org/index.d.mts.map +0 -1
  219. package/dist/org/index.mjs.map +0 -1
  220. package/dist/org/types.d.mts.map +0 -1
  221. package/dist/permissions/index.d.mts.map +0 -1
  222. package/dist/permissions/index.mjs.map +0 -1
  223. package/dist/plugins/index.d.mts.map +0 -1
  224. package/dist/plugins/index.mjs.map +0 -1
  225. package/dist/plugins/response-cache.d.mts.map +0 -1
  226. package/dist/plugins/response-cache.mjs.map +0 -1
  227. package/dist/plugins/tracing-entry.mjs.map +0 -1
  228. package/dist/pluralize-CEweyOEm.mjs.map +0 -1
  229. package/dist/policies/index.d.mts.map +0 -1
  230. package/dist/policies/index.mjs.map +0 -1
  231. package/dist/presets/index.d.mts.map +0 -1
  232. package/dist/presets/index.mjs.map +0 -1
  233. package/dist/presets/multiTenant.d.mts.map +0 -1
  234. package/dist/presets/multiTenant.mjs.map +0 -1
  235. package/dist/presets-BITljm96.mjs.map +0 -1
  236. package/dist/presets-DzSMwlKj.d.mts.map +0 -1
  237. package/dist/prisma-DJbMt3yf.mjs.map +0 -1
  238. package/dist/prisma-Dg9GoVdj.d.mts.map +0 -1
  239. package/dist/queryCachePlugin-7THaI5mt.d.mts.map +0 -1
  240. package/dist/queryCachePlugin-DMBnp2Q0.mjs.map +0 -1
  241. package/dist/redis-D-JAeLtm.d.mts.map +0 -1
  242. package/dist/redis-stream-Bdh_vUU8.d.mts.map +0 -1
  243. package/dist/registry/index.d.mts.map +0 -1
  244. package/dist/requestContext-QQD6ROJc.mjs.map +0 -1
  245. package/dist/schemaConverter-BwrmWroW.mjs.map +0 -1
  246. package/dist/schemas/index.d.mts.map +0 -1
  247. package/dist/schemas/index.mjs.map +0 -1
  248. package/dist/scope/index.d.mts.map +0 -1
  249. package/dist/scope/index.mjs.map +0 -1
  250. package/dist/sessionManager-jPKLbHE0.d.mts.map +0 -1
  251. package/dist/sse-B3c3_yZp.mjs.map +0 -1
  252. package/dist/testing/index.d.mts.map +0 -1
  253. package/dist/testing/index.mjs.map +0 -1
  254. package/dist/tracing-Cc7vVQPp.d.mts.map +0 -1
  255. package/dist/typeGuards-DhMNLuvU.mjs.map +0 -1
  256. package/dist/types/index.d.mts.map +0 -1
  257. package/dist/types/index.mjs.map +0 -1
  258. package/dist/types-Beqn1Un7.mjs.map +0 -1
  259. package/dist/types-CIgB7UUl.d.mts.map +0 -1
  260. package/dist/types-aYB4V7uN.d.mts.map +0 -1
  261. package/dist/utils/index.d.mts.map +0 -1
@@ -1,11 +1,11 @@
1
- import "../elevation-B_2dRLVP.mjs";
2
- import { D as CrudRepository, T as ResourceDefinition } from "../interface-Ch8HU9uM.mjs";
3
- import "../types-aYB4V7uN.mjs";
1
+ import "../elevation-DGo5shaX.mjs";
2
+ import { D as CrudRepository, T as ResourceDefinition } from "../interface-e9XfSsUV.mjs";
3
+ import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord } from "../types/index.mjs";
5
- import "../queryCachePlugin-7THaI5mt.mjs";
6
- import "../eventPlugin-CTrLH3mt.mjs";
7
- import "../errorHandler-BbcgBmIH.mjs";
8
- import { r as CreateAppOptions } from "../types-CIgB7UUl.mjs";
5
+ import "../queryCachePlugin-Q6SYuHZ6.mjs";
6
+ import "../eventPlugin-H6wDDjGO.mjs";
7
+ import "../errorHandler-CW3OOeYq.mjs";
8
+ import { r as CreateAppOptions } from "../types-B0dhNrnd.mjs";
9
9
  import Fastify, { FastifyInstance } from "fastify";
10
10
  import { Mock } from "vitest";
11
11
  import { Connection } from "mongoose";
@@ -904,5 +904,4 @@ declare class DatabaseSnapshot {
904
904
  clear(): void;
905
905
  }
906
906
  //#endregion
907
- export { type AuthProvider, type AuthResponse, type BetterAuthTestHelpers, type BetterAuthTestHelpersOptions, type CreateTestAppOptions, DatabaseSnapshot, TestFixtures as DbTestFixtures, type GenerateTestFileOptions, HttpTestHarness, type HttpTestHarnessOptions, InMemoryDatabase, type OrgResponse, type SetupBetterAuthOrgOptions, type SetupUserConfig, type TestAppResult, TestDataLoader, TestDatabase, type TestFixtures$1 as TestFixtures, TestHarness, type TestHarnessOptions, type TestOrgContext, TestRequestBuilder, TestSeeder, TestTransaction, type TestUserContext, createBetterAuthProvider, createBetterAuthTestHelpers, createConfigTestSuite, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSnapshotMatcher, createSpy, createTestApp, createTestAuth, createTestHarness, createTestTimer, generateTestFile, request, safeParseBody, setupBetterAuthOrg, waitFor, withTestDb };
908
- //# sourceMappingURL=index.d.mts.map
907
+ export { type AuthProvider, type AuthResponse, type BetterAuthTestHelpers, type BetterAuthTestHelpersOptions, type CreateTestAppOptions, DatabaseSnapshot, TestFixtures as DbTestFixtures, type GenerateTestFileOptions, HttpTestHarness, type HttpTestHarnessOptions, InMemoryDatabase, type OrgResponse, type SetupBetterAuthOrgOptions, type SetupUserConfig, type TestAppResult, TestDataLoader, TestDatabase, type TestFixtures$1 as TestFixtures, TestHarness, type TestHarnessOptions, type TestOrgContext, TestRequestBuilder, TestSeeder, TestTransaction, type TestUserContext, createBetterAuthProvider, createBetterAuthTestHelpers, createConfigTestSuite, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSnapshotMatcher, createSpy, createTestApp, createTestAuth, createTestHarness, createTestTimer, generateTestFile, request, safeParseBody, setupBetterAuthOrg, waitFor, withTestDb };
@@ -1,5 +1,5 @@
1
1
  import { t as CRUD_OPERATIONS } from "../constants-DdXFXQtN.mjs";
2
- import { n as applyFieldWritePermissions, t as applyFieldReadPermissions } from "../fields-iagOozy0.mjs";
2
+ import { n as applyFieldWritePermissions, t as applyFieldReadPermissions } from "../fields-CTd_CrKr.mjs";
3
3
  import Fastify from "fastify";
4
4
  import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
5
5
  import mongoose, { Model } from "mongoose";
@@ -1000,7 +1000,7 @@ var DatabaseSnapshot = class {
1000
1000
  * ```
1001
1001
  */
1002
1002
  async function createTestApp(options = {}) {
1003
- const { createApp } = await import("../createApp-CUgNqegw.mjs").then((n) => n.r);
1003
+ const { createApp } = await import("../createApp-D2D5XXaV.mjs").then((n) => n.r);
1004
1004
  const { useInMemoryDb = true, mongoUri: providedMongoUri, ...appOptions } = options;
1005
1005
  const defaultAuth = {
1006
1006
  type: "jwt",
@@ -1973,5 +1973,4 @@ function createHttpTestHarness(resource, optionsOrGetter) {
1973
1973
  }
1974
1974
 
1975
1975
  //#endregion
1976
- export { DatabaseSnapshot, TestFixtures as DbTestFixtures, HttpTestHarness, InMemoryDatabase, TestDataLoader, TestDatabase, TestHarness, TestRequestBuilder, TestSeeder, TestTransaction, createBetterAuthProvider, createBetterAuthTestHelpers, createConfigTestSuite, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSnapshotMatcher, createSpy, createTestApp, createTestAuth, createTestHarness, createTestTimer, generateTestFile, request, safeParseBody, setupBetterAuthOrg, waitFor, withTestDb };
1977
- //# sourceMappingURL=index.mjs.map
1976
+ export { DatabaseSnapshot, TestFixtures as DbTestFixtures, HttpTestHarness, InMemoryDatabase, TestDataLoader, TestDatabase, TestHarness, TestRequestBuilder, TestSeeder, TestTransaction, createBetterAuthProvider, createBetterAuthTestHelpers, createConfigTestSuite, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSnapshotMatcher, createSpy, createTestApp, createTestAuth, createTestHarness, createTestTimer, generateTestFile, request, safeParseBody, setupBetterAuthOrg, waitFor, withTestDb };
@@ -67,5 +67,4 @@ declare function traced(spanName?: string): (target: any, propertyKey: string, d
67
67
  declare function isTracingAvailable(): boolean;
68
68
  declare const _default: typeof tracingPlugin;
69
69
  //#endregion
70
- export { traced as a, isTracingAvailable as i, _default as n, createSpan as r, TracingOptions as t };
71
- //# sourceMappingURL=tracing-Cc7vVQPp.d.mts.map
70
+ export { traced as a, isTracingAvailable as i, _default as n, createSpan as r, TracingOptions as t };
@@ -6,5 +6,4 @@ function hasEvents(instance) {
6
6
  }
7
7
 
8
8
  //#endregion
9
- export { hasEvents as t };
10
- //# sourceMappingURL=typeGuards-DhMNLuvU.mjs.map
9
+ export { hasEvents as t };
@@ -1,7 +1,7 @@
1
- import { a as AUTHENTICATED_SCOPE, c as getOrgId, d as hasOrgAccess, f as isAuthenticated, l as getOrgRoles, m as isMember, n as ElevationOptions, o as PUBLIC_SCOPE, p as isElevated, s as RequestScope, t as ElevationEvent, u as getTeamId } from "../elevation-B_2dRLVP.mjs";
2
- import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-Ch8HU9uM.mjs";
3
- import { n as FieldPermissionMap } from "../fields-DyaDVX4J.mjs";
4
- import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-aYB4V7uN.mjs";
1
+ import { a as AUTHENTICATED_SCOPE, c as getOrgId, d as hasOrgAccess, f as isAuthenticated, l as getOrgRoles, m as isMember, n as ElevationOptions, o as PUBLIC_SCOPE, p as isElevated, s as RequestScope, t as ElevationEvent, u as getTeamId } from "../elevation-DGo5shaX.mjs";
2
+ import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-e9XfSsUV.mjs";
3
+ import { n as FieldPermissionMap } from "../fields-Bi_AVKSo.mjs";
4
+ import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-RLkFVgaw.mjs";
5
5
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
6
6
  import { Types } from "mongoose";
7
7
 
@@ -649,7 +649,7 @@ interface TokenPair {
649
649
  * const tokens = fastify.auth.issueTokens({
650
650
  * id: user._id,
651
651
  * email: user.email,
652
- * roles: user.roles,
652
+ * role: user.role,
653
653
  * });
654
654
  *
655
655
  * return { success: true, ...tokens, user };
@@ -943,5 +943,4 @@ type TypedResourceConfig<TDoc> = ResourceConfig<TDoc>;
943
943
  type TypedController<TDoc> = IController<TDoc>;
944
944
  type TypedRepository<TDoc> = CrudRepository<TDoc>;
945
945
  //#endregion
946
- export { AUTHENTICATED_SCOPE, AdditionalRoute, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, type BaseControllerOptions, ConfigError, type ControllerHandler, type ControllerLike, ControllerQueryOptions, CrudController, type CrudRepository, CrudRouteKey, CrudRouterOptions, CrudSchemas, type ElevationEvent, type ElevationOptions, EventDefinition, EventsDecorator, type FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, type IController, type IControllerResponse, type IRequestContext, InferAdapterDoc, type InferDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, type PaginatedResult, type PaginationParams, ParsedQuery, type PermissionCheck, type PermissionContext, type PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, type QueryOptions, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, type RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHooks, ResourceMetadata, ResourcePermissions, type RouteHandler, type RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, type UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
947
- //# sourceMappingURL=index.d.mts.map
946
+ export { AUTHENTICATED_SCOPE, AdditionalRoute, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, type BaseControllerOptions, ConfigError, type ControllerHandler, type ControllerLike, ControllerQueryOptions, CrudController, type CrudRepository, CrudRouteKey, CrudRouterOptions, CrudSchemas, type ElevationEvent, type ElevationOptions, EventDefinition, EventsDecorator, type FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, type IController, type IControllerResponse, type IRequestContext, InferAdapterDoc, type InferDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, type PaginatedResult, type PaginationParams, ParsedQuery, type PermissionCheck, type PermissionContext, type PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, type QueryOptions, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, type RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHooks, ResourceMetadata, ResourcePermissions, type RouteHandler, type RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, type UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
@@ -11,5 +11,4 @@ function getUserId(user) {
11
11
  }
12
12
 
13
13
  //#endregion
14
- export { AUTHENTICATED_SCOPE, PUBLIC_SCOPE, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
15
- //# sourceMappingURL=index.mjs.map
14
+ export { AUTHENTICATED_SCOPE, PUBLIC_SCOPE, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
@@ -1,12 +1,12 @@
1
- import { n as ElevationOptions } from "./elevation-B_2dRLVP.mjs";
1
+ import { n as ElevationOptions } from "./elevation-DGo5shaX.mjs";
2
2
  import { Authenticator } from "./types/index.mjs";
3
- import { t as ExternalOpenApiPaths } from "./externalPaths-DlINfKbP.mjs";
4
- import { i as CacheStore } from "./interface-CZe8IkMf.mjs";
5
- import { r as QueryCachePluginOptions } from "./queryCachePlugin-7THaI5mt.mjs";
6
- import { i as EventTransport } from "./EventTransport-BD2U0BTc.mjs";
7
- import { t as EventPluginOptions } from "./eventPlugin-CTrLH3mt.mjs";
8
- import { o as CachingOptions, r as SSEOptions, t as ErrorHandlerOptions } from "./errorHandler-BbcgBmIH.mjs";
9
- import { r as IdempotencyStore } from "./interface-B01JvPVc.mjs";
3
+ import { t as ExternalOpenApiPaths } from "./externalPaths-SyPF2tgK.mjs";
4
+ import { i as CacheStore } from "./interface-DTbsvIWe.mjs";
5
+ import { r as QueryCachePluginOptions } from "./queryCachePlugin-Q6SYuHZ6.mjs";
6
+ import { i as EventTransport } from "./EventTransport-BkUDYZEb.mjs";
7
+ import { t as EventPluginOptions } from "./eventPlugin-H6wDDjGO.mjs";
8
+ import { o as CachingOptions, r as SSEOptions, t as ErrorHandlerOptions } from "./errorHandler-CW3OOeYq.mjs";
9
+ import { r as IdempotencyStore } from "./interface-CSNjltAc.mjs";
10
10
  import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
11
11
  import { FastifyCorsOptions } from "@fastify/cors";
12
12
  import { FastifyHelmetOptions } from "@fastify/helmet";
@@ -442,5 +442,4 @@ interface RawBodyOptions {
442
442
  runFirst?: boolean;
443
443
  }
444
444
  //#endregion
445
- export { CustomPluginAuthOption as a, RawBodyOptions as c, CustomAuthenticatorOption as i, UnderPressureOptions as l, BetterAuthOption as n, JwtAuthOption as o, CreateAppOptions as r, MultipartOptions as s, AuthOption as t };
446
- //# sourceMappingURL=types-CIgB7UUl.d.mts.map
445
+ export { CustomPluginAuthOption as a, RawBodyOptions as c, CustomAuthenticatorOption as i, UnderPressureOptions as l, BetterAuthOption as n, JwtAuthOption as o, CreateAppOptions as r, MultipartOptions as s, AuthOption as t };
@@ -35,5 +35,4 @@ const PUBLIC_SCOPE = Object.freeze({ kind: "public" });
35
35
  const AUTHENTICATED_SCOPE = Object.freeze({ kind: "authenticated" });
36
36
 
37
37
  //#endregion
38
- export { getTeamId as a, isElevated as c, getOrgRoles as i, isMember as l, PUBLIC_SCOPE as n, hasOrgAccess as o, getOrgId as r, isAuthenticated as s, AUTHENTICATED_SCOPE as t };
39
- //# sourceMappingURL=types-Beqn1Un7.mjs.map
38
+ export { getTeamId as a, isElevated as c, getOrgRoles as i, isMember as l, PUBLIC_SCOPE as n, hasOrgAccess as o, getOrgId as r, isAuthenticated as s, AUTHENTICATED_SCOPE as t };
@@ -0,0 +1,25 @@
1
+ //#region src/permissions/types.ts
2
+ /**
3
+ * Extract normalized roles from a user object.
4
+ *
5
+ * Reads `user.role` which can be:
6
+ * - A comma-separated string: `"superadmin,user"` (Better Auth admin plugin)
7
+ * - A string array: `["admin", "user"]` (JWT / custom auth)
8
+ * - A single string: `"admin"`
9
+ */
10
+ /**
11
+ * Normalize a raw role value (string, comma-separated string, or array) into a string[].
12
+ * Shared low-level helper used by both getUserRoles() and the Better Auth adapter.
13
+ */
14
+ function normalizeRoles(value) {
15
+ if (Array.isArray(value)) return value.map((r) => String(r).trim()).filter(Boolean);
16
+ if (typeof value === "string" && value.length > 0) return value.split(",").map((r) => r.trim()).filter(Boolean);
17
+ return [];
18
+ }
19
+ function getUserRoles(user) {
20
+ if (!user) return [];
21
+ return normalizeRoles(user.role);
22
+ }
23
+
24
+ //#endregion
25
+ export { normalizeRoles as n, getUserRoles as t };
@@ -8,9 +8,24 @@ import { FastifyRequest } from "fastify";
8
8
  interface UserBase {
9
9
  id?: string;
10
10
  _id?: string;
11
- roles?: string[];
11
+ /** User roles string (comma-separated), string[], or undefined. Matches Better Auth's admin plugin pattern. */
12
+ role?: string | string[];
12
13
  [key: string]: unknown;
13
14
  }
15
+ /**
16
+ * Extract normalized roles from a user object.
17
+ *
18
+ * Reads `user.role` which can be:
19
+ * - A comma-separated string: `"superadmin,user"` (Better Auth admin plugin)
20
+ * - A string array: `["admin", "user"]` (JWT / custom auth)
21
+ * - A single string: `"admin"`
22
+ */
23
+ /**
24
+ * Normalize a raw role value (string, comma-separated string, or array) into a string[].
25
+ * Shared low-level helper used by both getUserRoles() and the Better Auth adapter.
26
+ */
27
+ declare function normalizeRoles(value: unknown): string[];
28
+ declare function getUserRoles(user: UserBase | null | undefined): string[];
14
29
  /**
15
30
  * Context passed to permission check functions
16
31
  */
@@ -50,7 +65,7 @@ interface PermissionResult {
50
65
  * @example
51
66
  * ```typescript
52
67
  * // Simple boolean return
53
- * const isAdmin: PermissionCheck = (ctx) => ctx.user?.roles?.includes('admin') ?? false;
68
+ * const isAdmin: PermissionCheck = (ctx) => getUserRoles(ctx.user).includes('admin');
54
69
  *
55
70
  * // With filters for ownership
56
71
  * const ownedByUser: PermissionCheck = (ctx) => ({
@@ -83,5 +98,4 @@ interface PermissionCheckMeta {
83
98
  _teamPermission?: string;
84
99
  }
85
100
  //#endregion
86
- export { UserBase as i, PermissionContext as n, PermissionResult as r, PermissionCheck as t };
87
- //# sourceMappingURL=types-aYB4V7uN.d.mts.map
101
+ export { getUserRoles as a, UserBase as i, PermissionContext as n, normalizeRoles as o, PermissionResult as r, PermissionCheck as t };
@@ -1,8 +1,8 @@
1
- import "../elevation-B_2dRLVP.mjs";
2
- import "../interface-Ch8HU9uM.mjs";
3
- import "../types-aYB4V7uN.mjs";
1
+ import "../elevation-DGo5shaX.mjs";
2
+ import "../interface-e9XfSsUV.mjs";
3
+ import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord, OpenApiSchemas, ParsedQuery, QueryParserInterface } from "../types/index.mjs";
5
- import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createError, i as ForbiddenError, l as ServiceUnavailableError, n as ConflictError, o as OrgAccessDeniedError, p as isArcError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-ChKiFz62.mjs";
5
+ import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createError, i as ForbiddenError, l as ServiceUnavailableError, n as ConflictError, o as OrgAccessDeniedError, p as isArcError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-DAWRdiYP.mjs";
6
6
  import { FastifyInstance } from "fastify";
7
7
 
8
8
  //#region src/utils/responseSchemas.d.ts
@@ -744,5 +744,4 @@ declare function convertOpenApiSchemas(schemas: OpenApiSchemas): OpenApiSchemas;
744
744
  */
745
745
  declare function convertRouteSchema(schema: Record<string, unknown>): Record<string, unknown>;
746
746
  //#endregion
747
- export { ArcError, ArcQueryParser, type ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitState, ConflictError, type ErrorDetails, type EventsDecorator, ForbiddenError, type JsonSchema, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, type StateMachine, type TransitionConfig, UnauthorizedError, ValidationError, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createError, createQueryParser, createStateMachine, deleteResponse, errorResponseSchema, getDefaultCrudSchemas, getListQueryParams, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, itemWrapper, listResponse, messageWrapper, mutationResponse, paginateWrapper, paginationSchema, queryParams, responses, successResponseSchema, toJsonSchema, wrapResponse };
748
- //# sourceMappingURL=index.d.mts.map
747
+ export { ArcError, ArcQueryParser, type ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, type CircuitBreakerOptions, CircuitBreakerRegistry, type CircuitBreakerStats, CircuitState, ConflictError, type ErrorDetails, type EventsDecorator, ForbiddenError, type JsonSchema, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, type StateMachine, type TransitionConfig, UnauthorizedError, ValidationError, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createError, createQueryParser, createStateMachine, deleteResponse, errorResponseSchema, getDefaultCrudSchemas, getListQueryParams, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, itemWrapper, listResponse, messageWrapper, mutationResponse, paginateWrapper, paginationSchema, queryParams, responses, successResponseSchema, toJsonSchema, wrapResponse };
@@ -1,6 +1,6 @@
1
- import { C as ArcQueryParser, S as wrapResponse, _ as paginateWrapper, a as createCircuitBreaker, b as responses, c as deleteResponse, d as getListQueryParams, f as itemResponse, g as mutationResponse, h as messageWrapper, i as CircuitState, l as errorResponseSchema, m as listResponse, n as CircuitBreakerError, o as createCircuitBreakerRegistry, p as itemWrapper, r as CircuitBreakerRegistry, s as createStateMachine, t as CircuitBreaker, u as getDefaultCrudSchemas, v as paginationSchema, w as createQueryParser, x as successResponseSchema, y as queryParams } from "../circuitBreaker-DeY4FCjs.mjs";
2
- import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createError, f as isArcError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-B9bZok84.mjs";
3
- import { t as hasEvents } from "../typeGuards-DhMNLuvU.mjs";
4
- import { a as toJsonSchema, i as isZodSchema, n as convertRouteSchema, r as isJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-BwrmWroW.mjs";
1
+ import { C as ArcQueryParser, S as wrapResponse, _ as paginateWrapper, a as createCircuitBreaker, b as responses, c as deleteResponse, d as getListQueryParams, f as itemResponse, g as mutationResponse, h as messageWrapper, i as CircuitState, l as errorResponseSchema, m as listResponse, n as CircuitBreakerError, o as createCircuitBreakerRegistry, p as itemWrapper, r as CircuitBreakerRegistry, s as createStateMachine, t as CircuitBreaker, u as getDefaultCrudSchemas, v as paginationSchema, w as createQueryParser, x as successResponseSchema, y as queryParams } from "../circuitBreaker-DYhWBW_D.mjs";
2
+ import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createError, f as isArcError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-DBANPbGr.mjs";
3
+ import { t as hasEvents } from "../typeGuards-DwxA1t_L.mjs";
4
+ import { a as toJsonSchema, i as isZodSchema, n as convertRouteSchema, r as isJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-Dtg0Kt9T.mjs";
5
5
 
6
6
  export { ArcError, ArcQueryParser, CircuitBreaker, CircuitBreakerError, CircuitBreakerRegistry, CircuitState, ConflictError, ForbiddenError, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, UnauthorizedError, ValidationError, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createError, createQueryParser, createStateMachine, deleteResponse, errorResponseSchema, getDefaultCrudSchemas, getListQueryParams, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, itemWrapper, listResponse, messageWrapper, mutationResponse, paginateWrapper, paginationSchema, queryParams, responses, successResponseSchema, toJsonSchema, wrapResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Resource-oriented backend framework for Fastify — clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"EventTransport-BD2U0BTc.d.mts","names":[],"sources":["../src/events/EventTransport.ts"],"mappings":";;AAmBA;;;;;;;;;;;;;;;;;UAAiB,WAAA;EAoBA;EAlBf,IAAA;EAsBsB;EApBtB,OAAA,EAAS,CAAA;EAoBiD;EAlB1D,IAAA;IAkBwE,sBAhBtE,EAAA,UAgB6E;IAd7E,SAAA,EAAW,IAAA,EAciC;IAZ5C,QAAA,WAYqC;IAVrC,UAAA,WAU6E;IAR7E,MAAA,WA0Ba;IAxBb,cAAA,WAwBwB;IAtBxB,aAAA;EAAA;AAAA;AAAA,KAIQ,YAAA,iBAA6B,KAAA,EAAO,WAAA,CAAY,CAAA,aAAc,OAAA;;;;;;AAuB1E;;;;;;;;;;;UALiB,WAAA;EACf,IAAA,CAAK,OAAA,aAAoB,IAAA;EACzB,KAAA,CAAM,OAAA,aAAoB,IAAA;AAAA;AAAA,UAGX,cAAA;EAeL;EAAA,SAbD,IAAA;EAakB;;;EAR3B,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,OAAA;EAaZ;;AAGnB;;;;EARE,SAAA,CAAU,OAAA,UAAiB,OAAA,EAAS,YAAA,GAAe,OAAA;EAkBxC;;;EAbX,KAAA,KAAU,OAAA;AAAA;AAAA,UAGK,2BAAA;EAiD2B;EA/C1C,MAAA,GAAS,WAAA;AAAA;;;;;;cAQE,oBAAA,YAAgC,cAAA;EAAA,SAClC,IAAA;EAAA,QACD,QAAA;EAAA,QACA,MAAA;cAEI,OAAA,GAAU,2BAAA;EAIhB,OAAA,CAAQ,KAAA,EAAO,WAAA,GAAc,OAAA;EA8B7B,SAAA,CAAU,OAAA,UAAiB,OAAA,EAAS,YAAA,GAAe,OAAA;EAWnD,KAAA,CAAA,GAAS,OAAA;AAAA;;;;iBAQD,WAAA,GAAA,CACd,IAAA,UACA,OAAA,EAAS,CAAA,EACT,IAAA,GAAO,OAAA,CAAQ,WAAA,YACd,WAAA,CAAY,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"HookSystem-BsGV-j2l.mjs","names":[],"sources":["../src/hooks/HookSystem.ts"],"sourcesContent":["/**\n * Hook System\n *\n * Lifecycle hooks for resource operations.\n * Allows intercepting and modifying data at various points.\n */\n\nimport type { AnyRecord, RequestContext, UserBase } from '../types/index.js';\n\n// ============================================================================\n// Hook Types\n// ============================================================================\n\nexport type HookPhase = 'before' | 'around' | 'after';\nexport type HookOperation = 'create' | 'update' | 'delete' | 'read' | 'list';\n\nexport interface HookContext<T = AnyRecord> {\n resource: string;\n operation: HookOperation;\n phase: HookPhase;\n data?: T;\n result?: T | T[];\n user?: UserBase;\n context?: RequestContext;\n meta?: AnyRecord;\n}\n\nexport type HookHandler<T = AnyRecord> = (\n ctx: HookContext<T>\n) => void | Promise<void> | T | Promise<T>;\n\n/**\n * Around hook handler — wraps the core operation.\n * Call `next()` to proceed to the next around hook or the actual operation.\n */\nexport type AroundHookHandler<T = AnyRecord> = (\n ctx: HookContext<T>,\n next: () => Promise<T | undefined>,\n) => T | undefined | Promise<T | undefined>;\n\nexport interface HookRegistration {\n /** Hook name for dependency resolution and debugging */\n name?: string;\n resource: string;\n operation: HookOperation;\n phase: HookPhase;\n handler: HookHandler;\n priority: number;\n /** Names of hooks that must execute before this one */\n dependsOn?: string[];\n}\n\n// ============================================================================\n// Hook System Types\n// ============================================================================\n\nexport interface HookSystemOptions {\n /** Custom logger for error/warning reporting. Defaults to console */\n logger?: {\n error: (message: string, ...args: unknown[]) => void;\n warn?: (message: string, ...args: unknown[]) => void;\n };\n}\n\n// ============================================================================\n// Hook System Class\n// ============================================================================\n\nexport class HookSystem {\n private hooks: Map<string, HookRegistration[]>;\n private logger: { error: (message: string, ...args: unknown[]) => void };\n private warn: (message: string, ...args: unknown[]) => void;\n\n constructor(options?: HookSystemOptions) {\n this.hooks = new Map();\n // Default to console.error/warn so developers see hook issues during development\n // Pass custom logger to redirect to fastify.log or silence in tests\n // Use arrow function wrapper to allow spying in tests\n this.logger = options?.logger ?? { error: (...args: unknown[]) => console.error(...args) };\n this.warn = options?.logger?.warn ?? ((...args: unknown[]) => console.warn(...args));\n }\n\n /**\n * Generate hook key\n */\n private getKey(resource: string, operation: HookOperation, phase: HookPhase): string {\n return `${resource}:${operation}:${phase}`;\n }\n\n /**\n * Register a hook\n * Supports both object parameter and positional arguments\n */\n register<T = AnyRecord>(\n resourceOrOptions: string | {\n name?: string;\n resource: string;\n operation: HookOperation;\n phase: HookPhase;\n handler: HookHandler<T>;\n priority?: number;\n dependsOn?: string[];\n },\n operation?: HookOperation,\n phase?: HookPhase,\n handler?: HookHandler<T>,\n priority = 10\n ): () => void {\n // Handle object parameter\n let hookName: string | undefined;\n let resource: string;\n let finalOperation: HookOperation;\n let finalPhase: HookPhase;\n let finalHandler: HookHandler<T>;\n let finalPriority: number;\n let dependsOn: string[] | undefined;\n\n if (typeof resourceOrOptions === 'object') {\n // Object syntax: register({ name, resource, operation, phase, handler, priority, dependsOn })\n hookName = resourceOrOptions.name;\n resource = resourceOrOptions.resource;\n finalOperation = resourceOrOptions.operation;\n finalPhase = resourceOrOptions.phase;\n finalHandler = resourceOrOptions.handler;\n finalPriority = resourceOrOptions.priority ?? 10;\n dependsOn = resourceOrOptions.dependsOn;\n } else {\n // Positional syntax: register(resource, operation, phase, handler, priority)\n resource = resourceOrOptions;\n finalOperation = operation!;\n finalPhase = phase!;\n finalHandler = handler!;\n finalPriority = priority;\n }\n\n const key = this.getKey(resource, finalOperation, finalPhase);\n\n if (!this.hooks.has(key)) {\n this.hooks.set(key, []);\n }\n\n const registration: HookRegistration = {\n name: hookName,\n resource,\n operation: finalOperation,\n phase: finalPhase,\n handler: finalHandler as HookHandler,\n priority: finalPriority,\n dependsOn,\n };\n\n const hooks = this.hooks.get(key)!;\n hooks.push(registration);\n\n // Sort by priority (lower runs first) — topological sort done at execution time\n hooks.sort((a, b) => a.priority - b.priority);\n\n // Return unregister function\n return () => {\n const idx = hooks.indexOf(registration);\n if (idx !== -1) {\n hooks.splice(idx, 1);\n }\n };\n }\n\n /**\n * Register before hook\n */\n before<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n handler: HookHandler<T>,\n priority = 10\n ): () => void {\n return this.register(resource, operation, 'before', handler, priority);\n }\n\n /**\n * Register after hook\n */\n after<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n handler: HookHandler<T>,\n priority = 10\n ): () => void {\n return this.register(resource, operation, 'after', handler, priority);\n }\n\n /**\n * Register around hook — wraps the core operation.\n * Call `next()` inside the handler to proceed.\n */\n around<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n handler: AroundHookHandler<T>,\n priority = 10\n ): () => void {\n return this.register(resource, operation, 'around', handler as HookHandler, priority);\n }\n\n /**\n * Execute around hooks as a nested middleware chain.\n * Each around hook receives `next()` to call the next hook or the core operation.\n */\n async executeAround<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n data: T,\n execute: () => Promise<T | undefined>,\n options?: {\n user?: UserBase;\n context?: RequestContext;\n meta?: AnyRecord;\n }\n ): Promise<T | undefined> {\n const key = this.getKey(resource, operation, 'around');\n const hooks = [...(this.hooks.get(key) ?? [])];\n\n // Also check wildcard\n const wildcardKey = this.getKey('*', operation, 'around');\n const wildcardHooks = this.hooks.get(wildcardKey) ?? [];\n const allHooks = [...wildcardHooks, ...hooks];\n allHooks.sort((a, b) => a.priority - b.priority);\n\n if (allHooks.length === 0) {\n return execute();\n }\n\n // Build nested next() chain\n let index = 0;\n const next = async (): Promise<T | undefined> => {\n if (index < allHooks.length) {\n const hook = allHooks[index++]!;\n const ctx: HookContext<T> = {\n resource,\n operation,\n phase: 'around',\n data,\n user: options?.user,\n context: options?.context,\n meta: options?.meta,\n };\n return (hook.handler as unknown as AroundHookHandler<T>)(ctx, next);\n }\n return execute();\n };\n\n return next();\n }\n\n /**\n * Execute hooks for a given context\n */\n async execute<T = AnyRecord>(ctx: HookContext<T>): Promise<T | undefined> {\n const key = this.getKey(ctx.resource, ctx.operation, ctx.phase);\n const hooks = this.hooks.get(key) ?? [];\n\n // Also check for wildcard hooks\n const wildcardKey = this.getKey('*', ctx.operation, ctx.phase);\n const wildcardHooks = this.hooks.get(wildcardKey) ?? [];\n\n let allHooks = [...wildcardHooks, ...hooks];\n allHooks.sort((a, b) => a.priority - b.priority);\n\n // Apply topological sort if any hook has dependsOn\n if (allHooks.some((h) => h.dependsOn?.length)) {\n allHooks = this.topologicalSort(allHooks);\n }\n\n let result: T | undefined = ctx.data as T | undefined;\n\n for (const hook of allHooks) {\n // Cast context to HookContext<AnyRecord> for handler compatibility\n const handlerContext: HookContext<AnyRecord> = {\n resource: ctx.resource,\n operation: ctx.operation,\n phase: ctx.phase,\n data: result as AnyRecord | undefined,\n result: ctx.result as AnyRecord | AnyRecord[] | undefined,\n user: ctx.user,\n context: ctx.context,\n meta: ctx.meta,\n };\n const hookResult = await hook.handler(handlerContext);\n if (hookResult !== undefined && hookResult !== null) {\n result = hookResult as T;\n }\n }\n\n return result;\n }\n\n /**\n * Execute before hooks\n */\n async executeBefore<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n data: T,\n options?: {\n user?: UserBase;\n context?: RequestContext;\n meta?: AnyRecord;\n }\n ): Promise<T> {\n const result = await this.execute<T>({\n resource,\n operation,\n phase: 'before',\n data,\n user: options?.user,\n context: options?.context,\n meta: options?.meta,\n });\n\n return result ?? data;\n }\n\n /**\n * Execute after hooks\n * Errors in after hooks are logged but don't fail the request\n */\n async executeAfter<T = AnyRecord>(\n resource: string,\n operation: HookOperation,\n result: T | T[],\n options?: {\n user?: UserBase;\n context?: RequestContext;\n meta?: AnyRecord;\n }\n ): Promise<void> {\n try {\n await this.execute({\n resource,\n operation,\n phase: 'after',\n result,\n user: options?.user,\n context: options?.context,\n meta: options?.meta,\n });\n } catch (error) {\n // Log error but don't fail the request\n this.logger.error(\n `[HookSystem] Error in after hook for ${resource}:${operation}:`,\n error\n );\n }\n }\n\n /**\n * Topological sort with Kahn's algorithm.\n * Hooks with `dependsOn` are ordered after their dependencies.\n * Within the same dependency level, priority ordering is preserved.\n * Hooks without names or dependencies pass through in their original order.\n */\n private topologicalSort(hooks: HookRegistration[]): HookRegistration[] {\n // Build adjacency list and in-degree map\n const byName = new Map<string, HookRegistration>();\n const inDegree = new Map<HookRegistration, number>();\n const dependents = new Map<string, HookRegistration[]>();\n\n for (const hook of hooks) {\n inDegree.set(hook, 0);\n if (hook.name) {\n byName.set(hook.name, hook);\n }\n }\n\n for (const hook of hooks) {\n if (hook.dependsOn) {\n let resolvedDeps = 0;\n for (const dep of hook.dependsOn) {\n if (byName.has(dep)) {\n resolvedDeps++;\n if (!dependents.has(dep)) dependents.set(dep, []);\n dependents.get(dep)!.push(hook);\n } else {\n this.warn(\n `[HookSystem] Hook '${hook.name ?? '<unnamed>'}' depends on '${dep}' which is not registered ` +\n 'in the same phase/resource. Dependency will be ignored.'\n );\n }\n }\n inDegree.set(hook, resolvedDeps);\n }\n }\n\n // Kahn's algorithm: start with hooks that have no dependencies\n const queue: HookRegistration[] = [];\n const result: HookRegistration[] = [];\n\n for (const hook of hooks) {\n if (inDegree.get(hook)! === 0) {\n queue.push(hook);\n }\n }\n\n // Sort queue by priority within each level\n queue.sort((a, b) => a.priority - b.priority);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n result.push(current);\n\n if (current.name && dependents.has(current.name)) {\n const deps = dependents.get(current.name)!;\n for (const dep of deps) {\n const newDegree = inDegree.get(dep)! - 1;\n inDegree.set(dep, newDegree);\n if (newDegree === 0) {\n // Insert sorted by priority\n const insertIdx = queue.findIndex((q) => q.priority > dep.priority);\n if (insertIdx === -1) {\n queue.push(dep);\n } else {\n queue.splice(insertIdx, 0, dep);\n }\n }\n }\n }\n }\n\n // Detect cycles: if result doesn't contain all hooks, there's a cycle\n if (result.length < hooks.length) {\n const missing = hooks.filter((h) => !result.includes(h));\n const names = missing.map((h) => h.name ?? '<unnamed>').join(', ');\n this.logger.error(\n `[HookSystem] Circular dependency detected in hooks: ${names}. ` +\n 'These hooks will be appended in priority order.',\n );\n // Append cycled hooks in priority order (best effort)\n missing.sort((a, b) => a.priority - b.priority);\n result.push(...missing);\n }\n\n return result;\n }\n\n /**\n * Get all registered hooks\n */\n getAll(): HookRegistration[] {\n const all: HookRegistration[] = [];\n for (const hooks of this.hooks.values()) {\n all.push(...hooks);\n }\n return all;\n }\n\n /**\n * Get hooks for a specific resource\n */\n getForResource(resource: string): HookRegistration[] {\n const all: HookRegistration[] = [];\n for (const [key, hooks] of this.hooks.entries()) {\n if (key.startsWith(`${resource}:`)) {\n all.push(...hooks);\n }\n }\n return all;\n }\n\n /**\n * Get hooks matching filter criteria.\n * Useful for debugging and testing specific hook combinations.\n *\n * @example\n * ```typescript\n * // Find all before-create hooks for products (including wildcards)\n * const hooks = hookSystem.getRegistered({\n * resource: 'product',\n * operation: 'create',\n * phase: 'before',\n * });\n * ```\n */\n getRegistered(filter?: {\n resource?: string;\n operation?: HookOperation;\n phase?: HookPhase;\n }): HookRegistration[] {\n let results = this.getAll();\n if (filter?.resource) {\n results = results.filter(\n (h) => h.resource === filter.resource || h.resource === '*',\n );\n }\n if (filter?.operation) {\n results = results.filter((h) => h.operation === filter.operation);\n }\n if (filter?.phase) {\n results = results.filter((h) => h.phase === filter.phase);\n }\n return results;\n }\n\n /**\n * Get a structured summary of all registered hooks for debugging.\n *\n * @example\n * ```typescript\n * const info = hookSystem.inspect();\n * // { total: 12, resources: { product: [...], '*': [...] }, summary: [...] }\n * ```\n */\n inspect(): {\n total: number;\n resources: Record<string, HookRegistration[]>;\n summary: Array<{\n name?: string;\n key: string;\n priority: number;\n dependsOn?: string[];\n }>;\n } {\n const all = this.getAll();\n const byResource = new Map<string, HookRegistration[]>();\n for (const hook of all) {\n const arr = byResource.get(hook.resource) ?? [];\n arr.push(hook);\n byResource.set(hook.resource, arr);\n }\n return {\n total: all.length,\n resources: Object.fromEntries(byResource),\n summary: all.map((h) => ({\n name: h.name,\n key: `${h.resource}:${h.operation}:${h.phase}`,\n priority: h.priority,\n ...(h.dependsOn?.length ? { dependsOn: h.dependsOn } : {}),\n })),\n };\n }\n\n /**\n * Check if any hooks exist for a specific resource/operation/phase combination.\n */\n has(resource: string, operation: HookOperation, phase: HookPhase): boolean {\n const key = this.getKey(resource, operation, phase);\n return (this.hooks.get(key)?.length ?? 0) > 0;\n }\n\n /**\n * Clear all hooks\n */\n clear(): void {\n this.hooks.clear();\n }\n\n /**\n * Clear hooks for a specific resource\n */\n clearResource(resource: string): void {\n for (const key of this.hooks.keys()) {\n if (key.startsWith(`${resource}:`)) {\n this.hooks.delete(key);\n }\n }\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create a new isolated HookSystem instance\n *\n * Use this for:\n * - Test isolation (parallel test suites)\n * - Multiple app instances with independent hooks\n *\n * @example\n * const hooks = createHookSystem();\n * await app.register(arcCorePlugin, { hookSystem: hooks });\n *\n * @example With custom logger\n * const hooks = createHookSystem({ logger: fastify.log });\n */\nexport function createHookSystem(options?: HookSystemOptions): HookSystem {\n return new HookSystem(options);\n}\n\n// ============================================================================\n// defineHook — Declarative hook with name + dependency support\n// ============================================================================\n\nexport interface DefineHookOptions<T = AnyRecord> {\n /** Unique hook name (required for dependency resolution) */\n name: string;\n /** Target resource */\n resource: string;\n /** CRUD operation */\n operation: HookOperation;\n /** before or after */\n phase: HookPhase;\n /** Hook handler */\n handler: HookHandler<T>;\n /** Priority (lower = earlier, default: 10) */\n priority?: number;\n /** Names of hooks that must execute before this one */\n dependsOn?: string[];\n}\n\n/**\n * Define a named hook with optional dependencies.\n * Returns a registration object — call `register(hookSystem)` to activate.\n *\n * @example\n * ```typescript\n * const generateSlug = defineHook({\n * name: 'generateSlug',\n * resource: 'product', operation: 'create', phase: 'before',\n * handler: (ctx) => ({ ...ctx.data, slug: slugify(ctx.data.name) }),\n * });\n *\n * const validateUniqueSlug = defineHook({\n * name: 'validateUniqueSlug',\n * resource: 'product', operation: 'create', phase: 'before',\n * dependsOn: ['generateSlug'],\n * handler: async (ctx) => { // check uniqueness },\n * });\n *\n * // Register on a hook system\n * generateSlug.register(hooks);\n * validateUniqueSlug.register(hooks);\n * ```\n */\nexport function defineHook<T = AnyRecord>(\n options: DefineHookOptions<T>,\n): DefineHookOptions<T> & { register: (hooks: HookSystem) => () => void } {\n return {\n ...options,\n register(hooks: HookSystem): () => void {\n return hooks.register({\n name: options.name,\n resource: options.resource,\n operation: options.operation,\n phase: options.phase,\n handler: options.handler,\n priority: options.priority,\n dependsOn: options.dependsOn,\n });\n },\n };\n}\n\n// ============================================================================\n// Convenience Functions (operate on a provided HookSystem instance)\n// ============================================================================\n\n/**\n * Create a before-create hook registration for a given hook system\n */\nexport function beforeCreate<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.before(resource, 'create', handler, priority);\n}\n\n/**\n * Create an after-create hook registration for a given hook system\n */\nexport function afterCreate<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.after(resource, 'create', handler, priority);\n}\n\n/**\n * Create a before-update hook registration for a given hook system\n */\nexport function beforeUpdate<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.before(resource, 'update', handler, priority);\n}\n\n/**\n * Create an after-update hook registration for a given hook system\n */\nexport function afterUpdate<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.after(resource, 'update', handler, priority);\n}\n\n/**\n * Create a before-delete hook registration for a given hook system\n */\nexport function beforeDelete<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.before(resource, 'delete', handler, priority);\n}\n\n/**\n * Create an after-delete hook registration for a given hook system\n */\nexport function afterDelete<T = AnyRecord>(\n hooks: HookSystem,\n resource: string,\n handler: HookHandler<T>,\n priority = 10\n): () => void {\n return hooks.after(resource, 'delete', handler, priority);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ResourceRegistry-DsN4KJjV.mjs","names":[],"sources":["../src/registry/ResourceRegistry.ts"],"sourcesContent":["/**\n * Resource Registry\n *\n * Singleton that tracks all registered resources for introspection.\n */\n\nimport type {\n IntrospectionData,\n OpenApiSchemas,\n RegistryEntry,\n RegistryStats,\n ResourcePermissions,\n} from '../types/index.js';\nimport type { ResourceDefinition } from '../core/defineResource.js';\nimport type { FieldPermissionMap } from '../permissions/fields.js';\nimport type { PipelineConfig, PipelineStep } from '../pipeline/types.js';\nimport { CRUD_OPERATIONS, DEFAULT_UPDATE_METHOD } from '../constants.js';\n\nexport interface RegisterOptions {\n module?: string;\n /** Pre-generated OpenAPI schemas */\n openApiSchemas?: OpenApiSchemas;\n}\n\nexport class ResourceRegistry {\n private _resources: Map<string, RegistryEntry>;\n private _frozen: boolean;\n\n constructor() {\n this._resources = new Map();\n this._frozen = false;\n }\n\n /**\n * Register a resource\n */\n register(resource: ResourceDefinition<unknown>, options: RegisterOptions = {}): this {\n if (this._frozen) {\n throw new Error(\n `Registry frozen. Cannot register '${resource.name}' after startup.`\n );\n }\n\n if (this._resources.has(resource.name)) {\n throw new Error(`Resource '${resource.name}' already registered.`);\n }\n\n const entry: RegistryEntry = {\n name: resource.name,\n displayName: resource.displayName,\n tag: resource.tag,\n prefix: resource.prefix,\n module: options.module ?? undefined,\n adapter: resource.adapter\n ? {\n type: resource.adapter.type,\n name: resource.adapter.name,\n }\n : null,\n permissions: resource.permissions as ResourcePermissions | undefined,\n presets: resource._appliedPresets ?? [],\n routes: [], // Populated later by getIntrospection()\n additionalRoutes: resource.additionalRoutes.map((r) => ({\n method: r.method,\n path: r.path,\n handler:\n typeof r.handler === 'string'\n ? r.handler\n : (r.handler as Function).name || 'anonymous',\n operation: r.operation,\n summary: r.summary,\n description: r.description,\n permissions: r.permissions,\n wrapHandler: r.wrapHandler,\n schema: r.schema, // Include schema for OpenAPI docs\n })),\n events: Object.keys(resource.events ?? {}),\n registeredAt: new Date().toISOString(),\n disableDefaultRoutes: resource.disableDefaultRoutes,\n updateMethod: resource.updateMethod,\n disabledRoutes: resource.disabledRoutes,\n openApiSchemas: options.openApiSchemas,\n fieldPermissions: extractFieldPermissions(resource.fields),\n pipelineSteps: extractPipelineSteps(resource.pipe),\n rateLimit: resource.rateLimit,\n plugin: resource.toPlugin(), // Store plugin factory\n };\n\n this._resources.set(resource.name, entry);\n return this;\n }\n\n /**\n * Get resource by name\n */\n get(name: string): RegistryEntry | undefined {\n return this._resources.get(name);\n }\n\n /**\n * Get all resources\n */\n getAll(): RegistryEntry[] {\n return Array.from(this._resources.values());\n }\n\n /**\n * Get resources by module\n */\n getByModule(moduleName: string): RegistryEntry[] {\n return this.getAll().filter((r) => r.module === moduleName);\n }\n\n /**\n * Get resources by preset\n */\n getByPreset(presetName: string): RegistryEntry[] {\n return this.getAll().filter((r) => r.presets.includes(presetName));\n }\n\n /**\n * Check if resource exists\n */\n has(name: string): boolean {\n return this._resources.has(name);\n }\n\n /**\n * Get registry statistics\n */\n getStats(): RegistryStats {\n const resources = this.getAll();\n const presetCounts: Record<string, number> = {};\n\n for (const r of resources) {\n for (const preset of r.presets) {\n presetCounts[preset] = (presetCounts[preset] ?? 0) + 1;\n }\n }\n\n return {\n totalResources: resources.length,\n byModule: this._groupBy(resources, 'module'),\n presetUsage: presetCounts,\n totalRoutes: resources.reduce((sum, r) => {\n if (r.disableDefaultRoutes) {\n return sum + (r.additionalRoutes?.length ?? 0);\n }\n const disabledSet = new Set(r.disabledRoutes ?? []);\n let defaultCount = CRUD_OPERATIONS.filter(route => !disabledSet.has(route)).length;\n // 'update' creates 2 routes when updateMethod is 'both' (PUT + PATCH)\n if (!disabledSet.has('update') && r.updateMethod === 'both') {\n defaultCount += 1;\n }\n return sum + defaultCount + (r.additionalRoutes?.length ?? 0);\n }, 0),\n totalEvents: resources.reduce((sum, r) => sum + (r.events?.length ?? 0), 0),\n };\n }\n\n /**\n * Get full introspection data\n */\n getIntrospection(): IntrospectionData {\n return {\n resources: this.getAll().map((r) => {\n // Build default routes accounting for disabledRoutes and updateMethod\n const disabledSet = new Set(r.disabledRoutes ?? []);\n const updateMethod = r.updateMethod ?? DEFAULT_UPDATE_METHOD;\n const defaultRoutes = r.disableDefaultRoutes ? [] : [\n ...(!disabledSet.has('list') ? [{ method: 'GET', path: r.prefix, operation: 'list' }] : []),\n ...(!disabledSet.has('get') ? [{ method: 'GET', path: `${r.prefix}/:id`, operation: 'get' }] : []),\n ...(!disabledSet.has('create') ? [{ method: 'POST', path: r.prefix, operation: 'create' }] : []),\n ...(!disabledSet.has('update') ? (\n updateMethod === 'both'\n ? [\n { method: 'PUT', path: `${r.prefix}/:id`, operation: 'update' },\n { method: 'PATCH', path: `${r.prefix}/:id`, operation: 'update' },\n ]\n : [{ method: updateMethod, path: `${r.prefix}/:id`, operation: 'update' }]\n ) : []),\n ...(!disabledSet.has('delete') ? [{ method: 'DELETE', path: `${r.prefix}/:id`, operation: 'delete' }] : []),\n ];\n\n return {\n name: r.name,\n displayName: r.displayName,\n prefix: r.prefix,\n module: r.module,\n presets: r.presets,\n permissions: r.permissions,\n routes: [\n ...defaultRoutes,\n ...(r.additionalRoutes?.map((ar) => ({\n method: ar.method,\n path: `${r.prefix}${ar.path}`,\n operation: ar.operation ?? (typeof ar.handler === 'string' ? ar.handler : 'custom'),\n handler: typeof ar.handler === 'string' ? ar.handler : undefined,\n summary: ar.summary,\n })) ?? []),\n ],\n events: r.events,\n };\n }),\n stats: this.getStats(),\n generatedAt: new Date().toISOString(),\n };\n }\n\n /**\n * Freeze registry (prevent further registrations)\n */\n freeze(): void {\n this._frozen = true;\n }\n\n /**\n * Check if frozen\n */\n isFrozen(): boolean {\n return this._frozen;\n }\n\n /**\n * Unfreeze registry (allow new registrations)\n */\n unfreeze(): void {\n this._frozen = false;\n }\n\n /**\n * Reset registry — clear all resources and unfreeze\n */\n reset(): void {\n this._resources.clear();\n this._frozen = false;\n }\n\n /** @internal Alias for unfreeze() */\n _unfreeze(): void {\n this.unfreeze();\n }\n\n /** @internal Alias for reset() */\n _clear(): void {\n this.reset();\n }\n\n /**\n * Group by key\n */\n private _groupBy(\n arr: RegistryEntry[],\n key: keyof RegistryEntry\n ): Record<string, number> {\n const result: Record<string, number> = {};\n for (const item of arr) {\n const k = String(item[key] ?? 'uncategorized');\n result[k] = (result[k] ?? 0) + 1;\n }\n return result;\n }\n}\n\nexport default ResourceRegistry;\n\n// ---------------------------------------------------------------------------\n// Helpers for extracting v2.0 metadata\n// ---------------------------------------------------------------------------\n\nfunction extractFieldPermissions(\n fields?: FieldPermissionMap,\n): RegistryEntry['fieldPermissions'] {\n if (!fields || Object.keys(fields).length === 0) return undefined;\n\n const result: NonNullable<RegistryEntry['fieldPermissions']> = {};\n for (const [field, perm] of Object.entries(fields)) {\n const entry: { type: string; roles?: readonly string[]; redactValue?: unknown } = {\n type: perm._type,\n };\n if (perm.roles?.length) entry.roles = perm.roles;\n if (perm.redactValue !== undefined) entry.redactValue = perm.redactValue;\n result[field] = entry;\n }\n return result;\n}\n\nfunction extractPipelineSteps(\n pipe?: PipelineConfig,\n): RegistryEntry['pipelineSteps'] {\n if (!pipe) return undefined;\n\n const steps: PipelineStep[] = [];\n if (Array.isArray(pipe)) {\n steps.push(...pipe);\n } else {\n const seen = new Set<string>();\n for (const opSteps of Object.values(pipe)) {\n if (Array.isArray(opSteps)) {\n for (const step of opSteps) {\n const key = `${step._type}:${step.name}`;\n if (!seen.has(key)) {\n seen.add(key);\n steps.push(step);\n }\n }\n }\n }\n }\n\n if (steps.length === 0) return undefined;\n\n return steps.map((s) => ({\n type: s._type,\n name: s.name,\n operations: s.operations ? [...s.operations] : undefined,\n }));\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/audit/auditPlugin.ts","../../src/audit/stores/memory.ts"],"mappings":";;;;;;;UAgCiB,kBAAA;EAoCc;EAlC7B,OAAA;EA6BE;EA3BF,MAAA;EA8BU;EA5BV,eAAA,GAAkB,eAAA;EA8BD;EA5BjB,eAAA;EA4B6B;EA1B7B,OAAA;EA8Be;EA5Bf,YAAA,GAAe,UAAA;;;;;;;;;;EAUf,SAAA;IACE,UAAA;IACA,OAAA;EAAA;AAAA;AAAA;EAAA,UAKQ,eAAA;IAoDL;IAlDH,KAAA,EAAO,WAAA;EAAA;EAAA,UAGC,cAAA;IAkDoE;IAhD5E,YAAA,GAAe,YAAA;EAAA;AAAA;AAAA,UAIF,WAAA;EAKP;EAHR,MAAA,GACE,QAAA,UACA,UAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA,GAAU,YAAA,KACP,OAAA;EADO;EAIZ,MAAA,GACE,QAAA,UACA,UAAA,UACA,MAAA,EAAQ,MAAA,mBACR,KAAA,EAAO,MAAA,mBACP,OAAA,GAAU,YAAA,KACP,OAAA;EATA;EAYL,MAAA,GACE,QAAA,UACA,UAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA,GAAU,YAAA,KACP,OAAA;EAbH;EAgBF,OAAA,GACE,QAAA,UACA,UAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA,GAAU,YAAA,KACP,OAAA;EAnBK;EAsBV,MAAA,GACE,QAAA,UACA,UAAA,UACA,MAAA,UACA,IAAA,GAAO,MAAA,mBACP,OAAA,GAAU,YAAA,KACP,OAAA;EA3BI;EA8BT,KAAA,GAAQ,OAAA,EAHI,iBAAA,KAG2D,OAAA,CAAQ,UAAA;AAAA;AAAA,cAG3E,WAAA,EAAa,kBAAA,CAAmB,kBAAA;AAAA,cAAkB,QAAA;;;UC9GvC,uBAAA;EDuBkB;ECrBjC,UAAA;AAAA;AAAA,cAGW,gBAAA,YAA4B,UAAA;EAAA,SAC9B,IAAA;EAAA,QACD,OAAA;EAAA,QACA,UAAA;cAEI,OAAA,GAAS,uBAAA;EAIf,GAAA,CAAI,KAAA,EAAO,UAAA,GAAa,OAAA;EASxB,KAAA,CAAM,OAAA,GAAS,iBAAA,GAAyB,OAAA,CAAQ,UAAA;EAwChD,KAAA,CAAA,GAAS,OAAA;EDlBf;ECuBA,MAAA,CAAA,GAAU,UAAA;EDrBR;EC0BF,KAAA,CAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/audit/stores/interface.ts","../../src/audit/stores/memory.ts","../../src/audit/auditPlugin.ts"],"sourcesContent":["/**\n * Audit Store Interface\n *\n * Pluggable storage backend for audit logs.\n * Implementations: memory (dev), mongodb, event (emit only)\n */\n\nimport type { UserBase } from '../../types/index.js';\n\nexport type AuditAction = 'create' | 'update' | 'delete' | 'restore' | 'custom';\n\nexport interface AuditEntry {\n /** Unique audit log ID */\n id: string;\n /** Resource name (e.g., 'product', 'user') */\n resource: string;\n /** Document/entity ID */\n documentId: string;\n /** Action performed */\n action: AuditAction;\n /** User who performed the action */\n userId?: string;\n /** Organization context */\n organizationId?: string;\n /** Previous state (for updates) */\n before?: Record<string, unknown>;\n /** New state (for creates/updates) */\n after?: Record<string, unknown>;\n /** Changed fields (for updates) */\n changes?: string[];\n /** Request ID for tracing */\n requestId?: string;\n /** IP address */\n ipAddress?: string;\n /** User agent */\n userAgent?: string;\n /** Custom metadata */\n metadata?: Record<string, unknown>;\n /** When the action occurred */\n timestamp: Date;\n}\n\nexport interface AuditContext {\n user?: UserBase;\n organizationId?: string;\n requestId?: string;\n ipAddress?: string;\n userAgent?: string;\n /** HTTP method + route pattern (e.g., 'PATCH /api/products/:id') */\n endpoint?: string;\n /** Request duration in milliseconds */\n duration?: number;\n}\n\nexport interface AuditStoreOptions {\n /** Store name for logging */\n name: string;\n}\n\n/**\n * Abstract audit store interface\n */\nexport interface AuditStore {\n /** Store name */\n readonly name: string;\n\n /** Log an audit entry */\n log(entry: AuditEntry): Promise<void>;\n\n /** Query audit logs (optional - not all stores support querying) */\n query?(options: AuditQueryOptions): Promise<AuditEntry[]>;\n\n /** Close/cleanup (optional) */\n close?(): Promise<void>;\n}\n\nexport interface AuditQueryOptions {\n resource?: string;\n documentId?: string;\n userId?: string;\n organizationId?: string;\n action?: AuditAction | AuditAction[];\n from?: Date;\n to?: Date;\n limit?: number;\n offset?: number;\n}\n\n/**\n * Create audit entry from context\n */\nexport function createAuditEntry(\n resource: string,\n documentId: string,\n action: AuditAction,\n context: AuditContext,\n data?: {\n before?: Record<string, unknown>;\n after?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n }\n): AuditEntry {\n const changes = data?.before && data?.after\n ? detectChanges(data.before, data.after)\n : undefined;\n\n return {\n id: generateAuditId(),\n resource,\n documentId,\n action,\n userId: context.user?._id?.toString() ?? context.user?.id,\n organizationId: context.organizationId,\n before: data?.before,\n after: data?.after,\n changes,\n requestId: context.requestId,\n ipAddress: context.ipAddress,\n userAgent: context.userAgent,\n metadata: data?.metadata,\n timestamp: new Date(),\n };\n}\n\n/**\n * Detect changed fields between two objects\n */\nfunction detectChanges(\n before: Record<string, unknown>,\n after: Record<string, unknown>\n): string[] {\n const changes: string[] = [];\n const allKeys = new Set([...Object.keys(before), ...Object.keys(after)]);\n\n for (const key of allKeys) {\n // Skip internal fields\n if (key.startsWith('_') || key === 'updatedAt') continue;\n\n const oldVal = JSON.stringify(before[key]);\n const newVal = JSON.stringify(after[key]);\n\n if (oldVal !== newVal) {\n changes.push(key);\n }\n }\n\n return changes;\n}\n\n/**\n * Generate unique audit ID\n */\nfunction generateAuditId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 10);\n return `aud_${timestamp}${random}`;\n}\n","/**\n * In-Memory Audit Store\n *\n * For development and testing. Not suitable for production.\n * Logs are lost on restart.\n */\n\nimport type { AuditEntry, AuditQueryOptions, AuditStore } from './interface.js';\n\nexport interface MemoryAuditStoreOptions {\n /** Maximum entries to keep (default: 1000) */\n maxEntries?: number;\n}\n\nexport class MemoryAuditStore implements AuditStore {\n readonly name = 'memory';\n private entries: AuditEntry[] = [];\n private maxEntries: number;\n\n constructor(options: MemoryAuditStoreOptions = {}) {\n this.maxEntries = options.maxEntries ?? 1000;\n }\n\n async log(entry: AuditEntry): Promise<void> {\n this.entries.unshift(entry);\n\n // Trim to max size\n if (this.entries.length > this.maxEntries) {\n this.entries = this.entries.slice(0, this.maxEntries);\n }\n }\n\n async query(options: AuditQueryOptions = {}): Promise<AuditEntry[]> {\n let results = [...this.entries];\n\n if (options.resource) {\n results = results.filter((e) => e.resource === options.resource);\n }\n\n if (options.documentId) {\n results = results.filter((e) => e.documentId === options.documentId);\n }\n\n if (options.userId) {\n results = results.filter((e) => e.userId === options.userId);\n }\n\n if (options.organizationId) {\n results = results.filter((e) => e.organizationId === options.organizationId);\n }\n\n if (options.action) {\n const actions = Array.isArray(options.action) ? options.action : [options.action];\n results = results.filter((e) => actions.includes(e.action));\n }\n\n if (options.from) {\n results = results.filter((e) => e.timestamp >= options.from!);\n }\n\n if (options.to) {\n results = results.filter((e) => e.timestamp <= options.to!);\n }\n\n // Pagination\n const offset = options.offset ?? 0;\n const limit = options.limit ?? 100;\n results = results.slice(offset, offset + limit);\n\n return results;\n }\n\n async close(): Promise<void> {\n this.entries = [];\n }\n\n /** Get all entries (for testing) */\n getAll(): AuditEntry[] {\n return [...this.entries];\n }\n\n /** Clear all entries (for testing) */\n clear(): void {\n this.entries = [];\n }\n}\n\nexport default MemoryAuditStore;\n","/**\n * Audit Plugin\n *\n * Optional audit trail with flexible storage options.\n * Disabled by default - enable explicitly for enterprise use cases.\n *\n * @example\n * import { auditPlugin } from '@classytic/arc/audit';\n *\n * // Development: in-memory\n * await fastify.register(auditPlugin, {\n * enabled: true,\n * stores: ['memory'],\n * });\n *\n * // Production: MongoDB with TTL\n * await fastify.register(auditPlugin, {\n * enabled: true,\n * stores: ['mongodb'],\n * mongoConnection: mongoose.connection,\n * ttlDays: 90,\n * });\n */\n\nimport fp from 'fastify-plugin';\nimport type { FastifyInstance, FastifyPluginAsync, FastifyRequest } from 'fastify';\nimport type { AuditContext, AuditEntry, AuditStore } from './stores/interface.js';\nimport { createAuditEntry } from './stores/interface.js';\nimport { MemoryAuditStore } from './stores/memory.js';\nimport { MongoAuditStore, type MongoConnection } from './stores/mongodb.js';\nimport type { UserBase, RequestContext } from '../types/index.js';\n\nexport interface AuditPluginOptions {\n /** Enable audit logging (default: false) */\n enabled?: boolean;\n /** Storage backends to use */\n stores?: ('memory' | 'mongodb')[];\n /** MongoDB connection (required if using mongodb store) */\n mongoConnection?: MongoConnection;\n /** MongoDB collection name (default: 'audit_logs') */\n mongoCollection?: string;\n /** TTL in days for MongoDB (default: 90) */\n ttlDays?: number;\n /** Custom stores (advanced) */\n customStores?: AuditStore[];\n /**\n * Automatically audit CRUD operations via the hook system (default: true when enabled).\n * When enabled, create/update/delete operations are auto-logged without manual calls.\n *\n * - `true`: Auto-audit all CRUD operations on all resources\n * - `{ operations: ['create', 'delete'] }`: Only auto-audit specific operations\n * - `{ exclude: ['health', 'metrics'] }`: Skip specific resources\n * - `false`: Disable auto-audit (manual calls only)\n */\n autoAudit?: boolean | {\n operations?: ('create' | 'update' | 'delete')[];\n exclude?: string[];\n };\n}\n\ndeclare module 'fastify' {\n interface FastifyInstance {\n /** Log an audit entry */\n audit: AuditLogger;\n }\n\n interface FastifyRequest {\n /** Audit context for current request */\n auditContext?: AuditContext;\n }\n}\n\nexport interface AuditLogger {\n /** Log a create action */\n create: (\n resource: string,\n documentId: string,\n data: Record<string, unknown>,\n context?: AuditContext\n ) => Promise<void>;\n\n /** Log an update action */\n update: (\n resource: string,\n documentId: string,\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n context?: AuditContext\n ) => Promise<void>;\n\n /** Log a delete action */\n delete: (\n resource: string,\n documentId: string,\n data: Record<string, unknown>,\n context?: AuditContext\n ) => Promise<void>;\n\n /** Log a restore action (soft delete undo) */\n restore: (\n resource: string,\n documentId: string,\n data: Record<string, unknown>,\n context?: AuditContext\n ) => Promise<void>;\n\n /** Log a custom action */\n custom: (\n resource: string,\n documentId: string,\n action: string,\n data?: Record<string, unknown>,\n context?: AuditContext\n ) => Promise<void>;\n\n /** Query audit logs (if stores support it) */\n query: (options: import('./stores/interface.js').AuditQueryOptions) => Promise<AuditEntry[]>;\n}\n\nconst auditPlugin: FastifyPluginAsync<AuditPluginOptions> = async (\n fastify: FastifyInstance,\n opts: AuditPluginOptions = {}\n) => {\n const {\n enabled = false,\n stores: storeTypes = ['memory'],\n mongoConnection,\n mongoCollection = 'audit_logs',\n ttlDays = 90,\n customStores = [],\n } = opts;\n\n // Skip if not enabled\n if (!enabled) {\n // Provide no-op audit methods\n fastify.decorate('audit', createNoopLogger());\n fastify.decorateRequest('auditContext', undefined);\n fastify.log?.debug?.('Audit plugin disabled');\n return;\n }\n\n // Initialize stores\n const stores: AuditStore[] = [...customStores];\n\n for (const type of storeTypes) {\n switch (type) {\n case 'memory':\n stores.push(new MemoryAuditStore());\n break;\n case 'mongodb':\n if (!mongoConnection) {\n throw new Error('Audit: mongoConnection required for mongodb store');\n }\n stores.push(new MongoAuditStore({\n connection: mongoConnection,\n collection: mongoCollection,\n ttlDays,\n }));\n break;\n }\n }\n\n if (stores.length === 0) {\n throw new Error('Audit: at least one store must be configured');\n }\n\n // Log to all stores\n async function logToStores(entry: AuditEntry): Promise<void> {\n await Promise.all(stores.map((store) => store.log(entry)));\n }\n\n // Create audit logger\n const audit: AuditLogger = {\n async create(resource, documentId, data, context) {\n const entry = createAuditEntry(resource, documentId, 'create', context ?? {}, {\n after: data,\n });\n await logToStores(entry);\n },\n\n async update(resource, documentId, before, after, context) {\n const entry = createAuditEntry(resource, documentId, 'update', context ?? {}, {\n before,\n after,\n });\n await logToStores(entry);\n },\n\n async delete(resource, documentId, data, context) {\n const entry = createAuditEntry(resource, documentId, 'delete', context ?? {}, {\n before: data,\n });\n await logToStores(entry);\n },\n\n async restore(resource, documentId, data, context) {\n const entry = createAuditEntry(resource, documentId, 'restore', context ?? {}, {\n after: data,\n });\n await logToStores(entry);\n },\n\n async custom(resource, documentId, action, data, context) {\n const entry = createAuditEntry(resource, documentId, 'custom', context ?? {}, {\n metadata: { customAction: action, ...data },\n });\n await logToStores(entry);\n },\n\n async query(options) {\n // Use first store that supports querying\n for (const store of stores) {\n if (store.query) {\n return store.query(options);\n }\n }\n return [];\n },\n };\n\n fastify.decorate('audit', audit);\n\n // Extract audit context from request\n fastify.decorateRequest('auditContext', undefined);\n\n fastify.addHook('onRequest', async (request) => {\n const user = (request as FastifyRequest & { user?: UserBase }).user;\n const context = (request as FastifyRequest & { context?: RequestContext }).context;\n\n // Derive org ID from request.scope (set by auth adapters)\n const scope = request.scope;\n const auditOrgId = scope?.kind === 'member' ? scope.organizationId\n : scope?.kind === 'elevated' ? scope.organizationId\n : undefined;\n\n request.auditContext = {\n user,\n organizationId: auditOrgId,\n requestId: request.id,\n ipAddress: request.ip,\n userAgent: request.headers['user-agent'],\n endpoint: undefined,\n duration: undefined,\n };\n });\n\n // Populate endpoint and duration after response is sent\n fastify.addHook('onResponse', async (request, reply) => {\n if (request.auditContext) {\n request.auditContext.endpoint = `${request.method} ${request.routeOptions?.url ?? request.url}`;\n request.auditContext.duration = Math.round(reply.elapsedTime);\n }\n });\n\n // Cleanup on close\n fastify.addHook('onClose', async () => {\n await Promise.all(stores.map((store) => store.close?.()));\n });\n\n // Auto-audit CRUD operations via hook system\n const autoAuditConfig = opts.autoAudit ?? true;\n if (autoAuditConfig !== false) {\n const defaultOps = ['create', 'update', 'delete'] as const;\n const ops = typeof autoAuditConfig === 'object'\n ? autoAuditConfig.operations ?? defaultOps\n : defaultOps;\n const excludeResources = new Set(\n typeof autoAuditConfig === 'object' ? autoAuditConfig.exclude ?? [] : [],\n );\n\n // Wire hooks after all plugins are registered (onReady) so arc-core is available\n fastify.addHook('onReady', async () => {\n // fastify.arc is declared via module augmentation in arcCorePlugin.ts\n const arc = 'arc' in fastify ? fastify.arc : undefined;\n if (!arc?.hooks) {\n fastify.log?.debug?.('Auto-audit skipped: arc-core plugin not registered');\n return;\n }\n\n for (const op of ops) {\n arc.hooks.after('*', op, async (ctx) => {\n if (excludeResources.has(ctx.resource)) return;\n\n const docId = autoAuditExtractId(ctx.result);\n const scope = (ctx.context as Record<string, unknown> | undefined)?._scope;\n const auditCtx: AuditContext = {\n user: ctx.user,\n organizationId: scope ? autoAuditGetOrgId(scope) : undefined,\n };\n\n try {\n if (op === 'create') {\n await audit.create(ctx.resource, docId, autoAuditToPlain(ctx.result), auditCtx);\n } else if (op === 'update') {\n await audit.update(\n ctx.resource,\n docId,\n autoAuditToPlain(ctx.meta?.existing),\n autoAuditToPlain(ctx.result),\n auditCtx,\n );\n } else if (op === 'delete') {\n await audit.delete(ctx.resource, docId, autoAuditToPlain(ctx.result), auditCtx);\n }\n } catch (err) {\n fastify.log?.warn?.(\n { resource: ctx.resource, op, err },\n 'Auto-audit failed',\n );\n }\n }, 90); // Priority 90 — after user hooks, before event hooks at 100\n }\n\n fastify.log?.debug?.({ ops, exclude: [...excludeResources] }, 'Auto-audit hooks registered');\n });\n }\n\n fastify.log?.debug?.({ stores: storeTypes }, 'Audit plugin enabled');\n};\n\n/** Extract document ID from a result */\nfunction autoAuditExtractId(doc: unknown): string {\n if (!doc || typeof doc !== 'object') return '';\n const d = doc as Record<string, unknown>;\n const rawId = d._id ?? d.id;\n return rawId != null ? String(rawId) : '';\n}\n\n/** Convert Mongoose doc or plain object to plain object */\nfunction autoAuditToPlain(doc: unknown): Record<string, unknown> {\n if (!doc || typeof doc !== 'object') return {};\n if (typeof (doc as Record<string, unknown>).toObject === 'function') {\n return (doc as { toObject: () => Record<string, unknown> }).toObject();\n }\n return doc as Record<string, unknown>;\n}\n\n/** Extract org ID from scope (avoids importing scope module to prevent circular deps) */\nfunction autoAuditGetOrgId(scope: unknown): string | undefined {\n if (!scope || typeof scope !== 'object') return undefined;\n const s = scope as Record<string, unknown>;\n if (s.kind === 'member' || s.kind === 'elevated') {\n return s.organizationId as string | undefined;\n }\n return undefined;\n}\n\n/**\n * Create no-op logger for when audit is disabled\n */\nfunction createNoopLogger(): AuditLogger {\n const noop = async () => {};\n return {\n create: noop,\n update: noop,\n delete: noop,\n restore: noop,\n custom: noop,\n query: async () => [],\n };\n}\n\nexport default fp(auditPlugin, {\n name: 'arc-audit',\n fastify: '5.x',\n dependencies: ['arc-core'],\n});\n\nexport { auditPlugin };\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"audited-C3T5DTUx.mjs","names":[],"sources":["../src/presets/softDelete.ts","../src/presets/slugLookup.ts","../src/presets/ownedByUser.ts","../src/presets/tree.ts","../src/presets/audited.ts"],"sourcesContent":["/**\n * Soft Delete Preset\n *\n * Adds routes for listing deleted items and restoring them.\n * The actual soft-delete behavior (deletedAt field, query filtering)\n * is handled by the repository/adapter layer (e.g., MongoKit's softDelete plugin).\n */\n\nimport type { AdditionalRoute, PresetResult, ResourcePermissions } from '../types/index.js';\nimport { requireRoles } from '../permissions/index.js';\n\nexport function softDeletePreset(): PresetResult {\n return {\n name: 'softDelete',\n additionalRoutes: (permissions: ResourcePermissions): AdditionalRoute[] => [\n {\n method: 'GET',\n path: '/deleted',\n handler: 'getDeleted',\n summary: 'Get soft-deleted items',\n permissions: permissions.list ?? requireRoles(['admin']),\n wrapHandler: true,\n operation: 'listDeleted',\n },\n {\n method: 'POST',\n path: '/:id/restore',\n handler: 'restore',\n summary: 'Restore soft-deleted item',\n permissions: permissions.update ?? requireRoles(['admin']),\n wrapHandler: true,\n operation: 'restore',\n },\n ],\n };\n}\n\nexport default softDeletePreset;\n","/**\n * Slug Lookup Preset\n *\n * Adds a route to get resource by slug.\n */\n\nimport type { AdditionalRoute, ResourcePermissions, PresetResult } from '../types/index.js';\nimport { allowPublic } from '../permissions/index.js';\n\nexport interface SlugLookupOptions {\n slugField?: string;\n}\n\nexport function slugLookupPreset(options: SlugLookupOptions = {}): PresetResult {\n const { slugField = 'slug' } = options;\n\n return {\n name: 'slugLookup',\n additionalRoutes: (permissions: ResourcePermissions): AdditionalRoute[] => [\n {\n method: 'GET',\n path: `/slug/:${slugField}`,\n handler: 'getBySlug',\n summary: 'Get by slug',\n permissions: permissions.get ?? allowPublic(),\n wrapHandler: true,\n operation: 'getBySlug',\n },\n ],\n // Pass to controller so it knows which param to read\n controllerOptions: {\n slugField,\n },\n };\n}\n\nexport default slugLookupPreset;\n","/**\n * Owned By User Preset\n *\n * Adds ownership validation for update/delete operations.\n *\n * BEHAVIOR:\n * - On update/remove, sets _ownershipCheck on request\n * - BaseController enforces ownership before mutation\n * - Users can only modify resources where ownerField matches their ID\n *\n * BYPASS:\n * - Users with bypassRoles (default: ['admin', 'superadmin']) skip check\n * - Resources without the ownerField are not checked\n *\n * @example\n * defineResource({\n * name: 'post',\n * presets: [{ name: 'ownedByUser', ownerField: 'authorId' }],\n * });\n *\n * // User A cannot update/delete User B's posts\n * // Admins can modify any post\n */\n\nimport type { FastifyReply } from 'fastify';\nimport type {\n MiddlewareConfig,\n PresetResult,\n RequestWithExtras,\n RouteHandler,\n} from '../types/index.js';\nimport { isElevated, PUBLIC_SCOPE } from '../scope/types.js';\nimport type { RequestScope } from '../scope/types.js';\n\nexport interface OwnedByUserOptions {\n ownerField?: string;\n}\n\n/**\n * Create ownership check middleware.\n * Elevated scope (platform admin) bypasses ownership checks.\n */\nfunction createOwnershipCheck(ownerField: string): RouteHandler {\n return async (request: RequestWithExtras, _reply: FastifyReply): Promise<void> => {\n const user = request.user;\n if (!user) return;\n\n // Elevated scope bypasses ownership check\n const scope = request.scope ?? PUBLIC_SCOPE;\n if (isElevated(scope)) return;\n\n // Set ownership check for controller to validate\n const userWithId = user as { _id?: string; id?: string };\n const userId = userWithId._id ?? userWithId.id;\n if (userId) {\n request._ownershipCheck = {\n field: ownerField,\n userId,\n };\n }\n };\n}\n\nexport function ownedByUserPreset(options: OwnedByUserOptions = {}): PresetResult {\n const { ownerField = 'userId' } = options;\n\n const ownershipMiddleware = createOwnershipCheck(ownerField);\n\n return {\n name: 'ownedByUser',\n middlewares: {\n update: [ownershipMiddleware],\n delete: [ownershipMiddleware],\n } as MiddlewareConfig,\n };\n}\n\nexport default ownedByUserPreset;\n","/**\n * Tree Preset\n *\n * Adds routes for hierarchical tree structures.\n */\n\nimport type { AdditionalRoute, ResourcePermissions, PresetResult } from '../types/index.js';\nimport { allowPublic } from '../permissions/index.js';\n\nexport interface TreeOptions {\n parentField?: string;\n}\n\nexport function treePreset(options: TreeOptions = {}): PresetResult {\n const { parentField = 'parent' } = options;\n\n return {\n name: 'tree',\n additionalRoutes: (permissions: ResourcePermissions): AdditionalRoute[] => [\n {\n method: 'GET',\n path: '/tree',\n handler: 'getTree',\n summary: 'Get hierarchical tree',\n permissions: permissions.list ?? allowPublic(),\n wrapHandler: true,\n operation: 'getTree',\n },\n {\n method: 'GET',\n path: `/:${parentField}/children`,\n handler: 'getChildren',\n summary: 'Get children of parent',\n permissions: permissions.list ?? allowPublic(),\n wrapHandler: true,\n operation: 'getChildren',\n },\n ],\n // Pass to controller so it knows which param to read\n controllerOptions: {\n parentField,\n },\n };\n}\n\nexport default treePreset;\n","/**\n * Audited Preset\n *\n * Adds createdBy/updatedBy tracking to resources.\n * Works with the audit plugin for full change tracking.\n *\n * @example\n * defineResource({\n * name: 'product',\n * presets: ['audited'],\n * // Fields createdBy, updatedBy auto-populated from user context\n * });\n */\n\nimport type { FastifyReply } from 'fastify';\nimport type { PresetResult, RequestWithExtras, MiddlewareHandler } from '../types/index.js';\n\nexport interface AuditedPresetOptions {\n /** Field name for creator (default: 'createdBy') */\n createdByField?: string;\n /** Field name for updater (default: 'updatedBy') */\n updatedByField?: string;\n}\n\n/**\n * Audited preset - adds createdBy/updatedBy tracking\n */\nexport function auditedPreset(options: AuditedPresetOptions = {}): PresetResult {\n const { createdByField = 'createdBy', updatedByField = 'updatedBy' } = options;\n\n const injectCreatedBy: MiddlewareHandler = async (\n request: RequestWithExtras,\n _reply: FastifyReply\n ): Promise<unknown> => {\n const userWithId = request.user as { _id?: string; id?: string };\n if (userWithId?._id || userWithId?.id) {\n const userId = userWithId._id ?? userWithId.id;\n (request.body as Record<string, unknown>)[createdByField] = userId;\n (request.body as Record<string, unknown>)[updatedByField] = userId;\n }\n return undefined;\n };\n\n const injectUpdatedBy: MiddlewareHandler = async (\n request: RequestWithExtras,\n _reply: FastifyReply\n ): Promise<unknown> => {\n const userWithId = request.user as { _id?: string; id?: string };\n if (userWithId?._id || userWithId?.id) {\n (request.body as Record<string, unknown>)[updatedByField] = userWithId._id ?? userWithId.id;\n }\n return undefined;\n };\n\n return {\n name: 'audited',\n schemaOptions: {\n fieldRules: {\n [createdByField]: { systemManaged: true },\n [updatedByField]: { systemManaged: true },\n createdAt: { systemManaged: true },\n updatedAt: { systemManaged: true },\n },\n },\n middlewares: {\n create: [injectCreatedBy],\n update: [injectUpdatedBy],\n },\n };\n}\n\nexport default auditedPreset;\n"],"mappings":";;;;AAWA,SAAgB,mBAAiC;AAC/C,QAAO;EACL,MAAM;EACN,mBAAmB,gBAAwD,CACzE;GACE,QAAQ;GACR,MAAM;GACN,SAAS;GACT,SAAS;GACT,aAAa,YAAY,QAAQ,aAAa,CAAC,QAAQ,CAAC;GACxD,aAAa;GACb,WAAW;GACZ,EACD;GACE,QAAQ;GACR,MAAM;GACN,SAAS;GACT,SAAS;GACT,aAAa,YAAY,UAAU,aAAa,CAAC,QAAQ,CAAC;GAC1D,aAAa;GACb,WAAW;GACZ,CACF;EACF;;;;;ACrBH,SAAgB,iBAAiB,UAA6B,EAAE,EAAgB;CAC9E,MAAM,EAAE,YAAY,WAAW;AAE/B,QAAO;EACL,MAAM;EACN,mBAAmB,gBAAwD,CACzE;GACE,QAAQ;GACR,MAAM,UAAU;GAChB,SAAS;GACT,SAAS;GACT,aAAa,YAAY,OAAO,aAAa;GAC7C,aAAa;GACb,WAAW;GACZ,CACF;EAED,mBAAmB,EACjB,WACD;EACF;;;;;;;;;ACSH,SAAS,qBAAqB,YAAkC;AAC9D,QAAO,OAAO,SAA4B,WAAwC;EAChF,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,KAAM;AAIX,MAAI,WADU,QAAQ,SAAS,aACV,CAAE;EAGvB,MAAM,aAAa;EACnB,MAAM,SAAS,WAAW,OAAO,WAAW;AAC5C,MAAI,OACF,SAAQ,kBAAkB;GACxB,OAAO;GACP;GACD;;;AAKP,SAAgB,kBAAkB,UAA8B,EAAE,EAAgB;CAChF,MAAM,EAAE,aAAa,aAAa;CAElC,MAAM,sBAAsB,qBAAqB,WAAW;AAE5D,QAAO;EACL,MAAM;EACN,aAAa;GACX,QAAQ,CAAC,oBAAoB;GAC7B,QAAQ,CAAC,oBAAoB;GAC9B;EACF;;;;;AC7DH,SAAgB,WAAW,UAAuB,EAAE,EAAgB;CAClE,MAAM,EAAE,cAAc,aAAa;AAEnC,QAAO;EACL,MAAM;EACN,mBAAmB,gBAAwD,CACzE;GACE,QAAQ;GACR,MAAM;GACN,SAAS;GACT,SAAS;GACT,aAAa,YAAY,QAAQ,aAAa;GAC9C,aAAa;GACb,WAAW;GACZ,EACD;GACE,QAAQ;GACR,MAAM,KAAK,YAAY;GACvB,SAAS;GACT,SAAS;GACT,aAAa,YAAY,QAAQ,aAAa;GAC9C,aAAa;GACb,WAAW;GACZ,CACF;EAED,mBAAmB,EACjB,aACD;EACF;;;;;;;;ACfH,SAAgB,cAAc,UAAgC,EAAE,EAAgB;CAC9E,MAAM,EAAE,iBAAiB,aAAa,iBAAiB,gBAAgB;CAEvE,MAAM,kBAAqC,OACzC,SACA,WACqB;EACrB,MAAM,aAAa,QAAQ;AAC3B,MAAI,YAAY,OAAO,YAAY,IAAI;GACrC,MAAM,SAAS,WAAW,OAAO,WAAW;AAC5C,GAAC,QAAQ,KAAiC,kBAAkB;AAC5D,GAAC,QAAQ,KAAiC,kBAAkB;;;CAKhE,MAAM,kBAAqC,OACzC,SACA,WACqB;EACrB,MAAM,aAAa,QAAQ;AAC3B,MAAI,YAAY,OAAO,YAAY,GACjC,CAAC,QAAQ,KAAiC,kBAAkB,WAAW,OAAO,WAAW;;AAK7F,QAAO;EACL,MAAM;EACN,eAAe,EACb,YAAY;IACT,iBAAiB,EAAE,eAAe,MAAM;IACxC,iBAAiB,EAAE,eAAe,MAAM;GACzC,WAAW,EAAE,eAAe,MAAM;GAClC,WAAW,EAAE,eAAe,MAAM;GACnC,EACF;EACD,aAAa;GACX,QAAQ,CAAC,gBAAgB;GACzB,QAAQ,CAAC,gBAAgB;GAC1B;EACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/auth/authPlugin.ts","../../src/auth/betterAuth.ts","../../src/auth/betterAuthOpenApi.ts"],"mappings":";;;;;;;;;;YA6CY,eAAA;IAIR;IAFA,YAAA,GAAe,OAAA,EAAS,cAAA,EAAgB,KAAA,EAAO,YAAA,KAAiB,OAAA;IAEzC;IAAvB,oBAAA,GAAuB,OAAA,EAAS,cAAA,EAAgB,KAAA,EAAO,YAAA,KAAiB,OAAA;IAAxB;IAEhD,SAAA,MAAe,KAAA,gBAAqB,OAAA,EAAS,cAAA,EAAgB,KAAA,EAAO,YAAA,KAAiB,OAAA;IAArF;IAEA,IAAA,EAAM,WAAA;EAAA;AAAA;AAAA,cAsCJ,UAAA,EAAY,kBAAA,CAAmB,iBAAA;AAAA,cAAiB,QAAA;;;;YChE1C,cAAA;IDwB6E;ICtBrF,OAAA,GAAU,MAAA;EAAA;AAAA;;;;;;UAaG,iBAAA;EACf,OAAA,GAAU,OAAA,EAAS,OAAA,KAAY,OAAA,CAAQ,QAAA;EDMrC;ECJF,GAAA,GAAM,MAAA;AAAA;AAAA,UAGS,wBAAA;EDCmC;ECClD,IAAA,EAAM,iBAAA;EDCJ;ECCF,QAAA;EDD+C;;;;;;;ECS/C,UAAA;EDPmB;;AAAA;;;;ECcnB,OAAA,aAAoB,oBAAA;EDwBgC;;;;;;;;ACvEe;;;;;;;;EAgEnE,UAAA,GAAa,MAAA;IACX,IAAA;IACA,WAAA;IACA,QAAA;IACA,KAAA;EAAA;EA7CqC;;;;;EAoDvC,gBAAA;AAAA;AAAA,UAGe,uBAAA;EAvDgB;EAyD/B,MAAA,EAAQ,kBAAA;EAvDR;EAyDA,YAAA,GAAe,OAAA,EAAS,gBAAA,EAAgB,KAAA,EAAO,cAAA,KAAiB,OAAA;EAzDpD;EA2DZ,oBAAA,GAAuB,OAAA,EAAS,gBAAA,EAAgB,KAAA,EAAO,cAAA,KAAiB,OAAA;EAxDzD;EA0Df,WAAA;IACE,cAAA,MAAoB,KAAA,eAHyD,eAAA;IAI7E,oBAAA,QADyF,eAAA;IAEzF,qBAAA,QAD6E,eAAA;EAAA;EAxB5D;EA4BnB,OAAA,GAAU,oBAAA;AAAA;AAAA;EAAA,UAQA,eAAA;IA5DV;;;;;IAkEE,YAAA,GAAe,OAAA,EAAS,gBAAA,EAAgB,KAAA,EAAO,cAAA,KAAiB,OAAA;IAxChE;;;;;;AAYJ;IAoCI,oBAAA,GAAuB,OAAA,EAAS,gBAAA,EAAgB,KAAA,EAAO,cAAA,KAAiB,OAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuX5D,uBAAA,CACd,OAAA,EAAS,wBAAA,GACR,uBAAA;;;UCrec,wBAAA;EFyBwE;EEvBvF,QAAA;EFyBmB;EEvBnB,OAAA;EFeU;EEbV,cAAA;EFe0B;EEb1B,YAAA;EFaiD;EEXjD,iBAAA;EFWkE;;;;;;;;EEFlE,UAAA,GAAa,MAAA;IACX,IAAA;IACA,WAAA,WFIoE;IEFpE,QAAA,YFEqF;IEArF,KAAA;EAAA;AAAA;;;AFEiB;;;;;iBE8EL,wBAAA,CACd,OAAA,EAAS,MAAA,mBACT,OAAA,GAAS,wBAAA,GACR,oBAAA"}