@classytic/arc 2.11.4 → 2.13.1

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 (166) hide show
  1. package/README.md +16 -12
  2. package/dist/{BaseController-swXruJ2_.mjs → BaseController-DX_T-bDB.mjs} +388 -423
  3. package/dist/EventTransport-CT_52aWU.d.mts +34 -0
  4. package/dist/EventTransport-DLWoUMHy.mjs +103 -0
  5. package/dist/{ResourceRegistry-DkAeAuTX.mjs → ResourceRegistry-CTERg_2x.mjs} +139 -66
  6. package/dist/audit/index.d.mts +2 -2
  7. package/dist/audit/index.mjs +1 -1
  8. package/dist/auth/audit.d.mts +199 -0
  9. package/dist/auth/audit.mjs +288 -0
  10. package/dist/auth/index.d.mts +3 -3
  11. package/dist/auth/index.mjs +117 -191
  12. package/dist/{betterAuthOpenApi-DwxtK3uG.mjs → betterAuthOpenApi--M_i87dQ.mjs} +1 -1
  13. package/dist/buildHandler-olo-gt94.mjs +610 -0
  14. package/dist/cache/index.mjs +3 -3
  15. package/dist/cli/commands/describe.d.mts +89 -13
  16. package/dist/cli/commands/describe.mjs +56 -2
  17. package/dist/cli/commands/docs.mjs +2 -2
  18. package/dist/cli/commands/generate.mjs +147 -48
  19. package/dist/cli/commands/init.d.mts +13 -0
  20. package/dist/cli/commands/init.mjs +130 -87
  21. package/dist/cli/commands/introspect.mjs +8 -1
  22. package/dist/context/index.mjs +1 -1
  23. package/dist/core/index.d.mts +3 -3
  24. package/dist/core/index.mjs +5 -5
  25. package/dist/core-D72ia0EH.mjs +1399 -0
  26. package/dist/{createActionRouter-CIKOcNA7.mjs → createActionRouter-CEvzKcy8.mjs} +7 -20
  27. package/dist/createAggregationRouter-CyecOxnO.mjs +114 -0
  28. package/dist/{createApp-C9bRrqlX.mjs → createApp-XX2-N0Yd.mjs} +28 -22
  29. package/dist/{defineEvent-D1Ky9M1D.mjs → defineEvent-D5h7EvAx.mjs} +1 -1
  30. package/dist/docs/index.d.mts +1 -1
  31. package/dist/docs/index.mjs +2 -2
  32. package/dist/{elevation-DOFoxoDs.mjs → elevation-DgoeTyfX.mjs} +1 -1
  33. package/dist/errorHandler-Bk-AGhkU.mjs +174 -0
  34. package/dist/errorHandler-DFr45ZG4.d.mts +45 -0
  35. package/dist/errors-j4aJm1Wg.mjs +184 -0
  36. package/dist/{eventPlugin-Cts2-Tfj.mjs → eventPlugin-CaKTYkYM.mjs} +28 -4
  37. package/dist/{eventPlugin-DDJoNEPL.d.mts → eventPlugin-qXpqTebY.d.mts} +24 -1
  38. package/dist/events/index.d.mts +6 -6
  39. package/dist/events/index.mjs +11 -35
  40. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  41. package/dist/events/transports/redis.d.mts +1 -1
  42. package/dist/factory/index.d.mts +2 -2
  43. package/dist/factory/index.mjs +2 -2
  44. package/dist/{fields-BRjxOAFp.d.mts → fields-COhcH3fk.d.mts} +23 -2
  45. package/dist/hooks/index.d.mts +1 -1
  46. package/dist/hooks/index.mjs +1 -1
  47. package/dist/idempotency/index.d.mts +1 -1
  48. package/dist/idempotency/index.mjs +1 -20
  49. package/dist/idempotency/redis.mjs +1 -1
  50. package/dist/{index-rHjXmJar.d.mts → index-BTqLEvhu.d.mts} +163 -3
  51. package/dist/{index-CXXRbnf8.d.mts → index-BtW7qYwa.d.mts} +660 -326
  52. package/dist/{index-m8mOOlFW.d.mts → index-Ds61mrJE.d.mts} +50 -4
  53. package/dist/{index-D9t1KNaB.d.mts → index-Dz5IKsrE.d.mts} +360 -219
  54. package/dist/index.d.mts +6 -7
  55. package/dist/index.mjs +9 -10
  56. package/dist/integrations/event-gateway.d.mts +1 -1
  57. package/dist/integrations/event-gateway.mjs +1 -1
  58. package/dist/integrations/index.d.mts +1 -1
  59. package/dist/integrations/mcp/index.d.mts +2 -2
  60. package/dist/integrations/mcp/index.mjs +1 -1
  61. package/dist/integrations/mcp/testing.d.mts +1 -1
  62. package/dist/integrations/mcp/testing.mjs +1 -1
  63. package/dist/integrations/streamline.d.mts +60 -11
  64. package/dist/integrations/streamline.mjs +75 -85
  65. package/dist/integrations/websocket.mjs +2 -8
  66. package/dist/middleware/index.d.mts +1 -1
  67. package/dist/middleware/index.mjs +2 -2
  68. package/dist/migrations/index.d.mts +23 -3
  69. package/dist/migrations/index.mjs +0 -7
  70. package/dist/{multipartBody-CvTR1Un6.mjs → multipartBody-BOvVSVCD.mjs} +11 -8
  71. package/dist/{openapi-D7G1V7ex.mjs → openapi-CiOMVW1p.mjs} +143 -13
  72. package/dist/org/index.d.mts +2 -2
  73. package/dist/org/index.mjs +1 -1
  74. package/dist/permissions/index.d.mts +3 -3
  75. package/dist/permissions/index.mjs +3 -3
  76. package/dist/{permissions-gd_aUWrR.mjs → permissions-ohQyv50e.mjs} +404 -176
  77. package/dist/{pipe-DVoIheVC.mjs → pipe-Zr0KXjQe.mjs} +1 -1
  78. package/dist/pipeline/index.d.mts +1 -1
  79. package/dist/pipeline/index.mjs +1 -1
  80. package/dist/plugins/index.d.mts +16 -31
  81. package/dist/plugins/index.mjs +33 -13
  82. package/dist/plugins/response-cache.mjs +1 -1
  83. package/dist/plugins/tracing-entry.mjs +1 -1
  84. package/dist/presets/filesUpload.d.mts +4 -4
  85. package/dist/presets/filesUpload.mjs +6 -9
  86. package/dist/presets/index.d.mts +1 -1
  87. package/dist/presets/index.mjs +1 -1
  88. package/dist/presets/multiTenant.d.mts +1 -1
  89. package/dist/presets/multiTenant.mjs +2 -2
  90. package/dist/presets/search.d.mts +2 -2
  91. package/dist/presets/search.mjs +6 -8
  92. package/dist/{presets-Z7P5w4gF.mjs → presets-BbkjdPeH.mjs} +6 -28
  93. package/dist/{queryCachePlugin-Bq6bO6vc.mjs → queryCachePlugin-m1XsgAIJ.mjs} +3 -3
  94. package/dist/{redis-stream-xTGxB2bm.d.mts → redis-stream-D6HzR1Z_.d.mts} +1 -1
  95. package/dist/registry/index.d.mts +1 -1
  96. package/dist/registry/index.mjs +2 -2
  97. package/dist/{replyHelpers-ByllIXXV.mjs → replyHelpers-CK-FNO8E.mjs} +3 -21
  98. package/dist/{resourceToTools-CxNmI6xF.mjs → resourceToTools-C5coh64w.mjs} +224 -71
  99. package/dist/{routerShared-BqLRb5l7.mjs → routerShared-D6_fEGHh.mjs} +40 -36
  100. package/dist/{schemaIR-Dy2p4MxS.mjs → schemaIR-7Vl611Qs.mjs} +1 -1
  101. package/dist/schemas/index.d.mts +100 -30
  102. package/dist/schemas/index.mjs +86 -29
  103. package/dist/scim/index.d.mts +264 -0
  104. package/dist/scim/index.mjs +963 -0
  105. package/dist/scope/index.d.mts +3 -3
  106. package/dist/scope/index.mjs +4 -4
  107. package/dist/{sse-V7aXc3bW.mjs → sse-Bz-5ZeTt.mjs} +1 -1
  108. package/dist/{store-helpers-Cp4uKC1U.mjs → store-helpers-BkIN9-vu.mjs} +1 -1
  109. package/dist/testing/index.d.mts +2 -8
  110. package/dist/testing/index.mjs +16 -24
  111. package/dist/types/index.d.mts +4 -4
  112. package/dist/{types-D7KpfiL1.d.mts → types-BvqwCCSx.d.mts} +73 -25
  113. package/dist/{types-DDyTPc6y.d.mts → types-CTYvcwHe.d.mts} +195 -1
  114. package/dist/{types-AOD8fxIw.mjs → types-C_s5moIu.mjs} +117 -1
  115. package/dist/{types-BQ9TJQNy.d.mts → types-DQHFc8PM.d.mts} +1 -1
  116. package/dist/utils/index.d.mts +2 -2
  117. package/dist/utils/index.mjs +5 -5
  118. package/dist/{utils-CcYTj09l.mjs → utils-_h9B3c57.mjs} +1269 -1334
  119. package/dist/{versioning-DsglKfM_.d.mts → versioning-DTTvc80y.d.mts} +1 -1
  120. package/package.json +24 -34
  121. package/skills/arc/SKILL.md +147 -51
  122. package/skills/arc/references/agent-auth.md +238 -0
  123. package/skills/arc/references/api-reference.md +187 -0
  124. package/skills/arc/references/auth.md +354 -7
  125. package/skills/arc/references/enterprise-auth.md +94 -0
  126. package/skills/arc/references/events.md +8 -6
  127. package/skills/arc/references/mcp.md +2 -2
  128. package/skills/arc/references/multi-tenancy.md +11 -2
  129. package/skills/arc/references/production.md +10 -9
  130. package/skills/arc/references/scim.md +247 -0
  131. package/skills/arc/references/testing.md +1 -1
  132. package/skills/arc-code-review/SKILL.md +141 -0
  133. package/skills/arc-code-review/references/anti-patterns.md +911 -0
  134. package/skills/arc-code-review/references/arc-cheatsheet.md +380 -0
  135. package/skills/arc-code-review/references/migration-recipes.md +700 -0
  136. package/skills/arc-code-review/references/mongokit-migration.md +386 -0
  137. package/skills/arc-code-review/references/scaffolding.md +230 -0
  138. package/skills/arc-code-review/references/severity.md +127 -0
  139. package/dist/EventTransport-BFQjw9pB.mjs +0 -133
  140. package/dist/EventTransport-CYNUXdCJ.d.mts +0 -293
  141. package/dist/adapters/index.d.mts +0 -3
  142. package/dist/adapters/index.mjs +0 -2
  143. package/dist/adapters-DUUiiimH.mjs +0 -964
  144. package/dist/auth/mongoose.d.mts +0 -191
  145. package/dist/auth/mongoose.mjs +0 -73
  146. package/dist/core-CbcQRIch.mjs +0 -1054
  147. package/dist/errorHandler-BQm8ZxTK.mjs +0 -173
  148. package/dist/errorHandler-DEWmGWPz.d.mts +0 -114
  149. package/dist/errors-D5c-5BJL.mjs +0 -232
  150. package/dist/index-Rg8axYPz.d.mts +0 -370
  151. /package/dist/{HookSystem-CGsMd6oK.mjs → HookSystem-Iiebom92.mjs} +0 -0
  152. /package/dist/{actionPermissions-sUUKDhtP.mjs → actionPermissions-CyUkQu6O.mjs} +0 -0
  153. /package/dist/{caching-CheW3m-S.mjs → caching-SM8gghN6.mjs} +0 -0
  154. /package/dist/{constants-BhY1OHoH.mjs → constants-Cxde4rpC.mjs} +0 -0
  155. /package/dist/{elevation-BQQXZ_VR.d.mts → elevation-BXOWoGCF.d.mts} +0 -0
  156. /package/dist/{keys-CARyUjiR.mjs → keys-CGcCbNyu.mjs} +0 -0
  157. /package/dist/{loadResources-CPpkyKfM.mjs → loadResources-DBMQg_Aj.mjs} +0 -0
  158. /package/dist/{memory-DikHSvWa.mjs → memory-UBydS5ku.mjs} +0 -0
  159. /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
  160. /package/dist/{pluralize-CWP6MB39.mjs → pluralize-DQgqgifU.mjs} +0 -0
  161. /package/dist/{registry-D63ee7fl.mjs → registry-I-ogLgL9.mjs} +0 -0
  162. /package/dist/{requestContext-C5XeK3VA.mjs → requestContext-SSaaTgW8.mjs} +0 -0
  163. /package/dist/{schemaConverter-B0oKLuqI.mjs → schemaConverter-De34B1ZG.mjs} +0 -0
  164. /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-BzkXkvVv.mjs} +0 -0
  165. /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
  166. /package/dist/{versioning-CGPjkqAg.mjs → versioning-BUrT5aP4.mjs} +0 -0
