@classytic/arc 2.22.0 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/{BaseController-C6FlRWxF.mjs → BaseController--M8EMzt0.mjs} +92 -22
  2. package/dist/QueryCache-DOMT_iq7.d.mts +72 -0
  3. package/dist/{ResourceRegistry-7RnrEWNP.mjs → ResourceRegistry-y9Hnypus.mjs} +1 -0
  4. package/dist/actionPermissions-CAphcmUG.mjs +24 -0
  5. package/dist/applyPermissionResult-Tw4iXtlf.mjs +264 -0
  6. package/dist/audit/index.d.mts +32 -3
  7. package/dist/audit/index.mjs +7 -4
  8. package/dist/auth/index.d.mts +2 -2
  9. package/dist/auth/index.mjs +264 -260
  10. package/dist/{buildHandler-D_2ULWxZ.mjs → buildHandler-Dtwd8fdz.mjs} +1 -1
  11. package/dist/cache/index.d.mts +41 -3
  12. package/dist/cache/index.mjs +33 -4
  13. package/dist/cli/commands/describe.d.mts +1 -1
  14. package/dist/cli/commands/describe.mjs +1 -1
  15. package/dist/cli/commands/docs.mjs +2 -2
  16. package/dist/cli/commands/generate.mjs +1 -1
  17. package/dist/cli/commands/init.mjs +1 -1
  18. package/dist/cli/commands/introspect.mjs +1 -1
  19. package/dist/cli/index.mjs +2 -2
  20. package/dist/context/index.mjs +2 -64
  21. package/dist/core/index.d.mts +3 -3
  22. package/dist/core/index.mjs +4 -4
  23. package/dist/{core-b6fgFgnd.mjs → core-EUNu0u07.mjs} +298 -12
  24. package/dist/{createActionRouter-h1cEEaEX.mjs → createActionRouter-B6GvAuAX.mjs} +4 -3
  25. package/dist/{createAggregationRouter-B1C0kvTL.mjs → createAggregationRouter-wzwFa_dW.mjs} +3 -3
  26. package/dist/docs/index.d.mts +1 -1
  27. package/dist/docs/index.mjs +2 -2
  28. package/dist/{elevation-COpYKt2h.mjs → elevation-CIz1GjGm.mjs} +4 -3
  29. package/dist/{errorHandler-BTzXSwIg.mjs → errorHandler-Bq2OeEQL.mjs} +10 -7
  30. package/dist/{eventPlugin-A6EbthXR.d.mts → eventPlugin-Bg3cP2_u.d.mts} +38 -3
  31. package/dist/{eventPlugin-DJG2D7sy.mjs → eventPlugin-DrQ_FesK.mjs} +22 -4
  32. package/dist/events/index.d.mts +57 -314
  33. package/dist/events/index.mjs +168 -93
  34. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  35. package/dist/events/transports/redis-stream-entry.mjs +24 -2
  36. package/dist/factory/index.d.mts +21 -6
  37. package/dist/factory/index.mjs +58 -18
  38. package/dist/{fastify-augmentation-9_fuetB4.d.mts → fastify-augmentation-dPNBVeIj.d.mts} +25 -2
  39. package/dist/{generate-usRSdQmP.mjs → generate-D0wZupBg.mjs} +1 -1
  40. package/dist/headers-BvlQSDMB.mjs +45 -0
  41. package/dist/health-CB_m4S32.mjs +377 -0
  42. package/dist/hooks/index.d.mts +1 -1
  43. package/dist/idempotency/index.d.mts +7 -0
  44. package/dist/idempotency/index.mjs +32 -20
  45. package/dist/{index-ogIHvOjo.d.mts → index-BMnbzvtO.d.mts} +70 -4
  46. package/dist/{integrations/jobs.d.mts → index-CG4yqMDB.d.mts} +82 -2
  47. package/dist/{index-DbtgCOCj.d.mts → index-DPRH0Cme.d.mts} +46 -94
  48. package/dist/{module-B4u10iOJ.d.mts → index-KUoxjIq1.d.mts} +263 -23
  49. package/dist/{index-D8MKYGDa.d.mts → index-f4PTrk3B.d.mts} +37 -5
  50. package/dist/index.d.mts +6 -6
  51. package/dist/index.mjs +6 -5
  52. package/dist/{init-DleK3p9f.mjs → init-tlRSt667.mjs} +206 -205
  53. package/dist/integrations/event-gateway.d.mts +1 -1
  54. package/dist/integrations/event-gateway.mjs +1 -1
  55. package/dist/integrations/index.d.mts +3 -3
  56. package/dist/integrations/jobs/index.d.mts +2 -0
  57. package/dist/integrations/{jobs.mjs → jobs/index.mjs} +110 -67
  58. package/dist/integrations/mcp/index.d.mts +68 -5
  59. package/dist/integrations/mcp/index.mjs +2 -2
  60. package/dist/integrations/mcp/testing.d.mts +1 -1
  61. package/dist/integrations/mcp/testing.mjs +1 -1
  62. package/dist/integrations/webhooks.d.mts +149 -22
  63. package/dist/integrations/webhooks.mjs +186 -42
  64. package/dist/integrations/websocket-redis.d.mts +1 -1
  65. package/dist/integrations/websocket.d.mts +1 -1
  66. package/dist/integrations/websocket.mjs +41 -14
  67. package/dist/{interface-C1_WLTMK.d.mts → interface-BGZCzOGL.d.mts} +24 -31
  68. package/dist/interface-n5hpKg1d.mjs +16 -0
  69. package/dist/{loadResourcesFromEntry-OMCvIEE7.mjs → loadResourcesFromEntry-kvGT6EcO.mjs} +1 -1
  70. package/dist/{mcpPlugin-ByA2tf6D.mjs → mcpPlugin-Cb7olw0j.mjs} +316 -45
  71. package/dist/{memory-CLXA2VeJ.mjs → memory-CmnzXE5Z.mjs} +29 -0
  72. package/dist/middleware/index.d.mts +17 -1
  73. package/dist/middleware/index.mjs +1 -1
  74. package/dist/migrations/index.d.mts +94 -44
  75. package/dist/migrations/index.mjs +196 -44
  76. package/dist/{multipartBody-CHEQSZ6G.mjs → multipartBody-D0eBvkeq.mjs} +17 -0
  77. package/dist/{openapi-BRpMZD7C.mjs → openapi-DrLtog_B.mjs} +4 -4
  78. package/dist/permissions/index.d.mts +3 -3
  79. package/dist/permissions/index.mjs +4 -3
  80. package/dist/{permissions-BJMuKMl7.mjs → permissions-BrtiBKGs.mjs} +305 -492
  81. package/dist/pipeline/index.d.mts +1 -1
  82. package/dist/{actionPermissions-ze70xXJi.mjs → pipeline-BN5G05rd.mjs} +4 -27
  83. package/dist/plugins/index.d.mts +7 -78
  84. package/dist/plugins/index.mjs +14 -97
  85. package/dist/plugins/response-cache.mjs +1 -0
  86. package/dist/plugins/tracing-entry.mjs +1 -1
  87. package/dist/{index-BEu4wjbL.d.mts → preloadResources-0oe-JSSS.d.mts} +59 -50
  88. package/dist/{createApp-Ci7yG5gv.mjs → preloadResources-DfyngIN9.mjs} +240 -68
  89. package/dist/presets/filesUpload.d.mts +3 -3
  90. package/dist/presets/filesUpload.mjs +3 -3
  91. package/dist/presets/index.d.mts +2 -1
  92. package/dist/presets/index.mjs +1 -1
  93. package/dist/presets/multiTenant.d.mts +1 -1
  94. package/dist/presets/multiTenant.mjs +1 -1
  95. package/dist/presets/search.d.mts +2 -2
  96. package/dist/presets/search.mjs +1 -1
  97. package/dist/{presets-gw0ciIUD.mjs → presets-DwFDVKP0.mjs} +2 -2
  98. package/dist/{queryCachePlugin-DzqLN904.mjs → queryCachePlugin-DSGuSVLW.mjs} +39 -8
  99. package/dist/{queryCachePlugin-CfYWq-Ak.d.mts → queryCachePlugin-br4otiqF.d.mts} +2 -2
  100. package/dist/{registerRoute-xHc42fwB.mjs → rateLimit-DrED-C4v.mjs} +2 -109
  101. package/dist/realtime-Cuw_deA-.mjs +375 -0
  102. package/dist/{redis-stream-iVR2l7aS.d.mts → redis-stream-uIaauNpZ.d.mts} +22 -0
  103. package/dist/registerRoute-v0Wb6Plt.mjs +108 -0
  104. package/dist/registry/index.d.mts +2 -2
  105. package/dist/registry/index.mjs +1 -1
  106. package/dist/renewingLease-3cuQH7h8.mjs +44 -0
  107. package/dist/{requestContext-BZKOr13H.mjs → requestContext-MrlJwECf.mjs} +2 -2
  108. package/dist/schedules-CjOd2MG9.mjs +113 -0
  109. package/dist/{schemaConverter-Ds5reSGs.mjs → schemaConverter-DJvodiHj.mjs} +4 -1
  110. package/dist/{schemaIR-B-6SPe7g.mjs → schemaIR-Ca7ySNPx.mjs} +1 -1
  111. package/dist/schemas/index.d.mts +67 -67
  112. package/dist/schemas/index.mjs +2 -3
  113. package/dist/scim/index.mjs +1 -2
  114. package/dist/scope/index.d.mts +2 -2
  115. package/dist/scope/index.mjs +4 -4
  116. package/dist/scope-DfaPntpo.mjs +36 -0
  117. package/dist/simpleEqualityMatcher-Cg05HPsn.mjs +68 -0
  118. package/dist/{sse-CfUjwjDk.mjs → sse-BQ1w0dfl.mjs} +8 -31
  119. package/dist/sseStream-BQ7Qaynp.mjs +57 -0
  120. package/dist/testing/index.d.mts +4 -3
  121. package/dist/testing/index.mjs +2 -2
  122. package/dist/transactionContext-PNdoyLLm.mjs +64 -0
  123. package/dist/types/index.d.mts +4 -4
  124. package/dist/{types-bHblZ9YN.mjs → types-CSyCxl2V.mjs} +38 -7
  125. package/dist/{types-DH0GupI7.d.mts → types-DjC-KUCz.d.mts} +118 -20
  126. package/dist/{types-Csxga7d3.d.mts → types-Dmw-6Qeo.d.mts} +96 -4
  127. package/dist/{types-Bc42CUyk.d.mts → types-QFGc3Cjv.d.mts} +37 -2
  128. package/dist/usage/index.d.mts +3 -52
  129. package/dist/usage/index.mjs +0 -0
  130. package/dist/userHelpers-Cg_y3fBz.mjs +29 -0
  131. package/dist/utils/index.d.mts +90 -57
  132. package/dist/utils/index.mjs +7 -3
  133. package/dist/{utils-FhJ88TJE.mjs → utils-taUVD4p3.mjs} +47 -385
  134. package/dist/{validate-C2mGgSXg.mjs → validate-Bk44F2yT.mjs} +1 -1
  135. package/dist/{versioning-DLwklPlG.d.mts → versioning-DXgY5BUm.d.mts} +52 -31
  136. package/dist/{versioning-Dk-71iIz.mjs → versioning-gKWyryT3.mjs} +8 -1
  137. package/dist/{websocket-uuWqM6UY.d.mts → websocket-_Pd0CgR0.d.mts} +15 -1
  138. package/package.json +526 -453
  139. package/skills/arc/references/api-reference.md +3 -1
  140. package/skills/arc/references/integrations.md +20 -11
  141. package/skills/arc/references/production.md +734 -696
  142. package/dist/QueryCache-Z1B38koh.d.mts +0 -40
  143. package/dist/betterAuthOpenApi-CV1lxpRX.mjs +0 -2
  144. package/dist/health-ScyjIVo5.mjs +0 -202
  145. package/dist/requestId-5BhTVzBv.mjs +0 -113
  146. package/dist/scope-k15RXfcq.mjs +0 -64
  147. package/dist/types-XTApa8b6.mjs +0 -24
