@classytic/arc 2.31.0 → 2.32.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 (151) hide show
  1. package/dist/{BaseController-De7GqHck.mjs → BaseController-Dk34dxhI.mjs} +16 -13
  2. package/dist/{EventTransport-9mlTgqzE.mjs → EventTransport-BV10D0oG.mjs} +1 -1
  3. package/dist/{HookSystem-BcmPyq5I.mjs → HookSystem-vimw5D7Z.mjs} +2 -2
  4. package/dist/{ResourceRegistry-qq0mn2s9.mjs → ResourceRegistry-BVr7PgA0.mjs} +17 -15
  5. package/dist/{actionPermissions-BE5NwaQk.mjs → actionPermissions-Dti7ebyv.mjs} +1 -1
  6. package/dist/audit/index.mjs +2 -2
  7. package/dist/auth/audit.mjs +1 -1
  8. package/dist/auth/index.mjs +11 -10
  9. package/dist/auth/redis-session.mjs +1 -1
  10. package/dist/{authorizationDecision-ChvUQGG1.mjs → authorizationDecision-__T3EJDA.mjs} +2 -2
  11. package/dist/{buildHandler-CDrCJzmB.mjs → buildHandler-Dn7rzUJo.mjs} +6 -5
  12. package/dist/cache/index.mjs +4 -4
  13. package/dist/{caching-BFHA6Scf.mjs → caching-DFJqHyFs.mjs} +2 -2
  14. package/dist/cleanup/index.d.mts +36 -14
  15. package/dist/cleanup/index.mjs +45 -29
  16. package/dist/cli/commands/describe.mjs +4 -6
  17. package/dist/cli/commands/docs.mjs +3 -3
  18. package/dist/cli/commands/doctor.mjs +1 -1
  19. package/dist/cli/commands/generate.mjs +2 -2
  20. package/dist/cli/commands/init.mjs +2 -2
  21. package/dist/cli/commands/introspect.mjs +2 -2
  22. package/dist/cli/index.mjs +3 -3
  23. package/dist/{constants-D3Dv4LAV.mjs → constants-J99LGTJI.mjs} +1 -1
  24. package/dist/context/index.mjs +3 -3
  25. package/dist/core/index.d.mts +1 -1
  26. package/dist/core/index.mjs +7 -7
  27. package/dist/{core-BGpIxINN.mjs → core-BwwmNSp7.mjs} +3 -3
  28. package/dist/{createActionRouter-CDXEdasl.mjs → createActionRouter-DkJZWo0m.mjs} +14 -11
  29. package/dist/{createAggregationRouter-KrQDzx-k.mjs → createAggregationRouter-B1exOVD8.mjs} +10 -8
  30. package/dist/{createApp-Df89BEni.mjs → createApp-Bv0m-Q6_.mjs} +182 -61
  31. package/dist/{defineAggregation-DbPPS8RI.mjs → defineAggregation-gX4No1gt.mjs} +1 -1
  32. package/dist/{defineResource-Bv6EtN1x.mjs → defineResource-XFPPUu2c.mjs} +41 -32
  33. package/dist/discovery/index.mjs +1 -1
  34. package/dist/docs/index.mjs +3 -3
  35. package/dist/{elevation-D2l1mh4g.mjs → elevation-DNXXxgjl.mjs} +4 -4
  36. package/dist/encryption/index.mjs +5 -4
  37. package/dist/{errorHandler-C5NeD6bT.mjs → errorHandler-B2AZUJUj.mjs} +3 -3
  38. package/dist/{errors-Cj42AntO.mjs → errors-Bh1KK5ps.mjs} +1 -1
  39. package/dist/{eventPlugin-CkffEihm.mjs → eventPlugin-Dk_TyXeE.mjs} +8 -7
  40. package/dist/events/index.d.mts +108 -41
  41. package/dist/events/index.mjs +166 -142
  42. package/dist/events/transports/redis-stream-entry.mjs +14 -10
  43. package/dist/events/transports/redis.mjs +1 -1
  44. package/dist/factory/index.d.mts +5 -5
  45. package/dist/factory/index.mjs +131 -8
  46. package/dist/fastify-augmentation-BppG5bMT.d.mts +179 -0
  47. package/dist/{fields-CB5Cuzk9.mjs → fields-DEi65pGj.mjs} +6 -11
  48. package/dist/{generate-EcA6ui4i.mjs → generate-CRSG0jTv.mjs} +2 -2
  49. package/dist/{headers-3zvE0rM3.mjs → headers-BXjQYbeC.mjs} +2 -2
  50. package/dist/{health-DjZYjM7H.mjs → health-5XnTa2uo.mjs} +1 -1
  51. package/dist/hooks/index.mjs +2 -2
  52. package/dist/idempotency/index.mjs +8 -6
  53. package/dist/idempotency/redis.mjs +1 -1
  54. package/dist/{index-Bc2ox8_U.d.mts → index-DXlHwvuE.d.mts} +1 -1
  55. package/dist/{index-CFThn1K9.d.mts → index-ZWhLTp_s.d.mts} +70 -4
  56. package/dist/{index-CEJNZFtX.d.mts → index-zq6VrjaB.d.mts} +70 -1
  57. package/dist/index.d.mts +3 -3
  58. package/dist/index.mjs +11 -11
  59. package/dist/{init-BEiNZBsJ.mjs → init-BbfP8aky.mjs} +7 -5
  60. package/dist/integrations/event-gateway.mjs +2 -2
  61. package/dist/integrations/index.mjs +1 -1
  62. package/dist/integrations/jobs/index.mjs +3 -3
  63. package/dist/integrations/mcp/index.mjs +2 -2
  64. package/dist/integrations/mcp/testing.mjs +2 -2
  65. package/dist/integrations/streamline.mjs +3 -3
  66. package/dist/integrations/webhooks.mjs +1 -1
  67. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  68. package/dist/integrations/websocket-redis.mjs +1 -1
  69. package/dist/integrations/websocket.mjs +38 -35
  70. package/dist/{interface-DYzM0q-u.mjs → interface-BP4IJCBO.mjs} +1 -1
  71. package/dist/{jsonBody-BYbLDi5D.mjs → jsonBody-DDSR2HFl.mjs} +2 -2
  72. package/dist/{keys-C0_pa1tY.mjs → keys-B-HBTGXl.mjs} +1 -1
  73. package/dist/{loadResources-yawi9tAE.mjs → loadResources-DisEAmkm.mjs} +4 -3
  74. package/dist/{loadResourcesFromEntry-BAjYZonx.mjs → loadResourcesFromEntry-D1MJp13f.mjs} +2 -2
  75. package/dist/logger/index.mjs +1 -1
  76. package/dist/{mcpPlugin-B_es0hiF.mjs → mcpPlugin-CpfVpKHE.mjs} +32 -31
  77. package/dist/{memory-DR6wpa9F.mjs → memory-DsuWnj4T.mjs} +5 -5
  78. package/dist/{metrics-CUdw_wLB.mjs → metrics-DdQL8syd.mjs} +2 -2
  79. package/dist/middleware/index.mjs +3 -3
  80. package/dist/migrations/index.mjs +3 -3
  81. package/dist/{module-0pFJA6YW.mjs → module-Br81am6m.mjs} +1 -1
  82. package/dist/{multipartBody-wOgj_fnj.mjs → multipartBody-BnkBLN7v.mjs} +3 -3
  83. package/dist/{openapi-B2L4js1v.mjs → openapi-DIRzvxC0.mjs} +6 -6
  84. package/dist/outbox-admin/index.d.mts +85 -0
  85. package/dist/outbox-admin/index.mjs +115 -0
  86. package/dist/permissions/index.d.mts +2 -2
  87. package/dist/permissions/index.mjs +6 -6
  88. package/dist/{permissions-L--QDAir.mjs → permissions-Dl_m0NCe.mjs} +101 -8
  89. package/dist/{pipe-DRDNsI2T.mjs → pipe-ELHCP3zj.mjs} +3 -5
  90. package/dist/pipeline/index.mjs +2 -2
  91. package/dist/{pipeline-UPQFatit.mjs → pipeline-CPA-jx0M.mjs} +17 -15
  92. package/dist/plugins/index.d.mts +2 -2
  93. package/dist/plugins/index.mjs +16 -16
  94. package/dist/plugins/response-cache.mjs +2 -2
  95. package/dist/plugins/tracing-entry.mjs +2 -2
  96. package/dist/{pluralize-O0FZgESl.mjs → pluralize-C2ZkKbsn.mjs} +1 -1
  97. package/dist/{preloadResources-Dz6BjzM6.mjs → preloadResources-CDs87fTw.mjs} +1 -1
  98. package/dist/{preloadResources-CyoJMSiO.d.mts → preloadResources-T1hmlTEZ.d.mts} +2 -2
  99. package/dist/presets/filesUpload.mjs +6 -6
  100. package/dist/presets/index.mjs +2 -2
  101. package/dist/presets/multiTenant.mjs +3 -3
  102. package/dist/presets/search.mjs +2 -2
  103. package/dist/{presets-C4-g4_4P.mjs → presets-Dntd_pUO.mjs} +6 -5
  104. package/dist/{projection-BHw6xlOQ.mjs → projection-CjHhM5W1.mjs} +2 -2
  105. package/dist/{queryCachePlugin-BZr8v46E.mjs → queryCachePlugin-Dhps-Ldt.mjs} +6 -6
  106. package/dist/{rateLimit-CMPY5Qms.mjs → rateLimit-C7mmAGs3.mjs} +2 -2
  107. package/dist/{rateLimitKey-Dn5JNmkj.mjs → rateLimitKey-CccEFBfk.mjs} +1 -1
  108. package/dist/{realtime-C5NoxWFY.mjs → realtime-DVvVZZFz.mjs} +10 -10
  109. package/dist/{registerRoute-CBN84fc7.mjs → registerRoute-B_QrjYZS.mjs} +10 -8
  110. package/dist/registry/index.d.mts +1 -1
  111. package/dist/registry/index.mjs +3 -3
  112. package/dist/{registry-4213U4zb.mjs → registry-DqUmzA9W.mjs} +2 -2
  113. package/dist/{renewingLease-Dll8mGgc.mjs → renewingLease-BpP9wwj7.mjs} +1 -1
  114. package/dist/{replyHelpers-DIiZKGUt.mjs → replyHelpers-DS-P0b32.mjs} +2 -2
  115. package/dist/{repositoryFilter-f9eAfq_l.mjs → repositoryFilter-DotlxG3L.mjs} +1 -1
  116. package/dist/{requestContext-2TxXOJ7T.mjs → requestContext-B6vQF-sy.mjs} +1 -1
  117. package/dist/{rolldown-runtime-CUsjNX9R.mjs → rolldown-runtime-BhflRrBs.mjs} +1 -1
  118. package/dist/{schedules-DdtlICTf.mjs → schedules-C2Q3uv2d.mjs} +3 -3
  119. package/dist/{schemaConverter-D--wdJM-.mjs → schemaConverter-Crjvczi_.mjs} +1 -1
  120. package/dist/{schemaIR-Bm2enbnh.mjs → schemaIR-CnyKK_1j.mjs} +2 -2
  121. package/dist/schemas/index.mjs +1 -1
  122. package/dist/scim/index.mjs +2 -2
  123. package/dist/scope/index.mjs +5 -5
  124. package/dist/{scope-DHx5Fous.mjs → scope-afz_Ieek.mjs} +4 -4
  125. package/dist/{simpleEqualityMatcher-DjQJ7FKA.mjs → simpleEqualityMatcher-C4KiMWUa.mjs} +1 -1
  126. package/dist/{sse-CUTo9y0X.mjs → sse-B9P4Y-UI.mjs} +7 -6
  127. package/dist/{sseStream-B_5XcVVd.mjs → sseStream-B3zb_d1h.mjs} +2 -2
  128. package/dist/{store-helpers-D1MP_gRG.mjs → store-helpers-DmEMHlPQ.mjs} +1 -1
  129. package/dist/{streaming-PSZwi8JV.mjs → streaming-DPZdQmDz.mjs} +1 -1
  130. package/dist/{subscribe-helpers-C0Tb2aUp.mjs → subscribe-helpers-sp5xTDVA.mjs} +2 -2
  131. package/dist/sync/changelog.mjs +1 -1
  132. package/dist/testing/cleanupStoreContract.mjs +10 -6
  133. package/dist/testing/index.d.mts +31 -4
  134. package/dist/testing/index.mjs +97 -39
  135. package/dist/testing/outboxStoreContract.d.mts +11 -2
  136. package/dist/testing/outboxStoreContract.mjs +110 -21
  137. package/dist/testing/storageContract.mjs +11 -6
  138. package/dist/{transactionContext-dAfBVUrk.mjs → transactionContext-BvLKvOIL.mjs} +1 -1
  139. package/dist/{typeGuards-B0ryPo3I.mjs → typeGuards-B_5-hKjJ.mjs} +1 -1
  140. package/dist/types/index.mjs +1 -1
  141. package/dist/types/storage.mjs +1 -1
  142. package/dist/{types-CBgvkp8O.d.mts → types-CT5vu6M0.d.mts} +87 -11
  143. package/dist/{types-Cys0ko9Z.mjs → types-DXYX7dIR.mjs} +4 -4
  144. package/dist/usage/index.mjs +0 -0
  145. package/dist/{userHelpers-ChYJ6CdK.mjs → userHelpers-BNsOXzOd.mjs} +1 -1
  146. package/dist/utils/index.mjs +10 -10
  147. package/dist/{utils-vL8BrDE2.mjs → utils-BtOha_Sp.mjs} +3 -3
  148. package/dist/{validate-_KbifpHF.mjs → validate-PMCPR9El.mjs} +2 -2
  149. package/dist/{versioning-CHDTor3P.mjs → versioning-CKv2jz_U.mjs} +4 -4
  150. package/package.json +23 -13
  151. package/dist/fastify-augmentation-zh0_AYHa.d.mts +0 -85
