@classytic/arc 2.3.0 → 2.4.2

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 (175) hide show
  1. package/README.md +187 -18
  2. package/bin/arc.js +11 -3
  3. package/dist/BaseController-CkM5dUh_.mjs +1031 -0
  4. package/dist/{EventTransport-BkUDYZEb.d.mts → EventTransport-wc5hSLik.d.mts} +1 -1
  5. package/dist/{HookSystem-BsGV-j2l.mjs → HookSystem-COkyWztM.mjs} +2 -3
  6. package/dist/{ResourceRegistry-7Ic20ZMw.mjs → ResourceRegistry-DeCIFlix.mjs} +8 -5
  7. package/dist/adapters/index.d.mts +3 -5
  8. package/dist/adapters/index.mjs +2 -3
  9. package/dist/{prisma-DJbMt3yf.mjs → adapters-DTC4Ug66.mjs} +45 -12
  10. package/dist/audit/index.d.mts +4 -7
  11. package/dist/audit/index.mjs +2 -29
  12. package/dist/audit/mongodb.d.mts +1 -4
  13. package/dist/audit/mongodb.mjs +2 -3
  14. package/dist/auth/index.d.mts +7 -9
  15. package/dist/auth/index.mjs +65 -63
  16. package/dist/auth/redis-session.d.mts +1 -1
  17. package/dist/auth/redis-session.mjs +1 -2
  18. package/dist/{betterAuthOpenApi-DjWDddNc.mjs → betterAuthOpenApi-lz0IRbXJ.mjs} +4 -6
  19. package/dist/cache/index.d.mts +23 -23
  20. package/dist/cache/index.mjs +4 -6
  21. package/dist/{caching-GSDJcA6-.mjs → caching-BSXB-Xr7.mjs} +2 -24
  22. package/dist/chunk-BpYLSNr0.mjs +14 -0
  23. package/dist/circuitBreaker-BOBOpN2w.mjs +284 -0
  24. package/dist/circuitBreaker-JP2GdJ4b.d.mts +206 -0
  25. package/dist/cli/commands/describe.mjs +24 -7
  26. package/dist/cli/commands/docs.mjs +6 -7
  27. package/dist/cli/commands/doctor.d.mts +10 -0
  28. package/dist/cli/commands/doctor.mjs +156 -0
  29. package/dist/cli/commands/generate.mjs +66 -17
  30. package/dist/cli/commands/init.mjs +315 -45
  31. package/dist/cli/commands/introspect.mjs +2 -4
  32. package/dist/cli/index.d.mts +1 -10
  33. package/dist/cli/index.mjs +4 -153
  34. package/dist/{constants-DdXFXQtN.mjs → constants-Cxde4rpC.mjs} +1 -2
  35. package/dist/core/index.d.mts +3 -5
  36. package/dist/core/index.mjs +5 -4
  37. package/dist/core-C1XCMtqM.mjs +185 -0
  38. package/dist/{createApp-CgKOPhA4.mjs → createApp-ByWNRsZj.mjs} +64 -35
  39. package/dist/{defineResource-DWbpJYtm.mjs → defineResource-D9aY5Cy6.mjs} +108 -1157
  40. package/dist/discovery/index.mjs +37 -5
  41. package/dist/docs/index.d.mts +6 -9
  42. package/dist/docs/index.mjs +3 -21
  43. package/dist/dynamic/index.d.mts +93 -0
  44. package/dist/dynamic/index.mjs +122 -0
  45. package/dist/{elevation-DSTbVvYj.mjs → elevation-BEdACOLB.mjs} +5 -36
  46. package/dist/{elevation-DGo5shaX.d.mts → elevation-Ca_yveIO.d.mts} +41 -7
  47. package/dist/{errorHandler-C3GY3_ow.mjs → errorHandler--zp54tGc.mjs} +3 -5
  48. package/dist/errorHandler-Do4vVQ1f.d.mts +139 -0
  49. package/dist/{errors-DBANPbGr.mjs → errors-rxhfP7Hf.mjs} +1 -2
  50. package/dist/{eventPlugin-BEOvaDqo.mjs → eventPlugin-Ba00swHF.mjs} +25 -27
  51. package/dist/{eventPlugin-H6wDDjGO.d.mts → eventPlugin-iGrSEmwJ.d.mts} +105 -5
  52. package/dist/events/index.d.mts +72 -7
  53. package/dist/events/index.mjs +216 -4
  54. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  55. package/dist/events/transports/redis-stream-entry.mjs +19 -7
  56. package/dist/events/transports/redis.d.mts +1 -1
  57. package/dist/events/transports/redis.mjs +3 -4
  58. package/dist/factory/index.d.mts +23 -9
  59. package/dist/factory/index.mjs +48 -3
  60. package/dist/{fields-Bi_AVKSo.d.mts → fields-DFwdaWCq.d.mts} +1 -1
  61. package/dist/{fields-CTd_CrKr.mjs → fields-ipsbIRPK.mjs} +1 -2
  62. package/dist/hooks/index.d.mts +1 -3
  63. package/dist/hooks/index.mjs +2 -3
  64. package/dist/idempotency/index.d.mts +5 -5
  65. package/dist/idempotency/index.mjs +3 -7
  66. package/dist/idempotency/mongodb.d.mts +1 -1
  67. package/dist/idempotency/mongodb.mjs +4 -5
  68. package/dist/idempotency/redis.d.mts +1 -1
  69. package/dist/idempotency/redis.mjs +2 -5
  70. package/dist/{fastifyAdapter-6b_eRDBw.d.mts → index-BL8CaQih.d.mts} +56 -57
  71. package/dist/index-Diqcm14c.d.mts +369 -0
  72. package/dist/{prisma-Dy5S5F5i.d.mts → index-yhxyjqNb.d.mts} +4 -5
  73. package/dist/index.d.mts +100 -105
  74. package/dist/index.mjs +85 -58
  75. package/dist/integrations/event-gateway.d.mts +1 -1
  76. package/dist/integrations/event-gateway.mjs +8 -4
  77. package/dist/integrations/index.d.mts +4 -2
  78. package/dist/integrations/index.mjs +1 -1
  79. package/dist/integrations/jobs.d.mts +2 -2
  80. package/dist/integrations/jobs.mjs +63 -14
  81. package/dist/integrations/mcp/index.d.mts +219 -0
  82. package/dist/integrations/mcp/index.mjs +572 -0
  83. package/dist/integrations/mcp/testing.d.mts +53 -0
  84. package/dist/integrations/mcp/testing.mjs +104 -0
  85. package/dist/integrations/streamline.mjs +39 -19
  86. package/dist/integrations/webhooks.d.mts +56 -0
  87. package/dist/integrations/webhooks.mjs +139 -0
  88. package/dist/integrations/websocket-redis.d.mts +46 -0
  89. package/dist/integrations/websocket-redis.mjs +50 -0
  90. package/dist/integrations/websocket.d.mts +68 -2
  91. package/dist/integrations/websocket.mjs +96 -13
  92. package/dist/{interface-CSNjltAc.d.mts → interface-B4awm1RJ.d.mts} +2 -2
  93. package/dist/interface-DGmPxakH.d.mts +2213 -0
  94. package/dist/{keys-DhqDRxv3.mjs → keys-qcD-TVJl.mjs} +3 -4
  95. package/dist/{logger-ByrvQWZO.mjs → logger-Dz3j1ItV.mjs} +2 -4
  96. package/dist/{memory-B2v7KrCB.mjs → memory-Cb_7iy9e.mjs} +2 -4
  97. package/dist/metrics-Csh4nsvv.mjs +224 -0
  98. package/dist/migrations/index.d.mts +113 -44
  99. package/dist/migrations/index.mjs +84 -102
  100. package/dist/{mongodb-DNKEExbf.mjs → mongodb-BuQ7fNTg.mjs} +1 -4
  101. package/dist/{mongodb-ClykrfGo.d.mts → mongodb-CUpYfxfD.d.mts} +2 -3
  102. package/dist/{mongodb-Dg8O_gvd.d.mts → mongodb-bga9AbkD.d.mts} +2 -2
  103. package/dist/{openapi-9nB_kiuR.mjs → openapi-CBmZ6EQN.mjs} +4 -21
  104. package/dist/org/index.d.mts +12 -14
  105. package/dist/org/index.mjs +92 -119
  106. package/dist/org/types.d.mts +2 -2
  107. package/dist/org/types.mjs +1 -1
  108. package/dist/permissions/index.d.mts +4 -278
  109. package/dist/permissions/index.mjs +4 -579
  110. package/dist/permissions-CA5zg0yK.mjs +751 -0
  111. package/dist/plugins/index.d.mts +104 -107
  112. package/dist/plugins/index.mjs +203 -313
  113. package/dist/plugins/response-cache.mjs +4 -69
  114. package/dist/plugins/tracing-entry.d.mts +1 -1
  115. package/dist/plugins/tracing-entry.mjs +24 -11
  116. package/dist/{pluralize-CM-jZg7p.mjs → pluralize-CcT6qF0a.mjs} +12 -13
  117. package/dist/policies/index.d.mts +2 -2
  118. package/dist/policies/index.mjs +80 -83
  119. package/dist/presets/index.d.mts +26 -19
  120. package/dist/presets/index.mjs +2 -142
  121. package/dist/presets/multiTenant.d.mts +1 -4
  122. package/dist/presets/multiTenant.mjs +4 -6
  123. package/dist/presets-C9QXJV1u.mjs +422 -0
  124. package/dist/{queryCachePlugin-B6R0d4av.mjs → queryCachePlugin-ClosZdNS.mjs} +6 -27
  125. package/dist/{queryCachePlugin-Q6SYuHZ6.d.mts → queryCachePlugin-DcmETvcB.d.mts} +3 -3
  126. package/dist/queryParser-CgCtsjti.mjs +352 -0
  127. package/dist/{redis-UwjEp8Ea.d.mts → redis-CQ5YxMC5.d.mts} +2 -2
  128. package/dist/{redis-stream-CBg0upHI.d.mts → redis-stream-BW9UKLZM.d.mts} +9 -2
  129. package/dist/registry/index.d.mts +1 -4
  130. package/dist/registry/index.mjs +3 -4
  131. package/dist/{introspectionPlugin-B3JkrjwU.mjs → registry-I-ogLgL9.mjs} +1 -8
  132. package/dist/{requestContext-xi6OKBL-.mjs → requestContext-DYtmNpm5.mjs} +1 -3
  133. package/dist/resourceToTools-PMFE8HIv.mjs +533 -0
  134. package/dist/rpc/index.d.mts +90 -0
  135. package/dist/rpc/index.mjs +248 -0
  136. package/dist/{schemaConverter-Dtg0Kt9T.mjs → schemaConverter-DjzHpFam.mjs} +1 -2
  137. package/dist/schemas/index.d.mts +30 -30
  138. package/dist/schemas/index.mjs +2 -4
  139. package/dist/scope/index.d.mts +13 -2
  140. package/dist/scope/index.mjs +18 -5
  141. package/dist/{sessionManager-D_iEHjQl.d.mts → sessionManager-wbkYj2HL.d.mts} +2 -2
  142. package/dist/{sse-DkqQ1uxb.mjs → sse-BkViJPlT.mjs} +4 -25
  143. package/dist/testing/index.d.mts +551 -567
  144. package/dist/testing/index.mjs +1744 -1799
  145. package/dist/{tracing-8CEbhF0w.d.mts → tracing-bz_U4EM1.d.mts} +6 -1
  146. package/dist/{typeGuards-DwxA1t_L.mjs → typeGuards-Cj5Rgvlg.mjs} +1 -2
  147. package/dist/types/index.d.mts +4 -946
  148. package/dist/types/index.mjs +2 -4
  149. package/dist/types-BJmgxNbF.d.mts +275 -0
  150. package/dist/{types-RLkFVgaw.d.mts → types-BNUccdcf.d.mts} +2 -2
  151. package/dist/{types-Beqn1Un7.mjs → types-C6TQjtdi.mjs} +30 -2
  152. package/dist/{types-tKwaViYB.d.mts → types-Dt0-AI6E.d.mts} +68 -27
  153. package/dist/{types-DelU6kln.mjs → types-ZUu_h0jp.mjs} +1 -2
  154. package/dist/utils/index.d.mts +254 -351
  155. package/dist/utils/index.mjs +7 -6
  156. package/dist/utils-Dc0WhlIl.mjs +594 -0
  157. package/dist/versioning-BzfeHmhj.mjs +37 -0
  158. package/package.json +44 -10
  159. package/skills/arc/SKILL.md +518 -0
  160. package/skills/arc/references/auth.md +250 -0
  161. package/skills/arc/references/events.md +272 -0
  162. package/skills/arc/references/integrations.md +385 -0
  163. package/skills/arc/references/mcp.md +431 -0
  164. package/skills/arc/references/production.md +610 -0
  165. package/skills/arc/references/testing.md +183 -0
  166. package/dist/audited-CGdLiSlE.mjs +0 -140
  167. package/dist/chunk-C7Uep-_p.mjs +0 -20
  168. package/dist/circuitBreaker-CSS2VvL6.mjs +0 -1109
  169. package/dist/errorHandler-CW3OOeYq.d.mts +0 -72
  170. package/dist/interface-BtdYtQUA.d.mts +0 -1114
  171. package/dist/presets-BTeYbw7h.d.mts +0 -57
  172. package/dist/presets-CeFtfDR8.mjs +0 -119
  173. /package/dist/{errors-DAWRdiYP.d.mts → errors-CPpvPHT0.d.mts} +0 -0
  174. /package/dist/{externalPaths-SyPF2tgK.d.mts → externalPaths-DpO-s7r8.d.mts} +0 -0
  175. /package/dist/{interface-DTbsvIWe.d.mts → interface-D_BWALyZ.d.mts} +0 -0