@@ -1,7 +1,7 @@
1
- import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, H as CrudController, L as RequestWithExtras, Lt as IController, Rt as IControllerResponse, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, qt as AnyRecord, tt as ArcFieldRule, ut as AggregationConfig, zt as IRequestContext } from "./index-DbtgCOCj.mjs";
2
- import { i as RequestScope } from "./types-DH0GupI7.mjs";
3
- import { t as PermissionCheck } from "./types-Csxga7d3.mjs";
4
- import "./fastify-augmentation-9_fuetB4.mjs";
1
+ import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, H as CrudController, L as RequestWithExtras, Lt as IController, Rt as IControllerResponse, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig, zt as IRequestContext } from "./index-DPRH0Cme.mjs";
2
+ import { i as RequestScope } from "./types-DjC-KUCz.mjs";
3
+ import { c as AnyRecord, t as PermissionCheck } from "./types-Dmw-6Qeo.mjs";
4
+ import "./fastify-augmentation-dPNBVeIj.mjs";
5
5
  import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
6
6
  import { z } from "zod";
7
7
  import { DataAdapter } from "@classytic/repo-core/adapter";
@@ -425,4 +425,36 @@ declare function isFieldReadable(rule: ArcFieldRule | undefined): boolean;
425
425
  */
426
426
  declare function collectReadBlockedFields(schemaOptions: RouteSchemaOptions | undefined): Set<string> | null;