package/dist/index.d.mts CHANGED
@@ -1,11 +1,10 @@
1
- import { $t as ArcListResult, A as RequestIdOptions, An as FieldMetadata, B as ResourceDefinition, Bt as UserOrganization, C as RequestContext, D as HealthCheck, Dn as AdapterRepositoryInput, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, Gt as TreeMixin, Ht as SoftDeleteExt, It as ArcRequest, J as CrudRouteKey, Jt as BulkExt, Kt as SlugExt, L as RequestWithExtras, Lt as JWTPayload, Mn as RepositoryLike, N as FastifyRequestExtras, Nn as SchemaMetadata, O as HealthOptions, P as FastifyWithAuth, Pn as ValidationResult, Pt as AnyRecord, Q as MiddlewareConfig, Qt as ArcGetResult, S as QueryParserInterface, T as CrudRouterOptions, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, X as EventDefinition, Xt as ArcCreateResult, Y as CrudSchemas, Yt as BulkMixin, Z as FieldRule, Zt as ArcDeleteResult, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, c as TypedController, d as PaginationResult, en as ArcUpdateResult, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, i as ValidationResult$1, jn as RelationMetadata, k as IntrospectionPluginOptions, kn as DataAdapter, kt as AuthPluginOptions, l as TypedRepository, m as RegistryStats, mt as ControllerLike, n as ConfigError, nn as BaseCrudController, nt as PresetResult, o as InferDocType, p as RegistryEntry, q as CrudController, qt as SlugMixin, r as ValidateOptions, rn as ListResult, rt as RateLimitConfig, s as InferResourceDoc, t as RouteHandlerMethod, tn as BaseControllerOptions, u as TypedResourceConfig, vt as IRequestContext, w as ServiceContext, y as OwnershipCheck, yt as RouteHandler } from "./index-CXXRbnf8.mjs";
2
- import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-BRjxOAFp.mjs";
3
- import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-Rg8axYPz.mjs";
4
- import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, m as DEFAULT_MAX_LIMIT, p as DEFAULT_LIMIT, s as defineResourceVariants, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "./index-m8mOOlFW.mjs";
5
- import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-rHjXmJar.mjs";
6
- import { ft as UnauthorizedError, j as envelope, mt as createDomainError, ot as ForbiddenError, pt as ValidationError, rt as ArcError, st as NotFoundError, t as getUserId } from "./index-D9t1KNaB.mjs";
1
+ import { $t as SoftDeleteMixin, A as RequestIdOptions, B as defineResource, C as RequestContext, Ct as AggregationConfig, D as HealthCheck, Dt as AggregationMaterializedResult, E as GracefulShutdownOptions, Et as AggregationMaterializedContext, F as FastifyWithDecorators, Gt as ApiResponse, J as CrudRouteKey, Kt as ArcRequest, L as RequestWithExtras, N as FastifyRequestExtras, O as HealthOptions, Ot as AggregationRateLimit, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as SoftDeleteExt, S as QueryParserInterface, St as AggregationCacheConfig, T as CrudRouterOptions, Tt as AggregationIndexHint, V as ResourceDefinition, Wt as AnyRecord, X as EventDefinition, Xt as UserOrganization, Y as CrudSchemas, Z as FieldRule, Zt as BaseController, _t as IControllerResponse, a as InferAdapterDoc, an as BulkMixin, at as ResourceConfig, bt as AggMeasureInput, c as TypedController, d as PaginationResult, dn as ArcDeleteResult, en as TreeExt, et as PresetFunction, f as IntrospectionData, fn as ArcGetResult, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, hn as ListResult, i as ValidationResult, in as BulkExt, k as IntrospectionPluginOptions, kt as AggregationsMap, l as TypedRepository, m as RegistryStats, mn as ArcUpdateResult, mt as ControllerLike, n as ConfigError, nn as SlugExt, nt as PresetResult, o as InferDocType, on as BaseControllerOptions, p as RegistryEntry, pn as ArcListResult, q as CrudController, qt as JWTPayload, r as ValidateOptions, rn as SlugMixin, rt as RateLimitConfig, s as InferResourceDoc, sn as BaseCrudController, t as RouteHandlerMethod, tn as TreeMixin, u as TypedResourceConfig, un as ArcCreateResult, vt as IRequestContext, w as ServiceContext, wt as AggregationDateRangeRequirement, xt as AggMeasureShorthand, y as OwnershipCheck, yt as RouteHandler, zt as AuthPluginOptions } from "./index-BtW7qYwa.mjs";
2
+ import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-COhcH3fk.mjs";
3
+ import { C as MAX_FILTER_DEPTH, D as MutationOperation, E as MUTATION_OPERATIONS, O as RESERVED_QUERY_PARAMS, S as HookPhase, T as MAX_SEARCH_LENGTH, _ as DEFAULT_TENANT_FIELD, a as getControllerScope, b as HOOK_PHASES, d as CRUD_OPERATIONS, f as CrudOperation, g as DEFAULT_SORT, h as DEFAULT_MAX_LIMIT, k as SYSTEM_FIELDS, m as DEFAULT_LIMIT, p as DEFAULT_ID_FIELD, s as defineResourceVariants, u as defineAggregation, v as DEFAULT_UPDATE_METHOD, w as MAX_REGEX_LENGTH, x as HookOperation, y as HOOK_OPERATIONS } from "./index-Ds61mrJE.mjs";
4
+ import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-BTqLEvhu.mjs";
5
+ import { ct as NotFoundError, ht as createDomainError, it as ArcError, mt as ValidationError, pt as UnauthorizedError, st as ForbiddenError, t as getUserId } from "./index-Dz5IKsrE.mjs";
7
6
 