@@ -1,946 +1,4 @@
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-BtdYtQUA.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
- import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
6
- import { Types } from "mongoose";
7
-
8
- //#region src/types/index.d.ts
9
- declare module 'fastify' {
10
- interface FastifyRequest {
11
- /** Request scope — set by auth adapter, read by permissions/presets/guards */
12
- scope: RequestScope;
13
- /** Current user — set by auth adapter (Better Auth, JWT, custom) */
14
- user: Record<string, unknown>;
15
- /** Policy-injected query filters (e.g. ownership, org-scoping) */
16
- _policyFilters?: Record<string, unknown>;
17
- /** Field mask — fields to include/exclude in responses */
18
- fieldMask?: {
19
- include?: string[];
20
- exclude?: string[];
21
- };
22
- /** Arbitrary policy metadata for downstream consumers */
23
- policyMetadata?: Record<string, unknown>;
24
- /** Document loaded by policy middleware for ownership checks */
25
- document?: unknown;
26
- /** Ownership check context (field name + user field) */
27
- _ownershipCheck?: Record<string, unknown>;
28
- }
29
- }
30
- type AnyRecord = Record<string, unknown>;
31
- type ObjectId = Types.ObjectId | string;
32
- /**
33
- * Flexible user type that accepts any object with id/ID properties.
34
- * Use this instead of `any` when dealing with user objects.
35
- * Re-exports UserBase from permissions module for convenience.
36
- * The actual user structure is defined by your app's auth system.
37
- */
38
- type UserLike = UserBase & {
39
- /** User email (optional) */email?: string;
40
- };
41
- /**
42
- * Extract user ID from a user object (supports both id and _id)
43
- */
44
- declare function getUserId(user: UserLike | null | undefined): string | undefined;
45
- type CrudController<TDoc> = IController<TDoc>;
46
- interface ApiResponse<T = unknown> {
47
- success: boolean;
48
- data?: T;
49
- error?: string;
50
- message?: string;
51
- meta?: Record<string, unknown>;
52
- }
53
- interface UserOrganization {
54
- userId: string;
55
- organizationId: string;
56
- [key: string]: unknown;
57
- }
58
- interface JWTPayload {
59
- sub: string;
60
- [key: string]: unknown;
61
- }
62
- interface RequestContext {
63
- operation?: string;
64
- user?: unknown;
65
- filters?: Record<string, unknown>;
66
- [key: string]: unknown;
67
- }
68
- /**
69
- * Internal metadata shape injected by Arc's Fastify adapter.
70
- * Extends RequestContext with known internal fields so controllers
71
- * can access them without `as AnyRecord` casts.
72
- */
73
- interface ArcInternalMetadata extends RequestContext {
74
- /** Policy filters from permission middleware */
75
- _policyFilters?: Record<string, unknown>;
76
- /** Request scope from scope resolution */
77
- _scope?: RequestScope;
78
- /** Ownership check config from ownedByUser preset */
79
- _ownershipCheck?: {
80
- field: string;
81
- userId: string;
82
- };
83
- /** Arc instance references (hooks, field permissions, etc.) */
84
- arc?: {
85
- hooks?: HookSystem;
86
- fields?: FieldPermissionMap;
87
- [key: string]: unknown;
88
- };
89
- }
90
- /**
91
- * Controller-level query options - parsed from request query string
92
- * Includes pagination, filtering, and context data
93
- */
94
- interface ControllerQueryOptions {
95
- page?: number;
96
- limit?: number;
97
- sort?: string | Record<string, 1 | -1>;
98
- /** Simple populate (comma-separated string or array) */
99
- populate?: string | string[] | Record<string, unknown>;
100
- /**
101
- * Advanced populate options (Mongoose-compatible)
102
- * When set, takes precedence over simple `populate`
103
- */
104
- populateOptions?: PopulateOption[];
105
- select?: string | string[] | Record<string, 0 | 1>;
106
- filters?: Record<string, unknown>;
107
- search?: string;
108
- lean?: boolean;
109
- after?: string;
110
- user?: unknown;
111
- context?: Record<string, unknown>;
112
- /** Allow additional options */
113
- [key: string]: unknown;
114
- }
115
- /**
116
- * Mongoose-compatible populate option for advanced field selection
117
- * Used when you need to select specific fields from populated documents
118
- *
119
- * @example
120
- * ```typescript
121
- * // URL: ?populate[author][select]=name,email
122
- * // Generates: { path: 'author', select: 'name email' }
123
- * ```
124
- */
125
- interface PopulateOption {
126
- /** Field path to populate */
127
- path: string;
128
- /** Fields to select (space-separated) */
129
- select?: string;
130
- /** Filter conditions for populated documents */
131
- match?: Record<string, unknown>;
132
- /** Query options (limit, sort, skip) */
133
- options?: {
134
- limit?: number;
135
- sort?: Record<string, 1 | -1>;
136
- skip?: number;
137
- };
138
- /** Nested populate configuration */
139
- populate?: PopulateOption;
140
- }
141
- /**
142
- * Parsed query result from QueryParser
143
- * Includes pagination, sorting, filtering, etc.
144
- *
145
- * The index signature allows custom query parsers (like MongoKit's QueryParser)
146
- * to add additional fields without breaking Arc's type system.
147
- */
148
- interface ParsedQuery {
149
- filters?: Record<string, unknown>;
150
- limit?: number;
151
- sort?: string | Record<string, 1 | -1>;
152
- /** Simple populate (comma-separated string or array) */
153
- populate?: string | string[] | Record<string, unknown>;
154
- /**
155
- * Advanced populate options (Mongoose-compatible)
156
- * When set, takes precedence over simple `populate`
157
- * @example [{ path: 'author', select: 'name email' }]
158
- */
159
- populateOptions?: PopulateOption[];
160
- search?: string;
161
- page?: number;
162
- after?: string;
163
- select?: string | string[] | Record<string, 0 | 1>;
164
- /** Allow additional fields from custom query parsers */
165
- [key: string]: unknown;
166
- }
167
- /**
168
- * Query Parser Interface
169
- * Implement this to create custom query parsers
170
- *
171
- * @example MongoKit QueryParser
172
- * ```typescript
173
- * import { QueryParser } from '@classytic/mongokit';
174
- * const queryParser = new QueryParser();
175
- * ```
176
- */
177
- interface QueryParserInterface {
178
- parse(query: Record<string, unknown> | null | undefined): ParsedQuery;
179
- /**
180
- * Optional: Export OpenAPI schema for query parameters
181
- * Use this to document query parameters in OpenAPI/Swagger
182
- */
183
- getQuerySchema?(): {
184
- type: 'object';
185
- properties: Record<string, unknown>;
186
- required?: string[];
187
- };
188
- }
189
- interface FastifyRequestExtras {
190
- user?: Record<string, unknown>;
191
- }
192
- interface RequestWithExtras extends FastifyRequest {
193
- /**
194
- * Arc metadata - set by createCrudRouter
195
- * Contains resource configuration and schema options
196
- */
197
- arc?: {
198
- resourceName?: string;
199
- schemaOptions?: RouteSchemaOptions;
200
- permissions?: ResourcePermissions;
201
- };
202
- context?: Record<string, unknown>;
203
- _policyFilters?: Record<string, unknown>;
204
- fieldMask?: {
205
- include?: string[];
206
- exclude?: string[];
207
- };
208
- _ownershipCheck?: Record<string, unknown>;
209
- }
210
- type FastifyWithAuth = FastifyInstance & {
211
- authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
212
- };
213
- /**
214
- * Arc core decorator interface
215
- * Added by arcCorePlugin to provide instance-scoped hooks and registry
216
- */
217
- interface ArcDecorator {
218
- /** Instance-scoped hook system */
219
- hooks: HookSystem;
220
- /** Instance-scoped resource registry */
221
- registry: ResourceRegistry;
222
- /** Whether event emission is enabled */
223
- emitEvents: boolean;
224
- }
225
- /**
226
- * Events decorator interface
227
- * Added by eventPlugin to provide event pub/sub
228
- */
229
- interface EventsDecorator {
230
- /** Publish an event */
231
- publish: <T>(type: string, payload: T, meta?: Partial<{
232
- id: string;
233
- timestamp: Date;
234
- }>) => Promise<void>;
235
- /** Subscribe to events */
236
- subscribe: (pattern: string, handler: (event: unknown) => void | Promise<void>) => Promise<() => void>;
237
- /** Get transport name */
238
- transportName: string;
239
- }
240
- /**
241
- * Fastify instance with Arc decorators
242
- * Arc adds these decorators via plugins/presets
243
- */
244
- type FastifyWithDecorators = FastifyInstance & {
245
- arc?: ArcDecorator;
246
- events?: EventsDecorator;
247
- authenticate?: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
248
- optionalAuthenticate?: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
249
- organizationScoped?: (options?: {
250
- required?: boolean;
251
- }) => RouteHandlerMethod$1;
252
- [key: string]: unknown;
253
- };
254
- interface OwnershipCheck {
255
- field: string;
256
- userField?: string;
257
- }
258
- /**
259
- * Per-resource rate limit configuration.
260
- *
261
- * Applied to all routes of the resource when `@fastify/rate-limit` is registered
262
- * on the Fastify instance. Set to `false` to explicitly disable rate limiting
263
- * for a resource even when a global rate limit is configured.
264
- *
265
- * @example
266
- * ```typescript
267
- * defineResource({
268
- * name: 'product',
269
- * rateLimit: { max: 100, timeWindow: '1 minute' },
270
- * });
271
- * ```
272
- */
273
- /**
274
- * Per-resource cache configuration for QueryCache.
275
- * Enables stale-while-revalidate, auto-invalidation on mutations,
276
- * and cross-resource tag-based invalidation.
277
- */
278
- interface ResourceCacheConfig {
279
- /** Seconds data is "fresh" (no revalidation). Default: 0 */
280
- staleTime?: number;
281
- /** Seconds stale data stays cached (SWR window). Default: 60 */
282
- gcTime?: number;
283
- /** Per-operation overrides */
284
- list?: {
285
- staleTime?: number;
286
- gcTime?: number;
287
- };
288
- byId?: {
289
- staleTime?: number;
290
- gcTime?: number;
291
- };
292
- /** Tags for cross-resource invalidation grouping */
293
- tags?: string[];
294
- /**
295
- * Cross-resource invalidation: event pattern → tag targets.
296
- * When matched event fires, all caches with those tags are invalidated.
297
- * @example { 'category.*': ['catalog'] }
298
- */
299
- invalidateOn?: Record<string, string[]>;
300
- /** Disable caching for this resource */
301
- disabled?: boolean;
302
- }
303
- interface RateLimitConfig {
304
- /** Maximum number of requests allowed within the time window */
305
- max: number;
306
- /** Time window for rate limiting (e.g., '1 minute', '15 seconds', '1 hour') */
307
- timeWindow: string;
308
- }
309
- interface ResourceConfig<TDoc = AnyRecord> {
310
- name: string;
311
- displayName?: string;
312
- tag?: string;
313
- prefix?: string;
314
- adapter?: DataAdapter<TDoc>;
315
- /** Controller instance - accepts any object with CRUD methods */
316
- controller?: IController<TDoc> | ControllerLike;
317
- queryParser?: unknown;
318
- permissions?: ResourcePermissions;
319
- schemaOptions?: RouteSchemaOptions;
320
- openApiSchemas?: OpenApiSchemas;
321
- customSchemas?: Partial<CrudSchemas>;
322
- presets?: Array<string | PresetResult | {
323
- name: string;
324
- [key: string]: unknown;
325
- }>;
326
- hooks?: ResourceHooks;
327
- /**
328
- * Functional pipeline — guards, transforms, and interceptors.
329
- * Can be a flat array (all operations) or per-operation map.
330
- *
331
- * @example
332
- * ```typescript
333
- * import { pipe, guard, transform, intercept } from '@classytic/arc';
334
- *
335
- * resource('product', {
336
- * pipe: pipe(isActive, slugify, timing),
337
- * // OR per-operation:
338
- * pipe: { create: pipe(isActive, slugify), list: pipe(timing) },
339
- * });
340
- * ```
341
- */
342
- pipe?: PipelineConfig;
343
- /**
344
- * Field-level permissions — control visibility and writability per role.
345
- *
346
- * @example
347
- * ```typescript
348
- * import { fields } from '@classytic/arc';
349
- * fields: {
350
- * salary: fields.visibleTo(['admin', 'hr']),
351
- * password: fields.hidden(),
352
- * }
353
- * ```
354
- */
355
- fields?: FieldPermissionMap;
356
- middlewares?: MiddlewareConfig;
357
- additionalRoutes?: AdditionalRoute[];
358
- disableCrud?: boolean;
359
- disableDefaultRoutes?: boolean;
360
- disabledRoutes?: CrudRouteKey[];
361
- /**
362
- * Field name used for multi-tenant scoping (default: 'organizationId').
363
- * Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
364
- * Takes effect when org context is present (via multiTenant preset).
365
- */
366
- tenantField?: string | false;
367
- /**
368
- * Primary key field name (default: '_id').
369
- * Override for non-MongoDB adapters (e.g., 'id' for SQL databases).
370
- */
371
- idField?: string;
372
- module?: string;
373
- events?: Record<string, EventDefinition>;
374
- skipValidation?: boolean;
375
- skipRegistry?: boolean;
376
- _appliedPresets?: string[];
377
- /** HTTP method for update routes. Default: 'PATCH' */
378
- updateMethod?: 'PUT' | 'PATCH' | 'both';
379
- /**
380
- * Per-resource rate limiting.
381
- * Requires `@fastify/rate-limit` to be registered on the Fastify instance.
382
- * Set to `false` to disable rate limiting for this resource.
383
- */
384
- rateLimit?: RateLimitConfig | false;
385
- /**
386
- * QueryCache configuration for this resource.
387
- * Enables stale-while-revalidate and auto-invalidation.
388
- * Requires `queryCachePlugin` to be registered.
389
- */
390
- cache?: ResourceCacheConfig;
391
- }
392
- /**
393
- * Resource-level permissions
394
- * ONLY PermissionCheck functions allowed - no string arrays
395
- */
396
- interface ResourcePermissions {
397
- list?: PermissionCheck;
398
- get?: PermissionCheck;
399
- create?: PermissionCheck;
400
- update?: PermissionCheck;
401
- delete?: PermissionCheck;
402
- }
403
- interface ResourceHooks {
404
- beforeCreate?: (data: AnyRecord) => Promise<AnyRecord> | AnyRecord;
405
- afterCreate?: (doc: AnyRecord) => Promise<void> | void;
406
- beforeUpdate?: (id: string, data: AnyRecord) => Promise<AnyRecord> | AnyRecord;
407
- afterUpdate?: (doc: AnyRecord) => Promise<void> | void;
408
- beforeDelete?: (id: string) => Promise<void> | void;
409
- afterDelete?: (id: string) => Promise<void> | void;
410
- }
411
- /**
412
- * Additional route definition for custom endpoints
413
- */
414
- interface AdditionalRoute {
415
- /** HTTP method */
416
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
417
- /** Route path (relative to resource prefix) */
418
- path: string;
419
- /**
420
- * Handler - string (controller method name) or function
421
- * Function can be Fastify handler or (request, reply) => Promise<unknown>
422
- */
423
- handler: string | RouteHandlerMethod$1 | ((request: FastifyRequest, reply: FastifyReply) => unknown);
424
- /** Permission check - REQUIRED */
425
- permissions: PermissionCheck;
426
- /**
427
- * Handler type - REQUIRED, no auto-detection
428
- * true = ControllerHandler (receives context object)
429
- * false = FastifyHandler (receives request, reply)
430
- */
431
- wrapHandler: boolean;
432
- /**
433
- * Logical operation name for pipeline keys and permission actions.
434
- * Defaults to handler name (string handlers) or method+path slug.
435
- * Prevents collisions when multiple routes share the same HTTP method.
436
- *
437
- * @example
438
- * operation: 'listDeleted' // Used as pipeline key and permission action
439
- * operation: 'restore'
440
- */
441
- operation?: string;
442
- /** OpenAPI summary */
443
- summary?: string;
444
- /** OpenAPI description */
445
- description?: string;
446
- /** OpenAPI tags */
447
- tags?: string[];
448
- /**
449
- * Custom route-level middleware
450
- * Can be an array of handlers or a function that receives fastify and returns handlers
451
- * @example
452
- * // Direct array
453
- * preHandler: [myMiddleware]
454
- * // Function that receives fastify (for accessing decorators)
455
- * preHandler: (fastify) => [fastify.customerContext({ required: true })]
456
- */
457
- preHandler?: RouteHandlerMethod$1[] | ((fastify: FastifyInstance) => RouteHandlerMethod$1[]);
458
- /** Fastify route schema */
459
- schema?: Record<string, unknown>;
460
- }
461
- interface RouteSchemaOptions {
462
- hiddenFields?: string[];
463
- readonlyFields?: string[];
464
- requiredFields?: string[];
465
- optionalFields?: string[];
466
- excludeFields?: string[];
467
- fieldRules?: Record<string, {
468
- systemManaged?: boolean;
469
- [key: string]: unknown;
470
- }>;
471
- query?: Record<string, unknown>;
472
- }
473
- interface FieldRule {
474
- field: string;
475
- required?: boolean;
476
- readonly?: boolean;
477
- hidden?: boolean;
478
- }
479
- /**
480
- * CRUD Route Schemas (Fastify Native Format)
481
- *
482
- * @example
483
- * {
484
- * list: {
485
- * querystring: { type: 'object', properties: { page: { type: 'number' } } },
486
- * response: { 200: { type: 'object', properties: { docs: { type: 'array' } } } }
487
- * },
488
- * create: {
489
- * body: { type: 'object', properties: { name: { type: 'string' } } },
490
- * response: { 201: { type: 'object' } }
491
- * }
492
- * }
493
- */
494
- interface CrudSchemas {
495
- /** GET / - List all resources */
496
- list?: {
497
- querystring?: Record<string, unknown>;
498
- response?: Record<number, unknown>;
499
- [key: string]: unknown;
500
- };
501
- /** GET /:id - Get single resource */
502
- get?: {
503
- params?: Record<string, unknown>;
504
- response?: Record<number, unknown>;
505
- [key: string]: unknown;
506
- };
507
- /** POST / - Create resource */
508
- create?: {
509
- body?: Record<string, unknown>;
510
- response?: Record<number, unknown>;
511
- [key: string]: unknown;
512
- };
513
- /** PATCH /:id - Update resource */
514
- update?: {
515
- params?: Record<string, unknown>;
516
- body?: Record<string, unknown>;
517
- response?: Record<number, unknown>;
518
- [key: string]: unknown;
519
- };
520
- /** DELETE /:id - Delete resource */
521
- delete?: {
522
- params?: Record<string, unknown>;
523
- response?: Record<number, unknown>;
524
- [key: string]: unknown;
525
- };
526
- [key: string]: unknown;
527
- }
528
- interface OpenApiSchemas {
529
- entity?: unknown;
530
- createBody?: unknown;
531
- updateBody?: unknown;
532
- params?: unknown;
533
- listQuery?: unknown;
534
- /**
535
- * Explicit response schema for OpenAPI documentation.
536
- * If provided, this will be used as-is for the response schema.
537
- * If not provided, response schema is auto-generated from createBody.
538
- *
539
- * Note: This is for OpenAPI docs only - does NOT affect Fastify serialization.
540
- *
541
- * @example
542
- * response: {
543
- * type: 'object',
544
- * properties: {
545
- * _id: { type: 'string' },
546
- * name: { type: 'string' },
547
- * email: { type: 'string' },
548
- * // Exclude password, include virtuals
549
- * fullName: { type: 'string' },
550
- * }
551
- * }
552
- */
553
- response?: unknown;
554
- [key: string]: unknown;
555
- }
556
- /** Handler for middleware functions */
557
- type MiddlewareHandler = (request: RequestWithExtras, reply: FastifyReply) => Promise<unknown>;
558
- type CrudRouteKey = 'list' | 'get' | 'create' | 'update' | 'delete';
559
- interface MiddlewareConfig {
560
- list?: MiddlewareHandler[];
561
- get?: MiddlewareHandler[];
562
- create?: MiddlewareHandler[];
563
- update?: MiddlewareHandler[];
564
- delete?: MiddlewareHandler[];
565
- [key: string]: MiddlewareHandler[] | undefined;
566
- }
567
- /**
568
- * JWT utilities provided to authenticator
569
- * Arc provides these helpers, app uses them as needed
570
- */
571
- interface JwtContext {
572
- /** Verify a JWT token and return decoded payload */
573
- verify: <T = Record<string, unknown>>(token: string) => T;
574
- /** Sign a payload and return JWT token */
575
- sign: (payload: Record<string, unknown>, options?: {
576
- expiresIn?: string;
577
- }) => string;
578
- /** Decode without verification (for inspection) */
579
- decode: <T = Record<string, unknown>>(token: string) => T | null;
580
- }
581
- /**
582
- * Context passed to app's authenticator function
583
- */
584
- interface AuthenticatorContext {
585
- /** JWT utilities (available if jwt.secret provided) */
586
- jwt: JwtContext | null;
587
- /** Fastify instance for advanced use cases */
588
- fastify: FastifyInstance;
589
- }
590
- /**
591
- * App-provided authenticator function
592
- *
593
- * Arc calls this for every non-public route.
594
- * App has FULL control over authentication logic.
595
- *
596
- * @example
597
- * ```typescript
598
- * // Simple JWT auth
599
- * authenticate: async (request, { jwt }) => {
600
- * const token = request.headers.authorization?.split(' ')[1];
601
- * if (!token || !jwt) return null;
602
- * const decoded = jwt.verify(token);
603
- * return userRepo.findById(decoded.id);
604
- * }
605
- *
606
- * // Multi-strategy (JWT + API Key)
607
- * authenticate: async (request, { jwt }) => {
608
- * const apiKey = request.headers['x-api-key'];
609
- * if (apiKey) {
610
- * const result = await apiKeyService.verify(apiKey);
611
- * if (result) return { _id: result.userId, isApiKey: true };
612
- * }
613
- * const token = request.headers.authorization?.split(' ')[1];
614
- * if (token && jwt) {
615
- * const decoded = jwt.verify(token);
616
- * return userRepo.findById(decoded.id);
617
- * }
618
- * return null;
619
- * }
620
- * ```
621
- */
622
- type Authenticator = (request: FastifyRequest, context: AuthenticatorContext) => Promise<unknown | null> | unknown | null;
623
- /**
624
- * Token pair returned by issueTokens helper
625
- */
626
- interface TokenPair {
627
- /** Access token (JWT) */
628
- accessToken: string;
629
- /** Refresh token (JWT with longer expiry) */
630
- refreshToken?: string;
631
- /** Access token expiry in seconds */
632
- expiresIn: number;
633
- /** Refresh token expiry in seconds */
634
- refreshExpiresIn?: number;
635
- /** Token type (always 'Bearer') */
636
- tokenType: 'Bearer';
637
- }
638
- /**
639
- * Auth helpers available on fastify.auth
640
- *
641
- * @example
642
- * ```typescript
643
- * // In login handler
644
- * const user = await userRepo.findByEmail(email);
645
- * if (!user || !await bcrypt.compare(password, user.password)) {
646
- * return reply.code(401).send({ error: 'Invalid credentials' });
647
- * }
648
- *
649
- * const tokens = fastify.auth.issueTokens({
650
- * id: user._id,
651
- * email: user.email,
652
- * role: user.role,
653
- * });
654
- *
655
- * return { success: true, ...tokens, user };
656
- * ```
657
- */
658
- interface AuthHelpers {
659
- /** JWT utilities (if configured) */
660
- jwt: JwtContext | null;
661
- /**
662
- * Issue access + refresh tokens for a user
663
- * App calls this after validating credentials
664
- */
665
- issueTokens: (payload: Record<string, unknown>, options?: {
666
- expiresIn?: string;
667
- refreshExpiresIn?: string;
668
- }) => TokenPair;
669
- /**
670
- * Verify a refresh token and return decoded payload
671
- */
672
- verifyRefreshToken: <T = Record<string, unknown>>(token: string) => T;
673
- }
674
- interface ServiceContext {
675
- user?: unknown;
676
- requestId?: string;
677
- select?: string[] | Record<string, 0 | 1>;
678
- populate?: string | string[];
679
- lean?: boolean;
680
- }
681
- interface PresetHook {
682
- operation: 'create' | 'update' | 'delete' | 'read' | 'list';
683
- phase: 'before' | 'after';
684
- handler: (ctx: AnyRecord) => void | Promise<void> | AnyRecord | Promise<AnyRecord>;
685
- priority?: number;
686
- }
687
- interface PresetResult {
688
- name: string;
689
- additionalRoutes?: AdditionalRoute[] | ((permissions: ResourcePermissions) => AdditionalRoute[]);
690
- middlewares?: MiddlewareConfig;
691
- schemaOptions?: RouteSchemaOptions;
692
- controllerOptions?: Record<string, unknown>;
693
- hooks?: PresetHook[];
694
- }
695
- type PresetFunction = (config: ResourceConfig) => PresetResult;
696
- interface GracefulShutdownOptions {
697
- timeout?: number;
698
- onShutdown?: () => Promise<void> | void;
699
- signals?: NodeJS.Signals[];
700
- logEvents?: boolean;
701
- }
702
- interface RequestIdOptions {
703
- headerName?: string;
704
- generator?: () => string;
705
- }
706
- interface HealthOptions {
707
- path?: string;
708
- check?: () => Promise<unknown>;
709
- }
710
- interface HealthCheck {
711
- healthy: boolean;
712
- timestamp: string;
713
- [key: string]: unknown;
714
- }
715
- /**
716
- * Auth Plugin Options - Clean, Minimal Configuration
717
- *
718
- * Arc provides JWT infrastructure and calls your authenticator.
719
- * You control ALL authentication logic.
720
- *
721
- * @example
722
- * ```typescript
723
- * // Minimal: just JWT (uses default jwtVerify)
724
- * auth: {
725
- * jwt: { secret: process.env.JWT_SECRET },
726
- * }
727
- *
728
- * // With custom authenticator (recommended)
729
- * auth: {
730
- * jwt: { secret: process.env.JWT_SECRET },
731
- * authenticate: async (request, { jwt }) => {
732
- * const token = request.headers.authorization?.split(' ')[1];
733
- * if (!token) return null;
734
- * const decoded = jwt.verify(token);
735
- * return userRepo.findById(decoded.id);
736
- * },
737
- * }
738
- *
739
- * // Multi-strategy (JWT + API Key)
740
- * auth: {
741
- * jwt: { secret: process.env.JWT_SECRET },
742
- * authenticate: async (request, { jwt }) => {
743
- * // Try API key first (faster)
744
- * const apiKey = request.headers['x-api-key'];
745
- * if (apiKey) {
746
- * const result = await apiKeyService.verify(apiKey);
747
- * if (result) return { _id: result.userId, isApiKey: true };
748
- * }
749
- * // Try JWT
750
- * const token = request.headers.authorization?.split(' ')[1];
751
- * if (token) {
752
- * const decoded = jwt.verify(token);
753
- * return userRepo.findById(decoded.id);
754
- * }
755
- * return null;
756
- * },
757
- * onFailure: (request, reply) => {
758
- * reply.code(401).send({
759
- * success: false,
760
- * error: 'Authentication required',
761
- * message: 'Use Bearer token or X-API-Key header',
762
- * });
763
- * },
764
- * }
765
- * ```
766
- */
767
- interface AuthPluginOptions {
768
- /**
769
- * JWT configuration (optional but recommended)
770
- * If provided, jwt utilities are available in authenticator context
771
- */
772
- jwt?: {
773
- /** JWT secret (required for JWT features) */secret: string; /** Access token expiry (default: '15m') */
774
- expiresIn?: string; /** Refresh token secret (defaults to main secret) */
775
- refreshSecret?: string; /** Refresh token expiry (default: '7d') */
776
- refreshExpiresIn?: string; /** Additional @fastify/jwt sign options */
777
- sign?: Record<string, unknown>; /** Additional @fastify/jwt verify options */
778
- verify?: Record<string, unknown>;
779
- };
780
- /**
781
- * Custom authenticator function (recommended)
782
- *
783
- * Arc calls this for non-public routes.
784
- * Return user object to authenticate, null/undefined to reject.
785
- *
786
- * If not provided and jwt.secret is set, uses default jwtVerify.
787
- */
788
- authenticate?: Authenticator;
789
- /**
790
- * Custom auth failure handler
791
- * Customize the 401 response when authentication fails
792
- */
793
- onFailure?: (request: FastifyRequest, reply: FastifyReply, error?: Error) => void | Promise<void>;
794
- /**
795
- * Expose detailed auth error messages in 401 responses.
796
- * When false (default), returns generic "Authentication required".
797
- * When true, includes the actual error message for debugging.
798
- * Decoupled from log level — set explicitly per environment.
799
- */
800
- exposeAuthErrors?: boolean;
801
- /**
802
- * Property name to store user on request (default: 'user')
803
- */
804
- userProperty?: string;
805
- }
806
- interface IntrospectionPluginOptions {
807
- path?: string;
808
- prefix?: string;
809
- enabled?: boolean;
810
- authRoles?: string[];
811
- }
812
- interface CrudRouterOptions {
813
- /** Route prefix */
814
- prefix?: string;
815
- /** Permission checks for CRUD operations */
816
- permissions?: ResourcePermissions;
817
- /** OpenAPI tag for grouping routes */
818
- tag?: string;
819
- /** JSON schemas for CRUD operations */
820
- schemas?: Partial<CrudSchemas>;
821
- /** Middlewares for each CRUD operation */
822
- middlewares?: MiddlewareConfig;
823
- /** Additional custom routes (from presets or user-defined) */
824
- additionalRoutes?: AdditionalRoute[];
825
- /** Disable all default CRUD routes */
826
- disableDefaultRoutes?: boolean;
827
- /** Disable specific CRUD routes */
828
- disabledRoutes?: CrudRouteKey[];
829
- /** Functional pipeline (guard/transform/intercept) */
830
- pipe?: PipelineConfig;
831
- /** Resource name for lifecycle hooks */
832
- resourceName?: string;
833
- /** Schema generation options */
834
- schemaOptions?: RouteSchemaOptions;
835
- /** Field-level permissions (visibility, writability per role) */
836
- fields?: FieldPermissionMap;
837
- /** HTTP method for update routes. Default: 'PATCH' */
838
- updateMethod?: 'PUT' | 'PATCH' | 'both';
839
- /**
840
- * Per-resource rate limiting.
841
- * Requires `@fastify/rate-limit` to be registered on the Fastify instance.
842
- * Set to `false` to disable rate limiting for this resource.
843
- */
844
- rateLimit?: RateLimitConfig | false;
845
- }
846
- interface ResourceMetadata {
847
- name: string;
848
- displayName?: string;
849
- tag?: string;
850
- prefix: string;
851
- module?: string;
852
- permissions?: ResourcePermissions;
853
- presets: string[];
854
- additionalRoutes?: AdditionalRoute[];
855
- routes: Array<{
856
- method: string;
857
- path: string;
858
- handler?: string;
859
- operation?: string;
860
- summary?: string;
861
- }>;
862
- events?: string[];
863
- }
864
- interface RegistryEntry extends ResourceMetadata {
865
- plugin: unknown;
866
- adapter?: {
867
- type: string;
868
- name: string;
869
- } | null;
870
- events?: string[];
871
- disableDefaultRoutes?: boolean;
872
- openApiSchemas?: OpenApiSchemas;
873
- registeredAt?: string;
874
- /** Field-level permissions metadata (for OpenAPI docs) */
875
- fieldPermissions?: Record<string, {
876
- type: string;
877
- roles?: readonly string[];
878
- redactValue?: unknown;
879
- }>;
880
- /** Pipeline step names (for OpenAPI docs) */
881
- pipelineSteps?: Array<{
882
- type: string;
883
- name: string;
884
- operations?: string[];
885
- }>;
886
- /** Update HTTP method(s) used for this resource */
887
- updateMethod?: 'PUT' | 'PATCH' | 'both';
888
- /** Routes disabled for this resource */
889
- disabledRoutes?: string[];
890
- /** Rate limit config */
891
- rateLimit?: RateLimitConfig | false;
892
- }
893
- interface RegistryStats {
894
- total?: number;
895
- totalResources: number;
896
- byTag?: Record<string, number>;
897
- byModule?: Record<string, number>;
898
- presetUsage?: Record<string, number>;
899
- totalRoutes?: number;
900
- totalEvents?: number;
901
- }
902
- interface IntrospectionData {
903
- resources: ResourceMetadata[];
904
- stats: RegistryStats;
905
- generatedAt?: string;
906
- }
907
- interface EventDefinition {
908
- name: string;
909
- handler: (data: unknown) => Promise<void> | void;
910
- schema?: Record<string, unknown>;
911
- description?: string;
912
- }
913
- interface ConfigError {
914
- field: string;
915
- message: string;
916
- code?: string;
917
- }
918
- interface ValidationResult {
919
- valid: boolean;
920
- errors: ConfigError[];
921
- }
922
- interface ValidateOptions {
923
- strict?: boolean;
924
- }
925
- /**
926
- * Infer document type from DataAdapter or ResourceConfig
927
- */
928
- type InferDocType<T> = T extends DataAdapter<infer D> ? D : T extends ResourceConfig<infer D> ? D : never;
929
- /**
930
- * Infer document type from a DataAdapter.
931
- * Falls back to `unknown` (not `never`) — safe for generic constraints.
932
- *
933
- * @example
934
- * ```typescript
935
- * const adapter = createMongooseAdapter({ model: ProductModel, repository: productRepo });
936
- * type ProductDoc = InferAdapterDoc<typeof adapter>;
937
- * // ProductDoc = the document type inferred from the adapter
938
- * ```
939
- */
940
- type InferAdapterDoc<A> = A extends DataAdapter<infer D> ? D : unknown;
941
- type InferResourceDoc<T> = T extends ResourceConfig<infer D> ? D : never;
942
- type TypedResourceConfig<TDoc> = ResourceConfig<TDoc>;
943
- type TypedController<TDoc> = IController<TDoc>;
944
- type TypedRepository<TDoc> = CrudRepository<TDoc>;
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 };
1
+ import { a as AUTHENTICATED_SCOPE, c as getOrgId, g as isMember, h as isElevated, l as getOrgRoles, m as isAuthenticated, n as ElevationOptions, o as PUBLIC_SCOPE, p as hasOrgAccess, s as RequestScope, t as ElevationEvent, u as getTeamId } from "../elevation-Ca_yveIO.mjs";
2
+ import { $ as RegistryStats, A as HealthCheck, At as FastifyHandler, B as MiddlewareConfig, Bt as InferDoc, C as EventDefinition, D as FastifyWithDecorators, E as FastifyWithAuth, F as IntrospectionData, G as ParsedQuery, H as ObjectId, Ht as PaginationParams, I as IntrospectionPluginOptions, J as PresetHook, K as PopulateOption, L as JWTPayload, M as InferAdapterDoc, Mt as IControllerResponse, N as InferDocType, Nt as IRequestContext, O as FieldRule, Ot as ControllerHandler, P as InferResourceDoc, Pt as RouteHandler, Q as RegistryEntry, R as JwtContext, S as CrudSchemas, T as FastifyRequestExtras, U as OpenApiSchemas, Ut as QueryOptions, V as MiddlewareHandler, Vt as PaginatedResult, W as OwnershipCheck, X as QueryParserInterface, Y as PresetResult, Z as RateLimitConfig, _ as ConfigError, _t as ValidateOptions, at as ResourceHooks, b as CrudRouteKey, c as AdditionalRoute, ct as RouteHandlerMethod, d as ArcDecorator, dt as TokenPair, et as RequestContext, f as ArcInternalMetadata, ft as TypedController, g as AuthenticatorContext, gt as UserOrganization, h as Authenticator, ht as UserLike, it as ResourceConfig, j as HealthOptions, jt as IController, k as GracefulShutdownOptions, kt as ControllerLike, l as AnyRecord, lt as RouteSchemaOptions, m as AuthPluginOptions, mt as TypedResourceConfig, nt as RequestWithExtras, ot as ResourceMetadata, p as AuthHelpers, pt as TypedRepository, q as PresetFunction, rt as ResourceCacheConfig, st as ResourcePermissions, tt as RequestIdOptions, u as ApiResponse, ut as ServiceContext, v as ControllerQueryOptions, vt as ValidationResult, w as EventsDecorator, x as CrudRouterOptions, xt as BaseControllerOptions, y as CrudController, yt as getUserId, z as LookupOption, zt as CrudRepository } from "../interface-DGmPxakH.mjs";
3
+ import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-BNUccdcf.mjs";
4
+ export { AUTHENTICATED_SCOPE, AdditionalRoute, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRepository, CrudRouteKey, CrudRouterOptions, CrudSchemas, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, PaginatedResult, PaginationParams, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryOptions, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteHandler, RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };