@classytic/arc 2.18.2 → 2.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BaseController-DPwe89qs.mjs → BaseController-B-uXzf6I.mjs} +403 -216
- package/dist/{QueryCache-8YmAQ-zW.d.mts → QueryCache-Dsyv2mLS.d.mts} +1 -1
- package/dist/audit/index.d.mts +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +4 -4
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-ClWxaceA.mjs → betterAuthOpenApi-DAAhMZff.mjs} +1 -1
- package/dist/{buildHandler-C_SkBNF3.mjs → buildHandler-Cvrc2p7r.mjs} +1 -1
- package/dist/cache/index.d.mts +3 -3
- package/dist/cache/index.mjs +3 -3
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.d.mts +1 -1
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.d.mts +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.mjs +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -3
- package/dist/{core-B41eZxyM.mjs → core-C88uIwd3.mjs} +161 -103
- package/dist/{createActionRouter-CRaIwB5S.mjs → createActionRouter-DGCCp-kP.mjs} +4 -2
- package/dist/{createAggregationRouter-n3O6WdLO.mjs → createAggregationRouter-Ca77b8iK.mjs} +3 -3
- package/dist/{createApp-DZvrb587.mjs → createApp-DLuUGVZQ.mjs} +11 -11
- package/dist/{defineEvent-NPKUJRt8.mjs → defineEvent-DC981g-o.mjs} +1 -1
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-6mfTLBC-.mjs → elevation-BzhyVWfn.mjs} +1 -1
- package/dist/{eventPlugin-Dxp9JlKK.mjs → eventPlugin-Bw4bUDEO.mjs} +2 -2
- package/dist/{eventPlugin-DjEx_J3j.d.mts → eventPlugin-C1W1CRbf.d.mts} +1 -1
- package/dist/events/index.d.mts +8 -5
- package/dist/events/index.mjs +26 -7
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +52 -5
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +3 -3
- package/dist/{fastify-augmentation-CL48B6gW.d.mts → fastify-augmentation-BdCl_eNo.d.mts} +2 -2
- package/dist/{fields-DqZLp5d6.d.mts → fields-CKLrhyOb.d.mts} +1 -1
- package/dist/{generate-CcM24hoq.mjs → generate-BaxDdmJ8.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +2 -2
- package/dist/idempotency/index.mjs +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-CNiryUMN.d.mts → index-Cvo1u9n6.d.mts} +3 -3
- package/dist/{index-C000faom.d.mts → index-QYma8mdC.d.mts} +215 -241
- package/dist/{index-3L-adFJO.d.mts → index-vcWUGkwf.d.mts} +3 -3
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +5 -5
- package/dist/{init-DQ_rY1J7.mjs → init-DSsdRfk9.mjs} +3 -3
- package/dist/integrations/event-gateway.d.mts +2 -2
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/jobs.mjs +66 -1
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.d.mts +16 -1
- package/dist/integrations/streamline.mjs +33 -2
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +2 -2
- package/dist/{loadResourcesFromEntry-DCjYMgfC.mjs → loadResourcesFromEntry-XHNeUWpu.mjs} +1 -1
- package/dist/{mcpPlugin-BrepZ0cV.mjs → mcpPlugin-CzKdt3B8.mjs} +9 -9
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/{openapi-CLZx9bwS.mjs → openapi-ButnRyOM.mjs} +5 -5
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-B1Qy55fg.mjs → permissions-3uzwkbQt.mjs} +99 -99
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +1 -1
- package/dist/pipeline-D4sqiokR.mjs +336 -0
- package/dist/plugins/index.d.mts +5 -5
- package/dist/plugins/index.mjs +9 -9
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +4 -4
- package/dist/presets/filesUpload.mjs +2 -2
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-BYbPobbF.mjs → presets-CF79RHEo.mjs} +1 -1
- package/dist/{queryCachePlugin-Do4P_WBC.d.mts → queryCachePlugin-Bd2tYgh5.d.mts} +2 -2
- package/dist/{queryCachePlugin-B4XMSSe7.mjs → queryCachePlugin-CnAeFqju.mjs} +3 -3
- package/dist/rateLimit-yKvxWAky.mjs +207 -0
- package/dist/{redis-cpqVb85w.d.mts → redis-3hqH_Qk_.d.mts} +1 -1
- package/dist/{redis-stream-BuiAS3aE.d.mts → redis-stream-BtEUtjxZ.d.mts} +5 -4
- package/dist/registerRoute-BEYn0ylk.mjs +108 -0
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{schemaIR-Bk6Tns82.mjs → schemaIR-CE6USIRi.mjs} +1 -1
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +2 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +12 -2
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-DH-7WO64.d.mts → types-BWBcb88c.d.mts} +1 -1
- package/dist/{types-DEEWwQFR.d.mts → types-WVlAVp8T.d.mts} +10 -10
- package/dist/utils/index.d.mts +3 -3
- package/dist/utils/index.mjs +3 -3
- package/dist/{utils-BMQK8mRl.mjs → utils-xAQeDyU_.mjs} +1 -1
- package/dist/{validate-DFIP2VrM.mjs → validate-0__MuUsK.mjs} +201 -190
- package/dist/{versioning-5H4930tj.d.mts → versioning-BSEDGXKC.d.mts} +1 -1
- package/dist/{websocket-BZMUP7Gr.d.mts → websocket-BFBT5rH-.d.mts} +1 -1
- package/package.json +5 -5
- package/skills/arc/references/api-reference.md +1 -1
- package/dist/routerShared-Dl0A77Ba.mjs +0 -724
- /package/dist/{EventTransport-ClEDfiMS.mjs → EventTransport-7LPXLEUX.mjs} +0 -0
- /package/dist/{EventTransport-B1GFiYUy.d.mts → EventTransport-CaaXM5Y1.d.mts} +0 -0
- /package/dist/{HookSystem-Cmf7-Etp.mjs → HookSystem-BfCpWbwM.mjs} +0 -0
- /package/dist/{ResourceRegistry-CzSzVK1m.mjs → ResourceRegistry-CWmOggxS.mjs} +0 -0
- /package/dist/{actionPermissions-Bjmvn7Eb.mjs → actionPermissions-CX9QIMTd.mjs} +0 -0
- /package/dist/{caching-8MfrrUYU.mjs → caching-C0DdKiYB.mjs} +0 -0
- /package/dist/{elevation-DvwtjDwu.d.mts → elevation-DW90z5bT.d.mts} +0 -0
- /package/dist/{errorHandler-wQejMBT3.mjs → errorHandler-Bua97SEt.mjs} +0 -0
- /package/dist/{errorHandler-DuqTqeqn.d.mts → errorHandler-_Lp2k9M3.d.mts} +0 -0
- /package/dist/{errors-4ZloYFvm.d.mts → errors-DZOemeGa.d.mts} +0 -0
- /package/dist/{externalPaths-ClykOQqa.d.mts → externalPaths-DLle0R07.d.mts} +0 -0
- /package/dist/{generate-cRnsafMS.d.mts → generate-Dmk8cfvX.d.mts} +0 -0
- /package/dist/{init-D-vrTZ1G.d.mts → init-BS4Daqnv.d.mts} +0 -0
- /package/dist/{interface-DoE6UoC2.d.mts → interface-CsrGR8LF.d.mts} +0 -0
- /package/dist/{interface-BVkZsvEe.d.mts → interface-DL7LlWS5.d.mts} +0 -0
- /package/dist/{keys-DopsCuyQ.mjs → keys-B3yyBEyH.mjs} +0 -0
- /package/dist/{loadResources-fol6JuvW.mjs → loadResources-CwXt9MCh.mjs} +0 -0
- /package/dist/{memory-QOLe11D5.mjs → memory-TdTHCS9-.mjs} +0 -0
- /package/dist/{metrics-B-PU4-Yu.mjs → metrics-Da2EUPi9.mjs} +0 -0
- /package/dist/{multipartBody-VjVWmZl8.mjs → multipartBody-709YcXi1.mjs} +0 -0
- /package/dist/{pipe-DiCyvyPN.mjs → pipe-9Tl-OAus.mjs} +0 -0
- /package/dist/{pluralize-B9M8xvy-.mjs → pluralize-BxdUl2P4.mjs} +0 -0
- /package/dist/{preloadResources-BOXzPhKU.mjs → preloadResources-B-j-iqo-.mjs} +0 -0
- /package/dist/{pushref-registry-Bq_-EVsC.d.mts → pushref-registry-Dqclzjy7.d.mts} +0 -0
- /package/dist/{registry-BrlHkrRS.mjs → registry-Br15xdGM.mjs} +0 -0
- /package/dist/{replyHelpers-boS5Rx26.mjs → replyHelpers-DXHVxrrj.mjs} +0 -0
- /package/dist/{schemaConverter-De34B1ZG.mjs → schemaConverter-DatAaVNj.mjs} +0 -0
- /package/dist/{sessionManager-DlmaHUAl.d.mts → sessionManager-CyHpYXoB.d.mts} +0 -0
- /package/dist/{sse-jh5OqFjR.mjs → sse-Xq8UtuQx.mjs} +0 -0
- /package/dist/{storage-BFmamN5m.d.mts → storage-C5q8fuEt.d.mts} +0 -0
- /package/dist/{store-helpers-5JgaxieH.mjs → store-helpers-DjSYI2uP.mjs} +0 -0
- /package/dist/{tracing-BYQ3hsbM.d.mts → tracing-Bnb1-YVd.d.mts} +0 -0
- /package/dist/{typeGuards-BzkXkvVv.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{types-CfapW2t8.d.mts → types-BJwJN2Pg.d.mts} +0 -0
- /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
- /package/dist/{versioning-CuIwUQZ2.mjs → versioning-C0K8KQLx.mjs} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as QueryCacheConfig } from "./QueryCache-
|
|
2
|
-
import { i as RequestScope } from "./types-
|
|
3
|
-
import { c as PermissionCheck, d as UserBase, n as FieldPermissionMap } from "./fields-
|
|
4
|
-
import { n as DomainEvent } from "./EventTransport-
|
|
1
|
+
import { a as QueryCacheConfig } from "./QueryCache-Dsyv2mLS.mjs";
|
|
2
|
+
import { i as RequestScope } from "./types-BJwJN2Pg.mjs";
|
|
3
|
+
import { c as PermissionCheck, d as UserBase, n as FieldPermissionMap } from "./fields-CKLrhyOb.mjs";
|
|
4
|
+
import { n as DomainEvent } from "./EventTransport-CaaXM5Y1.mjs";
|
|
5
5
|
import { KeysetPaginationResult, OffsetPaginationResult } from "@classytic/repo-core/pagination";
|
|
6
6
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
|
|
7
7
|
import * as _$_classytic_repo_core_adapter0 from "@classytic/repo-core/adapter";
|
|
@@ -10,6 +10,183 @@ import { AggDateBucket, AggMeasure, AggTopN, QueryOptions, StandardRepo, TenantP
|
|
|
10
10
|
import { LookupSpec } from "@classytic/repo-core/lookup";
|
|
11
11
|
import { FieldRule, SchemaBuilderOptions } from "@classytic/repo-core/schema";
|
|
12
12
|
|
|
13
|
+
//#region src/core/BodySanitizer.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Policy for handling fields the caller lacks write permission for.
|
|
16
|
+
*
|
|
17
|
+
* - `'reject'` (default, secure): throw 403 listing the denied fields so
|
|
18
|
+
* misconfigurations and attacks surface instead of silently disappearing.
|
|
19
|
+
* - `'strip'` (legacy): silently drop the field and continue. Preserved for
|
|
20
|
+
* apps that relied on the pre-2.9 behaviour — new code should not use it.
|
|
21
|
+
*/
|
|
22
|
+
type FieldWriteDenialPolicy = "reject" | "strip";
|
|
23
|
+
interface BodySanitizerConfig {
|
|
24
|
+
/** Schema options for field sanitization */
|
|
25
|
+
schemaOptions: RouteSchemaOptions;
|
|
26
|
+
/**
|
|
27
|
+
* What to do when a request contains fields the caller can't write.
|
|
28
|
+
* Default: `'reject'` — surface the misconfiguration as a 403.
|
|
29
|
+
*/
|
|
30
|
+
onFieldWriteDenied?: FieldWriteDenialPolicy;
|
|
31
|
+
}
|
|
32
|
+
declare class BodySanitizer {
|
|
33
|
+
private schemaOptions;
|
|
34
|
+
private onFieldWriteDenied;
|
|
35
|
+
constructor(config: BodySanitizerConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Strip readonly and system-managed fields from request body.
|
|
38
|
+
* Prevents clients from overwriting _id, timestamps, __v, etc.
|
|
39
|
+
*
|
|
40
|
+
* Also applies field-level write permissions when the request has
|
|
41
|
+
* field permission metadata.
|
|
42
|
+
*/
|
|
43
|
+
sanitize(body: AnyRecord, _operation: "create" | "update", req?: IRequestContext, meta?: ArcInternalMetadata): AnyRecord;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/core/controllerTypes.d.ts
|
|
47
|
+
/**
|
|
48
|
+
* Union of every return shape repo-core's `MinimalRepo.getAll()` is
|
|
49
|
+
* contractually allowed to produce. See repo-core's `MinimalRepo.getAll`
|
|
50
|
+
* docstring for the three-way split:
|
|
51
|
+
*
|
|
52
|
+
* - `OffsetPaginationResult<TDoc>` — `page` param drives pagination.
|
|
53
|
+
* - `KeysetPaginationResult<TDoc>` — `sort` + optional `after` drives pagination.
|
|
54
|
+
* - `TDoc[]` — raw array when neither drives pagination.
|
|
55
|
+
*
|
|
56
|
+
* Arc passes the kit's response verbatim; consumers narrow on shape.
|
|
57
|
+
*/
|
|
58
|
+
type ListResult<TDoc> = OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc> | TDoc[];
|
|
59
|
+
/**
|
|
60
|
+
* Discrete cache states reported via the `x-cache` response header.
|
|
61
|
+
*
|
|
62
|
+
* - `'HIT'` — fresh cache entry served, no upstream call made.
|
|
63
|
+
* - `'STALE'` — stale entry served, upstream refresh scheduled in the background.
|
|
64
|
+
* - `'MISS'` — no cache entry; upstream call ran and the result was cached.
|
|
65
|
+
*
|
|
66
|
+
* Exported as a literal union so test code and downstream clients can
|
|
67
|
+
* import + narrow without restating the literal triple.
|
|
68
|
+
*/
|
|
69
|
+
type CacheStatus = "HIT" | "STALE" | "MISS";
|
|
70
|
+
/**
|
|
71
|
+
* Controller-shape surface that the `Arc*Result` utilities read return
|
|
72
|
+
* types from. Internal — exported so the utility types can reference
|
|
73
|
+
* the minimal shape without a circular dependency on the full
|
|
74
|
+
* `BaseCrudController` / `BaseController` declarations.
|
|
75
|
+
*/
|
|
76
|
+
type ArcControllerLike = {
|
|
77
|
+
list: (...args: never[]) => unknown;
|
|
78
|
+
get: (...args: never[]) => unknown;
|
|
79
|
+
create: (...args: never[]) => unknown;
|
|
80
|
+
update: (...args: never[]) => unknown;
|
|
81
|
+
delete: (...args: never[]) => unknown;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Return type of the controller's `list` method.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* class ProductController extends BaseController<Product> {
|
|
89
|
+
* async list(ctx: IRequestContext): ArcListResult<this> {
|
|
90
|
+
* // return shape inferred from BaseController.list — no need to
|
|
91
|
+
* // restate `Promise<IControllerResponse<ListResult<Product>>>`
|
|
92
|
+
* return super.list(ctx);
|
|
93
|
+
* }
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
type ArcListResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["list"]>;
|
|
98
|
+
/** Return type of the controller's `get` method. See {@link ArcListResult}. */
|
|
99
|
+
type ArcGetResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["get"]>;
|
|
100
|
+
/** Return type of the controller's `create` method. See {@link ArcListResult}. */
|
|
101
|
+
type ArcCreateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["create"]>;
|
|
102
|
+
/** Return type of the controller's `update` method. See {@link ArcListResult}. */
|
|
103
|
+
type ArcUpdateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["update"]>;
|
|
104
|
+
/** Return type of the controller's `delete` method. See {@link ArcListResult}. */
|
|
105
|
+
type ArcDeleteResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["delete"]>;
|
|
106
|
+
/**
|
|
107
|
+
* Construction-only options — fields that participate in the
|
|
108
|
+
* controller's mixin composition / hook identity and **cannot** be
|
|
109
|
+
* re-tuned post-construction via `configure()`. Pass these once at
|
|
110
|
+
* construction; if they need to change, build a new controller.
|
|
111
|
+
*
|
|
112
|
+
* Layer split (2.15.0): keeping this distinct from the configurable
|
|
113
|
+
* surface makes the layer explicit at compile time — `configure()`
|
|
114
|
+
* can't accept these, so accidental "I'll re-name the resource at
|
|
115
|
+
* runtime" calls fail to typecheck.
|
|
116
|
+
*/
|
|
117
|
+
interface ControllerConstructionOptions {
|
|
118
|
+
/** Resource name for hook execution (e.g., 'product' → 'product.created'). */
|
|
119
|
+
resourceName?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Configurable options — fields arc can forward post-construction via
|
|
123
|
+
* `BaseController.configure(opts)`. `defineResource()` calls
|
|
124
|
+
* `configure()` automatically when a user-supplied controller exposes
|
|
125
|
+
* the method, so resource-level options reach the controller without a
|
|
126
|
+
* `super(repo, { ... })` dance. Everything except `resourceName` /
|
|
127
|
+
* `repository` lives here.
|
|
128
|
+
*
|
|
129
|
+
* Each field maps 1:1 to a resource-level option on `defineResource()`:
|
|
130
|
+
* the resource is the public-API source of truth, this interface is
|
|
131
|
+
* the controller-internal surface arc forwards into.
|
|
132
|
+
*/
|
|
133
|
+
interface ControllerConfigurableOptions {
|
|
134
|
+
/** Schema options for field sanitization. */
|
|
135
|
+
schemaOptions?: RouteSchemaOptions;
|
|
136
|
+
/**
|
|
137
|
+
* Query parser instance.
|
|
138
|
+
* Default: Arc built-in query parser (adapter-agnostic).
|
|
139
|
+
* Swap in MongoKit QueryParser, pgkit parser, etc.
|
|
140
|
+
*/
|
|
141
|
+
queryParser?: QueryParserInterface;
|
|
142
|
+
/** Maximum limit for pagination (default: 100). */
|
|
143
|
+
maxLimit?: number;
|
|
144
|
+
/** Default limit for pagination (default: 20). */
|
|
145
|
+
defaultLimit?: number;
|
|
146
|
+
/**
|
|
147
|
+
* Default sort applied when the request doesn't specify one.
|
|
148
|
+
* - `string` (default: `'-createdAt'`) — Mongo `-field` DESC convention.
|
|
149
|
+
* - `false` — disable the default sort entirely (SQL/Drizzle resources
|
|
150
|
+
* without a `createdAt` column).
|
|
151
|
+
*/
|
|
152
|
+
defaultSort?: string | false;
|
|
153
|
+
/**
|
|
154
|
+
* Field name used for multi-tenant scoping (default: 'organizationId').
|
|
155
|
+
* Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
|
|
156
|
+
* Set to `false` to disable org filtering for platform-universal resources.
|
|
157
|
+
*/
|
|
158
|
+
tenantField?: string | false;
|
|
159
|
+
/**
|
|
160
|
+
* Primary key field name (default: '_id'). Auto-derives from the repo's
|
|
161
|
+
* own `idField` when unset.
|
|
162
|
+
*/
|
|
163
|
+
idField?: string;
|
|
164
|
+
/**
|
|
165
|
+
* Custom filter matching for policy enforcement.
|
|
166
|
+
* Provided by the DataAdapter for non-MongoDB databases (SQL, etc.).
|
|
167
|
+
*/
|
|
168
|
+
matchesFilter?: (item: unknown, filters: Record<string, unknown>) => boolean;
|
|
169
|
+
/** Cache configuration for the resource. */
|
|
170
|
+
cache?: ResourceCacheConfig;
|
|
171
|
+
/** Internal preset fields map (slug, tree, etc.). */
|
|
172
|
+
presetFields?: {
|
|
173
|
+
slugField?: string;
|
|
174
|
+
parentField?: string;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Policy for requests that include fields the caller can't write.
|
|
178
|
+
* - `'reject'` (default): 403 with denied field names.
|
|
179
|
+
* - `'strip'`: legacy silent-drop.
|
|
180
|
+
*/
|
|
181
|
+
onFieldWriteDenied?: FieldWriteDenialPolicy;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Full constructor options — union of construction-only + configurable.
|
|
185
|
+
* The constructor accepts everything; `configure()` accepts only
|
|
186
|
+
* `ControllerConfigurableOptions`.
|
|
187
|
+
*/
|
|
188
|
+
interface BaseControllerOptions extends ControllerConstructionOptions, ControllerConfigurableOptions {}
|
|
189
|
+
//#endregion
|
|
13
190
|
//#region src/hooks/HookSystem.d.ts
|
|
14
191
|
type HookPhase = "before" | "around" | "after";
|
|
15
192
|
type HookOperation = "create" | "update" | "delete" | "restore" | "read" | "list";
|
|
@@ -389,100 +566,6 @@ declare class AccessControl {
|
|
|
389
566
|
private _meta;
|
|
390
567
|
}
|
|
391
568
|
//#endregion
|
|
392
|
-
//#region src/core/BodySanitizer.d.ts
|
|
393
|
-
/**
|
|
394
|
-
* Policy for handling fields the caller lacks write permission for.
|
|
395
|
-
*
|
|
396
|
-
* - `'reject'` (default, secure): throw 403 listing the denied fields so
|
|
397
|
-
* misconfigurations and attacks surface instead of silently disappearing.
|
|
398
|
-
* - `'strip'` (legacy): silently drop the field and continue. Preserved for
|
|
399
|
-
* apps that relied on the pre-2.9 behaviour — new code should not use it.
|
|
400
|
-
*/
|
|
401
|
-
type FieldWriteDenialPolicy = "reject" | "strip";
|
|
402
|
-
interface BodySanitizerConfig {
|
|
403
|
-
/** Schema options for field sanitization */
|
|
404
|
-
schemaOptions: RouteSchemaOptions;
|
|
405
|
-
/**
|
|
406
|
-
* What to do when a request contains fields the caller can't write.
|
|
407
|
-
* Default: `'reject'` — surface the misconfiguration as a 403.
|
|
408
|
-
*/
|
|
409
|
-
onFieldWriteDenied?: FieldWriteDenialPolicy;
|
|
410
|
-
}
|
|
411
|
-
declare class BodySanitizer {
|
|
412
|
-
private schemaOptions;
|
|
413
|
-
private onFieldWriteDenied;
|
|
414
|
-
constructor(config: BodySanitizerConfig);
|
|
415
|
-
/**
|
|
416
|
-
* Strip readonly and system-managed fields from request body.
|
|
417
|
-
* Prevents clients from overwriting _id, timestamps, __v, etc.
|
|
418
|
-
*
|
|
419
|
-
* Also applies field-level write permissions when the request has
|
|
420
|
-
* field permission metadata.
|
|
421
|
-
*/
|
|
422
|
-
sanitize(body: AnyRecord, _operation: "create" | "update", req?: IRequestContext, meta?: ArcInternalMetadata): AnyRecord;
|
|
423
|
-
}
|
|
424
|
-
//#endregion
|
|
425
|
-
//#region src/core/controllerTypes.d.ts
|
|
426
|
-
/**
|
|
427
|
-
* Union of every return shape repo-core's `MinimalRepo.getAll()` is
|
|
428
|
-
* contractually allowed to produce. See repo-core's `MinimalRepo.getAll`
|
|
429
|
-
* docstring for the three-way split:
|
|
430
|
-
*
|
|
431
|
-
* - `OffsetPaginationResult<TDoc>` — `page` param drives pagination.
|
|
432
|
-
* - `KeysetPaginationResult<TDoc>` — `sort` + optional `after` drives pagination.
|
|
433
|
-
* - `TDoc[]` — raw array when neither drives pagination.
|
|
434
|
-
*
|
|
435
|
-
* Arc passes the kit's response verbatim; consumers narrow on shape.
|
|
436
|
-
*/
|
|
437
|
-
type ListResult<TDoc> = OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc> | TDoc[];
|
|
438
|
-
/**
|
|
439
|
-
* Discrete cache states reported via the `x-cache` response header.
|
|
440
|
-
*
|
|
441
|
-
* - `'HIT'` — fresh cache entry served, no upstream call made.
|
|
442
|
-
* - `'STALE'` — stale entry served, upstream refresh scheduled in the background.
|
|
443
|
-
* - `'MISS'` — no cache entry; upstream call ran and the result was cached.
|
|
444
|
-
*
|
|
445
|
-
* Exported as a literal union so test code and downstream clients can
|
|
446
|
-
* import + narrow without restating the literal triple.
|
|
447
|
-
*/
|
|
448
|
-
type CacheStatus = "HIT" | "STALE" | "MISS";
|
|
449
|
-
/**
|
|
450
|
-
* Controller-shape surface that the `Arc*Result` utilities read return
|
|
451
|
-
* types from. Internal — exported so the utility types can reference
|
|
452
|
-
* the minimal shape without a circular dependency on the full
|
|
453
|
-
* `BaseCrudController` / `BaseController` declarations.
|
|
454
|
-
*/
|
|
455
|
-
type ArcControllerLike = {
|
|
456
|
-
list: (...args: never[]) => unknown;
|
|
457
|
-
get: (...args: never[]) => unknown;
|
|
458
|
-
create: (...args: never[]) => unknown;
|
|
459
|
-
update: (...args: never[]) => unknown;
|
|
460
|
-
delete: (...args: never[]) => unknown;
|
|
461
|
-
};
|
|
462
|
-
/**
|
|
463
|
-
* Return type of the controller's `list` method.
|
|
464
|
-
*
|
|
465
|
-
* @example
|
|
466
|
-
* ```ts
|
|
467
|
-
* class ProductController extends BaseController<Product> {
|
|
468
|
-
* async list(ctx: IRequestContext): ArcListResult<this> {
|
|
469
|
-
* // return shape inferred from BaseController.list — no need to
|
|
470
|
-
* // restate `Promise<IControllerResponse<ListResult<Product>>>`
|
|
471
|
-
* return super.list(ctx);
|
|
472
|
-
* }
|
|
473
|
-
* }
|
|
474
|
-
* ```
|
|
475
|
-
*/
|
|
476
|
-
type ArcListResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["list"]>;
|
|
477
|
-
/** Return type of the controller's `get` method. See {@link ArcListResult}. */
|
|
478
|
-
type ArcGetResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["get"]>;
|
|
479
|
-
/** Return type of the controller's `create` method. See {@link ArcListResult}. */
|
|
480
|
-
type ArcCreateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["create"]>;
|
|
481
|
-
/** Return type of the controller's `update` method. See {@link ArcListResult}. */
|
|
482
|
-
type ArcUpdateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["update"]>;
|
|
483
|
-
/** Return type of the controller's `delete` method. See {@link ArcListResult}. */
|
|
484
|
-
type ArcDeleteResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["delete"]>;
|
|
485
|
-
//#endregion
|
|
486
569
|
//#region src/core/QueryResolver.d.ts
|
|
487
570
|
interface QueryResolverConfig {
|
|
488
571
|
/** Query parser instance (default: Arc built-in parser) */
|
|
@@ -551,89 +634,6 @@ declare class QueryResolver {
|
|
|
551
634
|
}
|
|
552
635
|
//#endregion
|
|
553
636
|
//#region src/core/BaseCrudController.d.ts
|
|
554
|
-
/**
|
|
555
|
-
* Construction-only options — fields that participate in the
|
|
556
|
-
* controller's mixin composition / hook identity and **cannot** be
|
|
557
|
-
* re-tuned post-construction via `configure()`. Pass these once at
|
|
558
|
-
* construction; if they need to change, build a new controller.
|
|
559
|
-
*
|
|
560
|
-
* Layer split (2.15.0): keeping this distinct from the configurable
|
|
561
|
-
* surface makes the layer explicit at compile time — `configure()`
|
|
562
|
-
* can't accept these, so accidental "I'll re-name the resource at
|
|
563
|
-
* runtime" calls fail to typecheck.
|
|
564
|
-
*/
|
|
565
|
-
interface ControllerConstructionOptions {
|
|
566
|
-
/** Resource name for hook execution (e.g., 'product' → 'product.created'). */
|
|
567
|
-
resourceName?: string;
|
|
568
|
-
}
|
|
569
|
-
/**
|
|
570
|
-
* Configurable options — fields arc can forward post-construction via
|
|
571
|
-
* `BaseController.configure(opts)`. `defineResource()` calls
|
|
572
|
-
* `configure()` automatically when a user-supplied controller exposes
|
|
573
|
-
* the method, so resource-level options reach the controller without a
|
|
574
|
-
* `super(repo, { ... })` dance. Everything except `resourceName` /
|
|
575
|
-
* `repository` lives here.
|
|
576
|
-
*
|
|
577
|
-
* Each field maps 1:1 to a resource-level option on `defineResource()`:
|
|
578
|
-
* the resource is the public-API source of truth, this interface is
|
|
579
|
-
* the controller-internal surface arc forwards into.
|
|
580
|
-
*/
|
|
581
|
-
interface ControllerConfigurableOptions {
|
|
582
|
-
/** Schema options for field sanitization. */
|
|
583
|
-
schemaOptions?: RouteSchemaOptions;
|
|
584
|
-
/**
|
|
585
|
-
* Query parser instance.
|
|
586
|
-
* Default: Arc built-in query parser (adapter-agnostic).
|
|
587
|
-
* Swap in MongoKit QueryParser, pgkit parser, etc.
|
|
588
|
-
*/
|
|
589
|
-
queryParser?: QueryParserInterface;
|
|
590
|
-
/** Maximum limit for pagination (default: 100). */
|
|
591
|
-
maxLimit?: number;
|
|
592
|
-
/** Default limit for pagination (default: 20). */
|
|
593
|
-
defaultLimit?: number;
|
|
594
|
-
/**
|
|
595
|
-
* Default sort applied when the request doesn't specify one.
|
|
596
|
-
* - `string` (default: `'-createdAt'`) — Mongo `-field` DESC convention.
|
|
597
|
-
* - `false` — disable the default sort entirely (SQL/Drizzle resources
|
|
598
|
-
* without a `createdAt` column).
|
|
599
|
-
*/
|
|
600
|
-
defaultSort?: string | false;
|
|
601
|
-
/**
|
|
602
|
-
* Field name used for multi-tenant scoping (default: 'organizationId').
|
|
603
|
-
* Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
|
|
604
|
-
* Set to `false` to disable org filtering for platform-universal resources.
|
|
605
|
-
*/
|
|
606
|
-
tenantField?: string | false;
|
|
607
|
-
/**
|
|
608
|
-
* Primary key field name (default: '_id'). Auto-derives from the repo's
|
|
609
|
-
* own `idField` when unset.
|
|
610
|
-
*/
|
|
611
|
-
idField?: string;
|
|
612
|
-
/**
|
|
613
|
-
* Custom filter matching for policy enforcement.
|
|
614
|
-
* Provided by the DataAdapter for non-MongoDB databases (SQL, etc.).
|
|
615
|
-
*/
|
|
616
|
-
matchesFilter?: (item: unknown, filters: Record<string, unknown>) => boolean;
|
|
617
|
-
/** Cache configuration for the resource. */
|
|
618
|
-
cache?: ResourceCacheConfig;
|
|
619
|
-
/** Internal preset fields map (slug, tree, etc.). */
|
|
620
|
-
presetFields?: {
|
|
621
|
-
slugField?: string;
|
|
622
|
-
parentField?: string;
|
|
623
|
-
};
|
|
624
|
-
/**
|
|
625
|
-
* Policy for requests that include fields the caller can't write.
|
|
626
|
-
* - `'reject'` (default): 403 with denied field names.
|
|
627
|
-
* - `'strip'`: legacy silent-drop.
|
|
628
|
-
*/
|
|
629
|
-
onFieldWriteDenied?: FieldWriteDenialPolicy;
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Full constructor options — union of construction-only + configurable.
|
|
633
|
-
* The constructor accepts everything; `configure()` accepts only
|
|
634
|
-
* `ControllerConfigurableOptions`.
|
|
635
|
-
*/
|
|
636
|
-
interface BaseControllerOptions extends ControllerConstructionOptions, ControllerConfigurableOptions {}
|
|
637
637
|
/**
|
|
638
638
|
* Framework-agnostic CRUD controller implementing IController.
|
|
639
639
|
*
|
|
@@ -683,6 +683,15 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
683
683
|
parentField?: string;
|
|
684
684
|
};
|
|
685
685
|
protected _cacheConfig?: ResourceCacheConfig;
|
|
686
|
+
/**
|
|
687
|
+
* Retained construction-time values so partial `configure()` rebuilds
|
|
688
|
+
* (e.g. `configure({ schemaOptions })`) reuse them instead of silently
|
|
689
|
+
* falling back to the sub-component defaults (`-createdAt` sort,
|
|
690
|
+
* `reject` write-denial) — `defaultSort: false` matters for kits
|
|
691
|
+
* without a `createdAt` column, `strip` for legacy write semantics.
|
|
692
|
+
*/
|
|
693
|
+
protected _defaultSort?: string | false;
|
|
694
|
+
protected _onFieldWriteDenied?: FieldWriteDenialPolicy;
|
|
686
695
|
constructor(repository: TRepository, options?: BaseControllerOptions);
|
|
687
696
|
/**
|
|
688
697
|
* Swap the controller's query parser. Mutates the existing `QueryResolver`
|
|
@@ -730,38 +739,16 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
730
739
|
*/
|
|
731
740
|
protected getTenantField(): string | undefined;
|
|
732
741
|
/**
|
|
733
|
-
* Build the canonical repo-options bag
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
* `
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
* - **Tenant scope** — `[tenantField]: orgId` from `RequestScope`.
|
|
741
|
-
* Plugin-scoped repos (mongokit's `multiTenantPlugin`) read tenant
|
|
742
|
-
* scope from the TOP of the options bag, not `data.organizationId`.
|
|
743
|
-
* Without this stamping, a tenant-scoped repo throws "Missing
|
|
744
|
-
* 'organizationId' in context" even when arc has injected the
|
|
745
|
-
* tenant into the request body.
|
|
746
|
-
* Multi-field tenancy from `_tenantFields` (populated by
|
|
747
|
-
* `multiTenantPreset`) is merged in.
|
|
748
|
-
*
|
|
749
|
-
* - **Audit attribution** — `userId` + `user` from the authenticated
|
|
750
|
-
* actor. Mongokit's audit-log / audit-trail plugins read these
|
|
751
|
-
* into the `who` column; sqlitekit's audit plugin reads the same
|
|
752
|
-
* names. No host-side forwarding needed.
|
|
753
|
-
*
|
|
754
|
-
* - **Trace correlation** — `requestId` from Fastify's request id
|
|
755
|
-
* for stitching logs / events / downstream calls.
|
|
756
|
-
*
|
|
757
|
-
* - **`session` is intentionally NOT auto-set.** Sessions are tied
|
|
758
|
-
* to explicit transaction scopes the controller doesn't manage;
|
|
759
|
-
* pass `session` inline at the call site when running inside a
|
|
760
|
-
* `withTransaction` helper.
|
|
742
|
+
* Build the canonical repo-options bag (tenant scope, audit
|
|
743
|
+
* attribution, trace correlation) from the Fastify request. Full
|
|
744
|
+
* contract + rationale on `buildTenantRepoOptions` in
|
|
745
|
+
* `crud/requestPipeline.ts` — this delegate exists so host overrides
|
|
746
|
+
* and duck-typed consumers (aggregation router, MCP bridge) keep the
|
|
747
|
+
* same `protected` entry point.
|
|
761
748
|
*
|
|
762
749
|
* Method kept named `tenantRepoOptions` for back-compat with hosts
|
|
763
750
|
* that spread `...this.tenantRepoOptions(req)` (10+ call sites in
|
|
764
|
-
* arc, plus host overrides). The bag has always grown over time
|
|
751
|
+
* arc, plus host overrides). The bag has always grown over time —
|
|
765
752
|
* hosts that don't want audit forwarding never read those keys.
|
|
766
753
|
*/
|
|
767
754
|
protected tenantRepoOptions(req: IRequestContext): AnyRecord;
|
|
@@ -770,15 +757,10 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
770
757
|
/** Get hook system from request context (instance-scoped) */
|
|
771
758
|
protected getHooks(req: IRequestContext): HookSystem | null;
|
|
772
759
|
/**
|
|
773
|
-
* Resolve the repository primary key for mutation calls.
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
*
|
|
777
|
-
* because most Mongo repositories key mutation methods off `_id`.
|
|
778
|
-
*
|
|
779
|
-
* Exception: if the repo exposes a matching `idField` property (e.g.
|
|
780
|
-
* MongoKit's `new Repository(Model, [], {}, { idField: 'id' })`), the
|
|
781
|
-
* repo handles lookup itself — pass the route id through unchanged.
|
|
760
|
+
* Resolve the repository primary key for mutation calls. Translates a
|
|
761
|
+
* custom route `idField` (slug, jobId, UUID) to the fetched doc's `_id`
|
|
762
|
+
* unless the repo declares a matching `idField` of its own — see
|
|
763
|
+
* `resolveMutationRepoId` in `crud/requestPipeline.ts`.
|
|
782
764
|
*/
|
|
783
765
|
protected resolveRepoId(id: string, existing: AnyRecord | null): string;
|
|
784
766
|
/**
|
|
@@ -828,23 +810,14 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
828
810
|
* or `null` — every truthy non-null shape collapses to `true`.
|
|
829
811
|
*/
|
|
830
812
|
protected isExistsTruthy(result: unknown): boolean;
|
|
813
|
+
/** Assemble the per-request hook context from the protected accessors. */
|
|
814
|
+
private hookOpContext;
|
|
831
815
|
/**
|
|
832
816
|
* Run `executeBefore` then `executeAround` (or just the executor if no
|
|
833
817
|
* hooks are wired). Returns the around-phase result directly. Throws an
|
|
834
818
|
* `ArcError` (status 400, code `BEFORE_<OP>_HOOK_ERROR`) when the
|
|
835
|
-
* before-hook fails
|
|
836
|
-
* `
|
|
837
|
-
*
|
|
838
|
-
* The caller runs `executeAfter` separately via `runAfterHook` — typically
|
|
839
|
-
* after success-checking the result (delete checks `isDeleteSuccess`,
|
|
840
|
-
* update checks `if (!item)`).
|
|
841
|
-
*
|
|
842
|
-
* **Knobs:**
|
|
843
|
-
* - `meta` — passed verbatim into `executeBefore` / `executeAround` opts.
|
|
844
|
-
* - `pipeProcessedData` (default `true`) — whether `executeBefore`'s
|
|
845
|
-
* return value flows into `executeAround` as the data parameter.
|
|
846
|
-
* Set `false` for delete (current behaviour: discards before's
|
|
847
|
-
* return, passes original input to around).
|
|
819
|
+
* before-hook fails. Full contract on `executeHookedOp` in
|
|
820
|
+
* `crud/requestPipeline.ts`.
|
|
848
821
|
*/
|
|
849
822
|
protected runHookedOpUntilResult<TInput, TResult>(req: IRequestContext, args: {
|
|
850
823
|
op: "create" | "update" | "delete";
|
|
@@ -868,26 +841,27 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
868
841
|
* Resource-dispatch verbs router. Returns `null` when the request is
|
|
869
842
|
* a regular list query, otherwise returns the dispatch promise.
|
|
870
843
|
*
|
|
871
|
-
* Verbs (mutually exclusive
|
|
872
|
-
* - `?_count=true`
|
|
873
|
-
* - `?_distinct=field`
|
|
874
|
-
* - `?_exists=true`
|
|
844
|
+
* Verbs (mutually exclusive — first match wins):
|
|
845
|
+
* - `?_count=true` → `{ count: number }` via `repo.count()`
|
|
846
|
+
* - `?_distinct=field` → `unknown[]` via `repo.distinct(field)`
|
|
847
|
+
* - `?_exists=true` → `{ exists: boolean }` via `repo.exists()`
|
|
875
848
|
*
|
|
876
849
|
* All verbs share the resolved filter (parsed query + policy filters
|
|
877
850
|
* + tenant scope). Adapters that don't ship the underlying repo
|
|
878
851
|
* method get a `501` so failures surface loudly instead of falling
|
|
879
|
-
* back to a full table scan.
|
|
852
|
+
* back to a full table scan. Matching + repo invocation live in
|
|
853
|
+
* `crud/resourceVerbs.ts`.
|
|
880
854
|
*/
|
|
881
855
|
protected dispatchResourceVerb(req: IRequestContext): Promise<IControllerResponse<unknown>> | null;
|
|
882
856
|
/** Resolve filter + tenant/audit options for a dispatch verb. */
|
|
883
857
|
private resolveDispatchScope;
|
|
884
|
-
/** `?_count=true`
|
|
858
|
+
/** `?_count=true` → `repo.count(filter)` */
|
|
885
859
|
protected dispatchCount(req: IRequestContext): Promise<IControllerResponse<{
|
|
886
860
|
count: number;
|
|
887
861
|
}>>;
|
|
888
|
-
/** `?_distinct=field`
|
|
862
|
+
/** `?_distinct=field` → `repo.distinct(field, filter)` */
|
|
889
863
|
protected dispatchDistinct(req: IRequestContext, field: string): Promise<IControllerResponse<unknown[]>>;
|
|
890
|
-
/** `?_exists=true`
|
|
864
|
+
/** `?_exists=true` → `repo.exists(filter)` */
|
|
891
865
|
protected dispatchExists(req: IRequestContext): Promise<IControllerResponse<{
|
|
892
866
|
exists: boolean;
|
|
893
867
|
}>>;
|
|
@@ -4059,4 +4033,4 @@ interface ValidateOptions {
|
|
|
4059
4033
|
strict?: boolean;
|
|
4060
4034
|
}
|
|
4061
4035
|
//#endregion
|
|
4062
|
-
export { OnTenantDeleteConfig as $, BaseController as $t, RequestIdOptions as A,
|
|
4036
|
+
export { OnTenantDeleteConfig as $, BaseController as $t, RequestIdOptions as A, ArcDeleteResult as An, AggregationRateLimit as At, defineResource as B, AuthHelpers as Bt, RequestContext as C, afterUpdate as Cn, AggMeasureShorthand as Ct, HealthCheck as D, createHookSystem as Dn, AggregationIndexHint as Dt, GracefulShutdownOptions as E, beforeUpdate as En, AggregationDateRangeRequirement as Et, FastifyWithDecorators as F, ControllerConfigurableOptions as Fn, OperationFilter as Ft, ActionsMap as G, TokenPair as Gt, ActionDefinition as H, Authenticator as Ht, MiddlewareHandler as I, ControllerConstructionOptions as In, PipelineConfig as It, CrudRouteKey as J, ArcRequest as Jt, ArcFieldRule as K, AnyRecord as Kt, RequestWithExtras as L, ListResult as Ln, PipelineContext as Lt, EventsDecorator as M, ArcListResult as Mn, Guard as Mt, FastifyRequestExtras as N, ArcUpdateResult as Nn, Interceptor as Nt, HealthOptions as O, defineHook as On, AggregationMaterializedContext as Ot, FastifyWithAuth as P, BaseControllerOptions as Pn, NextFunction as Pt, MiddlewareConfig as Q, UserOrganization as Qt, RegisterOptions as R, BodySanitizer as Rn, PipelineStep as Rt, QueryParserInterface as S, afterDelete as Sn, AggMeasureInput as St, CrudRouterOptions as T, beforeDelete as Tn, AggregationConfig as Tt, ActionEntry as U, AuthenticatorContext as Ut, ResourceDefinition as V, AuthPluginOptions as Vt, ActionHandlerFn as W, JwtContext as Wt, EventDefinition as X, ObjectId as Xt, CrudSchemas as Y, JWTPayload as Yt, FieldRule$1 as Z, UserLike as Zt, ControllerQueryOptions as _, HookPhase as _n, FastifyHandler as _t, InferAdapterDoc as a, SlugMixin as an, ResolvedTenantPurge as at, ParsedQuery as b, HookSystemOptions as bn, IRequestContext as bt, TypedController as c, BaseCrudController as cn, ResourceHookContext as ct, PaginationResult as d, AccessControl as dn, RouteDefinition as dt, SoftDeleteExt as en, OpenApiSchemas as et, IntrospectionData as f, AccessControlConfig as fn, RouteMcpConfig as ft, ArcInternalMetadata as g, HookOperation as gn, ControllerLike as gt, ResourceMetadata as h, HookHandler as hn, ControllerHandler as ht, ValidationResult as i, SlugExt as in, RateLimitConfig as it, ArcDecorator as j, ArcGetResult as jn, AggregationsMap as jt, IntrospectionPluginOptions as k, ArcCreateResult as kn, AggregationMaterializedResult as kt, TypedRepository as l, QueryResolver as ln, ResourceHooks as lt, RegistryStats as m, HookContext as mn, RouteSchemaOptions as mt, ConfigError as n, TreeExt as nn, PresetHook as nt, InferDocType as o, BulkExt as on, ResourceCacheConfig as ot, RegistryEntry as p, DefineHookOptions as pn, RouteMethod as pt, CrudController as q, ApiResponse as qt, ValidateOptions as r, TreeMixin as rn, PresetResult as rt, InferResourceDoc as s, BulkMixin as sn, ResourceConfig as st, RouteHandlerMethod$1 as t, SoftDeleteMixin as tn, PresetFunction as tt, TypedResourceConfig as u, QueryResolverConfig as un, ResourcePermissions as ut, LookupOption as v, HookRegistration as vn, IController as vt, ServiceContext as w, beforeCreate as wn, AggregationCacheConfig as wt, PopulateOption as x, afterCreate as xn, RouteHandler as xt, OwnershipCheck as y, HookSystem as yn, IControllerResponse as yt, ResourceRegistry as z, BodySanitizerConfig as zn, Transform as zt };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as CacheStore, t as CacheLogger } from "./interface-
|
|
2
|
-
import { i as RequestScope, n as Mandate } from "./types-
|
|
3
|
-
import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-
|
|
1
|
+
import { r as CacheStore, t as CacheLogger } from "./interface-DL7LlWS5.mjs";
|
|
2
|
+
import { i as RequestScope, n as Mandate } from "./types-BJwJN2Pg.mjs";
|
|
3
|
+
import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-CKLrhyOb.mjs";
|
|
4
4
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/permissions/agent.d.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $t as BaseController, A as RequestIdOptions, At as AggregationRateLimit, B as defineResource, C as RequestContext, Ct as AggMeasureShorthand, D as HealthCheck, Dt as AggregationIndexHint, E as GracefulShutdownOptions, Et as AggregationDateRangeRequirement, F as FastifyWithDecorators, J as CrudRouteKey, Jt as ArcRequest, Kt as AnyRecord, L as RequestWithExtras, N as FastifyRequestExtras, O as HealthOptions, Ot as AggregationMaterializedContext, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, St as AggMeasureInput, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, Vt as AuthPluginOptions, X as EventDefinition, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule,
|
|
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-
|
|
3
|
-
import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-
|
|
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-
|
|
5
|
-
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-
|
|
1
|
+
import { $t as BaseController, A as RequestIdOptions, An as ArcDeleteResult, At as AggregationRateLimit, B as defineResource, C as RequestContext, Ct as AggMeasureShorthand, D as HealthCheck, Dt as AggregationIndexHint, E as GracefulShutdownOptions, Et as AggregationDateRangeRequirement, F as FastifyWithDecorators, Fn as ControllerConfigurableOptions, In as ControllerConstructionOptions, J as CrudRouteKey, Jt as ArcRequest, Kt as AnyRecord, L as RequestWithExtras, Ln as ListResult, Mn as ArcListResult, N as FastifyRequestExtras, Nn as ArcUpdateResult, O as HealthOptions, Ot as AggregationMaterializedContext, P as FastifyWithAuth, Pn as BaseControllerOptions, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, St as AggMeasureInput, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, Vt as AuthPluginOptions, X as EventDefinition, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule, a as InferAdapterDoc, an as SlugMixin, bt as IRequestContext, c as TypedController, cn as BaseCrudController, d as PaginationResult, en as SoftDeleteExt, f as IntrospectionData, g as ArcInternalMetadata, gt as ControllerLike, h as ResourceMetadata, i as ValidationResult, in as SlugExt, it as RateLimitConfig, jn as ArcGetResult, jt as AggregationsMap, k as IntrospectionPluginOptions, kn as ArcCreateResult, kt as AggregationMaterializedResult, l as TypedRepository, m as RegistryStats, mt as RouteSchemaOptions, n as ConfigError, nn as TreeExt, o as InferDocType, on as BulkExt, p as RegistryEntry, q as CrudController, qt as ApiResponse, r as ValidateOptions, rn as TreeMixin, rt as PresetResult, s as InferResourceDoc, sn as BulkMixin, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteMixin, tt as PresetFunction, u as TypedResourceConfig, vt as IController, w as ServiceContext, wt as AggregationCacheConfig, xt as RouteHandler, y as OwnershipCheck, yt as IControllerResponse } from "./index-QYma8mdC.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-CKLrhyOb.mjs";
|
|
3
|
+
import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-Cvo1u9n6.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-vcWUGkwf.mjs";
|
|
5
|
+
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DZOemeGa.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/index.d.ts
|
|
8
8
|
declare const version: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-TrJVIJl0.mjs";
|
|
2
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 { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-
|
|
4
|
-
import { C as requireAuth, D as when,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-B-uXzf6I.mjs";
|
|
4
|
+
import { C as requireAuth, D as when, F as applyFieldWritePermissions, I as fields, P as applyFieldReadPermissions, 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, 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-3uzwkbQt.mjs";
|
|
5
|
+
import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-C88uIwd3.mjs";
|
|
6
|
+
import { c as getControllerScope } from "./pipeline-D4sqiokR.mjs";
|
|
7
7
|
//#region src/index.ts
|
|
8
|
-
const version = "2.18.
|
|
8
|
+
const version = "2.18.3";
|
|
9
9
|
//#endregion
|
|
10
10
|
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, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
|
|
@@ -917,9 +917,9 @@ ${config.adapter === "mongokit" ? ` await mongoose.connection.collection('use
|
|
|
917
917
|
//#region src/cli/commands/init/dependency-plan.ts
|
|
918
918
|
const SCAFFOLD_DEP_VERSIONS = {
|
|
919
919
|
core: {
|
|
920
|
-
"@classytic/arc": "^2.
|
|
920
|
+
"@classytic/arc": "^2.18.3",
|
|
921
921
|
"@classytic/primitives": "^0.6.0",
|
|
922
|
-
"@classytic/repo-core": "^0.
|
|
922
|
+
"@classytic/repo-core": "^0.6.0",
|
|
923
923
|
"@fastify/cors": "^11.2.0",
|
|
924
924
|
"@fastify/helmet": "^13.0.2",
|
|
925
925
|
"@fastify/rate-limit": "^10.3.0",
|
|
@@ -938,7 +938,7 @@ const SCAFFOLD_DEP_VERSIONS = {
|
|
|
938
938
|
},
|
|
939
939
|
authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
|
|
940
940
|
adapterMongokit: {
|
|
941
|
-
"@classytic/mongokit": "^3.
|
|
941
|
+
"@classytic/mongokit": "^3.16.0",
|
|
942
942
|
mongoose: "^9.6.2"
|
|
943
943
|
},
|
|
944
944
|
devCommon: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as DomainEvent } from "../EventTransport-
|
|
2
|
-
import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-
|
|
1
|
+
import { n as DomainEvent } from "../EventTransport-CaaXM5Y1.mjs";
|
|
2
|
+
import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-BFBT5rH-.mjs";
|
|
3
3
|
import { FastifyPluginAsync, FastifyRequest } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/integrations/event-gateway.d.ts
|
|
@@ -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-
|
|
7
|
+
const { default: ssePlugin } = await import("../sse-Xq8UtuQx.mjs").then((n) => n.r);
|
|
8
8
|
await fastify.register(ssePlugin, {
|
|
9
9
|
path: opts.sse?.path ?? "/events/stream",
|
|
10
10
|
requireAuth: auth,
|