@classytic/arc 1.1.0 → 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 (200) hide show
  1. package/README.md +247 -794
  2. package/bin/arc.js +91 -52
  3. package/dist/EventTransport-BkUDYZEb.d.mts +99 -0
  4. package/dist/HookSystem-BsGV-j2l.mjs +404 -0
  5. package/dist/ResourceRegistry-7Ic20ZMw.mjs +249 -0
  6. package/dist/adapters/index.d.mts +5 -0
  7. package/dist/adapters/index.mjs +3 -0
  8. package/dist/audit/index.d.mts +81 -0
  9. package/dist/audit/index.mjs +275 -0
  10. package/dist/audit/mongodb.d.mts +5 -0
  11. package/dist/audit/mongodb.mjs +3 -0
  12. package/dist/audited-CGdLiSlE.mjs +140 -0
  13. package/dist/auth/index.d.mts +188 -0
  14. package/dist/auth/index.mjs +1096 -0
  15. package/dist/auth/redis-session.d.mts +43 -0
  16. package/dist/auth/redis-session.mjs +75 -0
  17. package/dist/betterAuthOpenApi-DjWDddNc.mjs +249 -0
  18. package/dist/cache/index.d.mts +145 -0
  19. package/dist/cache/index.mjs +91 -0
  20. package/dist/caching-GSDJcA6-.mjs +93 -0
  21. package/dist/chunk-C7Uep-_p.mjs +20 -0
  22. package/dist/circuitBreaker-DYhWBW_D.mjs +1096 -0
  23. package/dist/cli/commands/describe.d.mts +18 -0
  24. package/dist/cli/commands/describe.mjs +238 -0
  25. package/dist/cli/commands/docs.d.mts +13 -0
  26. package/dist/cli/commands/docs.mjs +52 -0
  27. package/dist/cli/commands/{generate.d.ts → generate.d.mts} +3 -2
  28. package/dist/cli/commands/generate.mjs +357 -0
  29. package/dist/cli/commands/{init.d.ts → init.d.mts} +11 -8
  30. package/dist/cli/commands/{init.js → init.mjs} +807 -617
  31. package/dist/cli/commands/introspect.d.mts +10 -0
  32. package/dist/cli/commands/introspect.mjs +75 -0
  33. package/dist/cli/index.d.mts +16 -0
  34. package/dist/cli/index.mjs +156 -0
  35. package/dist/constants-DdXFXQtN.mjs +84 -0
  36. package/dist/core/index.d.mts +5 -0
  37. package/dist/core/index.mjs +4 -0
  38. package/dist/createApp-D2D5XXaV.mjs +559 -0
  39. package/dist/defineResource-PXzSJ15_.mjs +2197 -0
  40. package/dist/discovery/index.d.mts +46 -0
  41. package/dist/discovery/index.mjs +109 -0
  42. package/dist/docs/index.d.mts +162 -0
  43. package/dist/docs/index.mjs +74 -0
  44. package/dist/elevation-DGo5shaX.d.mts +87 -0
  45. package/dist/elevation-DSTbVvYj.mjs +113 -0
  46. package/dist/errorHandler-C3GY3_ow.mjs +108 -0
  47. package/dist/errorHandler-CW3OOeYq.d.mts +72 -0
  48. package/dist/errors-DAWRdiYP.d.mts +124 -0
  49. package/dist/errors-DBANPbGr.mjs +211 -0
  50. package/dist/eventPlugin-BEOvaDqo.mjs +229 -0
  51. package/dist/eventPlugin-H6wDDjGO.d.mts +124 -0
  52. package/dist/events/index.d.mts +53 -0
  53. package/dist/events/index.mjs +51 -0
  54. package/dist/events/transports/redis-stream-entry.d.mts +2 -0
  55. package/dist/events/transports/redis-stream-entry.mjs +177 -0
  56. package/dist/events/transports/redis.d.mts +76 -0
  57. package/dist/events/transports/redis.mjs +124 -0
  58. package/dist/externalPaths-SyPF2tgK.d.mts +50 -0
  59. package/dist/factory/index.d.mts +63 -0
  60. package/dist/factory/index.mjs +3 -0
  61. package/dist/fastifyAdapter-C8DlE0YH.d.mts +216 -0
  62. package/dist/fields-Bi_AVKSo.d.mts +109 -0
  63. package/dist/fields-CTd_CrKr.mjs +114 -0
  64. package/dist/hooks/index.d.mts +4 -0
  65. package/dist/hooks/index.mjs +3 -0
  66. package/dist/idempotency/index.d.mts +96 -0
  67. package/dist/idempotency/index.mjs +319 -0
  68. package/dist/idempotency/mongodb.d.mts +2 -0
  69. package/dist/idempotency/mongodb.mjs +114 -0
  70. package/dist/idempotency/redis.d.mts +2 -0
  71. package/dist/idempotency/redis.mjs +103 -0
  72. package/dist/index.d.mts +260 -0
  73. package/dist/index.mjs +104 -0
  74. package/dist/integrations/event-gateway.d.mts +46 -0
  75. package/dist/integrations/event-gateway.mjs +43 -0
  76. package/dist/integrations/index.d.mts +5 -0
  77. package/dist/integrations/index.mjs +1 -0
  78. package/dist/integrations/jobs.d.mts +103 -0
  79. package/dist/integrations/jobs.mjs +123 -0
  80. package/dist/integrations/streamline.d.mts +60 -0
  81. package/dist/integrations/streamline.mjs +125 -0
  82. package/dist/integrations/websocket.d.mts +82 -0
  83. package/dist/integrations/websocket.mjs +288 -0
  84. package/dist/interface-CSNjltAc.d.mts +77 -0
  85. package/dist/interface-DTbsvIWe.d.mts +54 -0
  86. package/dist/interface-e9XfSsUV.d.mts +1097 -0
  87. package/dist/introspectionPlugin-B3JkrjwU.mjs +53 -0
  88. package/dist/keys-DhqDRxv3.mjs +42 -0
  89. package/dist/logger-ByrvQWZO.mjs +78 -0
  90. package/dist/memory-B2v7KrCB.mjs +143 -0
  91. package/dist/migrations/index.d.mts +156 -0
  92. package/dist/migrations/index.mjs +260 -0
  93. package/dist/mongodb-ClykrfGo.d.mts +118 -0
  94. package/dist/mongodb-DNKEExbf.mjs +93 -0
  95. package/dist/mongodb-Dg8O_gvd.d.mts +71 -0
  96. package/dist/openapi-9nB_kiuR.mjs +525 -0
  97. package/dist/org/index.d.mts +68 -0
  98. package/dist/org/index.mjs +513 -0
  99. package/dist/org/types.d.mts +82 -0
  100. package/dist/org/types.mjs +1 -0
  101. package/dist/permissions/index.d.mts +278 -0
  102. package/dist/permissions/index.mjs +579 -0
  103. package/dist/plugins/index.d.mts +172 -0
  104. package/dist/plugins/index.mjs +522 -0
  105. package/dist/plugins/response-cache.d.mts +87 -0
  106. package/dist/plugins/response-cache.mjs +283 -0
  107. package/dist/plugins/tracing-entry.d.mts +2 -0
  108. package/dist/plugins/tracing-entry.mjs +185 -0
  109. package/dist/pluralize-CM-jZg7p.mjs +86 -0
  110. package/dist/policies/{index.d.ts → index.d.mts} +204 -170
  111. package/dist/policies/index.mjs +321 -0
  112. package/dist/presets/{index.d.ts → index.d.mts} +62 -131
  113. package/dist/presets/index.mjs +143 -0
  114. package/dist/presets/multiTenant.d.mts +24 -0
  115. package/dist/presets/multiTenant.mjs +113 -0
  116. package/dist/presets-BTeYbw7h.d.mts +57 -0
  117. package/dist/presets-CeFtfDR8.mjs +119 -0
  118. package/dist/prisma-C3iornoK.d.mts +274 -0
  119. package/dist/prisma-DJbMt3yf.mjs +627 -0
  120. package/dist/queryCachePlugin-B6R0d4av.mjs +138 -0
  121. package/dist/queryCachePlugin-Q6SYuHZ6.d.mts +71 -0
  122. package/dist/redis-UwjEp8Ea.d.mts +49 -0
  123. package/dist/redis-stream-CBg0upHI.d.mts +103 -0
  124. package/dist/registry/index.d.mts +11 -0
  125. package/dist/registry/index.mjs +4 -0
  126. package/dist/requestContext-xi6OKBL-.mjs +55 -0
  127. package/dist/schemaConverter-Dtg0Kt9T.mjs +98 -0
  128. package/dist/schemas/index.d.mts +63 -0
  129. package/dist/schemas/index.mjs +82 -0
  130. package/dist/scope/index.d.mts +21 -0
  131. package/dist/scope/index.mjs +65 -0
  132. package/dist/sessionManager-D_iEHjQl.d.mts +186 -0
  133. package/dist/sse-DkqQ1uxb.mjs +123 -0
  134. package/dist/testing/index.d.mts +907 -0
  135. package/dist/testing/index.mjs +1976 -0
  136. package/dist/tracing-8CEbhF0w.d.mts +70 -0
  137. package/dist/typeGuards-DwxA1t_L.mjs +9 -0
  138. package/dist/types/index.d.mts +946 -0
  139. package/dist/types/index.mjs +14 -0
  140. package/dist/types-B0dhNrnd.d.mts +445 -0
  141. package/dist/types-Beqn1Un7.mjs +38 -0
  142. package/dist/types-DelU6kln.mjs +25 -0
  143. package/dist/types-RLkFVgaw.d.mts +101 -0
  144. package/dist/utils/index.d.mts +747 -0
  145. package/dist/utils/index.mjs +6 -0
  146. package/package.json +194 -68
  147. package/dist/BaseController-DVAiHxEQ.d.ts +0 -233
  148. package/dist/adapters/index.d.ts +0 -237
  149. package/dist/adapters/index.js +0 -668
  150. package/dist/arcCorePlugin-CsShQdyP.d.ts +0 -273
  151. package/dist/audit/index.d.ts +0 -195
  152. package/dist/audit/index.js +0 -319
  153. package/dist/auth/index.d.ts +0 -47
  154. package/dist/auth/index.js +0 -174
  155. package/dist/cli/commands/docs.d.ts +0 -11
  156. package/dist/cli/commands/docs.js +0 -474
  157. package/dist/cli/commands/generate.js +0 -334
  158. package/dist/cli/commands/introspect.d.ts +0 -8
  159. package/dist/cli/commands/introspect.js +0 -338
  160. package/dist/cli/index.d.ts +0 -4
  161. package/dist/cli/index.js +0 -3269
  162. package/dist/core/index.d.ts +0 -220
  163. package/dist/core/index.js +0 -2786
  164. package/dist/createApp-Ce9wl8W9.d.ts +0 -77
  165. package/dist/docs/index.d.ts +0 -166
  166. package/dist/docs/index.js +0 -658
  167. package/dist/errors-8WIxGS_6.d.ts +0 -122
  168. package/dist/events/index.d.ts +0 -117
  169. package/dist/events/index.js +0 -89
  170. package/dist/factory/index.d.ts +0 -38
  171. package/dist/factory/index.js +0 -1652
  172. package/dist/hooks/index.d.ts +0 -4
  173. package/dist/hooks/index.js +0 -199
  174. package/dist/idempotency/index.d.ts +0 -323
  175. package/dist/idempotency/index.js +0 -500
  176. package/dist/index-B4t03KQ0.d.ts +0 -1366
  177. package/dist/index.d.ts +0 -135
  178. package/dist/index.js +0 -4756
  179. package/dist/migrations/index.d.ts +0 -185
  180. package/dist/migrations/index.js +0 -274
  181. package/dist/org/index.d.ts +0 -129
  182. package/dist/org/index.js +0 -220
  183. package/dist/permissions/index.d.ts +0 -144
  184. package/dist/permissions/index.js +0 -103
  185. package/dist/plugins/index.d.ts +0 -46
  186. package/dist/plugins/index.js +0 -1069
  187. package/dist/policies/index.js +0 -196
  188. package/dist/presets/index.js +0 -384
  189. package/dist/presets/multiTenant.d.ts +0 -39
  190. package/dist/presets/multiTenant.js +0 -112
  191. package/dist/registry/index.d.ts +0 -16
  192. package/dist/registry/index.js +0 -253
  193. package/dist/testing/index.d.ts +0 -618
  194. package/dist/testing/index.js +0 -48020
  195. package/dist/types/index.d.ts +0 -4
  196. package/dist/types/index.js +0 -8
  197. package/dist/types-B99TBmFV.d.ts +0 -76
  198. package/dist/types-BvckRbs2.d.ts +0 -143
  199. package/dist/utils/index.d.ts +0 -679
  200. package/dist/utils/index.js +0 -931