427
427
  //#endregion
428
- export { HOOK_OPERATIONS as A, SYSTEM_FIELDS as B, CrudOperation as C, DEFAULT_SORT as D, DEFAULT_MAX_LIMIT as E, MAX_REGEX_LENGTH as F, MAX_SEARCH_LENGTH as I, MUTATION_OPERATIONS as L, HookOperation as M, HookPhase as N, DEFAULT_TENANT_FIELD as O, MAX_FILTER_DEPTH as P, MutationOperation as R, CRUD_OPERATIONS as S, DEFAULT_LIMIT as T, DefineActionConfig as _, createRequestContext as a, createPermissionMiddleware as b, sendControllerResponse as c, getEntityQuery as d, defineResourceVariants as f, mergeResourceConfig as g, SeamedResourceConfig as h, createFastifyHandler as i, HOOK_PHASES as j, DEFAULT_UPDATE_METHOD as k, getEntityId as l, ResourceSeams as m, isFieldReadable as n, getControllerContext as o, AdapterLike as p, createCrudHandlers as r, getControllerScope as s, collectReadBlockedFields as t, getEntityIdField as u, defineAction as v, DEFAULT_ID_FIELD as w, defineAggregation as x, createCrudRouter as y, RESERVED_QUERY_PARAMS as z };
428
+ //#region src/core/validateResourceConfig.d.ts
429
+ interface ConfigError {
430
+ field: string;
431
+ message: string;
432
+ suggestion?: string;
433
+ }
434
+ interface ValidationResult {
435
+ valid: boolean;
436
+ errors: ConfigError[];
437
+ warnings: ConfigError[];
438
+ }
439
+ interface ValidateOptions {
440
+ /** Skip controller method validation (for testing) */
441
+ skipControllerCheck?: boolean;
442
+ /** Allow unknown preset names */
443
+ allowUnknownPresets?: boolean;
444
+ /** Custom valid permission keys beyond CRUD */
445
+ additionalPermissionKeys?: string[];
446
+ }
447
+ /**
448
+ * Validate a resource configuration
449
+ */
450
+ declare function validateResourceConfig(config: ResourceConfig, options?: ValidateOptions): ValidationResult;
451
+ /**
452
+ * Format validation errors for display
453
+ */
454
+ declare function formatValidationErrors(resourceName: string, result: ValidationResult): string;
455
+ /**
456
+ * Validate and throw if invalid
457
+ */
458
+ declare function assertValidConfig(config: ResourceConfig, options?: ValidateOptions): void;
459
+ //#endregion
460
+ export { DEFAULT_ID_FIELD as A, MAX_FILTER_DEPTH as B, DefineActionConfig as C, defineAggregation as D, createPermissionMiddleware as E, DEFAULT_UPDATE_METHOD as F, RESERVED_QUERY_PARAMS as G, MAX_SEARCH_LENGTH as H, HOOK_OPERATIONS as I, SYSTEM_FIELDS as K, HOOK_PHASES as L, DEFAULT_MAX_LIMIT as M, DEFAULT_SORT as N, CRUD_OPERATIONS as O, DEFAULT_TENANT_FIELD as P, HookOperation as R, mergeResourceConfig as S, createCrudRouter as T, MUTATION_OPERATIONS as U, MAX_REGEX_LENGTH as V, MutationOperation as W, getEntityQuery as _, formatValidationErrors as a, ResourceSeams as b, isFieldReadable as c, createRequestContext as d, getControllerContext as f, getEntityIdField as g, getEntityId as h, assertValidConfig as i, DEFAULT_LIMIT as j, CrudOperation as k, createCrudHandlers as l, sendControllerResponse as m, ValidateOptions as n, validateResourceConfig as o, getControllerScope as p, ValidationResult as r, collectReadBlockedFields as s, ConfigError as t, createFastifyHandler as u, defineResourceVariants as v, defineAction as w, SeamedResourceConfig as x, AdapterLike as y, HookPhase as z };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
- import { $t as UserOrganization, A as RequestIdOptions, An as ArcCreateResult, B as defineResource, Bt as RouteHandler, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as BaseControllerOptions, Ft as ControllerLike, H as CrudController, Ht as AuthPluginOptions, In as ControllerConfigurableOptions, Jt as ApiResponse, L as RequestWithExtras, Ln as ControllerConstructionOptions, Lt as IController, Mn as ArcGetResult, N as FastifyRequestExtras, Nn as ArcListResult, Nt as RateLimitConfig, O as HealthOptions, P as FastifyWithAuth, Pn as ArcUpdateResult, Q as MiddlewareConfig, Rn as ListResult, Rt as IControllerResponse, S as QueryParserInterface, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, X as CrudRouteKey, Xt as JWTPayload, Y as PresetResult, Yt as ArcRequest, Z as CrudSchemas, a as InferAdapterDoc, an as SlugExt, c as TypedController, cn as BulkMixin, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, en as BaseController, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, in as TreeMixin, jn as ArcDeleteResult, k as IntrospectionPluginOptions, l as TypedRepository, ln as BaseCrudController, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nn as SoftDeleteMixin, nt as FieldRule, o as InferDocType, on as SlugMixin, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, qt as AnyRecord, r as ValidateOptions, rn as TreeExt, s as InferResourceDoc, sn as BulkExt, st as AggMeasureInput, t as RouteHandlerMethod, tn as SoftDeleteExt, u as TypedResourceConfig, ut as AggregationConfig, w as ServiceContext, y as OwnershipCheck, zt as IRequestContext } from "./index-DbtgCOCj.mjs";
2
- import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-Csxga7d3.mjs";
1
+ import { $t as SlugExt, A as RequestIdOptions, An as ControllerConfigurableOptions, B as defineResource, Bt as RouteHandler, C as RequestContext, D as HealthCheck, Dn as ArcListResult, E as GracefulShutdownOptions, En as ArcGetResult, F as FastifyWithDecorators, Ft as ControllerLike, H as CrudController, Jt as BaseController, L as RequestWithExtras, Lt as IController, Mn as ListResult, N as FastifyRequestExtras, Nt as RateLimitConfig, O as HealthOptions, On as ArcUpdateResult, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as TreeMixin, Rt as IControllerResponse, S as QueryParserInterface, T as CrudRouterOptions, Tn as ArcDeleteResult, U as ResourceConfig, Ut as AuthPluginOptions, V as ResourceDefinition, X as CrudRouteKey, Xt as SoftDeleteMixin, Y as PresetResult, Yt as SoftDeleteExt, Z as CrudSchemas, Zt as TreeExt, a as InferAdapterDoc, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, en as SlugMixin, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, jn as ControllerConstructionOptions, k as IntrospectionPluginOptions, kn as BaseControllerOptions, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nn as BulkMixin, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, r as ValidateOptions, rn as BaseCrudController, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, tn as BulkExt, u as TypedResourceConfig, ut as AggregationConfig, w as ServiceContext, wn as ArcCreateResult, y as OwnershipCheck, zt as IRequestContext } from "./index-DPRH0Cme.mjs";
2
+ import { c as AnyRecord, i as UserBase, l as ArcRequest, n as PermissionContext, p as UserOrganization, r as PermissionResult, t as PermissionCheck, u as JWTPayload } from "./types-Dmw-6Qeo.mjs";
3
3
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-D3lhgzhD.mjs";
4
- import "./fastify-augmentation-9_fuetB4.mjs";
5
- import { A as HOOK_OPERATIONS, B as SYSTEM_FIELDS, C as CrudOperation, D as DEFAULT_SORT, E as DEFAULT_MAX_LIMIT, F as MAX_REGEX_LENGTH, I as MAX_SEARCH_LENGTH, L as MUTATION_OPERATIONS, M as HookOperation, N as HookPhase, O as DEFAULT_TENANT_FIELD, P as MAX_FILTER_DEPTH, R as MutationOperation, S as CRUD_OPERATIONS, T as DEFAULT_LIMIT, f as defineResourceVariants, g as mergeResourceConfig, h as SeamedResourceConfig, j as HOOK_PHASES, k as DEFAULT_UPDATE_METHOD, m as ResourceSeams, p as AdapterLike, s as getControllerScope, v as defineAction, w as DEFAULT_ID_FIELD, x as defineAggregation, z as RESERVED_QUERY_PARAMS } from "./index-D8MKYGDa.mjs";
6
- import { A as requireOwnership, C as createOrgPermissions, D as denyAll, E as anyOf, N as when, S as createDynamicPermissionMatrix, T as allowPublic, b as DynamicPermissionMatrixConfig, c as publicReadAdminWrite, d as requireOrgMembership, f as requireOrgRole, h as requireTeamMembership, i as ownerWithAdminBypass, j as requireRoles, k as requireAuth, l as readOnly, m as requireServiceScope, n as authenticated, o as presets_d_exports, p as requireScopeContext, r as fullPublic, s as publicRead, t as adminOnly, u as requireOrgInScope, w as allOf, y as DynamicPermissionMatrix } from "./index-ogIHvOjo.mjs";
4
+ import "./fastify-augmentation-dPNBVeIj.mjs";
5
+ import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, D as defineAggregation, F as DEFAULT_UPDATE_METHOD, G as RESERVED_QUERY_PARAMS, H as MAX_SEARCH_LENGTH, I as HOOK_OPERATIONS, K as SYSTEM_FIELDS, L as HOOK_PHASES, M as DEFAULT_MAX_LIMIT, N as DEFAULT_SORT, O as CRUD_OPERATIONS, P as DEFAULT_TENANT_FIELD, R as HookOperation, S as mergeResourceConfig, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, b as ResourceSeams, j as DEFAULT_LIMIT, k as CrudOperation, p as getControllerScope, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "./index-f4PTrk3B.mjs";
6
+ import { A as allOf, E as DynamicPermissionMatrixConfig, F as requireAuth, I as requireOwnership, L as requireRoles, M as anyOf, N as denyAll, O as createDynamicPermissionMatrix, T as DynamicPermissionMatrix, c as publicReadAdminWrite, d as requireOrgMembership, f as requireOrgRole, h as requireTeamMembership, i as ownerWithAdminBypass, j as allowPublic, k as createOrgPermissions, l as readOnly, m as requireServiceScope, n as authenticated, o as presets_d_exports, p as requireScopeContext, r as fullPublic, s as publicRead, t as adminOnly, u as requireOrgInScope, z as when } from "./index-BMnbzvtO.mjs";
7
7
  import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DHcHVAgk.mjs";