@@ -0,0 +1,179 @@
1
+
2
+ import { hn as HookSystem, z as ResourceRegistry } from "./index-CpzxqePp.mjs";
3
+ import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
4
+ import { _ as HealthCheck, f as ScheduleDefinition, r as ArcModuleRegistry, t as ArcModule } from "./types-CT5vu6M0.mjs";
5
+ import { s as ModuleState } from "./index-ZWhLTp_s.mjs";
6
+ import { FastifyPluginAsync } from "fastify";
7
+ //#region src/factory/module/descriptor.d.ts
8
+ /**
9
+ * Resolved module introspection — what a module ACTUALLY composed to.
10
+ *
11
+ * `ArcModule` is the authoring shape: `resources` may be an array or a factory,
12
+ * `owns` may be a list or `"provided"`, and neither tells you what the module
13
+ * ended up mounting. Consumers that needed the resolved answer were reduced to
14
+ * inspecting that shape — a downstream conformance suite had to treat every
15
+ * resource FACTORY as a violation, because it could not distinguish "late-bound
16
+ * and legitimate" from "unresolvable", and so rejected valid modules.
17
+ *
18
+ * A descriptor is the resolved, read-only answer, published after arc has done
19
+ * the work exactly once. It lets tooling assert on the real graph without
20
+ * touching arc internals:
21
+ *
22
+ * - conformance suites verify what a module provides and supersedes;
23
+ * - `doctor` surfaces duplicate resources and unmet dependencies;
24
+ * - tests assert the composed graph instead of re-deriving it;
25
+ * - operators inspect a large installation;
26
+ * - documentation generators read one stable contract.
27
+ *
28
+ * Deliberately DATA — no functions, no live handles. It survives
29
+ * `structuredClone`, so it can cross a worker boundary or be written to a file
30
+ * as-is, and holding one cannot keep a closed app alive.
31
+ */
32
+ /** One resource as arc resolved it. */
33
+ interface ResolvedResourceDescriptor {
34
+ /** Resource name; absent for an anonymous resource (participates in no dedup). */
35
+ readonly name?: string;
36
+ /** Route prefix, when the resource declared one. */
37
+ readonly prefix?: string;
38
+ /** Whether the resource opted out of the app-wide `resourcePrefix`. */
39
+ readonly skipGlobalPrefix: boolean;
40
+ }
41
+ /** Lifecycle surface a module ended up with — counts, not handles. */
42
+ interface ResolvedModuleLifecycle {
43
+ /** Does the module tear anything down? */
44
+ readonly hasClose: boolean;
45
+ /** Event-handler subscriptions arc owns for this module. */
46
+ readonly subscriptions: number;
47
+ /** Recurring schedules contributed. */
48
+ readonly scheduledJobs: number;
49
+ /** Readiness checks contributed. */
50
+ readonly healthChecks: number;
51
+ /** Whether the module contributed a public export at `arc.modules[name]`. */
52
+ readonly exports: boolean;
53
+ }
54
+ /** The resolved, read-only description of one composed module. */
55
+ interface ResolvedModuleDescriptor {
56
+ readonly name: string;
57
+ /** Declared composition edges, in the order the module listed them. */
58
+ readonly dependsOn: readonly string[];
59
+ /** Resources this module actually mounted, in registration order. */
60
+ readonly resources: readonly ResolvedResourceDescriptor[];
61
+ /**
62
+ * The EFFECTIVE supersession list — already derived when the module declared
63
+ * `owns: "provided"`, so callers never re-implement that resolution.
64
+ */
65
+ readonly owns: readonly string[];
66
+ readonly lifecycle: ResolvedModuleLifecycle;
67
+ }
68
+ /** Minimal resource shape the descriptor reads. Structural — matches `ResourceLike`. */
69
+ interface DescribableResource {
70
+ readonly name?: string | undefined;
71
+ readonly prefix?: string | undefined;
72
+ readonly skipGlobalPrefix?: boolean | undefined;
73
+ }
74
+ /**
75
+ * Build a descriptor. Called by `registerResources` once per module, after
76
+ * resources are resolved and `owns` is effective.
77
+ *
78
+ * Frozen at every level: a descriptor is a snapshot of a completed decision,
79
+ * and a consumer mutating it would silently disagree with the running app.
80
+ */
81
+ declare function describeResolvedModule(input: {
82
+ readonly name: string;
83
+ readonly dependsOn?: readonly string[] | undefined;
84
+ readonly resources: readonly DescribableResource[];
85
+ readonly owns: readonly string[];
86
+ readonly lifecycle: ResolvedModuleLifecycle;
87
+ }): ResolvedModuleDescriptor;
88
+ //#endregion
89
+ //#region src/core/arcCorePlugin.d.ts
90
+ interface ArcCorePluginOptions {
91
+ /** Enable event emission for CRUD operations (requires eventPlugin) */
92
+ emitEvents?: boolean;
93
+ /** Hook system instance (for testing/custom setup) */
94
+ hookSystem?: HookSystem;
95
+ /** Resource registry instance (for testing/custom setup) */
96
+ registry?: ResourceRegistry;
97
+ }
98
+ interface PluginMeta {
99
+ name: string;
100
+ version?: string;
101
+ options?: Record<string, unknown>;
102
+ registeredAt: string;
103
+ }
104
+ interface ArcCore {
105
+ /** Instance-scoped hook system */
106
+ hooks: HookSystem;
107
+ /** Instance-scoped resource registry */
108
+ registry: ResourceRegistry;
109
+ /** Whether event emission is enabled */
110
+ emitEvents: boolean;
111
+ /** External OpenAPI paths contributed by auth adapters or third-party integrations */
112
+ externalOpenApiPaths: ExternalOpenApiPaths[];
113
+ /** Registered plugins for introspection */
114
+ plugins: Map<string, PluginMeta>;
115
+ /**
116
+ * Module public exports — `bootstrap()` return values keyed by module name
117
+ * (see `src/factory/module.ts`). Read via `getModuleExports(fastify, name)`:
118
+ * augment `ArcModuleRegistry` once and the name infers the export type;
119
+ * otherwise pass it inline. `Partial<ArcModuleRegistry>` gives augmented
120
+ * apps typed direct access (`fastify.arc.modules.order`), while the
121
+ * `Record<string, unknown>` intersection keeps un-augmented reads open.
122
+ * Populated lazily by `registerResources` — absent until a module exports.
123
+ */
124
+ modules?: Partial<ArcModuleRegistry> & Record<string, unknown>;
125
+ /**
126
+ * Lifecycle state per composed module (null-proto map, populated by
127
+ * `registerResources` the moment the graph is validated — so it answers
128
+ * "is this module composed?" even for resource-only modules that never
129
+ * record an export). Read via `hasModule(fastify, name)` /
130
+ * `getModuleState(fastify, name)`; the map itself is internal.
131
+ */
132
+ moduleStates?: Record<string, ModuleState>;
133
+ /**
134
+ * Module-contributed readiness checks, collected in dependency order and
135
+ * frozen by `createApp`. The API role merges these into its `healthPlugin`;
136
+ * `createWorker` reads this to give its probe listener the identical union
137
+ * (the worker preset disables the main health plugin, so this is how module
138
+ * checks reach the probe without a double registration). Empty until
139
+ * `createApp` populates it.
140
+ */
141
+ healthChecks?: readonly HealthCheck[];
142
+ /**
143
+ * The resolved, dependency-ordered module definitions (frozen by createApp).
144
+ * Integrations that collect a module arm at their OWN init time — e.g. the
145
+ * streamline integration calling `collectModuleWorkflows(fastify, defs)` after
146
+ * it has created + decorated its container — read the list from here. Empty
147
+ * until createApp populates it.
148
+ */
149
+ moduleDefinitions?: readonly ArcModule[];
150
+ /**
151
+ * RESOLVED module descriptors — what each module actually composed to
152
+ * (resources mounted, effective `owns`, lifecycle counts), published once
153
+ * boot has settled them.
154
+ *
155
+ * Read this rather than `moduleDefinitions` for anything that needs the real
156
+ * graph: a definition's `resources` may still be an unresolved factory and
157
+ * its `owns` may be `"provided"`, so the authoring shape cannot answer "what
158
+ * did this module actually mount?". Frozen, plain data — safe to clone, log,
159
+ * or hand to tooling.
160
+ */
161
+ moduleDescriptors?: readonly ResolvedModuleDescriptor[];
162
+ /**
163
+ * Module-contributed recurring schedules, resolved once in dependency order
164
+ * and frozen after bootstraps. The same definitions are executed by Arc's
165
+ * schedules plugin and exposed here for introspection. Empty until collection.
166
+ */
167
+ scheduledJobs?: readonly Readonly<ScheduleDefinition>[];
168
+ }
169
+ declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
170
+ declare const _default: FastifyPluginAsync<ArcCorePluginOptions>;
171
+ //#endregion
172
+ //#region src/types/fastify-augmentation.d.ts
173
+ declare module "fastify" {
174
+ interface FastifyInstance {
175
+ arc?: ArcCore;
176
+ }
177
+ }
178
+ //#endregion
179
+ export { arcCorePlugin as a, ResolvedResourceDescriptor as c, _default as i, describeResolvedModule as l, ArcCorePluginOptions as n, ResolvedModuleDescriptor as o, PluginMeta as r, ResolvedModuleLifecycle as s, ArcCore as t };
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/permissions/fields.ts
3
3
  /**
4
4
  * Field-Level Permissions
@@ -111,10 +111,7 @@ function applyFieldReadPermissions(data, fieldPermissions, userRoles) {
111
111
  case "visibleTo":
112
112
  if (!perm.roles?.some((r) => userRoles.includes(r))) delete result[field];
113
113
  break;
114
- case "redactFor":
115
- if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
116
- break;
117
- case "writableBy": break;
114
+ case "redactFor": if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
118
115
  }
119
116
  return result;
120
117
  }
@@ -140,12 +137,10 @@ function applyFieldWritePermissions(body, fieldPermissions, userRoles) {
140
137
  delete result[field];
141
138
  }
142
139
  break;
143
- case "writableBy":
144
- if (field in result && !perm.roles?.some((r) => userRoles.includes(r))) {
145
- deniedFields.push(field);
146
- delete result[field];
147
- }
148
- break;
140
+ case "writableBy": if (field in result && !perm.roles?.some((r) => userRoles.includes(r))) {
141
+ deniedFields.push(field);
142
+ delete result[field];
143
+ }
149
144
  }
150
145
  return {
151
146
  body: result,
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as pluralize } from "./pluralize-O0FZgESl.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as pluralize } from "./pluralize-C2ZkKbsn.mjs";
3
3
  import { join } from "node:path";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  //#region src/cli/commands/generate/name-helpers.ts
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { u as ValidationError } from "./errors-Cj42AntO.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { u as ValidationError } from "./errors-Bh1KK5ps.mjs";
3
3
  //#region src/utils/headers.ts
4
4
  /**
5
5
  * Canonical header typing + accessor.
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import { randomUUID } from "node:crypto";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/plugins/requestId.ts
@@ -1,3 +1,3 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-BcmPyq5I.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-vimw5D7Z.mjs";
3
3
  export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as requireSingleHeaderValue } from "../headers-3zvE0rM3.mjs";
3
- import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-D1MP_gRG.mjs";
4
- import { t as createIdempotencyResult } from "../interface-DYzM0q-u.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as requireSingleHeaderValue } from "../headers-BXjQYbeC.mjs";
3
+ import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-DmEMHlPQ.mjs";
4
+ import { t as createIdempotencyResult } from "../interface-BP4IJCBO.mjs";
5
5
  import { and, eq, exists, gt, lt, or, startsWith } from "@classytic/repo-core/filter";
6
6
  import { createHash } from "node:crypto";
7
7
  import fp from "fastify-plugin";
@@ -138,8 +138,10 @@ var MemoryIdempotencyStore = class {
138
138
  }
139
139
  async tryLock(key, requestId, ttlMs) {
140
140
  const existing = this.locks.get(key);
141
- if (existing) if (/* @__PURE__ */ new Date() > existing.expiresAt) this.locks.delete(key);
142
- else return false;
141
+ if (existing) {
142
+ if (/* @__PURE__ */ new Date() > existing.expiresAt) this.locks.delete(key);
143
+ else return false;
144
+ }
143
145
  this.locks.set(key, {
144
146
  key,
145
147
  requestId,
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/idempotency/stores/redis.ts
3
3
  var RedisIdempotencyStore = class {
4
4
  name = "redis";
@@ -2,7 +2,7 @@
2
2
  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-CpzxqePp.mjs";
3
3
  import { i as RequestScope } from "./types-ChuShpCP.mjs";
4
4
  import { l as AnyRecord, r as PermissionCheck } from "./types-B7XeLEgK.mjs";
5
- import "./fastify-augmentation-zh0_AYHa.mjs";
5
+ import "./fastify-augmentation-BppG5bMT.mjs";
6
6
  import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
7
7
  import { z } from "zod";
8
8
  import { DataAdapter } from "@classytic/repo-core/adapter";
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as ModuleContribution, h as HealthCheck, n as ArcModuleInput, r as ArcModuleRegistry, t as ArcModule, u as ScheduleDefinition } from "./types-CBgvkp8O.mjs";
2
+ import { _ as HealthCheck, a as ModuleContribution, f as ScheduleDefinition, n as ArcModuleInput, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule } from "./types-CT5vu6M0.mjs";
3
3
  import { FastifyInstance } from "fastify";
4
4
  //#region src/factory/module/contributions.d.ts
5
5
  /**
@@ -25,7 +25,67 @@ declare function collectModuleWorkflows(fastify: FastifyInstance, modules: reado
25
25
  * modules. The caller passes the returned definitions to the canonical
26
26
  * schedules plugin; factories must therefore be resolved only once.
27
27
  */
28
- declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: readonly ArcModule[]): Promise<ScheduleDefinition[]>;
28
+ declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: readonly ArcModule[],
29
+ /**
30
+ * Optional sink for per-module counts, filled as each arm resolves.
31
+ *
32
+ * Exists so `arc.moduleDescriptors` can report real numbers without
33
+ * resolving the factories a SECOND time — a contribution factory closes over
34
+ * booted engines and may register or allocate, so running it twice is not a
35
+ * free read. One resolution feeds both activation and introspection.
36
+ */
37
+ countsByModule?: Map<string, number>): Promise<ScheduleDefinition[]>;
38
+ //#endregion
39
+ //#region src/factory/module/extend.d.ts
40
+ /**
41
+ * What a caller may add. Every mergeable arm of `ArcModule`, plus `bootstrap`
42
+ * in wrapper form only.
43
+ *
44
+ * `name` is absent on purpose: renaming a module mid-composition breaks the
45
+ * `dependsOn` graph and the registry key its consumers read, and it is the one
46
+ * "extension" that is never additive.
47
+ */
48
+ interface ModuleExtension<TExports = unknown> {
49
+ dependsOn?: readonly string[];
50
+ owns?: readonly string[] | "provided";
51
+ resources?: ArcModule<TExports>["resources"];
52
+ eventHandlers?: ArcModule<TExports>["eventHandlers"];
53
+ scheduledJobs?: ArcModule<TExports>["scheduledJobs"];
54
+ workflows?: ArcModule<TExports>["workflows"];
55
+ healthChecks?: ArcModule<TExports>["healthChecks"];
56
+ errorMappers?: ArcModule<TExports>["errorMappers"];
57
+ plugins?: ArcModule<TExports>["plugins"];
58
+ afterResources?: ArcModule<TExports>["afterResources"];
59
+ onClose?: ArcModule<TExports>["onClose"];
60
+ /**
61
+ * WRAP the module's bootstrap — it is never replaced.
62
+ *
63
+ * Bootstrap returns the module's exports, so two of them cannot be
64
+ * concatenated: one value has to win, and a host silently winning is the gym
65
+ * failure (`{ ...mod, bootstrap }` overwrote the factory's own, so the engine
66
+ * the module published was never created). The wrapper form makes the
67
+ * relationship explicit — call `inner` and decorate its result, or
68
+ * deliberately do not.
69
+ *
70
+ * `inner` is `undefined` when the module has no bootstrap of its own.
71
+ */
72
+ bootstrap?: (inner: ((f: FastifyInstance, c: ModuleSetupContext) => TExports | Promise<TExports>) | undefined) => (f: FastifyInstance, c: ModuleSetupContext) => TExports | Promise<TExports>;
73
+ }
74
+ /**
75
+ * Merge a host's additions onto a module. Nothing the module declared is lost.
76
+ *
77
+ * ```ts
78
+ * return extendModule(createOrderModule({ … }), {
79
+ * eventHandlers: () => hostHandlers(), // appended after the module's
80
+ * dependsOn: ["outbox"], // unioned
81
+ * bootstrap: (inner) => async (f, c) => { // wraps, never replaces
82
+ * const exports = await inner?.(f, c);
83
+ * return decorate(exports);
84
+ * },
85
+ * });
86
+ * ```
87
+ */
88
+ declare function extendModule<TExports = unknown>(mod: ArcModule<TExports>, extension: ModuleExtension<TExports>): ArcModule<TExports>;
29
89
  //#endregion
