@classytic/arc 2.6.3 → 2.7.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/README.md +98 -3
- package/dist/{BaseController-DzRtluEF.mjs → BaseController-CpMfCXdn.mjs} +134 -16
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +1 -1
- package/dist/{adapters-gM-WYjNe.mjs → adapters-BxGgSHjj.mjs} +1 -9
- package/dist/applyPermissionResult-D6GPMsvh.mjs +37 -0
- package/dist/audit/index.d.mts +1 -1
- package/dist/audit/index.mjs +1 -1
- package/dist/audit/mongodb.d.mts +1 -1
- package/dist/audit/mongodb.mjs +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +7 -6
- package/dist/auth/mongoose.d.mts +191 -0
- package/dist/auth/mongoose.mjs +73 -0
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-lz0IRbXJ.mjs → betterAuthOpenApi-CCw3YX0g.mjs} +1 -1
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +7 -5
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-C1XCMtqM.mjs → core-BWekSEju.mjs} +41 -13
- package/dist/{createApp-D2w0LdYJ.mjs → createApp-D7e77m8C.mjs} +25 -14
- package/dist/{defineResource-wWMBB4GP.mjs → defineResource-DZzyl4a4.mjs} +42 -37
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/dynamic/index.d.mts +2 -2
- package/dist/dynamic/index.mjs +2 -2
- package/dist/{elevation-BEdACOLB.mjs → elevation-By_p2lnn.mjs} +1 -1
- package/dist/elevation-D7WK0RXq.d.mts +23 -0
- package/dist/{errorHandler-r2595m8T.mjs → errorHandler-CH8wk1eD.mjs} +17 -2
- package/dist/{errorHandler-Do4vVQ1f.d.mts → errorHandler-pCpEtNd7.d.mts} +46 -2
- package/dist/{eventPlugin-Ba00swHF.mjs → eventPlugin-B6U_nCFU.mjs} +4 -3
- package/dist/{eventPlugin-DW45v4V5.d.mts → eventPlugin-CdvUoUna.d.mts} +1 -1
- package/dist/events/index.d.mts +3 -3
- package/dist/events/index.mjs +1 -1
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +3 -3
- package/dist/idempotency/mongodb.d.mts +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/index-B0extFr4.d.mts +640 -0
- package/dist/{index-gz6iuzCp.d.mts → index-BjShrzoj.d.mts} +47 -4
- package/dist/{index-CHeJa4Zd.d.mts → index-C9eYNjGR.d.mts} +1 -1
- package/dist/index.d.mts +9 -8
- package/dist/index.mjs +10 -9
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +2 -2
- package/dist/integrations/mcp/index.mjs +8 -5
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/webhooks.d.mts +58 -1
- package/dist/integrations/webhooks.mjs +78 -7
- package/dist/integrations/websocket.d.mts +7 -1
- package/dist/integrations/websocket.mjs +7 -1
- package/dist/{interface-DYH8AXGe.d.mts → interface-B91alUzq.d.mts} +151 -15
- package/dist/{mongodb-pMvOlR5_.d.mts → mongodb-B7zupyck.d.mts} +1 -1
- package/dist/{mongodb-kltrBPa1.d.mts → mongodb-Cgu9F1Nd.d.mts} +1 -1
- package/dist/{openapi-CBmZ6EQN.mjs → openapi-BBSTVcMm.mjs} +1 -1
- package/dist/org/index.d.mts +2 -2
- package/dist/org/index.mjs +1 -1
- package/dist/permissions/index.d.mts +4 -4
- package/dist/permissions/index.mjs +3 -2
- package/dist/{permissions-C8ImI8gC.mjs → permissions-CH4cNwJi.mjs} +358 -64
- package/dist/plugins/index.d.mts +52 -5
- package/dist/plugins/index.mjs +12 -11
- 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/policies/index.d.mts +1 -1
- package/dist/presets/index.d.mts +3 -3
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +53 -3
- package/dist/presets/multiTenant.mjs +89 -47
- package/dist/{presets-BMfdy34e.mjs → presets-BFrGvvjL.mjs} +2 -2
- package/dist/{queryCachePlugin-DcmETvcB.d.mts → queryCachePlugin-Ckl71mkc.d.mts} +1 -1
- package/dist/{queryCachePlugin-XtFplYO9.mjs → queryCachePlugin-CwTpR04-.mjs} +2 -2
- package/dist/{redis-D0Qc-9EW.d.mts → redis-3TQxm2VZ.d.mts} +1 -1
- package/dist/{redis-stream-BW9UKLZM.d.mts → redis-stream-Dag5LFa9.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/replyHelpers-uDUIYh7u.mjs +40 -0
- package/dist/{resourceToTools-nCJWnG1r.mjs → resourceToTools-BJkoQoUP.mjs} +74 -25
- package/dist/rpc/index.d.mts +1 -1
- package/dist/rpc/index.mjs +1 -1
- package/dist/scope/index.d.mts +3 -2
- package/dist/scope/index.mjs +4 -3
- package/dist/{sse-BF7GR7IB.mjs → sse-6W0hjVS_.mjs} +2 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +1 -1
- package/dist/types/index.d.mts +4 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types--D3vvfdt.d.mts +286 -0
- package/dist/{types-By-5mIfn.d.mts → types-2FlNl0mL.d.mts} +44 -9
- package/dist/types-AOD8fxIw.mjs +229 -0
- package/dist/types-B4BNthET.d.mts +178 -0
- package/dist/{types-B4_TDdPe.d.mts → types-C5g2oRC7.d.mts} +18 -2
- package/dist/utils/index.d.mts +3 -3
- package/dist/utils/index.mjs +5 -5
- package/package.json +21 -6
- package/skills/arc/SKILL.md +314 -6
- package/skills/arc/references/integrations.md +32 -7
- package/skills/arc/references/mcp.md +31 -7
- package/skills/arc/references/multi-tenancy.md +208 -0
- package/skills/arc/references/production.md +69 -0
- package/dist/elevation-C_taLQrM.d.mts +0 -147
- package/dist/index-NGZksqM5.d.mts +0 -398
- package/dist/types-BNUccdcf.d.mts +0 -101
- package/dist/types-BhtYdxZU.mjs +0 -91
- /package/dist/{EventTransport-wc5hSLik.d.mts → EventTransport-C4VheKeC.d.mts} +0 -0
- /package/dist/{HookSystem-COkyWztM.mjs → HookSystem-D7lfx--K.mjs} +0 -0
- /package/dist/{ResourceRegistry-C6ngvOnn.mjs → ResourceRegistry-DsHiG9cL.mjs} +0 -0
- /package/dist/{caching-BSXB-Xr7.mjs → caching-5DtLwIqb.mjs} +0 -0
- /package/dist/{circuitBreaker-JP2GdJ4b.d.mts → circuitBreaker-BBPDt-J_.d.mts} +0 -0
- /package/dist/{circuitBreaker-BOBOpN2w.mjs → circuitBreaker-l18oRgL5.mjs} +0 -0
- /package/dist/{errors-CcVbl1-T.d.mts → errors-BS6lZvWy.d.mts} +0 -0
- /package/dist/{errors-NoQKsbAT.mjs → errors-Cg58SLNi.mjs} +0 -0
- /package/dist/{externalPaths-DpO-s7r8.d.mts → externalPaths-iba7jD3d.d.mts} +0 -0
- /package/dist/{fields-DFwdaWCq.d.mts → fields-D4nMDqnK.d.mts} +0 -0
- /package/dist/{interface-D_BWALyZ.d.mts → interface-CG7oRZjX.d.mts} +0 -0
- /package/dist/{interface-gr-7qo9j.d.mts → interface-CSbZdv_3.d.mts} +0 -0
- /package/dist/{logger-Dz3j1ItV.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{memory-BFAYkf8H.mjs → memory-Cp7_cAko.mjs} +0 -0
- /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
- /package/dist/{mongodb-BuQ7fNTg.mjs → mongodb-B7X7P1P8.mjs} +0 -0
- /package/dist/{pluralize-CcT6qF0a.mjs → pluralize-Dckfq6US.mjs} +0 -0
- /package/dist/{registry-I-ogLgL9.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{schemaConverter-DjzHpFam.mjs → schemaConverter-0TyONAwM.mjs} +0 -0
- /package/dist/{sessionManager-wbkYj2HL.d.mts → sessionManager-CEo9jwPI.d.mts} +0 -0
- /package/dist/{tracing-bz_U4EM1.d.mts → tracing-DEqdGkr-.d.mts} +0 -0
- /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{utils-Dc0WhlIl.mjs → utils-B-l6410F.mjs} +0 -0
- /package/dist/{versioning-BzfeHmhj.mjs → versioning-CdBbFefk.mjs} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as FieldPermissionMap } from "./fields-
|
|
3
|
-
import { i as UserBase, t as PermissionCheck } from "./types-
|
|
1
|
+
import { r as RequestScope } from "./types--D3vvfdt.mjs";
|
|
2
|
+
import { n as FieldPermissionMap } from "./fields-D4nMDqnK.mjs";
|
|
3
|
+
import { i as UserBase, t as PermissionCheck } from "./types-B4BNthET.mjs";
|
|
4
4
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/hooks/HookSystem.d.ts
|
|
@@ -618,17 +618,54 @@ interface ServerAccessor {
|
|
|
618
618
|
};
|
|
619
619
|
}
|
|
620
620
|
/**
|
|
621
|
-
* Request context passed to controller handlers
|
|
621
|
+
* Request context passed to controller handlers.
|
|
622
|
+
*
|
|
623
|
+
* **Generic parameters** (all default to safe permissive types so existing code keeps working):
|
|
624
|
+
* - `TBody` — request body shape (default: `unknown`)
|
|
625
|
+
* - `TParams` — route param shape (default: `Record<string, string>`)
|
|
626
|
+
* - `TQuery` — query string shape (default: `Record<string, unknown>`)
|
|
627
|
+
* - `TUser` — authenticated user shape (default: `UserBase`)
|
|
628
|
+
* - `TMetadata` — internal metadata shape (default: `Record<string, unknown>`;
|
|
629
|
+
* override with `ArcInternalMetadata` or your own augmentation when you
|
|
630
|
+
* need typed access to `_scope`, `_policyFilters`, custom hook context, etc.)
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```typescript
|
|
634
|
+
* // Untyped (default) — req.body is `unknown`, must be narrowed
|
|
635
|
+
* async create(req: IRequestContext) {
|
|
636
|
+
* const data = req.body as Partial<Product>;
|
|
637
|
+
* return { success: true, data: await productRepo.create(data) };
|
|
638
|
+
* }
|
|
639
|
+
*
|
|
640
|
+
* // Typed body — req.body is `CreateProductInput`, narrowing not needed
|
|
641
|
+
* async create(req: IRequestContext<CreateProductInput>) {
|
|
642
|
+
* return { success: true, data: await productRepo.create(req.body) };
|
|
643
|
+
* }
|
|
644
|
+
*
|
|
645
|
+
* // Fully typed — body, route params, query, and metadata
|
|
646
|
+
* async update(
|
|
647
|
+
* req: IRequestContext<
|
|
648
|
+
* Partial<Product>,
|
|
649
|
+
* { id: string },
|
|
650
|
+
* { fields?: string },
|
|
651
|
+
* ArcInternalMetadata
|
|
652
|
+
* >,
|
|
653
|
+
* ) {
|
|
654
|
+
* const fields = req.query.fields?.split(',');
|
|
655
|
+
* const orgId = req.metadata?._scope ? getOrgId(req.metadata._scope) : undefined;
|
|
656
|
+
* return { success: true, data: await productRepo.update(req.params.id, req.body) };
|
|
657
|
+
* }
|
|
658
|
+
* ```
|
|
622
659
|
*/
|
|
623
|
-
interface IRequestContext {
|
|
660
|
+
interface IRequestContext<TBody = unknown, TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, unknown> = Record<string, unknown>, TUser extends UserBase = UserBase, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
|
|
624
661
|
/** Route parameters (e.g., { id: '123' }) */
|
|
625
|
-
params:
|
|
662
|
+
params: TParams;
|
|
626
663
|
/** Query string parameters */
|
|
627
|
-
query:
|
|
664
|
+
query: TQuery;
|
|
628
665
|
/** Request body */
|
|
629
|
-
body:
|
|
666
|
+
body: TBody;
|
|
630
667
|
/** Authenticated user or null */
|
|
631
|
-
user:
|
|
668
|
+
user: TUser | null;
|
|
632
669
|
/** Request headers */
|
|
633
670
|
headers: Record<string, string | undefined>;
|
|
634
671
|
/** Organization ID (for multi-tenant apps) */
|
|
@@ -649,8 +686,12 @@ interface IRequestContext {
|
|
|
649
686
|
* ```
|
|
650
687
|
*/
|
|
651
688
|
context?: RequestContext;
|
|
652
|
-
/**
|
|
653
|
-
|
|
689
|
+
/**
|
|
690
|
+
* Internal metadata (includes context + Arc internals like `_policyFilters`,
|
|
691
|
+
* `_scope`, `log`). Type as `ArcInternalMetadata` for typed access to Arc's
|
|
692
|
+
* built-in fields, or supply your own interface to layer custom fields.
|
|
693
|
+
*/
|
|
694
|
+
metadata?: TMetadata;
|
|
654
695
|
/**
|
|
655
696
|
* Fastify server accessor — publish events, log, and audit
|
|
656
697
|
* from any handler without switching to `wrapHandler: false`.
|
|
@@ -686,18 +727,41 @@ interface IControllerResponse<T = unknown> {
|
|
|
686
727
|
headers?: Record<string, string>;
|
|
687
728
|
}
|
|
688
729
|
/**
|
|
689
|
-
* Controller handler
|
|
730
|
+
* Controller handler — Arc's standard pattern.
|
|
690
731
|
*
|
|
691
732
|
* Receives a request context object, returns IControllerResponse.
|
|
692
733
|
* Use with `wrapHandler: true` in additionalRoutes.
|
|
693
734
|
*
|
|
735
|
+
* **Generic parameters:**
|
|
736
|
+
* - `TResponse` — shape of `IControllerResponse.data` (default: `unknown`)
|
|
737
|
+
* - `TBody` — shape of `req.body` (default: `unknown`)
|
|
738
|
+
* - `TParams` — shape of `req.params` (default: `Record<string, string>`)
|
|
739
|
+
* - `TQuery` — shape of `req.query` (default: `Record<string, unknown>`)
|
|
740
|
+
*
|
|
741
|
+
* Backward-compatible: `ControllerHandler<Product>` still works (only the
|
|
742
|
+
* response data is typed); add more generics as needed when you want
|
|
743
|
+
* type-safe access to the request body, params, or query string.
|
|
744
|
+
*
|
|
694
745
|
* @example
|
|
695
746
|
* ```typescript
|
|
747
|
+
* // Untyped req — body is unknown, must be narrowed
|
|
696
748
|
* const createProduct: ControllerHandler<Product> = async (req) => {
|
|
697
|
-
* const product = await productRepo.create(req.body);
|
|
749
|
+
* const product = await productRepo.create(req.body as Partial<Product>);
|
|
698
750
|
* return { success: true, data: product, status: 201 };
|
|
699
751
|
* };
|
|
700
752
|
*
|
|
753
|
+
* // Fully typed — body, params, query, and response all inferred
|
|
754
|
+
* const updateProduct: ControllerHandler<
|
|
755
|
+
* Product,
|
|
756
|
+
* Partial<Product>,
|
|
757
|
+
* { id: string },
|
|
758
|
+
* { upsert?: string }
|
|
759
|
+
* > = async (req) => {
|
|
760
|
+
* const upsert = req.query.upsert === "true";
|
|
761
|
+
* const product = await productRepo.update(req.params.id, req.body, { upsert });
|
|
762
|
+
* return { success: true, data: product };
|
|
763
|
+
* };
|
|
764
|
+
*
|
|
701
765
|
* additionalRoutes: [{
|
|
702
766
|
* method: 'POST',
|
|
703
767
|
* path: '/products',
|
|
@@ -707,7 +771,7 @@ interface IControllerResponse<T = unknown> {
|
|
|
707
771
|
* }]
|
|
708
772
|
* ```
|
|
709
773
|
*/
|
|
710
|
-
type ControllerHandler<
|
|
774
|
+
type ControllerHandler<TResponse = unknown, TBody = unknown, TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, unknown> = Record<string, unknown>> = (req: IRequestContext<TBody, TParams, TQuery>) => Promise<IControllerResponse<TResponse>>;
|
|
711
775
|
/**
|
|
712
776
|
* Fastify native handler
|
|
713
777
|
*
|
|
@@ -731,7 +795,7 @@ type ControllerHandler<T = unknown> = (req: IRequestContext) => Promise<IControl
|
|
|
731
795
|
* }]
|
|
732
796
|
* ```
|
|
733
797
|
*/
|
|
734
|
-
type FastifyHandler = (request: FastifyRequest
|
|
798
|
+
type FastifyHandler<RouteGeneric extends Record<string, unknown> = Record<string, unknown>> = (request: FastifyRequest<RouteGeneric>, reply: FastifyReply) => Promise<unknown> | unknown;
|
|
735
799
|
/**
|
|
736
800
|
* Union type for route handlers
|
|
737
801
|
*/
|
|
@@ -951,6 +1015,14 @@ interface BaseControllerOptions {
|
|
|
951
1015
|
tenantField?: string | false;
|
|
952
1016
|
/**
|
|
953
1017
|
* Primary key field name (default: '_id').
|
|
1018
|
+
*
|
|
1019
|
+
* If not set, the controller auto-derives it from the repository's own
|
|
1020
|
+
* `idField` property (e.g. MongoKit's `Repository({ idField: 'id' })`),
|
|
1021
|
+
* so you only need to configure it in one place.
|
|
1022
|
+
*
|
|
1023
|
+
* Set explicitly to override the repo's setting (e.g. `'_id'` to opt out
|
|
1024
|
+
* of native pass-through and force the slug-translation path).
|
|
1025
|
+
*
|
|
954
1026
|
* Override for non-MongoDB adapters (e.g., 'id' for SQL databases).
|
|
955
1027
|
*/
|
|
956
1028
|
idField?: string;
|
|
@@ -1010,6 +1082,23 @@ declare class BaseController<TDoc = AnyRecord, TRepository extends RepositoryLik
|
|
|
1010
1082
|
private meta;
|
|
1011
1083
|
/** Get hook system from request context (instance-scoped) */
|
|
1012
1084
|
private getHooks;
|
|
1085
|
+
/**
|
|
1086
|
+
* Resolve the repository primary key for mutation calls (update/delete/restore).
|
|
1087
|
+
*
|
|
1088
|
+
* When the resource declares a custom `idField` (e.g. `slug`, `jobId`, UUID),
|
|
1089
|
+
* the default behavior is to translate the route id → the fetched doc's `_id`
|
|
1090
|
+
* because most Mongo repositories key their mutation methods off `_id`.
|
|
1091
|
+
*
|
|
1092
|
+
* Exception: if the repository itself exposes a matching `idField` property
|
|
1093
|
+
* (e.g. MongoKit's `new Repository(Model, [], {}, { idField: 'id' })`), the
|
|
1094
|
+
* repository already knows how to look up by that field — so we pass the
|
|
1095
|
+
* route id through unchanged and skip the translation.
|
|
1096
|
+
*
|
|
1097
|
+
* This makes `defineResource({ idField: 'id' })` work end-to-end with repos
|
|
1098
|
+
* that natively support custom primary keys, without breaking the slug-style
|
|
1099
|
+
* aliasing that Arc 2.6.3 introduced for repos keyed on `_id`.
|
|
1100
|
+
*/
|
|
1101
|
+
private resolveRepoId;
|
|
1013
1102
|
/** Resolve cache config for a specific operation, merging per-op overrides */
|
|
1014
1103
|
private resolveCacheConfig;
|
|
1015
1104
|
/**
|
|
@@ -1056,10 +1145,43 @@ declare class BaseController<TDoc = AnyRecord, TRepository extends RepositoryLik
|
|
|
1056
1145
|
* Returns the merged filter, or `null` when access must be denied.
|
|
1057
1146
|
*/
|
|
1058
1147
|
private buildBulkFilter;
|
|
1148
|
+
/**
|
|
1149
|
+
* Sanitize a bulk update data payload through the same write-permission
|
|
1150
|
+
* pipeline as single-doc update(). Handles both shapes:
|
|
1151
|
+
*
|
|
1152
|
+
* - Flat: `{ name: 'x', status: 'y' }`
|
|
1153
|
+
* - Mongo operator: `{ $set: { name: 'x' }, $inc: { views: 1 }, $unset: { tag: '' } }`
|
|
1154
|
+
*
|
|
1155
|
+
* For each operand, runs `bodySanitizer.sanitize('update', ...)` so that
|
|
1156
|
+
* system fields, systemManaged/readonly/immutable rules, AND field-level
|
|
1157
|
+
* write permissions are enforced. Without this, a tenant-scoped user could
|
|
1158
|
+
* pass `{ $set: { organizationId: 'org-b' } }` to move records across orgs.
|
|
1159
|
+
*
|
|
1160
|
+
* Returns the sanitized payload along with the list of stripped fields for
|
|
1161
|
+
* audit/error reporting.
|
|
1162
|
+
*/
|
|
1163
|
+
private sanitizeBulkUpdateData;
|
|
1059
1164
|
bulkUpdate(req: IRequestContext): Promise<IControllerResponse<{
|
|
1060
1165
|
matchedCount: number;
|
|
1061
1166
|
modifiedCount: number;
|
|
1062
1167
|
}>>;
|
|
1168
|
+
/**
|
|
1169
|
+
* Bulk delete by `filter` or `ids`.
|
|
1170
|
+
*
|
|
1171
|
+
* Body shape (one of):
|
|
1172
|
+
* - `{ filter: { status: 'archived' } }` — delete by query filter
|
|
1173
|
+
* - `{ ids: ['id1', 'id2', 'id3'] }` — delete specific docs by id
|
|
1174
|
+
*
|
|
1175
|
+
* The `ids` form translates to `{ [idField]: { $in: ids } }` using the
|
|
1176
|
+
* resource's `idField` (so it works with custom PKs like `slug`, `jobId`,
|
|
1177
|
+
* UUID, etc.). Tenant scope and policy filters are merged in either way,
|
|
1178
|
+
* so cross-tenant deletes are blocked at the controller layer.
|
|
1179
|
+
*
|
|
1180
|
+
* Both forms perform a single `repo.deleteMany()` DB call — no per-doc
|
|
1181
|
+
* fetch loop. Per-doc lifecycle hooks (`before:delete`/`after:delete`) do
|
|
1182
|
+
* NOT fire for bulk operations; use the single-doc `delete()` if you need
|
|
1183
|
+
* them, or subscribe to the bulk lifecycle event from the events plugin.
|
|
1184
|
+
*/
|
|
1063
1185
|
bulkDelete(req: IRequestContext): Promise<IControllerResponse<{
|
|
1064
1186
|
deletedCount: number;
|
|
1065
1187
|
}>>;
|
|
@@ -2369,6 +2491,20 @@ interface RepositoryLike {
|
|
|
2369
2491
|
create(data: unknown, options?: unknown): Promise<unknown>;
|
|
2370
2492
|
update(id: string, data: unknown, options?: unknown): Promise<unknown>;
|
|
2371
2493
|
delete(id: string, options?: unknown): Promise<unknown>;
|
|
2494
|
+
/**
|
|
2495
|
+
* The repository's native primary key field. When set, Arc's BaseController
|
|
2496
|
+
* will pass route params through to `update()`/`delete()`/`restore()` calls
|
|
2497
|
+
* unchanged instead of translating them to `_id`.
|
|
2498
|
+
*
|
|
2499
|
+
* Set this to match your `defineResource({ idField })` for repositories that
|
|
2500
|
+
* natively look up by a custom field (e.g. MongoKit's
|
|
2501
|
+
* `new Repository(Model, [], {}, { idField: 'id' })`). Without it, Arc will
|
|
2502
|
+
* try to translate route ids → fetched doc's `_id` which 404s on repos that
|
|
2503
|
+
* don't key on `_id`.
|
|
2504
|
+
*
|
|
2505
|
+
* Defaults to `'_id'` (Mongo). Repositories that always use `_id` may omit it.
|
|
2506
|
+
*/
|
|
2507
|
+
readonly idField?: string;
|
|
2372
2508
|
/** Find single doc by compound filter — used by AccessControl for idField + org/policy scoping.
|
|
2373
2509
|
* Without this, Arc falls back to getById + post-fetch security checks. */
|
|
2374
2510
|
getOne?(filter: Record<string, unknown>, options?: unknown): Promise<unknown>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getUserRoles } from "./types-ZUu_h0jp.mjs";
|
|
2
|
-
import { n as convertRouteSchema } from "./schemaConverter-
|
|
2
|
+
import { n as convertRouteSchema } from "./schemaConverter-0TyONAwM.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/docs/openapi.ts
|
|
5
5
|
const openApiPlugin = async (fastify, opts = {}) => {
|
package/dist/org/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Rt as RouteHandler } from "../interface-
|
|
2
|
-
import { i as UserBase } from "../types-
|
|
1
|
+
import { Rt as RouteHandler } from "../interface-B91alUzq.mjs";
|
|
2
|
+
import { i as UserBase } from "../types-B4BNthET.mjs";
|
|
3
3
|
import { InvitationAdapter, InvitationDoc, MemberDoc, OrgAdapter, OrgDoc, OrgPermissionStatement, OrgRole, OrganizationPluginOptions } from "./types.mjs";
|
|
4
4
|
import { FastifyPluginAsync, RouteHandlerMethod } from "fastify";
|
|
5
5
|
|
package/dist/org/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as isElevated, h as hasOrgAccess, n as PUBLIC_SCOPE, s as getOrgRoles, v as isMember } from "../types-AOD8fxIw.mjs";
|
|
2
2
|
import fp from "fastify-plugin";
|
|
3
3
|
//#region src/org/organizationPlugin.ts
|
|
4
4
|
const DEFAULT_ROLES = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission } from "../fields-
|
|
2
|
-
import { a as getUserRoles, i as UserBase, n as PermissionContext, o as normalizeRoles, r as PermissionResult, t as PermissionCheck } from "../types-
|
|
3
|
-
import { C as
|
|
4
|
-
export { ConnectEventsOptions, DynamicPermissionMatrix, DynamicPermissionMatrixConfig, FieldPermission, FieldPermissionMap, FieldPermissionType, PermissionCheck, PermissionContext, PermissionEventBus, PermissionResult, RoleHierarchy, UserBase, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizeRoles, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, resolveEffectiveRoles, roles, when };
|
|
1
|
+
import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission } from "../fields-D4nMDqnK.mjs";
|
|
2
|
+
import { a as getUserRoles, i as UserBase, n as PermissionContext, o as normalizeRoles, r as PermissionResult, t as PermissionCheck } from "../types-B4BNthET.mjs";
|
|
3
|
+
import { A as RoleHierarchy, C as authenticated, D as publicRead, E as presets_d_exports, M as applyPermissionResult, N as normalizePermissionResult, O as publicReadAdminWrite, S as adminOnly, T as ownerWithAdminBypass, _ as requireScopeContext, a as allOf, b as roles, c as createDynamicPermissionMatrix, d as requireAuth, f as requireOrgInScope, g as requireRoles, h as requireOwnership, i as PermissionEventBus, j as createRoleHierarchy, k as readOnly, l as createOrgPermissions, m as requireOrgRole, n as DynamicPermissionMatrix, o as allowPublic, p as requireOrgMembership, r as DynamicPermissionMatrixConfig, s as anyOf, t as ConnectEventsOptions, u as denyAll, v as requireServiceScope, w as fullPublic, x as when, y as requireTeamMembership } from "../index-B0extFr4.mjs";
|
|
4
|
+
export { ConnectEventsOptions, DynamicPermissionMatrix, DynamicPermissionMatrixConfig, FieldPermission, FieldPermissionMap, FieldPermissionType, PermissionCheck, PermissionContext, PermissionEventBus, PermissionResult, RoleHierarchy, UserBase, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-ipsbIRPK.mjs";
|
|
2
2
|
import { n as normalizeRoles, t as getUserRoles } from "../types-ZUu_h0jp.mjs";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { n as normalizePermissionResult, t as applyPermissionResult } from "../applyPermissionResult-D6GPMsvh.mjs";
|
|
4
|
+
import { C as publicRead, E as createRoleHierarchy, S as presets_exports, T as readOnly, _ as when, a as createOrgPermissions, b as fullPublic, c as requireOrgInScope, d as requireOwnership, f as requireRoles, g as roles, h as requireTeamMembership, i as createDynamicPermissionMatrix, l as requireOrgMembership, m as requireServiceScope, n as allowPublic, o as denyAll, p as requireScopeContext, r as anyOf, s as requireAuth, t as allOf, u as requireOrgRole, v as adminOnly, w as publicReadAdminWrite, x as ownerWithAdminBypass, y as authenticated } from "../permissions-CH4cNwJi.mjs";
|
|
5
|
+
export { adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
|