@@ -0,0 +1,103 @@
1
+ //#region src/idempotency/stores/redis.ts
2
+ var RedisIdempotencyStore = class {
3
+ name = "redis";
4
+ client;
5
+ prefix;
6
+ lockPrefix;
7
+ ttlMs;
8
+ constructor(options) {
9
+ this.client = options.client;
10
+ this.prefix = options.prefix ?? "idem:";
11
+ this.lockPrefix = options.lockPrefix ?? "idem:lock:";
12
+ this.ttlMs = options.ttlMs ?? 864e5;
13
+ }
14
+ resultKey(key) {
15
+ return `${this.prefix}${key}`;
16
+ }
17
+ lockKey(key) {
18
+ return `${this.lockPrefix}${key}`;
19
+ }
20
+ async get(key) {
21
+ const data = await this.client.get(this.resultKey(key));
22
+ if (!data) return void 0;
23
+ try {
24
+ const result = JSON.parse(data);
25
+ if (new Date(result.expiresAt) < /* @__PURE__ */ new Date()) {
26
+ await this.delete(key);
27
+ return;
28
+ }
29
+ return {
30
+ ...result,
31
+ createdAt: new Date(result.createdAt),
32
+ expiresAt: new Date(result.expiresAt)
33
+ };
34
+ } catch {
35
+ return;
36
+ }
37
+ }
38
+ async set(key, result) {
39
+ const data = {
40
+ key,
41
+ ...result
42
+ };
43
+ const ttlSeconds = Math.ceil((new Date(result.expiresAt).getTime() - Date.now()) / 1e3);
44
+ if (ttlSeconds > 0) await this.client.set(this.resultKey(key), JSON.stringify(data), { EX: ttlSeconds });
45
+ }
46
+ async tryLock(key, requestId, ttlMs) {
47
+ const ttlSeconds = Math.ceil(ttlMs / 1e3);
48
+ return await this.client.set(this.lockKey(key), requestId, {
49
+ EX: ttlSeconds,
50
+ NX: true
51
+ }) === "OK";
52
+ }
53
+ async unlock(key, requestId) {
54
+ if (await this.client.get(this.lockKey(key)) === requestId) await this.client.del(this.lockKey(key));
55
+ }
56
+ async isLocked(key) {
57
+ return await this.client.exists(this.lockKey(key)) > 0;
58
+ }
59
+ async delete(key) {
60
+ await this.client.del([this.resultKey(key), this.lockKey(key)]);
61
+ }
62
+ async deleteByPrefix(prefix) {
63
+ const resultKeys = await this.scanByPrefix(this.resultKey(prefix));
64
+ const lockKeys = await this.scanByPrefix(this.lockKey(prefix));
65
+ const allKeys = [...resultKeys, ...lockKeys];
66
+ if (allKeys.length === 0) return 0;
67
+ return this.client.del(allKeys);
68
+ }
69
+ async findByPrefix(prefix) {
70
+ const keys = await this.scanByPrefix(this.resultKey(prefix));
71
+ for (const key of keys) {
72
+ const data = await this.client.get(key);
73
+ if (!data) continue;
74
+ try {
75
+ const result = JSON.parse(data);
76
+ if (new Date(result.expiresAt) < /* @__PURE__ */ new Date()) continue;
77
+ return {
78
+ ...result,
79
+ createdAt: new Date(result.createdAt),
80
+ expiresAt: new Date(result.expiresAt)
81
+ };
82
+ } catch {
83
+ continue;
84
+ }
85
+ }
86
+ }
87
+ /** Scan Redis keys matching a prefix pattern. Falls back to empty if SCAN unavailable. */
88
+ async scanByPrefix(prefix) {
89
+ if (!this.client.scan) return [];
90
+ const keys = [];
91
+ let cursor = "0";
92
+ do {
93
+ const [nextCursor, batch] = await this.client.scan(cursor, "MATCH", `${prefix}*`, "COUNT", 100);
94
+ cursor = nextCursor;
95
+ keys.push(...batch);
96
+ } while (String(cursor) !== "0");
97
+ return keys;
98
+ }
99
+ async close() {}
100
+ };
101
+
102
+ //#endregion
103
+ export { RedisIdempotencyStore };
@@ -0,0 +1,260 @@
1
+ import "./elevation-DGo5shaX.mjs";
2
+ import { D as CrudRepository, E as defineResource, F as OperationFilter, I as PipelineConfig, L as PipelineContext, M as Guard, N as Interceptor, P as NextFunction, R as PipelineStep, S as RouteHandler, T as ResourceDefinition, _ as ControllerLike, a as RepositoryLike, b as IControllerResponse, c as BaseController, i as RelationMetadata, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, x as IRequestContext, y as IController, z as Transform } from "./interface-e9XfSsUV.mjs";
3
+ import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } 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 { AdditionalRoute, AnyRecord, ApiResponse, ArcInternalMetadata, AuthPluginOptions, ConfigError, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, EventDefinition, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, MiddlewareConfig, MiddlewareHandler, OwnershipCheck, PresetFunction, PresetResult, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestWithExtras, ResourceConfig, ResourceMetadata, RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TypedController, TypedRepository, TypedResourceConfig, UserOrganization, ValidateOptions, ValidationResult as ValidationResult$1 } from "./types/index.mjs";
6
+ import { c as MongooseAdapterOptions, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./prisma-C3iornoK.mjs";
7
+ import "./adapters/index.mjs";
8
+ import { C as MutationOperation, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, p as DEFAULT_TENANT_FIELD, s as CRUD_OPERATIONS, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "./fastifyAdapter-C8DlE0YH.mjs";
9
+ import "./core/index.mjs";
10
+ import { a as NotFoundError, d as ValidationError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DAWRdiYP.mjs";
11
+ import { a as presets_d_exports, c as readOnly, i as ownerWithAdminBypass, n as authenticated, o as publicRead, r as fullPublic, s as publicReadAdminWrite, t as adminOnly } from "./presets-BTeYbw7h.mjs";
12
+ import { DynamicPermissionMatrix, DynamicPermissionMatrixConfig, allOf, allowPublic, anyOf, createDynamicPermissionMatrix, createOrgPermissions, denyAll, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, when } from "./permissions/index.mjs";
13
+ import { AsyncLocalStorage } from "node:async_hooks";
14
+
15
+ //#region src/core/validateResourceConfig.d.ts
16
+ interface ConfigError$1 {
17
+ field: string;
18
+ message: string;
19
+ suggestion?: string;
20
+ }
21
+ interface ValidationResult$2 {
22
+ valid: boolean;
23
+ errors: ConfigError$1[];
24
+ warnings: ConfigError$1[];
25
+ }
26
+ interface ValidateOptions$1 {
27
+ /** Skip controller method validation (for testing) */
28
+ skipControllerCheck?: boolean;
29
+ /** Allow unknown preset names */
30
+ allowUnknownPresets?: boolean;
31
+ /** Custom valid permission keys beyond CRUD */
32
+ additionalPermissionKeys?: string[];
33
+ }
34
+ /**
35
+ * Validate a resource configuration
36
+ */
37
+ declare function validateResourceConfig(config: ResourceConfig, options?: ValidateOptions$1): ValidationResult$2;
38
+ /**
39
+ * Format validation errors for display
40
+ */
41
+ declare function formatValidationErrors(resourceName: string, result: ValidationResult$2): string;
42
+ /**
43
+ * Validate and throw if invalid
44
+ */
45
+ declare function assertValidConfig(config: ResourceConfig, options?: ValidateOptions$1): void;
46
+ //#endregion
47
+ //#region src/pipeline/guard.d.ts
48
+ interface GuardOptions {
49
+ operations?: OperationFilter;
50
+ handler: (ctx: PipelineContext) => boolean | Promise<boolean>;
51
+ }
52
+ /**
53
+ * Create a named guard.
54
+ *
55
+ * @param name - Guard name (for debugging/introspection)
56
+ * @param handlerOrOptions - Handler function or options object
57
+ */
58
+ declare function guard(name: string, handlerOrOptions: ((ctx: PipelineContext) => boolean | Promise<boolean>) | GuardOptions): Guard;
59
+ //#endregion
60
+ //#region src/pipeline/transform.d.ts
61
+ interface TransformOptions {
62
+ operations?: OperationFilter;
63
+ handler: (ctx: PipelineContext) => PipelineContext | void | Promise<PipelineContext | void>;
64
+ }
65
+ /**
66
+ * Create a named transform.
67
+ *
68
+ * @param name - Transform name (for debugging/introspection)
69
+ * @param handlerOrOptions - Handler function or options object
70
+ */
71
+ declare function transform(name: string, handlerOrOptions: ((ctx: PipelineContext) => PipelineContext | void | Promise<PipelineContext | void>) | TransformOptions): Transform;
72
+ //#endregion
73
+ //#region src/pipeline/intercept.d.ts
74
+ interface InterceptOptions {
75
+ operations?: OperationFilter;
76
+ handler: (ctx: PipelineContext, next: NextFunction) => Promise<IControllerResponse<unknown>>;
77
+ }
78
+ /**
79
+ * Create a named interceptor.
80
+ *
81
+ * @param name - Interceptor name (for debugging/introspection)
82
+ * @param handlerOrOptions - Handler function or options object
83
+ */
84
+ declare function intercept(name: string, handlerOrOptions: ((ctx: PipelineContext, next: NextFunction) => Promise<IControllerResponse<unknown>>) | InterceptOptions): Interceptor;
85
+ //#endregion
86
+ //#region src/pipeline/pipe.d.ts
87
+ /**
88
+ * Compose pipeline steps into an ordered array.
89
+ * Accepts guards, transforms, and interceptors in any order.
90
+ */
91
+ declare function pipe(...steps: PipelineStep[]): PipelineStep[];
92
+ //#endregion
93
+ //#region src/middleware/middleware.d.ts
94
+ interface NamedMiddleware {
95
+ /** Unique name for debugging/introspection */
96
+ readonly name: string;
97
+ /** Operations this middleware applies to (default: all) */
98
+ readonly operations?: Array<'list' | 'get' | 'create' | 'update' | 'delete' | string>;
99
+ /** Priority — lower numbers run first (default: 10) */
100
+ readonly priority: number;
101
+ /** Conditional execution — return true to run, false to skip */
102
+ readonly when?: (request: RequestWithExtras) => boolean | Promise<boolean>;
103
+ /** The middleware handler */
104
+ readonly handler: MiddlewareHandler;
105
+ }
106
+ interface MiddlewareOptions {
107
+ operations?: NamedMiddleware['operations'];
108
+ priority?: number;
109
+ when?: NamedMiddleware['when'];
110
+ handler: MiddlewareHandler;
111
+ }
112
+ /**
113
+ * Create a named middleware with priority and conditions.
114
+ */
115
+ declare function middleware(name: string, options: MiddlewareOptions): NamedMiddleware;
116
+ /**
117
+ * Sort named middlewares by priority (ascending — lower runs first).
118
+ * Returns a MiddlewareConfig map keyed by operation, ready to pass to `defineResource()`.
119
+ */
120
+ declare function sortMiddlewares(middlewares: NamedMiddleware[]): MiddlewareConfig;
121
+ //#endregion
122
+ //#region src/context/requestContext.d.ts
123
+ /**
124
+ * Shape of the request-scoped context store.
125
+ * Populated by Arc's onRequest hook in arcCorePlugin.
126
+ */
127
+ interface RequestStore {
128
+ /** Unique request identifier */
129
+ requestId?: string;
130
+ /** Authenticated user (if any) */
131
+ user?: {
132
+ id?: string;
133
+ _id?: string;
134
+ roles?: string[];
135
+ [key: string]: unknown;
136
+ } | null;
137
+ /** Active organization ID (multi-tenant) */
138
+ organizationId?: string;
139
+ /** Active team ID (team-scoped resources) */
140
+ teamId?: string;
141
+ /** Current resource name (set by arcDecorator in CRUD routes) */
142
+ resourceName?: string;
143
+ /** Request start time (for timing) */
144
+ startTime: number;
145
+ /** Additional context — extensible by app */
146
+ [key: string]: unknown;
147
+ }
148
+ /**
149
+ * Request context API.
150
+ *
151
+ * - `get()` — returns current store or undefined if outside request scope
152
+ * - `run(store, fn)` — run a function with a specific store (used by Arc internals)
153
+ * - `getStore()` — alias for get() (matches Node.js API naming)
154
+ */
155
+ declare const requestContext: {
156
+ /**
157
+ * Get the current request context.
158
+ * Returns undefined if called outside a request lifecycle.
159
+ */
160
+ get(): RequestStore | undefined;
161
+ /**
162
+ * Alias for get() — matches Node.js AsyncLocalStorage API naming.
163
+ */
164
+ getStore(): RequestStore | undefined;
165
+ /**
166
+ * Run a function within a specific request context.
167
+ * Used internally by Arc's onRequest hook.
168
+ */
169
+ run<T>(store: RequestStore, fn: () => T): T;
170
+ /**
171
+ * The underlying AsyncLocalStorage instance.
172
+ * Exposed for advanced use cases (testing, custom integrations).
173
+ */
174
+ storage: AsyncLocalStorage<RequestStore>;
175
+ };
176
+ //#endregion
177
+ //#region src/logger/index.d.ts
178
+ /**
179
+ * Arc Logger — Centralized debug & warning system
180
+ *
181
+ * Lightweight, zero-dependency logger for Arc framework internals.
182
+ * Inspired by the `debug` npm package — disabled by default, opt-in via
183
+ * environment variable or `createApp({ debug })` option.
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * // Enable via env var
188
+ * ARC_DEBUG=1 node server.js // all modules
189
+ * ARC_DEBUG=scope,elevation node server.js // specific modules
190
+ *
191
+ * // Enable via createApp
192
+ * const app = await createApp({ debug: true });
193
+ * const app = await createApp({ debug: 'scope,elevation' });
194
+ *
195
+ * // Suppress warnings (not recommended)
196
+ * ARC_SUPPRESS_WARNINGS=1 node server.js
197
+ *
198
+ * // Framework internals use:
199
+ * import { arcLog } from '../logger/index.js';
200
+ * const log = arcLog('elevation');
201
+ * log.debug('Elevation applied', { userId });
202
+ * log.warn('Something unexpected');
203
+ * ```
204
+ */
205
+ interface ArcLoggerOptions {
206
+ /**
207
+ * Enable debug output.
208
+ * - `true` or `'*'` — all modules
209
+ * - `string` — comma-separated module names (e.g., `'scope,elevation'`)
210
+ * - `false` — disabled (default)
211
+ */
212
+ debug?: boolean | string;
213
+ /**
214
+ * Custom log writer. Defaults to `console`.
215
+ * Useful for routing Arc logs into Fastify's pino logger or test fixtures.
216
+ */
217
+ writer?: ArcLogWriter;
218
+ }
219
+ interface ArcLogWriter {
220
+ debug: (...args: unknown[]) => void;
221
+ info: (...args: unknown[]) => void;
222
+ warn: (...args: unknown[]) => void;
223
+ error: (...args: unknown[]) => void;
224
+ }
225
+ interface ArcLogger {
226
+ debug: (...args: unknown[]) => void;
227
+ info: (...args: unknown[]) => void;
228
+ warn: (...args: unknown[]) => void;
229
+ error: (...args: unknown[]) => void;
230
+ }
231
+ /**
232
+ * Configure the Arc logger globally.
233
+ *
234
+ * Called automatically by `createApp({ debug })`, but can also be
235
+ * called manually for standalone usage outside of `createApp`.
236
+ */
237
+ declare function configureArcLogger(options: ArcLoggerOptions): void;
238
+ /**
239
+ * Create a module-scoped logger.
240
+ *
241
+ * Debug and info messages are gated by the `ARC_DEBUG` env var or
242
+ * `createApp({ debug })` option. Warnings always show (unless
243
+ * `ARC_SUPPRESS_WARNINGS=1`). Errors always show.
244
+ *
245
+ * @param module - Module name (e.g., 'scope', 'elevation', 'sse', 'preset')
246
+ * @returns Logger instance for that module
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * const log = arcLog('elevation');
251
+ * log.debug('Checking elevation header');
252
+ * log.warn('No authenticate decorator found');
253
+ * ```
254
+ */
255
+ declare function arcLog(module: string): ArcLogger;
256
+ //#endregion
257
+ //#region src/index.d.ts
258
+ declare const version: string;
259
+ //#endregion
260
+ export { type ValidationResult as AdapterValidationResult, type AdditionalRoute, type AnyRecord, type ApiResponse, ArcError, type ArcInternalMetadata, type ArcLogWriter, type ArcLogger, type ArcLoggerOptions, type AuthPluginOptions, BaseController, type BaseControllerOptions, CRUD_OPERATIONS, type ConfigError, type ControllerLike, type CrudController, CrudOperation, type CrudRepository, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DataAdapter, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldMetadata, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, type Guard, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, HookOperation, HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type Interceptor, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, MongooseAdapter, type MongooseAdapterOptions, MutationOperation, type NamedMiddleware, NotFoundError, type OwnershipCheck, type PaginatedResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PipelineConfig, type PipelineContext, type PipelineStep, type PresetFunction, type PresetResult, PrismaAdapter, type PrismaAdapterOptions, type QueryOptions, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RelationMetadata, type RepositoryLike, type RequestContext, type RequestIdOptions, type RequestStore, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SchemaMetadata, type ServiceContext, type Transform, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult$1 as ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, arcLog, assertValidConfig, authenticated, configureArcLogger, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, denyAll, fields, formatValidationErrors, fullPublic, getControllerScope, guard, intercept, middleware, ownerWithAdminBypass, presets_d_exports as permissions, pipe, publicRead, publicReadAdminWrite, readOnly, requestContext, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, sortMiddlewares, transform, validateResourceConfig, version, when };
package/dist/index.mjs ADDED
@@ -0,0 +1,104 @@
1
+ import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-DdXFXQtN.mjs";
2
+ import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./prisma-DJbMt3yf.mjs";
3
+ import { a as validateResourceConfig, g as BaseController, i as formatValidationErrors, l as pipe, m as getControllerScope, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-PXzSJ15_.mjs";
4
+ import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CTd_CrKr.mjs";
5
+ import { i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DBANPbGr.mjs";
6
+ import { t as requestContext } from "./requestContext-xi6OKBL-.mjs";
7
+ import { a as presets_exports, c as readOnly, i as ownerWithAdminBypass, n as authenticated, o as publicRead, r as fullPublic, s as publicReadAdminWrite, t as adminOnly } from "./presets-CeFtfDR8.mjs";
8
+ import { allOf, allowPublic, anyOf, createDynamicPermissionMatrix, createOrgPermissions, denyAll, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, when } from "./permissions/index.mjs";
9
+ import { n as configureArcLogger, t as arcLog } from "./logger-ByrvQWZO.mjs";
10
+
11
+ //#region src/pipeline/guard.ts
12
+ /**
13
+ * Create a named guard.
14
+ *
15
+ * @param name - Guard name (for debugging/introspection)
16
+ * @param handlerOrOptions - Handler function or options object
17
+ */
18
+ function guard(name, handlerOrOptions) {
19
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
20
+ return {
21
+ _type: "guard",
22
+ name,
23
+ operations: opts.operations,
24
+ handler: opts.handler
25
+ };
26
+ }
27
+
28
+ //#endregion
29
+ //#region src/pipeline/transform.ts
30
+ /**
31
+ * Create a named transform.
32
+ *
33
+ * @param name - Transform name (for debugging/introspection)
34
+ * @param handlerOrOptions - Handler function or options object
35
+ */
36
+ function transform(name, handlerOrOptions) {
37
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
38
+ return {
39
+ _type: "transform",
40
+ name,
41
+ operations: opts.operations,
42
+ handler: opts.handler
43
+ };
44
+ }
45
+
46
+ //#endregion
47
+ //#region src/pipeline/intercept.ts
48
+ /**
49
+ * Create a named interceptor.
50
+ *
51
+ * @param name - Interceptor name (for debugging/introspection)
52
+ * @param handlerOrOptions - Handler function or options object
53
+ */
54
+ function intercept(name, handlerOrOptions) {
55
+ const opts = typeof handlerOrOptions === "function" ? { handler: handlerOrOptions } : handlerOrOptions;
56
+ return {
57
+ _type: "interceptor",
58
+ name,
59
+ operations: opts.operations,
60
+ handler: opts.handler
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ //#region src/middleware/middleware.ts
66
+ /**
67
+ * Create a named middleware with priority and conditions.
68
+ */
69
+ function middleware(name, options) {
70
+ return {
71
+ name,
72
+ operations: options.operations,
73
+ priority: options.priority ?? 10,
74
+ when: options.when,
75
+ handler: options.handler
76
+ };
77
+ }
78
+ /**
79
+ * Sort named middlewares by priority (ascending — lower runs first).
80
+ * Returns a MiddlewareConfig map keyed by operation, ready to pass to `defineResource()`.
81
+ */
82
+ function sortMiddlewares(middlewares) {
83
+ const sorted = [...middlewares].sort((a, b) => a.priority - b.priority);
84
+ const operations = CRUD_OPERATIONS;
85
+ const result = {};
86
+ for (const op of operations) {
87
+ const applicable = sorted.filter((m) => !m.operations || m.operations.length === 0 || m.operations.includes(op));
88
+ if (applicable.length > 0) result[op] = applicable.map((m) => {
89
+ if (!m.when) return m.handler;
90
+ const wrapped = async (request, reply) => {
91
+ if (await m.when(request)) return m.handler(request, reply);
92
+ };
93
+ return wrapped;
94
+ });
95
+ }
96
+ return result;
97
+ }
98
+
99
+ //#endregion
100
+ //#region src/index.ts
101
+ const version = "__ARC_VERSION__";
102
+
103
+ //#endregion
104
+ export { ArcError, BaseController, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MongooseAdapter, NotFoundError, PrismaAdapter, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, arcLog, assertValidConfig, authenticated, configureArcLogger, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, denyAll, fields, formatValidationErrors, fullPublic, getControllerScope, guard, intercept, middleware, ownerWithAdminBypass, presets_exports as permissions, pipe, publicRead, publicReadAdminWrite, readOnly, requestContext, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, sortMiddlewares, transform, validateResourceConfig, version, when };
@@ -0,0 +1,46 @@
1
+ import { t as DomainEvent } from "../EventTransport-BkUDYZEb.mjs";
2
+ import { WebSocketClient, WebSocketMessage } from "./websocket.mjs";
3
+ import { FastifyPluginAsync, FastifyRequest } from "fastify";
4
+
5
+ //#region src/integrations/event-gateway.d.ts
6
+ interface EventGatewayOptions {
7
+ /** Require auth for all real-time connections (default: true) */
8
+ auth?: boolean;
9
+ /** Custom auth function for WebSocket upgrade */
10
+ authenticate?: (request: unknown) => Promise<{
11
+ userId?: string;
12
+ organizationId?: string;
13
+ } | null>;
14
+ /** Filter events by org from request.scope (default: false) */
15
+ orgScoped?: boolean;
16
+ /** Room/subscription authorization policy */
17
+ roomPolicy?: (client: {
18
+ userId?: string;
19
+ organizationId?: string;
20
+ }, room: string) => boolean | Promise<boolean>;
21
+ /** Max message size from WS clients in bytes (default: 16384) */
22
+ maxMessageBytes?: number;
23
+ /** Max subscriptions per client (default: 100) */
24
+ maxSubscriptionsPerClient?: number;
25
+ /** SSE config. Set false to disable SSE. */
26
+ sse?: false | {
27
+ path?: string;
28
+ patterns?: string[];
29
+ heartbeat?: number;
30
+ filter?: (event: DomainEvent<unknown>, request: FastifyRequest) => boolean;
31
+ };
32
+ /** WebSocket config. Set false to disable WebSocket. */
33
+ ws?: false | {
34
+ path?: string;
35
+ resources?: string[];
36
+ heartbeatInterval?: number;
37
+ maxClientsPerRoom?: number;
38
+ exposeStats?: boolean | "authenticated";
39
+ onMessage?: (client: WebSocketClient, message: WebSocketMessage) => void | Promise<void>;
40
+ onConnect?: (client: WebSocketClient) => void | Promise<void>;
41
+ onDisconnect?: (client: WebSocketClient) => void | Promise<void>;
42
+ };
43
+ }
44
+ declare const eventGatewayPlugin: FastifyPluginAsync<EventGatewayOptions>;
45
+ //#endregion
46
+ export { EventGatewayOptions, eventGatewayPlugin as default, eventGatewayPlugin };
@@ -0,0 +1,43 @@
1
+ import fp from "fastify-plugin";
2
+
3
+ //#region src/integrations/event-gateway.ts
4
+ const eventGatewayPluginImpl = async (fastify, opts = {}) => {
5
+ const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
6
+ if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
7
+ if (opts.sse !== false) {
8
+ const { default: ssePlugin } = await import("../sse-DkqQ1uxb.mjs").then((n) => n.r);
9
+ await fastify.register(ssePlugin, {
10
+ path: opts.sse?.path ?? "/events/stream",
11
+ requireAuth: auth,
12
+ patterns: opts.sse?.patterns ?? ["*"],
13
+ heartbeat: opts.sse?.heartbeat ?? 3e4,
14
+ orgScoped,
15
+ filter: opts.sse?.filter
16
+ });
17
+ }
18
+ if (opts.ws !== false) {
19
+ const { websocketPlugin } = await import("./websocket.mjs");
20
+ await fastify.register(websocketPlugin, {
21
+ path: opts.ws?.path ?? "/ws",
22
+ auth,
23
+ authenticate,
24
+ resources: opts.ws?.resources ?? [],
25
+ heartbeatInterval: opts.ws?.heartbeatInterval ?? 3e4,
26
+ maxClientsPerRoom: opts.ws?.maxClientsPerRoom,
27
+ roomPolicy,
28
+ maxMessageBytes,
29
+ maxSubscriptionsPerClient,
30
+ exposeStats: opts.ws?.exposeStats,
31
+ onMessage: opts.ws?.onMessage,
32
+ onConnect: opts.ws?.onConnect,
33
+ onDisconnect: opts.ws?.onDisconnect
34
+ });
35
+ }
36
+ };
37
+ const eventGatewayPlugin = fp(eventGatewayPluginImpl, {
38
+ name: "arc-event-gateway",
39
+ fastify: "5.x"
40
+ });
41
+
42
+ //#endregion
43
+ export { eventGatewayPlugin as default, eventGatewayPlugin };
@@ -0,0 +1,5 @@
1
+ import { WebSocketClient, WebSocketMessage, WebSocketPluginOptions } from "./websocket.mjs";
2
+ import { EventGatewayOptions } from "./event-gateway.mjs";
3
+ import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
4
+ import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
5
+ export { type EventGatewayOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobsPluginOptions, type QueueStats, type StreamlinePluginOptions, type WebSocketClient, type WebSocketMessage, type WebSocketPluginOptions, type WorkflowLike, type WorkflowRunLike };
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,103 @@
1
+ import { FastifyPluginAsync } from "fastify";
2
+
3
+ //#region src/integrations/jobs.d.ts
4
+ interface JobDefinition<TData = unknown, TResult = unknown> {
5
+ /** Unique job name */
6
+ name: string;
7
+ /** Job handler function */
8
+ handler: (data: TData, meta: JobMeta) => Promise<TResult>;
9
+ /** Number of retries on failure (default: 3) */
10
+ retries?: number;
11
+ /** Backoff strategy */
12
+ backoff?: {
13
+ type: 'exponential' | 'fixed';
14
+ delay: number;
15
+ };
16
+ /** Job timeout in ms (default: 30000) */
17
+ timeout?: number;
18
+ /** Concurrency per worker (default: 1) */
19
+ concurrency?: number;
20
+ /** Rate limit: max jobs per duration */
21
+ rateLimit?: {
22
+ max: number;
23
+ duration: number;
24
+ };
25
+ /** Dead letter queue name (default: '{name}:dead') */
26
+ deadLetterQueue?: string;
27
+ }
28
+ interface JobMeta {
29
+ jobId: string;
30
+ attemptsMade: number;
31
+ timestamp: number;
32
+ }
33
+ interface JobDispatchOptions {
34
+ /** Delay job execution by ms */
35
+ delay?: number;
36
+ /** Job priority (lower = higher priority) */
37
+ priority?: number;
38
+ /** Unique job ID (for deduplication) */
39
+ jobId?: string;
40
+ /** Remove job after completion */
41
+ removeOnComplete?: boolean | number;
42
+ /** Remove job after failure */
43
+ removeOnFail?: boolean | number;
44
+ }
45
+ interface JobsPluginOptions {
46
+ /** Redis connection options (passed to BullMQ) */
47
+ connection: {
48
+ host: string;
49
+ port: number;
50
+ password?: string;
51
+ db?: number;
52
+ } | unknown;
53
+ /** Job definitions to register */
54
+ jobs: JobDefinition[];
55
+ /** URL prefix for job management endpoints (default: '/jobs') */
56
+ prefix?: string;
57
+ /** Bridge job events to Arc's event bus (default: true) */
58
+ bridgeEvents?: boolean;
59
+ /** Default job options applied to all jobs */
60
+ defaults?: {
61
+ retries?: number;
62
+ backoff?: {
63
+ type: 'exponential' | 'fixed';
64
+ delay: number;
65
+ };
66
+ timeout?: number;
67
+ removeOnComplete?: boolean | number;
68
+ removeOnFail?: boolean | number;
69
+ };
70
+ }
71
+ interface JobDispatcher {
72
+ dispatch<TData = unknown>(name: string, data: TData, options?: JobDispatchOptions): Promise<{
73
+ jobId: string;
74
+ }>;
75
+ getQueue(name: string): unknown | null;
76
+ getStats(): Promise<Record<string, QueueStats>>;
77
+ close(): Promise<void>;
78
+ }
79
+ interface QueueStats {
80
+ waiting: number;
81
+ active: number;
82
+ completed: number;
83
+ failed: number;
84
+ delayed: number;
85
+ }
86
+ /**
87
+ * Define a background job with typed data and configuration.
88
+ *
89
+ * @example
90
+ * const processImage = defineJob({
91
+ * name: 'process-image',
92
+ * handler: async (data: { url: string; width: number }) => {
93
+ * return await sharp(data.url).resize(data.width).toBuffer();
94
+ * },
95
+ * retries: 3,
96
+ * timeout: 60000,
97
+ * });
98
+ */
99
+ declare function defineJob<TData = unknown, TResult = unknown>(definition: JobDefinition<TData, TResult>): JobDefinition<TData, TResult>;
100
+ /** Pluggable BullMQ job queue integration for Arc */
101
+ declare const jobsPlugin: FastifyPluginAsync<JobsPluginOptions>;
102
+ //#endregion
103
+ export { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats, jobsPlugin as default, jobsPlugin, defineJob };