30
90
  //#region src/factory/module/lifecycle.d.ts
31
91
  /**
@@ -38,7 +98,13 @@ declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: r
38
98
  * Resolves factory contributions (after bootstraps) so a handler can close over
39
99
  * booted engines rather than a global getter.
40
100
  */
41
- declare function subscribeModuleEventHandlers(fastify: FastifyInstance, modules: readonly ArcModule[]): Promise<Array<() => void | Promise<void>>>;
101
+ declare function subscribeModuleEventHandlers(fastify: FastifyInstance, modules: readonly ArcModule[],
102
+ /**
103
+ * Optional sink for per-module handler counts, filled as each arm resolves.
104
+ * Lets `arc.moduleDescriptors` report real numbers without resolving the
105
+ * factories a SECOND time — see the note on `collectModuleScheduledJobs`.
106
+ */
107
+ countsByModule?: Map<string, number>): Promise<Array<() => void | Promise<void>>>;
42
108
  //#endregion
43
109
  //#region src/factory/module/order.d.ts
44
110
  /**
@@ -221,4 +287,4 @@ declare function lazyModuleExports<TExports = unknown>(fastify: FastifyInstance,
221
287
  declare function lazyRequiredModuleExports<K extends keyof ArcModuleRegistry>(fastify: FastifyInstance, name: K): () => ArcModuleRegistry[K];
222
288
  declare function lazyRequiredModuleExports<TExports = unknown>(fastify: FastifyInstance, name: string): () => TExports;
223
289
  //#endregion
224
- export { lazyModuleExports as a, getModuleState as c, resolveModule as d, orderModules as f, collectModuleWorkflows as g, collectModuleScheduledJobs as h, hasModuleExports as i, hasModule as l, collectModuleHealthChecks as m, getModuleExports as n, lazyRequiredModuleExports as o, subscribeModuleEventHandlers as p, getOptionalModuleExports as r, ModuleState as s, defineModule as t, resolveContribution as u };
290
+ export { collectModuleScheduledJobs as _, lazyModuleExports as a, getModuleState as c, resolveModule as d, orderModules as f, collectModuleHealthChecks as g, extendModule as h, hasModuleExports as i, hasModule as l, ModuleExtension as m, getModuleExports as n, lazyRequiredModuleExports as o, subscribeModuleEventHandlers as p, getOptionalModuleExports as r, ModuleState as s, defineModule as t, resolveContribution as u, collectModuleWorkflows as v };
@@ -990,4 +990,73 @@ declare function fullPublic<TDoc = Record<string, unknown>>(overrides?: Permissi
990
990
  */