8
8
  //#region src/index.d.ts
9
9
  declare const version: string;
10
10
  //#endregion
11
- export { type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ApiResponse, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type ResourceSeams, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SeamedResourceConfig, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
11
+ export { type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type ResourceSeams, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SeamedResourceConfig, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
package/dist/index.mjs CHANGED
@@ -1,10 +1,11 @@
1
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-DNre0wRg.mjs";
2
2
  import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DkO8Nk6-.mjs";
3
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-C6FlRWxF.mjs";
4
- import { E as requireRoles, F as applyFieldReadPermissions, I as applyFieldWritePermissions, L as fields, O as when, S as denyAll, T as requireOwnership, _ as requireServiceScope, b as allowPublic, c as publicReadAdminWrite, d as createDynamicPermissionMatrix, f as createOrgPermissions, g as requireScopeContext, h as requireOrgRole, i as ownerWithAdminBypass, l as readOnly, m as requireOrgMembership, n as authenticated, o as presets_exports, p as requireOrgInScope, r as fullPublic, s as publicRead, t as adminOnly, v as requireTeamMembership, w as requireAuth, x as anyOf, y as allOf } from "./permissions-BJMuKMl7.mjs";
5
- import { a as defineResource, c as defineAction, d as defineAggregation, i as defineResourceVariants, o as ResourceDefinition, s as mergeResourceConfig } from "./core-b6fgFgnd.mjs";
6
- import { l as getControllerScope } from "./actionPermissions-ze70xXJi.mjs";
3
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController--M8EMzt0.mjs";
4
+ import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, o as fields } from "./applyPermissionResult-Tw4iXtlf.mjs";
5
+ import { a as defineResource, d as defineAction, i as defineResourceVariants, l as ResourceDefinition, m as defineAggregation, u as mergeResourceConfig } from "./core-EUNu0u07.mjs";
6
+ import { c as getControllerScope } from "./pipeline-BN5G05rd.mjs";
7
+ import { A as requireAuth, D as anyOf, E as allowPublic, M as requireRoles, O as denyAll, P as when, T as allOf, _ as requireOrgMembership, b as requireServiceScope, c as publicReadAdminWrite, g as requireOrgInScope, h as createOrgPermissions, i as ownerWithAdminBypass, j as requireOwnership, l as readOnly, m as createDynamicPermissionMatrix, n as authenticated, o as presets_exports, r as fullPublic, s as publicRead, t as adminOnly, v as requireOrgRole, x as requireTeamMembership, y as requireScopeContext } from "./permissions-BrtiBKGs.mjs";
7
8
  //#region src/index.ts
8
- const version = "2.22.0";
9
+ const version = "2.25.0";
9
10
  //#endregion
10
11
  export { ArcError, BaseController, BaseCrudController, BulkMixin, 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, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -1,4 +1,3 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
1
  import * as fs from "node:fs/promises";
3
2
  import * as path from "node:path";
4
3
  import { dirname, join } from "node:path";
@@ -6,6 +5,206 @@ import { fileURLToPath } from "node:url";
6
5
  import { accessSync, existsSync, readFileSync } from "node:fs";
7
6
  import * as readline from "node:readline";
8
7
  import { execSync, spawn } from "node:child_process";
8
+ //#region src/cli/commands/init/dependency-plan.ts
9
+ /**
10
+ * Single source of truth for scaffolded project dependencies.
11
+ *
12
+ * Two layers keep the scaffold from ever contradicting the arc release
13
+ * that ships it:
14
+ *
15
+ * 1. The static table below — tracks published npm latest, bumped on
16
+ * release. Serves as the offline fallback.
17
+ * 2. A runtime overlay from arc's OWN package.json (version + declared
18
+ * peer floors). The 2.20.0 review found the static pins had drifted
19
+ * (`arc ^2.18.5` + `primitives ^0.6.0` while arc 2.20 peers demand
20
+ * >=0.9.0 → ERESOLVE on the first `arc init` a new user runs).
21
+ * Deriving from the installed package.json makes that class of
22
+ * breakage structurally impossible: the scaffold always pins the
23
+ * arc version actually running and ranges that satisfy its peers.
24
+ *
25
+ * Used by both `packageJsonTemplate` (declares the deps in the generated
26
+ * `package.json` so `npm install` works without a pre-pass) and
27
+ * `installDependencies` (runs the package manager's `install` against
28
+ * the declared ranges). One source — no drift.
29
+ */
30
+ const SCAFFOLD_DEP_VERSIONS = {
31
+ core: {
32
+ "@classytic/arc": "^2.20.0",
33
+ "@classytic/primitives": "^0.11.0",
34
+ "@classytic/repo-core": "^0.8.0",
35
+ "@fastify/cors": "^11.2.0",
36
+ "@fastify/helmet": "^13.0.2",
37
+ "@fastify/rate-limit": "^10.3.0",
38
+ "@fastify/sensible": "^6.0.4",
39
+ "@fastify/under-pressure": "^9.0.3",
40
+ dotenv: "^17.4.2",
41
+ fastify: "^5.8.5",
42
+ zod: "^4.3.6"
43
+ },
44
+ authJwt: {
45
+ "@fastify/jwt": "^10.1.0",
46
+ bcryptjs: "^3.0.3"
47
+ },
48
+ authBetterAuth: {
49
+ "better-auth": "^1.6.11",
50
+ mongodb: "^7.2.0"
51
+ },
52
+ authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
53
+ adapterMongokit: {
54
+ "@classytic/mongokit": "^3.21.0",
55
+ mongoose: "^9.6.2"
56
+ },
57
+ devCommon: {
58
+ "@biomejs/biome": "^2.4.15",
59
+ "pino-pretty": "^13.1.3",
60
+ vitest: "^4.1.7"
61
+ },
62
+ devMongokit: { "mongodb-memory-server": "^11.1.0" },
63
+ devTypescript: {
64
+ "@types/node": "^22.10.0",
65
+ tsx: "^4.22.3",
66
+ typescript: "^7.0.2"
67
+ },
68
+ typesJwt: { "@types/bcryptjs": "^3.0.0" }
69
+ };
70
+ /**
71
+ * Locate arc's own package.json by walking up from the executing file.
72
+ * A path walk (vs `require.resolve('@classytic/arc/package.json')`) works
73
+ * regardless of bundle chunk layout and of package.json not being in the
74
+ * exports map. Returns undefined when not found — callers fall back to
75
+ * the static table.
76
+ */
77
+ function readOwnPackageJson() {
78
+ try {
79
+ let dir = dirname(fileURLToPath(import.meta.url));
80
+ for (let depth = 0; depth < 6; depth++) {
81
+ const candidate = join(dir, "package.json");
82
+ if (existsSync(candidate)) {
83
+ const parsed = JSON.parse(readFileSync(candidate, "utf8"));
84
+ if (parsed.name === "@classytic/arc") return parsed;
85
+ }
86
+ const parent = dirname(dir);
87
+ if (parent === dir) break;
88
+ dir = parent;
89
+ }
90
+ } catch {}
91
+ }
92
+ /** First x.y.z triple in a range string, or undefined. */
93
+ function parseFloor(range) {
94
+ const m = /(\d+)\.(\d+)\.(\d+)/.exec(range);
95
+ if (!m) return void 0;
96
+ return [
97
+ Number(m[1]),
98
+ Number(m[2]),
99
+ Number(m[3])
100
+ ];
101
+ }
102
+ function floorLessThan(a, b) {
103
+ if (a[0] !== b[0]) return a[0] < b[0];
104
+ if (a[1] !== b[1]) return a[1] < b[1];
105
+ return a[2] < b[2];
106
+ }
107
+ /**
108
+ * Overlay live truth from arc's own package.json onto the static pins:
109
+ * - `@classytic/arc` pins the exact running version (`^<version>`).
110
+ * - Any scaffolded dep that is also an arc peer gets raised to `^<peer
111
+ * floor>` when the static pin's floor is BELOW the declared peer floor
112
+ * (never lowered — static pins may legitimately be ahead of the floor).
113
+ */
114
+ const latestCache = /* @__PURE__ */ new Map();
115
+ function allScaffoldPackageNames() {
116
+ const names = /* @__PURE__ */ new Set();
117
+ for (const group of Object.values(SCAFFOLD_DEP_VERSIONS)) for (const name of Object.keys(group)) names.add(name);
118
+ return [...names];
119
+ }
120
+ async function primeLatestScaffoldVersions(options) {
121
+ const timeoutMs = options?.timeoutMs ?? 3500;
122
+ const registry = (options?.registry ?? process.env.npm_config_registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
123
+ const names = allScaffoldPackageNames();
124
+ const results = await Promise.allSettled(names.map(async (name) => {
125
+ const res = await fetch(`${registry}/${name}/latest`, {
126
+ signal: AbortSignal.timeout(timeoutMs),
127
+ headers: { accept: "application/json" }
128
+ });
129
+ if (!res.ok) throw new Error(String(res.status));
130
+ const body = await res.json();
131
+ if (typeof body.version === "string" && /^\d+\.\d+\.\d+$/.test(body.version)) latestCache.set(name, body.version);
132
+ }));
133
+ return {
134
+ resolved: latestCache.size,
135
+ total: results.length
136
+ };
137
+ }
138
+ function parseBareVersion(v) {
139
+ const m = /^(\d+)\.(\d+)\.(\d+)$/.exec(v);
140
+ return m ? [
141
+ Number(m[1]),
142
+ Number(m[2]),
143
+ Number(m[3])
144
+ ] : void 0;
145
+ }
146
+ function applyLatestOverlay(dependencies) {
147
+ if (latestCache.size === 0) return;
148
+ for (const [name, currentRange] of Object.entries(dependencies)) {
149
+ const latest = latestCache.get(name);
150
+ if (!latest || latest.includes("-")) continue;
151
+ const latestV = parseBareVersion(latest);
152
+ const currentFloor = parseFloor(currentRange);
153
+ if (!latestV || !currentFloor) continue;
154
+ if (!floorLessThan(currentFloor, latestV)) continue;
155
+ if (latestV[0] !== currentFloor[0] && !name.startsWith("@classytic/")) continue;
156
+ dependencies[name] = `^${latest}`;
157
+ }
158
+ }
159
+ function overlayLiveArcVersions(dependencies) {
160
+ const own = readOwnPackageJson();
161
+ if (!own) return;
162
+ if (own.version && dependencies["@classytic/arc"]) dependencies["@classytic/arc"] = `^${own.version}`;
163
+ const peers = own.peerDependencies ?? {};
164
+ for (const [name, staticRange] of Object.entries(dependencies)) {
165
+ const peerRange = peers[name];
166
+ if (!peerRange) continue;
167
+ const peerFloor = parseFloor(peerRange);
168
+ const staticFloor = parseFloor(staticRange);
169
+ if (!peerFloor || !staticFloor) continue;
170
+ if (floorLessThan(staticFloor, peerFloor)) dependencies[name] = `^${peerFloor.join(".")}`;
171
+ }
172
+ }
173
+ /**
174
+ * Resolve the dependency manifest for a scaffold configuration.
175
+ *
176
+ * Returns sorted records (alphabetical by package name) so the generated
177
+ * `package.json` is deterministic — diffs across re-runs stay clean.
178
+ */
179
+ function resolveScaffoldDependencies(config) {
180
+ const dependencies = { ...SCAFFOLD_DEP_VERSIONS.core };
181
+ const devDependencies = { ...SCAFFOLD_DEP_VERSIONS.devCommon };
182
+ if (config.auth === "better-auth") {
183
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuth);
184
+ devDependencies["@fastify/jwt"] = SCAFFOLD_DEP_VERSIONS.authJwt["@fastify/jwt"];
185
+ if (config.apiKey) Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuthApiKey);
186
+ } else {
187
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authJwt);
188
+ if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.typesJwt);
189
+ }
190
+ if (config.adapter === "mongokit") {
191
+ Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.adapterMongokit);
192
+ Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devMongokit);
193
+ }
194
+ if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devTypescript);
195
+ applyLatestOverlay(dependencies);
196
+ applyLatestOverlay(devDependencies);
197
+ overlayLiveArcVersions(dependencies);
198
+ return {
199
+ dependencies: sortByKey(dependencies),
200
+ devDependencies: sortByKey(devDependencies)
201
+ };
202
+ }
203
+ /** Sort a record alphabetically by key — package.json convention. */
204
+ function sortByKey(record) {
205
+ return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
206
+ }
207
+ //#endregion
9
208
  //#region src/cli/commands/init/templates/adapter.ts