8
7
  //#region src/index.d.ts
9
8
  declare const version: string;
10
9
  //#endregion
11
- export { type AdapterRepositoryInput, type ValidationResult as AdapterValidationResult, 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 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 DataAdapter, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldMetadata, 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, MongooseAdapter, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PresetFunction, type PresetResult, PrismaAdapter, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RelationMetadata, type RepositoryLike, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SchemaMetadata, 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$1 as ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, defineResourceVariants, denyAll, envelope, fields, fullPublic, getControllerScope, getUserId, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
10
+ export { 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 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 RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, 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, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, getUserId, 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,12 +1,11 @@
1
- import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./adapters-DUUiiimH.mjs";
2
- 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-BhY1OHoH.mjs";
3
- import { j as getUserId, r as envelope } from "./utils-CcYTj09l.mjs";
4
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-swXruJ2_.mjs";
5
- import { C as requireAuth, D as when, M as applyFieldWritePermissions, N as fields, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, j as applyFieldReadPermissions, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-gd_aUWrR.mjs";
6
- import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-D5c-5BJL.mjs";
7
- import { v as getControllerScope } from "./routerShared-BqLRb5l7.mjs";
8
- import { n as ResourceDefinition, r as defineResource, t as defineResourceVariants } from "./core-CbcQRIch.mjs";
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-Cxde4rpC.mjs";
2
+ import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-j4aJm1Wg.mjs";
3
+ import { t as getUserId } from "./utils-_h9B3c57.mjs";
4
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-DX_T-bDB.mjs";
5
+ import { C as allowPublic, D as requireAuth, O as requireOwnership, S as allOf, T as denyAll, _ as requireOrgMembership, a as presets_exports, b as requireServiceScope, c as readOnly, d as applyFieldWritePermissions, f as fields, g as requireOrgInScope, h as createOrgPermissions, i as ownerWithAdminBypass, j as when, k as requireRoles, m as createDynamicPermissionMatrix, n as authenticated, o as publicRead, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as applyFieldReadPermissions, v as requireOrgRole, w as anyOf, x as requireTeamMembership, y as requireScopeContext } from "./permissions-ohQyv50e.mjs";
6
+ import { v as getControllerScope } from "./routerShared-D6_fEGHh.mjs";
7
+ import { n as defineResource, o as defineAggregation, r as ResourceDefinition, t as defineResourceVariants } from "./core-D72ia0EH.mjs";
9
8
  //#region src/index.ts
10
- const version = "2.11.4";
9
+ const version = "2.13.1";
11
10
  //#endregion
12
- 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, MongooseAdapter, NotFoundError, PrismaAdapter, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, defineResourceVariants, denyAll, envelope, fields, fullPublic, getControllerScope, getUserId, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
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, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, getUserId, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -1,4 +1,4 @@
1
- import { n as DomainEvent } from "../EventTransport-CYNUXdCJ.mjs";
1
+ import { n as DomainEvent } from "../EventTransport-CT_52aWU.mjs";
2
2
  import { a as WebSocketMessage, i as WebSocketClient } from "../websocket-ChC2rqe1.mjs";
3
3
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
4
4
 
@@ -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-V7aXc3bW.mjs").then((n) => n.r);
7
+ const { default: ssePlugin } = await import("../sse-Bz-5ZeTt.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
1
  import { a as WebSocketMessage, i as WebSocketClient, o as WebSocketPluginOptions } from "../websocket-ChC2rqe1.mjs";
2
2
  import { EventGatewayOptions } from "./event-gateway.mjs";
3
3
  import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
4
- import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-BQ9TJQNy.mjs";
4
+ import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-DQHFc8PM.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, type CallToolResult, type CreateMcpServerConfig, type CrudOperation, type EventGatewayOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobsPluginOptions, type McpAuthResult, type McpPluginOptions, type McpResourceConfig, type PromptDefinition, type QueueStats, type StreamlinePluginOptions, type ToolAnnotations, type ToolContext, type ToolDefinition, type WebSocketClient, type WebSocketMessage, type WebSocketPluginOptions, type WebhookDeliveryRecord, type WebhookManager, type WebhookPluginOptions, type WebhookStore, type WebhookSubscription, type WorkflowLike, type WorkflowRunLike };
@@ -1,5 +1,5 @@
1
- import { B as ResourceDefinition } from "../../index-CXXRbnf8.mjs";
2
- import { a as McpAuthResolver, c as McpResourceConfig, d as SessionEntry, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler, u as PromptResult } from "../../types-BQ9TJQNy.mjs";
1
+ import { V as ResourceDefinition } from "../../index-BtW7qYwa.mjs";
2
+ import { a as McpAuthResolver, c as McpResourceConfig, d as SessionEntry, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler, u as PromptResult } from "../../types-DQHFc8PM.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
  import { z } from "zod";
5
5
 
@@ -1,4 +1,4 @@
1
- import { n as fieldRulesToZod, r as createMcpServer, t as resourceToTools } from "../../resourceToTools-CxNmI6xF.mjs";
1
+ import { n as fieldRulesToZod, r as createMcpServer, t as resourceToTools } from "../../resourceToTools-C5coh64w.mjs";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/integrations/mcp/defineTool.ts
@@ -1,4 +1,4 @@
1
- import { o as McpAuthResult, s as McpPluginOptions } from "../../types-BQ9TJQNy.mjs";
1
+ import { o as McpAuthResult, s as McpPluginOptions } from "../../types-DQHFc8PM.mjs";
2
2
 
3
3
  //#region src/integrations/mcp/testing.d.ts
4
4
  interface TestMcpClientOptions {
@@ -1,4 +1,4 @@
1
- import { r as createMcpServer, t as resourceToTools } from "../../resourceToTools-CxNmI6xF.mjs";
1
+ import { r as createMcpServer, t as resourceToTools } from "../../resourceToTools-C5coh64w.mjs";
2
2
  //#region src/integrations/mcp/testing.ts
3
3
  /**
4
4
  * @classytic/arc/mcp/testing — MCP Test Utilities
@@ -1,11 +1,21 @@
1
- import { FastifyPluginAsync } from "fastify";
1
+ import { FastifyPluginAsync, FastifyRequest } from "fastify";
2
2
 
3
3
  //#region src/integrations/streamline.d.ts
4
- /** Start options — matches @classytic/streamline v2.1+ StartOptions */
4
+ /**
5
+ * Start options — matches @classytic/streamline v2.3+ `StartOptions`.
6
+ *
7
+ * v2.3 additions:
8
+ * - `tenantId` — required when streamline's `multiTenant.strict: true`.
9
+ * Hosts should NOT accept this from the request body in untrusted
10
+ * contexts; use `tenantResolver` to extract from auth context instead.
11
+ * - `bypassTenant` — admin/cross-tenant operations. Same caveat.
12
+ */
5
13
  interface WorkflowStartOptions {
6
14
  meta?: Record<string, unknown>;
7
15
  idempotencyKey?: string;
8
16
  priority?: number;
17
+ tenantId?: string;
18
+ bypassTenant?: boolean;
9
19
  }
10
20
  /** Minimal workflow interface — matches @classytic/streamline's createWorkflow() return */
11
21
  interface WorkflowLike {
@@ -32,11 +42,14 @@ interface WorkflowLike {
32
42
  cancel(runId: string): Promise<WorkflowRunLike>;
33
43
  get(runId: string): Promise<WorkflowRunLike | null>;
34
44
  shutdown?(): void;
35
- /** Streamline container for event bridging (streamline >=2.1) */
45
+ /** Streamline container for event bridging + repository access (streamline >=2.1) */
36
46
  container?: {
37
47
  eventBus: {
38
48
  on(event: string, listener: (...args: unknown[]) => void): void;
39
49
  off(event: string, listener: (...args: unknown[]) => void): void;
50
+ }; /** Repository — used by the list-runs endpoint to query workflow_runs. */
51
+ repository?: {
52
+ getAll(params: Record<string, unknown>, options?: Record<string, unknown>): Promise<unknown>;
40
53
  };
41
54
  };
42
55
  }
@@ -69,7 +82,7 @@ interface StreamlinePluginOptions {
69
82
  * engine telemetry) to Arc's event bus, topic-scoped as
70
83
  * `workflow.${workflowId}.${eventName}`.
71
84
  *
72
- * Covers the full streamline 2.2 event surface:
85
+ * Covers the full streamline 2.3 event surface:
73
86
  * - Step events: started, completed, failed, waiting, skipped,
74
87
  * retry-scheduled, compensated
75
88
  * - Workflow lifecycle: started, completed, failed, waiting, resumed,
@@ -86,12 +99,6 @@ interface StreamlinePluginOptions {
86
99
  * @default false
87
100
  */
88
101
  bridgeBusEvents?: boolean;
89
- /**
90
- * @deprecated v2.11.0 — renamed to `bridgeBusEvents` which now covers
91
- * step + workflow + engine events (not just step-level). Still accepted
92
- * as an alias; will be removed in v3. Prefer `bridgeBusEvents`.
93
- */
94
- bridgeStepEvents?: boolean;
95
102
  /**
96
103
  * Enable SSE streaming endpoint: GET /:workflowId/runs/:runId/stream
97
104
  * Streams step-level + lifecycle events as Server-Sent Events for live
@@ -100,6 +107,48 @@ interface StreamlinePluginOptions {
100
107
  * @default false
101
108
  */
102
109
  enableStreaming?: boolean;
110
+ /**
111
+ * Enable webhook resume endpoint: POST /hooks/:token
112
+ *
113
+ * Routes incoming webhook calls through streamline's `resumeHook(token,
114
+ * body)` — which validates the token against the stored `hookToken` on
115
+ * the waiting step (fail-closed since streamline 2.3). Hosts use this
116
+ * for "wait for external approval / SaaS callback" patterns.
117
+ *
118
+ * Workflows MUST pass `{ hookToken: hook.token }` to `ctx.wait(...)` —
119
+ * streamline 2.3 rejects resume otherwise (security). The endpoint is
120
+ * registered at the plugin's `prefix` root, NOT scoped per workflow,
121
+ * because the token encodes the runId.
122
+ *
123
+ * Auth is OPTIONAL on this route by design — the token IS the
124
+ * authentication. If you also want to gate by user (e.g. only the
125
+ * inviting user can approve), set `auth: true` and a permission check.
126
+ *
127
+ * @default false
128
+ */
129
+ enableHookEndpoint?: boolean;
130
+ /**
131
+ * Resolve the tenant id for a request — extract from auth context
132
+ * (JWT claim, session, header), NOT from the request body. Returning
133
+ * `undefined` skips tenant injection (use for non-multi-tenant routes
134
+ * or admin paths that pass `bypassTenant` explicitly).
135
+ *
136
+ * When set, the resolved tenantId is forwarded to every streamline
137
+ * call (`start`, `resume`, `cancel`, `get`, `list`, etc.) so
138
+ * streamline's `multiTenant.strict` mode never throws "missing
139
+ * tenantId" inside arc's request lifecycle.
140
+ *
141
+ * @example
142
+ * tenantResolver: (req) => req.user?.organizationId
143
+ */
144
+ tenantResolver?: (request: FastifyRequest) => string | undefined;
145
+ /**
146
+ * Per-call bypass-tenant resolver. Returns `true` for requests that
147
+ * should skip tenant scoping entirely (cross-tenant admin operations).
148
+ * Honored only when streamline's tenant-filter plugin allows bypass
149
+ * (`allowBypass: true`, the default).
150
+ */
151
+ bypassTenantResolver?: (request: FastifyRequest) => boolean;
103
152
  /** Custom permission check for workflow operations */
104
153
  permissions?: {
105
154
  start?: (request: unknown) => boolean | Promise<boolean>;
@@ -111,7 +160,7 @@ interface StreamlinePluginOptions {
111
160
  }
112
161
  /**
113
162
  * Full event list published on a streamline workflow's internal `eventBus`
114
- * (tracks streamline 2.2's `EventPayloadMap` in
163
+ * (tracks streamline 2.3's `EventPayloadMap` in
115
164
  * `@classytic/streamline/src/core/events.ts`).
116
165
  *
117
166
  * Hardcoded here by design — arc subscribes via structural
@@ -1,7 +1,8 @@
1
+ import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-j4aJm1Wg.mjs";
1
2
  //#region src/integrations/streamline.ts
2
3
  /**
3
4
  * Full event list published on a streamline workflow's internal `eventBus`
4
- * (tracks streamline 2.2's `EventPayloadMap` in
5
+ * (tracks streamline 2.3's `EventPayloadMap` in
5
6
  * `@classytic/streamline/src/core/events.ts`).
6
7
  *
7
8
  * Hardcoded here by design — arc subscribes via structural
@@ -42,8 +43,8 @@ const STREAMLINE_TERMINAL_EVENTS = [
42
43
  "workflow:cancelled"
43
44
  ];
44
45
  const streamlinePluginImpl = async (fastify, options) => {
45
- const { workflows, prefix = "/workflows", auth = true, bridgeEvents = true, enableStreaming = false, permissions: perms } = options;
46
- const bridgeBus = options.bridgeBusEvents ?? options.bridgeStepEvents ?? false;
46
+ const { workflows, prefix = "/workflows", auth = true, bridgeEvents = true, enableStreaming = false, enableHookEndpoint = false, tenantResolver, bypassTenantResolver, permissions: perms } = options;
47
+ const bridgeBus = options.bridgeBusEvents ?? false;
47
48
  const registry = /* @__PURE__ */ new Map();
48
49
  for (const wf of workflows) {
49
50
  const id = wf.definition.id;
@@ -53,6 +54,16 @@ const streamlinePluginImpl = async (fastify, options) => {
53
54
  if (!fastify.hasDecorator("workflows")) fastify.decorate("workflows", registry);
54
55
  if (!fastify.hasDecorator("getWorkflow")) fastify.decorate("getWorkflow", (id) => registry.get(id) ?? null);
55
56
  const authPreHandler = auth && typeof fastify.authenticate === "function" ? [fastify.authenticate] : [];
57
+ const resolveTenantOpts = (request) => {
58
+ const opts = {};
59
+ if (bypassTenantResolver?.(request)) {
60
+ opts.bypassTenant = true;
61
+ return opts;
62
+ }
63
+ const tenantId = tenantResolver?.(request);
64
+ if (tenantId !== void 0) opts.tenantId = tenantId;
65
+ return opts;
66
+ };
56
67
  const checkPerm = async (op, request) => {
57
68
  const check = perms?.[op];
58
69
  if (!check) return true;
@@ -61,15 +72,14 @@ const streamlinePluginImpl = async (fastify, options) => {
61
72
  for (const [id, wf] of registry) {
62
73
  const routePrefix = `${prefix}/${id}`;
63
74
  fastify.post(`${routePrefix}/start`, { preHandler: authPreHandler }, async (request, reply) => {
64
- if (!await checkPerm("start", request)) return reply.status(403).send({
65
- success: false,
66
- error: "Forbidden"
67
- });
75
+ if (!await checkPerm("start", request)) throw new ForbiddenError();
68
76
  const { input, meta, idempotencyKey, priority } = request.body ?? {};
77
+ const tenantOpts = resolveTenantOpts(request);
69
78
  const run = await wf.start(input, {
70
79
  meta,
71
80
  idempotencyKey,
72
- priority
81
+ priority,
82
+ ...tenantOpts
73
83
  });
74
84
  if (bridgeEvents && fastify.events?.publish) try {
75
85
  await fastify.events.publish(`workflow.${id}.started`, {
@@ -83,32 +93,36 @@ const streamlinePluginImpl = async (fastify, options) => {
83
93
  workflowId: id
84
94
  }, "Failed to publish workflow.started event");
85
95
  }
86
- return reply.status(201).send({
87
- success: true,
88
- data: run
89
- });
96
+ return reply.status(201).send(run);
90
97
  });
91
- fastify.get(`${routePrefix}/runs/:runId`, { preHandler: authPreHandler }, async (request, reply) => {
92
- if (!await checkPerm("get", request)) return reply.status(403).send({
93
- success: false,
94
- error: "Forbidden"
98
+ const listRepo = wf.container?.repository;
99
+ if (listRepo?.getAll) fastify.get(`${routePrefix}/runs`, { preHandler: authPreHandler }, async (request, _reply) => {
100
+ if (!await checkPerm("list", request)) throw new ForbiddenError();
101
+ const tenantOpts = resolveTenantOpts(request);
102
+ const { page = "1", limit = "20", cursor, status } = request.query ?? {};
103
+ const filters = { workflowId: id };
104
+ if (status) filters.status = status;
105
+ return await listRepo.getAll({
106
+ filters,
107
+ sort: { createdAt: -1 },
108
+ page: Number.parseInt(page, 10) || 1,
109
+ limit: Math.min(Number.parseInt(limit, 10) || 20, 100),
110
+ ...cursor ? { cursor } : {},
111
+ ...tenantOpts.tenantId !== void 0 ? { tenantId: tenantOpts.tenantId } : {}
112
+ }, {
113
+ lean: true,
114
+ ...tenantOpts.bypassTenant ? { bypassTenant: true } : {}
95
115
  });
116
+ });
117
+ fastify.get(`${routePrefix}/runs/:runId`, { preHandler: authPreHandler }, async (request, _reply) => {
118
+ if (!await checkPerm("get", request)) throw new ForbiddenError();
96
119
  const { runId } = request.params;
97
120
  const run = await wf.get(runId);
98
- if (!run) return reply.status(404).send({
99
- success: false,
100
- error: "Workflow run not found"
101
- });
102
- return {
103
- success: true,
104
- data: run
105
- };
121
+ if (!run) throw new NotFoundError("Workflow run", runId);
122
+ return run;
106
123
  });
107
- fastify.post(`${routePrefix}/runs/:runId/resume`, { preHandler: authPreHandler }, async (request, reply) => {
108
- if (!await checkPerm("resume", request)) return reply.status(403).send({
109
- success: false,
110
- error: "Forbidden"
111
- });
124
+ fastify.post(`${routePrefix}/runs/:runId/resume`, { preHandler: authPreHandler }, async (request, _reply) => {
125
+ if (!await checkPerm("resume", request)) throw new ForbiddenError();
112
126
  const { runId } = request.params;
113
127
  const { payload } = request.body ?? {};
114
128
  const run = await wf.resume(runId, payload);
@@ -124,16 +138,10 @@ const streamlinePluginImpl = async (fastify, options) => {
124
138
  workflowId: id
125
139
  }, "Failed to publish workflow.resumed event");
126
140
  }
127
- return {
128
- success: true,
129
- data: run
130
- };
141
+ return run;
131
142
  });
132
- fastify.post(`${routePrefix}/runs/:runId/cancel`, { preHandler: authPreHandler }, async (request, reply) => {
133
- if (!await checkPerm("cancel", request)) return reply.status(403).send({
134
- success: false,
135
- error: "Forbidden"
136
- });
143
+ fastify.post(`${routePrefix}/runs/:runId/cancel`, { preHandler: authPreHandler }, async (request, _reply) => {
144
+ if (!await checkPerm("cancel", request)) throw new ForbiddenError();
137
145
  const { runId } = request.params;
138
146
  const run = await wf.cancel(runId);
139
147
  if (bridgeEvents && fastify.events?.publish) try {
@@ -147,49 +155,28 @@ const streamlinePluginImpl = async (fastify, options) => {
147
155
  workflowId: id
148
156
  }, "Failed to publish workflow.cancelled event");
149
157
  }
150
- return {
151
- success: true,
152
- data: run
153
- };
158
+ return run;
154
159
  });
155
160
  fastify.post(`${routePrefix}/runs/:runId/execute`, { preHandler: authPreHandler }, async (request, _reply) => {
156
161
  const { runId } = request.params;
157
- return {
158
- success: true,
159
- data: await wf.engine.execute(runId)
160
- };
162
+ return await wf.engine.execute(runId);
161
163
  });
162
- if (wf.engine.waitFor) fastify.get(`${routePrefix}/runs/:runId/wait`, { preHandler: authPreHandler }, async (request, reply) => {
163
- if (!await checkPerm("get", request)) return reply.status(403).send({
164
- success: false,
165
- error: "Forbidden"
166
- });
164
+ if (wf.engine.waitFor) fastify.get(`${routePrefix}/runs/:runId/wait`, { preHandler: authPreHandler }, async (request, _reply) => {
165
+ if (!await checkPerm("get", request)) throw new ForbiddenError();
167
166
  const { runId } = request.params;
168
167
  const { timeout } = request.query ?? {};
169
168
  const timeoutMs = timeout ? Number.parseInt(timeout, 10) : 3e4;
170
- return {
171
- success: true,
172
- data: await wf.engine.waitFor(runId, { timeout: Math.min(timeoutMs, 12e4) })
173
- };
169
+ return await wf.engine.waitFor?.(runId, { timeout: Math.min(timeoutMs, 12e4) });
174
170
  });
175
171
  if (wf.engine.pause) fastify.post(`${routePrefix}/runs/:runId/pause`, { preHandler: authPreHandler }, async (request, _reply) => {
176
172
  const { runId } = request.params;
177
- return {
178
- success: true,
179
- data: await wf.engine.pause?.(runId)
180
- };
173
+ return await wf.engine.pause?.(runId);
181
174
  });
182
- if (wf.engine.rewindTo) fastify.post(`${routePrefix}/runs/:runId/rewind`, { preHandler: authPreHandler }, async (request, reply) => {
175
+ if (wf.engine.rewindTo) fastify.post(`${routePrefix}/runs/:runId/rewind`, { preHandler: authPreHandler }, async (request, _reply) => {
183
176
  const { runId } = request.params;
184
177
  const { stepId } = request.body ?? {};
185
- if (!stepId) return reply.status(400).send({
186
- success: false,
187
- error: "stepId is required"
188
- });
189
- return {
190
- success: true,
191
- data: await wf.engine.rewindTo?.(runId, stepId)
192
- };
178
+ if (!stepId) throw createError(400, "stepId is required");
179
+ return await wf.engine.rewindTo?.(runId, stepId);
193
180
  });
194
181
  if (bridgeBus && wf.container?.eventBus && fastify.events?.publish) for (const eventName of STREAMLINE_BUS_EVENTS) wf.container.eventBus.on(eventName, (payload) => {
195
182
  const p = payload;
@@ -206,15 +193,9 @@ const streamlinePluginImpl = async (fastify, options) => {
206
193
  });
207
194
  });
208
195
  if (enableStreaming && wf.container?.eventBus) fastify.get(`${routePrefix}/runs/:runId/stream`, { preHandler: authPreHandler }, async (request, reply) => {
209
- if (!await checkPerm("get", request)) return reply.status(403).send({
210
- success: false,
211
- error: "Forbidden"
212
- });
196
+ if (!await checkPerm("get", request)) throw new ForbiddenError();
213
197
  const { runId } = request.params;
214
- if (!await wf.get(runId)) return reply.status(404).send({
215
- success: false,
216
- error: "Workflow run not found"
217
- });
198
+ if (!await wf.get(runId)) throw new NotFoundError("Workflow run", runId);
218
199
  reply.raw.writeHead(200, {
219
200
  "Content-Type": "text/event-stream",
220
201
  "Cache-Control": "no-cache",
@@ -247,7 +228,7 @@ const streamlinePluginImpl = async (fastify, options) => {
247
228
  send(eventName, p);
248
229
  if (terminalEvents.has(eventName) && p?.runId === runId) cleanup();
249
230
  };
250
- wf.container.eventBus.on(eventName, fn);
231
+ wf.container?.eventBus.on(eventName, fn);
251
232
  listeners.push({
252
233
  event: eventName,
253
234
  fn
@@ -256,15 +237,24 @@ const streamlinePluginImpl = async (fastify, options) => {
256
237
  request.raw.on("close", cleanup);
257
238
  });
258
239
  }
240
+ if (enableHookEndpoint) {
241
+ let resumeHookFn;
242
+ fastify.post(`${prefix}/hooks/:token`, { preHandler: authPreHandler }, async (request, _reply) => {
243
+ if (!resumeHookFn) resumeHookFn = (await import("@classytic/streamline")).resumeHook;
244
+ const { token } = request.params;
245
+ const result = await resumeHookFn(token, request.body);
246
+ return {
247
+ runId: result.runId,
248
+ run: result.run
249
+ };
250
+ });
251
+ }
259
252
  fastify.get(prefix, { preHandler: authPreHandler }, async () => {
260
- return {
261
- success: true,
262
- data: Array.from(registry.entries()).map(([id, wf]) => ({
263
- id,
264
- name: wf.definition.name ?? id,
265
- steps: Array.isArray(wf.definition.steps) ? wf.definition.steps.map((s) => s.id ?? String(s)) : Object.keys(wf.definition.steps)
266
- }))
267
- };
253
+ return Array.from(registry.entries()).map(([id, wf]) => ({
254
+ id,
255
+ name: wf.definition.name ?? id,
256
+ steps: Array.isArray(wf.definition.steps) ? wf.definition.steps.map((s) => s.id ?? String(s)) : Object.keys(wf.definition.steps)
257
+ }));
268
258
  });
269
259
  fastify.addHook("onClose", async () => {
270
260
  for (const wf of registry.values()) wf.shutdown?.();
@@ -259,18 +259,12 @@ async function wireResourceEvents(fastify, rooms, resources) {
259
259
  */
260
260
  function registerStatsRoute(fastify, rooms, path, expose) {
261
261
  if (expose === true) {
262
- fastify.get(`${path}/stats`, async () => ({
263
- success: true,
264
- data: rooms.getStats()
265
- }));
262
+ fastify.get(`${path}/stats`, async () => rooms.getStats());
266
263
  return;
267
264
  }
268
265
  if (expose === "authenticated") if (fastify.hasDecorator("authenticate")) {
269
266
  const authenticate = fastify.authenticate;
270
- fastify.get(`${path}/stats`, { preHandler: authenticate }, async () => ({
271
- success: true,
272
- data: rooms.getStats()
273
- }));
267
+ fastify.get(`${path}/stats`, { preHandler: authenticate }, async () => rooms.getStats());
274
268
  } else fastify.log.warn("arc-websocket: exposeStats is \"authenticated\" but fastify.authenticate is not registered — stats endpoint skipped");
275
269
  }
276
270
  //#endregion
@@ -1,4 +1,4 @@
1
- import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-CXXRbnf8.mjs";
1
+ import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-BtW7qYwa.mjs";
2
2
  import { RouteHandlerMethod } from "fastify";
3
3
 
4
4
  //#region src/middleware/middleware.d.ts
@@ -1,5 +1,5 @@
1
- import { t as CRUD_OPERATIONS } from "../constants-BhY1OHoH.mjs";
2
- import { t as multipartBody } from "../multipartBody-CvTR1Un6.mjs";
1
+ import { t as CRUD_OPERATIONS } from "../constants-Cxde4rpC.mjs";
2
+ import { t as multipartBody } from "../multipartBody-BOvVSVCD.mjs";
3
3
  //#region src/middleware/middleware.ts
4
4
  /**
5
5
  * Named Middleware — Priority-based, conditional middleware execution.
@@ -94,12 +94,32 @@ interface MigrationLogger {
94
94
  * The `db` parameter accepts any object with a `.collection()` method
95
95
  * (Mongoose db, native MongoDB Db, etc.)
96
96
  */
97
+ /**
98
+ * Structural subset of a Mongo collection arc consumes. Held as a
99
+ * driver-free interface so this file never imports `mongodb` /
100
+ * `mongoose` — both Mongoose's `Connection.db.collection(...)` and the
101
+ * native `MongoClient.db().collection(...)` satisfy this shape.
102
+ *
103
+ * The fluent `find().sort().toArray()` chain is typed loosely with
104
+ * `unknown[]`; we cast to `MigrationRecord[]` once at the boundary
105
+ * inside `getApplied()`.
106
+ */
107
+ interface MongoCollectionLike {
108
+ find(query: Record<string, unknown>): {
109
+ sort(spec: Record<string, 1 | -1>): {
110
+ toArray(): Promise<unknown[]>;
111
+ };
112
+ };
113
+ insertOne(doc: Record<string, unknown>): Promise<unknown>;
114
+ deleteOne(filter: Record<string, unknown>): Promise<unknown>;
115
+ }
116
+ interface MongoDbLike {
117
+ collection(name: string): MongoCollectionLike;
118
+ }
97
119
  declare class MongoMigrationStore implements MigrationStore {
98
120
  private readonly collectionName;
99
121
  private readonly db;
100
- constructor(db: {
101
- collection(name: string): any;
102
- }, opts?: {
122
+ constructor(db: MongoDbLike, opts?: {
103
123
  collectionName?: string;
104
124
  });
105
125
  getApplied(): Promise<MigrationRecord[]>;
@@ -4,13 +4,6 @@ const defaultLogger = {
4
4
  info: (msg) => process.stdout.write(`${msg}\n`),
5
5
  error: (msg) => process.stderr.write(`${msg}\n`)
6
6
  };
7
- /**
8
- * MongoDB-backed migration store.
9
- *
10
- * Uses a `_migrations` collection in the same database.
11
- * The `db` parameter accepts any object with a `.collection()` method
12
- * (Mongoose db, native MongoDB Db, etc.)
13
- */
14
7
  var MongoMigrationStore = class {
15
8
  collectionName;
16
9
  db;