991
991
  declare function readOnly<TDoc = Record<string, unknown>>(overrides?: PermissionOverrides<TDoc>): ResourcePermissions<TDoc>;
992
992
  //#endregion
993
- export { evaluatePermissionDecision as $, explainAccess as A, anyOf as B, requireGrant as C, collectPublicSurface as D, PermissionRequirement as E, createDynamicPermissionMatrix as F, requireOwnership as G, denyAll as H, createOrgPermissions as I, roles as J, requirePlatformRole as K, allOf as L, DynamicPermissionMatrix as M, DynamicPermissionMatrixConfig as N, describePermission as O, PermissionEventBus as P, applyAuthorizationDecision as Q, allow as R, modeSatisfies as S, AccessExplanation as T, not as U, deny as V, requireAuth as W, scopeOf as X, when as Y, PermissionCheckReturn as Z, createRoleHierarchy as _, permissionMatrix as a, requireMandate as at, GrantResolution as b, publicReadAdminWrite as c, requireOrgMembership as d, normalizeToDecision as et, requireOrgRole as f, RoleHierarchy as g, requireTeamMembership as h, ownerWithAdminBypass as i, requireDPoP as it, ConnectEventsOptions as j, describePermissionMap as k, readOnly as l, requireServiceScope as m, authenticated as n, RequireMandateOptions as nt, presets_d_exports as o, requireScopeContext as p, requireRoles as q, fullPublic as r, requireAgentScope as rt, publicRead as s, adminOnly as t, RequireAgentScopeOptions as tt, requireOrgInScope as u, GRANT_MODES as v, conjoinPolicyFilters as w, RequireGrantOptions as x, GrantMode as y, allowPublic as z };
993
+ //#region src/permissions/matrix.d.ts
994
+ type PermissionEntryType = "public" | "authenticated" | "roles" | "scoped";
995
+ interface PermissionEntry {
996
+ type: PermissionEntryType;
997
+ roles: string[];
998
+ /**
999
+ * Present only for `scoped` — the caller-scope dimensions the gate requires
1000
+ * (e.g. `{ branchRole: "head_office" }`), for the client to resolve against
1001
+ * the viewer's active context.
1002
+ */
1003
+ scope?: Record<string, unknown>;
1004
+ }
1005
+ /**
1006
+ * The slice of arc's `ResourceRegistry` this reads.
1007
+ *
1008
+ * Structural on purpose: coupling to the full registry type would drag the
1009
+ * resource layer into the permissions layer, and this only ever reads names
1010
+ * and gates.
1011
+ */
1012
+ interface PermissionMatrixRegistry {
1013
+ getAll(): ReadonlyArray<{
1014
+ name: string;
1015
+ permissions?: Record<string, unknown>;
1016
+ actions?: ReadonlyArray<{
1017
+ name: string;
1018
+ permissions?: unknown;
1019
+ }>;
1020
+ aggregations?: ReadonlyArray<{
1021
+ name: string;
1022
+ permissions?: unknown;
1023
+ }>;
1024
+ }>;
1025
+ }
1026
+ interface PermissionMatrixOptions {
1027
+ /** The live registry. Omit and the matrix carries only curated modules. */
1028
+ registry?: PermissionMatrixRegistry;
1029
+ /**
1030
+ * Curated, human-named groupings the client already organises around
1031
+ * (`products`, `finance`, …). Overlaid FIRST — the live registry wins on an
1032
+ * exact name collision, because the enforced gate beats an approximation.
1033
+ */
1034
+ curatedModules?: Record<string, unknown>;
1035
+ /**
1036
+ * Second curated layer, applied only where `curatedModules` has no entry —
1037
+ * typically per-resource policies behind the domain groupings.
1038
+ */
1039
+ fallbackModules?: Record<string, unknown>;
1040
+ /** Platform-level role names. */
1041
+ platformRoles?: readonly string[];
1042
+ /** Organization/branch-level role names. */
1043
+ orgRoles?: readonly string[];
1044
+ }
1045
+ interface PermissionMatrix {
1046
+ /** Every role name, both namespaces — so a role picker has one source. */
1047
+ roles: string[];
1048
+ roleGroups: {
1049
+ platform: string[];
1050
+ branch: string[];
1051
+ };
1052
+ modules: Record<string, Record<string, PermissionEntry>>;
1053
+ }
1054
+ /** Re-shape arc's typed requirement into the wire entry. */
1055
+ declare function introspectCheck(check: PermissionCheck): PermissionEntry;
1056
+ /** Introspect a permission module, flattening nested groups to `a.b`. */
1057
+ declare function introspectModule(mod: Record<string, unknown>): Record<string, PermissionEntry>;
1058
+ /** Every live resource's ACTUAL gates, keyed by arc resource name. */
1059
+ declare function introspectRegistry(registry: PermissionMatrixRegistry): Record<string, Record<string, PermissionEntry>>;
1060
+ declare function buildPermissionMatrix(options?: PermissionMatrixOptions): PermissionMatrix;
1061
+ //#endregion
1062
+ export { requireAuth as $, RequireGrantOptions as A, ConnectEventsOptions as B, requireServiceScope as C, GRANT_MODES as D, createRoleHierarchy as E, PermissionRequirement as F, createOrgPermissions as G, DynamicPermissionMatrixConfig as H, collectPublicSurface as I, allowPublic as J, allOf as K, describePermission as L, requireGrant as M, conjoinPolicyFilters as N, GrantMode as O, AccessExplanation as P, not as Q, describePermissionMap as R, requireScopeContext as S, RoleHierarchy as T, PermissionEventBus as U, DynamicPermissionMatrix as V, createDynamicPermissionMatrix as W, deny as X, anyOf as Y, denyAll as Z, publicReadAdminWrite as _, PermissionMatrixRegistry as a, scopeOf as at, requireOrgMembership as b, introspectModule as c, evaluatePermissionDecision as ct, authenticated as d, RequireMandateOptions as dt, requireOwnership as et, fullPublic as f, requireAgentScope as ft, publicRead as g, presets_d_exports as h, PermissionMatrixOptions as i, when as it, modeSatisfies as j, GrantResolution as k, introspectRegistry as l, normalizeToDecision as lt, permissionMatrix as m, requireMandate as mt, PermissionEntryType as n, requireRoles as nt, buildPermissionMatrix as o, PermissionCheckReturn as ot, ownerWithAdminBypass as p, requireDPoP as pt, allow as q, PermissionMatrix as r, roles as rt, introspectCheck as s, applyAuthorizationDecision as st, PermissionEntry as t, requirePlatformRole as tt, adminOnly as u, RequireAgentScopeOptions as ut, readOnly as v, requireTeamMembership as w, requireOrgRole as x, requireOrgInScope as y, explainAccess as z };
package/dist/index.d.mts CHANGED
@@ -2,9 +2,9 @@
2
2
  import { $t as TreeMixin, A as RequestIdOptions, An as BaseControllerOptions, B as defineResource, Bt as RawRouteHandler, C as RequestContext, D as HealthCheck, Dn as ArcGetResult, E as GracefulShutdownOptions, En as ArcDeleteResult, F as FastifyWithDecorators, Ft as ControllerLike, H as CrudController, L as RequestWithExtras, Lt as IController, Mn as ControllerConstructionOptions, N as FastifyRequestExtras, Nn as ListResult, Nt as RateLimitConfig, O as HealthOptions, On as ArcListResult, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as TreeExt, Rt as IControllerResponse, S as QueryParserInterface, T as CrudRouterOptions, Tn as ArcCreateResult, U as ResourceConfig, V as ResourceDefinition, Vt as RouteHandler, Wt as AuthPluginOptions, X as CrudRouteKey, Xt as SoftDeleteExt, Y as PresetResult, Yt as BaseController, Z as CrudSchemas, Zt as SoftDeleteMixin, a as InferAdapterDoc, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, en as SlugExt, 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 BaseCrudController, jn as ControllerConfigurableOptions, k as IntrospectionPluginOptions, kn as ArcUpdateResult, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nn as BulkExt, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, r as ValidateOptions, rn as BulkMixin, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, tn as SlugMixin, u as TypedResourceConfig, ut as AggregationConfig, w as ServiceContext, y as OwnershipCheck, zt as IRequestContext } from "./index-CpzxqePp.mjs";
