@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
@@ -1,8 +1,168 @@
1
1
  import { r as CacheStore, t as CacheLogger } from "./interface-beEtJyWM.mjs";
2
- import { r as RequestScope } from "./types-DDyTPc6y.mjs";
3
- import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-BRjxOAFp.mjs";
2
+ import { i as RequestScope, n as Mandate } from "./types-CTYvcwHe.mjs";
3
+ import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-COhcH3fk.mjs";
4
4
  import { FastifyReply, FastifyRequest } from "fastify";
5
5
 
6
+ //#region src/permissions/agent.d.ts
7
+ /**
8
+ * Require a sender-constrained credential — the inbound token MUST carry a
9
+ * DPoP proof (RFC 9449) bound to a known key. Arc reads `scope.dpopJkt` (the
10
+ * JWK SHA-256 thumbprint per RFC 7638); your `authenticate` function performs
11
+ * the cryptographic `jose.dpop.verify(...)` and sets the field on success.
12
+ *
13
+ * **Pass behavior:**
14
+ * - `service` scope where `dpopJkt` is set → grant
15
+ * - `elevated` scope → grant (platform admin bypass)
16
+ * - Anything else → deny with a clear reason
17
+ *
18
+ * Use for high-value endpoints where bearer-token replay must be impossible:
19
+ * payment charges, data exports, account-takeover-class admin actions.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * permissions: { charge: allOf(requireServiceScope('payment.write'), requireDPoP()) }
24
+ * ```
25
+ */
26
+ declare function requireDPoP<TDoc = Record<string, unknown>>(): PermissionCheck<TDoc>;
27
+ /**
28
+ * Options for `requireMandate(capability, opts)`.
29
+ */
30
+ interface RequireMandateOptions<TDoc = Record<string, unknown>> {
31
+ /**
32
+ * Custom validator for the mandate's numeric ceiling against the inbound
33
+ * request. Arc passes the request body / params; you decide whether the
34
+ * action stays within the mandate's `cap`.
35
+ *
36
+ * Return `true` to accept, `false` (or a string reason) to deny. When
37
+ * omitted, arc skips amount validation — useful for boolean-capability
38
+ * mandates where presence of the mandate IS the authorization (no cap).
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * validateAmount: (ctx, mandate) => {
43
+ * const amount = (ctx.data as { amount?: number })?.amount ?? 0;
44
+ * if (amount <= (mandate.cap ?? 0)) return true;
45
+ * return `Amount ${amount} exceeds mandate cap ${mandate.cap}`;
46
+ * }
47
+ * ```
48
+ */
49
+ validateAmount?: (ctx: PermissionContext<TDoc>, mandate: Readonly<Mandate>) => boolean | string;
50
+ /**
51
+ * Resource the mandate must be bound to (`Mandate.audience`). Pass a
52
+ * static value or a function that derives it from the request (typically
53
+ * `ctx.params.id`). When set and the mandate's `audience` doesn't match,
54
+ * the request is denied — prevents a payment-mandate for invoice A being
55
+ * replayed against invoice B.
56
+ */
57
+ audience?: string | ((ctx: PermissionContext<TDoc>) => string | undefined);
58
+ /**
59
+ * Clock-skew tolerance for `Mandate.expiresAt`, in milliseconds.
60
+ * Default `30_000` (30s).
61
+ */
62
+ ttlGraceMs?: number;
63
+ /**
64
+ * When `true`, `elevated` scope is NOT allowed to bypass the mandate check.
65
+ * Defaults to `false` — platform admins normally bypass everything.
66
+ * Set when you genuinely want "even an admin needs a mandate" semantics
67
+ * (audited break-glass actions, regulated payment flows).
68
+ */
69
+ noElevatedBypass?: boolean;
70
+ }
71
+ /**
72
+ * Require a capability mandate (AP2 / x402 / MCP authorization) that
73
+ * authorizes the action being attempted.
74
+ *
75
+ * The mandate is set on `request.scope.mandate` by your authenticate function
76
+ * after verifying the inbound mandate JWT/VC. This check validates that the
77
+ * presented mandate covers the requested capability, hasn't expired, is bound
78
+ * to the right resource (when `audience` opt is set), and respects the
79
+ * mandate's numeric ceiling (when `validateAmount` opt is set).
80
+ *
81
+ * **Pass behavior:**
82
+ * - `elevated` scope → grant unless `noElevatedBypass: true`
83
+ * - `service` scope with mandate matching `capability`, not expired, and
84
+ * passing `validateAmount` + `audience` checks → grant
85
+ * - Anything else → deny with a precise reason
86
+ *
87
+ * Pair with `requireDPoP()` for replay-resistance, or use the bundled
88
+ * `requireAgentScope(...)` to declare both at once.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * // Single payment charge — amount must fit the mandate's cap
93
+ * permissions: {
94
+ * pay: requireMandate('payment.charge', {
95
+ * validateAmount: (ctx, m) => (ctx.data as { amount: number }).amount <= (m.cap ?? 0),
96
+ * audience: (ctx) => `invoice:${ctx.params?.id}`,
97
+ * }),
98
+ * }
99
+ *
100
+ * // Boolean capability — presence of mandate is the gate
101
+ * permissions: {
102
+ * exportData: requireMandate('data.export'),
103
+ * }
104
+ * ```
105
+ */
106
+ declare function requireMandate<TDoc = Record<string, unknown>>(capability: string, opts?: RequireMandateOptions<TDoc>): PermissionCheck<TDoc>;
107
+ /**
108
+ * Options for `requireAgentScope(opts)`.
109
+ */
110
+ interface RequireAgentScopeOptions<TDoc = Record<string, unknown>> extends RequireMandateOptions<TDoc> {
111
+ /**
112
+ * Capability the mandate must authorize (e.g., `payment.charge`,
113
+ * `inbox.send`). Required.
114
+ */
115
+ capability: string;
116
+ /**
117
+ * When `true`, the inbound credential must also be DPoP-bound (RFC 9449).
118
+ * Defaults to `true` — sender-constrained credentials are the standard
119
+ * for high-value agent flows. Set `false` only when you intentionally
120
+ * accept bearer tokens (rare; usually a regression).
121
+ */
122
+ requireDPoP?: boolean;
123
+ /**
124
+ * Optional OAuth-style scope strings the service identity must hold in
125
+ * addition to the mandate (e.g., `['payment.write']`). Pairs with the
126
+ * mandate's narrower per-request authorization — scopes answer "ever
127
+ * allowed?", mandate answers "right now?".
128
+ */
129
+ scopes?: readonly string[];
130
+ }
131
+ /**
132
+ * Composite gate for AI-agent / M2M flows on protected resources.
133
+ *
134
+ * Bundles the three things every high-value agent endpoint needs:
135
+ * 1. **Service identity** — `scope.kind === 'service'` with `clientId`
136
+ * 2. **Capability mandate** — narrows what *this request* may do
137
+ * 3. **DPoP binding** — credential cannot be replayed from a different key
138
+ *
139
+ * Use this instead of hand-composing `allOf(requireServiceScope(...),
140
+ * requireMandate(...), requireDPoP())` — fewer ways to misconfigure, one
141
+ * meta-tag downstream tools (audit, MCP, OpenAPI) can read.
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * import { requireAgentScope } from '@classytic/arc/permissions';
146
+ *
147
+ * defineResource({
148
+ * name: 'invoice',
149
+ * actions: {
150
+ * pay: {
151
+ * handler: payInvoice,
152
+ * permissions: requireAgentScope({
153
+ * capability: 'payment.charge',
154
+ * scopes: ['payment.write'],
155
+ * requireDPoP: true,
156
+ * audience: (ctx) => `invoice:${ctx.params?.id}`,
157
+ * validateAmount: (ctx, m) => (ctx.data as { amount: number }).amount <= (m.cap ?? 0),
158
+ * }),
159
+ * },
160
+ * },
161
+ * });
162
+ * ```
163
+ */
164
+ declare function requireAgentScope<TDoc = Record<string, unknown>>(opts: RequireAgentScopeOptions<TDoc>): PermissionCheck<TDoc>;
165
+ //#endregion
6
166
  //#region src/permissions/applyPermissionResult.d.ts