10
209
  function createAdapterTemplate(config) {
11
210
  const ts = config.typescript;
@@ -267,7 +466,10 @@ export async function createAppInstance()${ts ? ": Promise<FastifyInstance>" : "
267
466
  allowedHeaders: config.cors.allowedHeaders,
268
467
  credentials: config.cors.credentials,
269
468
  },
270
- trustProxy: true,
469
+ // One proxy hop (the typical LB / reverse-proxy deploy). Widen to a CIDR
470
+ // list or \`true\` only if you know every hop is yours; \`false\` if clients
471
+ // connect directly. Arc's production preset defaults to \`false\` (fail-closed).
472
+ trustProxy: 1,
271
473
  arcPlugins: {
272
474
  metrics: config.env === 'production', // Prometheus /_metrics endpoint
273
475
  ${config.adapter === "mongokit" ? ` // Readiness probe (/_health/ready) reports DOWN until Mongo connects —
@@ -1018,208 +1220,6 @@ ${config.adapter === "mongokit" ? ` await mongoose.connection.collection('use
1018
1220
  `;
1019
1221
  }
1020
1222
  //#endregion
1021
- //#region src/cli/commands/init/dependency-plan.ts
1022
- /**
1023
- * Single source of truth for scaffolded project dependencies.
1024
- *
1025
- * Two layers keep the scaffold from ever contradicting the arc release
1026
- * that ships it:
1027
- *
1028
- * 1. The static table below — tracks published npm latest, bumped on
1029
- * release. Serves as the offline fallback.
1030
- * 2. A runtime overlay from arc's OWN package.json (version + declared
1031
- * peer floors). The 2.20.0 review found the static pins had drifted
1032
- * (`arc ^2.18.5` + `primitives ^0.6.0` while arc 2.20 peers demand
1033
- * >=0.9.0 → ERESOLVE on the first `arc init` a new user runs).
1034
- * Deriving from the installed package.json makes that class of
1035
- * breakage structurally impossible: the scaffold always pins the
1036
- * arc version actually running and ranges that satisfy its peers.
1037
- *
1038
- * Used by both `packageJsonTemplate` (declares the deps in the generated
1039
- * `package.json` so `npm install` works without a pre-pass) and
1040
- * `installDependencies` (runs the package manager's `install` against
1041
- * the declared ranges). One source — no drift.
1042
- */
1043
- var dependency_plan_exports = /* @__PURE__ */ __exportAll({
1044
- SCAFFOLD_DEP_VERSIONS: () => SCAFFOLD_DEP_VERSIONS,
1045
- primeLatestScaffoldVersions: () => primeLatestScaffoldVersions,
1046
- resolveScaffoldDependencies: () => resolveScaffoldDependencies
1047
- });
1048
- const SCAFFOLD_DEP_VERSIONS = {
1049
- core: {
1050
- "@classytic/arc": "^2.20.0",
1051
- "@classytic/primitives": "^0.11.0",
1052
- "@classytic/repo-core": "^0.8.0",
1053
- "@fastify/cors": "^11.2.0",
1054
- "@fastify/helmet": "^13.0.2",
1055
- "@fastify/rate-limit": "^10.3.0",
1056
- "@fastify/sensible": "^6.0.4",
1057
- "@fastify/under-pressure": "^9.0.3",
1058
- dotenv: "^17.4.2",
1059
- fastify: "^5.8.5",
1060
- zod: "^4.3.6"
1061
- },
1062
- authJwt: {
1063
- "@fastify/jwt": "^10.1.0",
1064
- bcryptjs: "^3.0.3"
1065
- },
1066
- authBetterAuth: {
1067
- "better-auth": "^1.6.11",
1068
- mongodb: "^7.2.0"
1069
- },
1070
- authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
1071
- adapterMongokit: {
1072
- "@classytic/mongokit": "^3.21.0",
1073
- mongoose: "^9.6.2"
1074
- },
1075
- devCommon: {
1076
- "@biomejs/biome": "^2.4.15",
1077
- "mongodb-memory-server": "^11.1.0",
1078
- "pino-pretty": "^13.1.3",
1079
- vitest: "^4.1.7"
1080
- },
1081
- devTypescript: {
1082
- "@types/node": "^22.10.0",
1083
- tsx: "^4.22.3",
1084
- typescript: "^7.0.2"
1085
- },
1086
- typesJwt: { "@types/bcryptjs": "^3.0.0" }
1087
- };
1088
- /**
1089
- * Locate arc's own package.json by walking up from the executing file.
1090
- * A path walk (vs `require.resolve('@classytic/arc/package.json')`) works
1091
- * regardless of bundle chunk layout and of package.json not being in the
1092
- * exports map. Returns undefined when not found — callers fall back to
1093
- * the static table.
1094
- */
1095
- function readOwnPackageJson() {
1096
- try {
1097
- let dir = dirname(fileURLToPath(import.meta.url));
1098
- for (let depth = 0; depth < 6; depth++) {
1099
- const candidate = join(dir, "package.json");
1100
- if (existsSync(candidate)) {
1101
- const parsed = JSON.parse(readFileSync(candidate, "utf8"));
1102
- if (parsed.name === "@classytic/arc") return parsed;
1103
- }
1104
- const parent = dirname(dir);
1105
- if (parent === dir) break;
1106
- dir = parent;
1107
- }
1108
- } catch {}
1109
- }
1110
- /** First x.y.z triple in a range string, or undefined. */
1111
- function parseFloor(range) {
1112
- const m = /(\d+)\.(\d+)\.(\d+)/.exec(range);
1113
- if (!m) return void 0;
1114
- return [
1115
- Number(m[1]),
1116
- Number(m[2]),
1117
- Number(m[3])
1118
- ];
1119
- }
1120
- function floorLessThan(a, b) {
1121
- if (a[0] !== b[0]) return a[0] < b[0];
1122
- if (a[1] !== b[1]) return a[1] < b[1];
1123
- return a[2] < b[2];
1124
- }
1125
- /**
1126
- * Overlay live truth from arc's own package.json onto the static pins:
1127
- * - `@classytic/arc` pins the exact running version (`^<version>`).
1128
- * - Any scaffolded dep that is also an arc peer gets raised to `^<peer
1129
- * floor>` when the static pin's floor is BELOW the declared peer floor
1130
- * (never lowered — static pins may legitimately be ahead of the floor).
1131
- */
1132
- const latestCache = /* @__PURE__ */ new Map();
1133
- function allScaffoldPackageNames() {
1134
- const names = /* @__PURE__ */ new Set();
1135
- for (const group of Object.values(SCAFFOLD_DEP_VERSIONS)) for (const name of Object.keys(group)) names.add(name);
1136
- return [...names];
1137
- }
1138
- async function primeLatestScaffoldVersions(options) {
1139
- const timeoutMs = options?.timeoutMs ?? 3500;
1140
- const registry = (options?.registry ?? process.env.npm_config_registry ?? "https://registry.npmjs.org").replace(/\/$/, "");
1141
- const names = allScaffoldPackageNames();
1142
- const results = await Promise.allSettled(names.map(async (name) => {
1143
- const res = await fetch(`${registry}/${name}/latest`, {
1144
- signal: AbortSignal.timeout(timeoutMs),
1145
- headers: { accept: "application/json" }
1146
- });
1147
- if (!res.ok) throw new Error(String(res.status));
1148
- const body = await res.json();
1149
- if (typeof body.version === "string" && /^\d+\.\d+\.\d+$/.test(body.version)) latestCache.set(name, body.version);
1150
- }));
1151
- return {
1152
- resolved: latestCache.size,
1153
- total: results.length
1154
- };
1155
- }
1156
- function parseBareVersion(v) {
1157
- const m = /^(\d+)\.(\d+)\.(\d+)$/.exec(v);
1158
- return m ? [
1159
- Number(m[1]),
1160
- Number(m[2]),
1161
- Number(m[3])
1162
- ] : void 0;
1163
- }
1164
- function applyLatestOverlay(dependencies) {
1165
- if (latestCache.size === 0) return;
1166
- for (const [name, currentRange] of Object.entries(dependencies)) {
1167
- const latest = latestCache.get(name);
1168
- if (!latest || latest.includes("-")) continue;
1169
- const latestV = parseBareVersion(latest);
1170
- const currentFloor = parseFloor(currentRange);
1171
- if (!latestV || !currentFloor) continue;
1172
- if (!floorLessThan(currentFloor, latestV)) continue;
1173
- if (latestV[0] !== currentFloor[0] && !name.startsWith("@classytic/")) continue;
1174
- dependencies[name] = `^${latest}`;
1175
- }
1176
- }
1177
- function overlayLiveArcVersions(dependencies) {
1178
- const own = readOwnPackageJson();
1179
- if (!own) return;
1180
- if (own.version && dependencies["@classytic/arc"]) dependencies["@classytic/arc"] = `^${own.version}`;
1181
- const peers = own.peerDependencies ?? {};
1182
- for (const [name, staticRange] of Object.entries(dependencies)) {
1183
- const peerRange = peers[name];
1184
- if (!peerRange) continue;
1185
- const peerFloor = parseFloor(peerRange);
1186
- const staticFloor = parseFloor(staticRange);
1187
- if (!peerFloor || !staticFloor) continue;
1188
- if (floorLessThan(staticFloor, peerFloor)) dependencies[name] = `^${peerFloor.join(".")}`;
1189
- }
1190
- }
1191
- /**
1192
- * Resolve the dependency manifest for a scaffold configuration.
1193
- *
1194
- * Returns sorted records (alphabetical by package name) so the generated
1195
- * `package.json` is deterministic — diffs across re-runs stay clean.
1196
- */
1197
- function resolveScaffoldDependencies(config) {
1198
- const dependencies = { ...SCAFFOLD_DEP_VERSIONS.core };
1199
- const devDependencies = { ...SCAFFOLD_DEP_VERSIONS.devCommon };
1200
- if (config.auth === "better-auth") {
1201
- Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuth);
1202
- devDependencies["@fastify/jwt"] = SCAFFOLD_DEP_VERSIONS.authJwt["@fastify/jwt"];
1203
- if (config.apiKey) Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authBetterAuthApiKey);
1204
- } else {
1205
- Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.authJwt);
1206
- if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.typesJwt);
1207
- }
1208
- if (config.adapter === "mongokit") Object.assign(dependencies, SCAFFOLD_DEP_VERSIONS.adapterMongokit);
1209
- if (config.typescript) Object.assign(devDependencies, SCAFFOLD_DEP_VERSIONS.devTypescript);
1210
- applyLatestOverlay(dependencies);
1211
- applyLatestOverlay(devDependencies);
1212
- overlayLiveArcVersions(dependencies);
1213
- return {
1214
- dependencies: sortByKey(dependencies),
1215
- devDependencies: sortByKey(devDependencies)
1216
- };
1217
- }
1218
- /** Sort a record alphabetically by key — package.json convention. */
1219
- function sortByKey(record) {
1220
- return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
1221
- }
1222
- //#endregion
1223
1223
  //#region src/cli/commands/init/templates/config.ts
1224
1224
  /**
1225
1225
  * Project-level config templates — package.json, tsconfig, vitest, gitignore,
@@ -2056,6 +2056,8 @@ ${config.tenant === "multi" ? "import { flexibleMultiTenantPreset } from '#share
2056
2056
  import exampleRepository from './example.repository.js';
2057
2057
  import exampleController from './example.controller.js';
2058
2058
 
2059
+ // Fail-closed by default (mongokit >=3.25): invalid/blocked query input →
2060
+ // HTTP 400 instead of silently broadening the result set.
2059
2061
  const queryParser = new QueryParser({
2060
2062
  allowedFilterFields: ['isActive'],
2061
2063
  });
@@ -3438,7 +3440,6 @@ async function init(options = {}) {
3438
3440
  const packageManager = detectPackageManager();
3439
3441
  console.log(`Using package manager: ${packageManager}\n`);
3440
3442
  if (!process.env.VITEST && process.env.ARC_INIT_OFFLINE !== "1") {
3441
- const { primeLatestScaffoldVersions } = await Promise.resolve().then(() => dependency_plan_exports);
3442
3443
  const { resolved, total } = await primeLatestScaffoldVersions().catch(() => ({
3443
3444
  resolved: 0,
3444
3445
  total: 0
@@ -1,5 +1,5 @@
1
1
  import { n as DomainEvent } from "../EventTransport-QmY7A258.mjs";
2
- import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-uuWqM6UY.mjs";
2
+ import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-_Pd0CgR0.mjs";
3
3
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
4
4
  //#region src/integrations/event-gateway.d.ts
5
5
  interface EventGatewayOptions {
@@ -4,7 +4,7 @@ const eventGatewayPluginImpl = async (fastify, opts = {}) => {
4
4
  const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
5
5
  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.");
6
6
  if (opts.sse !== false) {
7
- const { default: ssePlugin } = await import("../sse-CfUjwjDk.mjs").then((n) => n.r);
7
+ const { default: ssePlugin } = await import("../sse-BQ1w0dfl.mjs").then((n) => n.r);
8
8
  await fastify.register(ssePlugin, {
9
9
  path: opts.sse?.path ?? "/events/stream",
10
10
  requireAuth: auth,
@@ -1,7 +1,7 @@
1
- import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-uuWqM6UY.mjs";
1
+ import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-_Pd0CgR0.mjs";
2
2
  import { EventGatewayOptions } from "./event-gateway.mjs";
3
- import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
4
- import { c as McpAuthResult, d as PromptDefinition, g as ToolDefinition, h as ToolContext, l as McpPluginOptions, m as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpResourceConfig } from "../types-Bc42CUyk.mjs";
3
+ import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-CG4yqMDB.mjs";
4
+ import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-QFGc3Cjv.mjs";
5
5
  import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
6
6
  import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
7
7
  export type { BetterAuthHandler, CallToolResult, CreateMcpServerConfig, CrudOperation, EventGatewayOptions, JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, McpAuthResult, McpPluginOptions, McpResourceConfig, PromptDefinition, QueueStats, StreamlinePluginOptions, ToolAnnotations, ToolContext, ToolDefinition, WebSocketClient, WebSocketMessage, WebSocketPluginOptions, WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription, WorkflowLike, WorkflowRunLike };
@@ -0,0 +1,2 @@
1
+ import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-CG4yqMDB.mjs";
2
+ export { type ExecuteTimedHandlerOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobRepeatOptions, type JobStatus, type JobsPluginOptions, type QueueStats, type TimedHandlerLogger, defineJob, executeTimedHandler, jobsPlugin };