3
3
  import { a as UserBase, d as JWTPayload, i as PermissionContext, l as AnyRecord, m as UserOrganization, n as DataPolicy, r as PermissionCheck, t as AuthorizationDecision, u as ArcRequest } from "./types-B7XeLEgK.mjs";
4
4
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-I_EeRWND.mjs";
5
- import "./fastify-augmentation-zh0_AYHa.mjs";
6
- 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-Bc2ox8_U.mjs";
7
- import { B as anyOf, F as createDynamicPermissionMatrix, G as requireOwnership, H as denyAll, I as createOrgPermissions, L as allOf, M as DynamicPermissionMatrix, N as DynamicPermissionMatrixConfig, W as requireAuth, Y as when, c as publicReadAdminWrite, d as requireOrgMembership, f as requireOrgRole, h as requireTeamMembership, i as ownerWithAdminBypass, l as readOnly, m as requireServiceScope, n as authenticated, o as presets_d_exports, p as requireScopeContext, q as requireRoles, r as fullPublic, s as publicRead, t as adminOnly, u as requireOrgInScope, z as allowPublic } from "./index-CEJNZFtX.mjs";
5
+ import "./fastify-augmentation-BppG5bMT.mjs";
6
+ 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-DXlHwvuE.mjs";
7
+ import { $ as requireAuth, C as requireServiceScope, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, J as allowPublic, K as allOf, S as requireScopeContext, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, b as requireOrgMembership, d as authenticated, et as requireOwnership, f as fullPublic, g as publicRead, h as presets_d_exports, it as when, nt as requireRoles, p as ownerWithAdminBypass, u as adminOnly, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope } from "./index-zq6VrjaB.mjs";
8
8
  import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-BGdVwP25.mjs";