7
167
  /**
8
168
  * Normalize a permission check return value (`boolean | PermissionResult`)
@@ -512,4 +672,4 @@ declare function fullPublic<TDoc = any>(overrides?: PermissionOverrides<TDoc>):
512
672
  */
513
673
  declare function readOnly<TDoc = any>(overrides?: PermissionOverrides<TDoc>): ResourcePermissions<TDoc>;
514
674
  //#endregion
515
- export { requireRoles as A, allOf as C, not as D, denyAll as E, when as M, applyPermissionResult as N, requireAuth as O, normalizePermissionResult as P, createOrgPermissions as S, anyOf as T, ConnectEventsOptions as _, presets_d_exports as a, PermissionEventBus as b, readOnly as c, requireOrgRole as d, requireScopeContext as f, createRoleHierarchy as g, RoleHierarchy as h, ownerWithAdminBypass as i, roles as j, requireOwnership as k, requireOrgInScope as l, requireTeamMembership as m, authenticated as n, publicRead as o, requireServiceScope as p, fullPublic as r, publicReadAdminWrite as s, adminOnly as t, requireOrgMembership as u, DynamicPermissionMatrix as v, allowPublic as w, createDynamicPermissionMatrix as x, DynamicPermissionMatrixConfig as y };
675
+ export { requireRoles as A, allOf as C, not as D, denyAll as E, RequireAgentScopeOptions as F, RequireMandateOptions as I, requireAgentScope as L, when as M, applyPermissionResult as N, requireAuth as O, normalizePermissionResult as P, requireDPoP as R, createOrgPermissions as S, anyOf as T, ConnectEventsOptions as _, presets_d_exports as a, PermissionEventBus as b, readOnly as c, requireOrgRole as d, requireScopeContext as f, createRoleHierarchy as g, RoleHierarchy as h, ownerWithAdminBypass as i, roles as j, requireOwnership as k, requireOrgInScope as l, requireTeamMembership as m, authenticated as n, publicRead as o, requireServiceScope as p, fullPublic as r, publicReadAdminWrite as s, adminOnly as t, requireOrgMembership as u, DynamicPermissionMatrix as v, allowPublic as w, createDynamicPermissionMatrix as x, DynamicPermissionMatrixConfig as y, requireMandate as z };