9
9
  //#region src/index.d.ts
10
10
  declare const version: string;
package/dist/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
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-D3Dv4LAV.mjs";
3
- import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-Cj42AntO.mjs";
4
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-De7GqHck.mjs";
5
- import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CB5Cuzk9.mjs";
6
- import { a as ResourceDefinition, t as defineResource } from "./defineResource-Bv6EtN1x.mjs";
7
- import { c as getControllerScope } from "./pipeline-UPQFatit.mjs";
8
- import { t as defineAggregation } from "./defineAggregation-DbPPS8RI.mjs";
9
- import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-BGpIxINN.mjs";
10
- import { C as requireScopeContext, I as requireAuth, L as requireOwnership, M as anyOf, P as denyAll, S as requireOrgRole, T as requireTeamMembership, V as when, b as requireOrgInScope, c as publicReadAdminWrite, i as ownerWithAdminBypass, j as allowPublic, k as allOf, l as readOnly, n as authenticated, o as presets_exports, r as fullPublic, s as publicRead, t as adminOnly, v as createDynamicPermissionMatrix, w as requireServiceScope, x as requireOrgMembership, y as createOrgPermissions, z as requireRoles } from "./permissions-L--QDAir.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
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-J99LGTJI.mjs";
3
+ import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-Bh1KK5ps.mjs";
4
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-Dk34dxhI.mjs";
5
+ import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-DEi65pGj.mjs";
6
+ import { a as ResourceDefinition, t as defineResource } from "./defineResource-XFPPUu2c.mjs";
7
+ import { c as getControllerScope } from "./pipeline-CPA-jx0M.mjs";
8
+ import { t as defineAggregation } from "./defineAggregation-gX4No1gt.mjs";
9
+ import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-BwwmNSp7.mjs";
10
+ import { B as requireAuth, C as createOrgPermissions, D as requireScopeContext, E as requireOrgRole, F as allowPublic, G as when, I as anyOf, N as allOf, O as requireServiceScope, R as denyAll, S as createDynamicPermissionMatrix, T as requireOrgMembership, U as requireRoles, V as requireOwnership, a as adminOnly, c as ownerWithAdminBypass, d as publicRead, f as publicReadAdminWrite, k as requireTeamMembership, o as authenticated, p as readOnly, s as fullPublic, u as presets_exports, w as requireOrgInScope } from "./permissions-Dl_m0NCe.mjs";
11
11
  //#region src/index.ts
12
- const version = "2.31.0";
12
+ const version = "2.32.0";
13
13
  //#endregion
14
14
  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,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  import { dirname, join } from "node:path";
@@ -997,7 +997,7 @@ export async function updateUserProfile(request${ts ? ": FastifyRequest" : ""},
997
997
  delete updates.role;
998
998
  delete updates.organizations;
999
999
 
1000
- const user = await userRepository.Model.findByIdAndUpdate(userId, updates, { new: true });
1000
+ const user = await userRepository.Model.findByIdAndUpdate(userId, updates, { returnDocument: 'after' });
1001
1001
  return reply.send(user);
1002
1002
  } catch (error) {
1003
1003
  request.log.error({ err: error }, 'Update profile error');
@@ -2379,7 +2379,8 @@ export const requireAdmin = ()${returnType} =>
2379
2379
  export const requireSuperadmin = ()${returnType} =>
2380
2380
  requireRoles(['superadmin']);
2381
2381
  `;
2382
- if (config.tenant === "multi") if (config.auth === "better-auth") content += `
2382
+ if (config.tenant === "multi") {
2383
+ if (config.auth === "better-auth") content += `
2383
2384
  // ============================================================================
2384
2385
  // Better Auth Organization & Team Permission Helpers
2385
2386
  // ============================================================================
@@ -2431,7 +2432,7 @@ export const requireOrgManager = ()${returnType} =>
2431
2432
  export const requireOrgStaff = ()${returnType} =>
2432
2433
  requireOrgMembership();
2433
2434
  `;
2434
- else content += `
2435
+ else content += `
2435
2436
  /**
2436
2437
  * Require organization owner (elevated scope auto-bypasses)
2437
2438
  */
@@ -2450,6 +2451,7 @@ export const requireOrgManager = ()${returnType} =>
2450
2451
  export const requireOrgStaff = ()${returnType} =>
2451
2452
  requireRoles(['owner', 'manager', 'staff', 'admin', 'superadmin']);
2452
2453
  `;
2454
+ }
2453
2455
  content += `
2454
2456
  // ============================================================================
2455
2457
  // Standard Permission Sets
@@ -3016,7 +3018,7 @@ class UserRepository extends Repository${ts ? "<UserDocument>" : ""} {
3016
3018
  return this.Model.findByIdAndUpdate(
3017
3019
  userId,
3018
3020
  { resetPasswordToken: token, resetPasswordExpires: expiresAt },
3019
- { new: true }
3021
+ { returnDocument: 'after' }
3020
3022
  );
3021
3023
  }
3022
3024
  ${config.tenant === "multi" ? `
@@ -1,11 +1,11 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import fp from "fastify-plugin";
3
3
  //#region src/integrations/event-gateway.ts
4
4
  const eventGatewayPluginImpl = async (fastify, opts = {}) => {
5
5
  const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
6
6
  if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
7
7
  if (opts.sse !== false) {
8
- const { default: ssePlugin } = await import("../sse-CUTo9y0X.mjs").then((n) => n.r);
8
+ const { default: ssePlugin } = await import("../sse-B9P4Y-UI.mjs").then((n) => n.r);
9
9
  await fastify.register(ssePlugin, {
10
10
  path: opts.sse?.path ?? "/events/stream",
11
11
  requireAuth: auth,
@@ -1,2 +1,2 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  export {};
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "../../authorizationDecision-ChvUQGG1.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "../../authorizationDecision-__T3EJDA.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/integrations/jobs/execution.ts
5
5
  async function executeTimedHandler(options) {
@@ -325,7 +325,7 @@ const jobsPluginImpl = async (fastify, options) => {
325
325
  });
326
326
  workers.set(queueName, worker);
327
327
  }
328
- const JOB_PAYLOAD_WARN_BYTES = 100 * 1024;
328
+ const JOB_PAYLOAD_WARN_BYTES = 102400;
329
329
  const jobDefsByName = /* @__PURE__ */ new Map();
330
330
  for (const job of jobs) if (!jobDefsByName.has(job.name)) jobDefsByName.set(job.name, job);
331
331
  const dispatcher = {
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-B_es0hiF.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-CpfVpKHE.mjs";
3
3
  //#region src/integrations/mcp/defineTool.ts
4
4
  /**
5
5
  * Define a type-safe MCP tool.
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-B_es0hiF.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-CpfVpKHE.mjs";
3
3
  //#region src/integrations/mcp/testing.ts
4
4
  /**
5
5
  * @classytic/arc/mcp/testing — MCP Test Utilities