@classytic/arc 2.41.1 → 2.44.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.
- package/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
- package/dist/{EventTransport-DSqD_Xsg.mjs → EventTransport-DZWDsaPa.mjs} +22 -17
- package/dist/{HookSystem-CMF94SEA.mjs → HookSystem-yjEgn7Cm.mjs} +2 -2
- package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
- package/dist/{ResourceRegistry-MGpXoxHZ.mjs → ResourceRegistry-DJxHUpE4.mjs} +44 -13
- package/dist/acquire-BozJ-9yt.mjs +35 -0
- package/dist/actionPermissions-5N04zBL4.mjs +772 -0
- package/dist/audit/index.d.mts +46 -8
- package/dist/audit/index.mjs +48 -26
- package/dist/auth/audit.d.mts +8 -8
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +46 -16
- package/dist/auth/index.mjs +134 -156
- package/dist/auth/redis-session.d.mts +4 -5
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-DawKGoXb.mjs → authorizationDecision-wX3SA9w_.mjs} +7 -102
- package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
- package/dist/boundedMap-DWiKW7lP.mjs +57 -0
- package/dist/{buildHandler-CvxKOc0m.mjs → buildHandler-Bswu_vNb.mjs} +4 -4
- package/dist/cache/index.d.mts +31 -43
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-DbCBxlgw.mjs → caching-Drp68DIS.mjs} +3 -3
- package/dist/claimed-DYvQoZLv.mjs +8 -0
- package/dist/cleanup/index.d.mts +18 -22
- package/dist/cleanup/index.mjs +27 -73
- package/dist/cli/commands/describe.d.mts +7 -5
- package/dist/cli/commands/describe.mjs +7 -4
- package/dist/cli/commands/docs.d.mts +2 -3
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.d.mts +2 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -3
- package/dist/cli/commands/init.mjs +2 -3
- package/dist/cli/commands/introspect.d.mts +2 -3
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-D5Ubn1fe.mjs → constants-B2QHb6u6.mjs} +4 -2
- package/dist/context/index.d.mts +11 -14
- package/dist/context/index.mjs +18 -38
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +8 -8
- package/dist/{core-5lazhva9.mjs → core-COcqo0Cp.mjs} +15 -5
- package/dist/{createActionRouter-DNqoaK81.mjs → createActionRouter-zG13rpPJ.mjs} +97 -39
- package/dist/{createAggregationRouter-BcbQJf10.mjs → createAggregationRouter-CWRz96Vr.mjs} +11 -8
- package/dist/{preloadResources-f3boenVZ.mjs → createApp-BGLYtErt.mjs} +305 -394
- package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-DSztofa9.d.mts} +1 -1
- package/dist/{defineAggregation-D_eJjm5A.mjs → defineAggregation--3xguLkk.mjs} +1 -1
- package/dist/{defineResource-DxkMTjRn.mjs → defineResource-gUp9ug66.mjs} +118 -1024
- package/dist/discovery/index.d.mts +6 -7
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +11 -5
- package/dist/docs/index.mjs +4 -4
- package/dist/{elevation-CkvG0LG2.mjs → elevation-BG4gnMsJ.mjs} +41 -12
- package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
- package/dist/encryption/index.d.mts +5 -5
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-D1GHKGlV.mjs → errorHandler-COHw3N1b.mjs} +26 -5
- package/dist/{errors-BH7YU_9O.mjs → errors-CW4anJBy.mjs} +58 -23
- package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
- package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
- package/dist/{eventPlugin-zZY-unhr.mjs → eventPlugin-BweHAVws.mjs} +82 -21
- package/dist/{subscribe-helpers-DatDkcuG.mjs → eventTypes-N4-omQFR.mjs} +151 -17
- package/dist/events/index.d.mts +43 -18
- package/dist/events/index.mjs +49 -53
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +139 -157
- package/dist/events/transports/redis.d.mts +5 -6
- package/dist/events/transports/redis.mjs +2 -2
- package/dist/factory/index.d.mts +42 -27
- package/dist/factory/index.mjs +213 -32
- package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DRlCIWE9.d.mts} +11 -25
- package/dist/{fields-BHrkoF5y.mjs → fields-A5crhsJb.mjs} +1 -1
- package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
- package/dist/filter-merge-DGM-GQ1J.mjs +99 -0
- package/dist/{generate-BLRf2m3y.mjs → generate-BXKo2Gc8.mjs} +2 -2
- package/dist/{headers-BIXWKrzQ.mjs → headers-DKZQKL-Z.mjs} +2 -2
- package/dist/health-BYAwA6YS.mjs +22 -0
- package/dist/{health-ZRHeDHXH.mjs → health-CrqUp3sz.mjs} +115 -55
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.mjs +2 -3
- package/dist/idempotency/index.d.mts +36 -10
- package/dist/idempotency/index.mjs +230 -111
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +77 -12
- package/dist/{index-D4u76eQW.d.mts → index-Beg3aNnK.d.mts} +23 -101
- package/dist/{preloadResources-CjS2OfpU.d.mts → index-BkV55WlV.d.mts} +37 -38
- package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
- package/dist/index-CUJvoyw3.d.mts +510 -0
- package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
- package/dist/{index-DHbyPo5j.d.mts → index-WH7xgvxS.d.mts} +304 -254
- package/dist/index.d.mts +9 -9
- package/dist/index.mjs +11 -11
- package/dist/{init-CpLkjU18.mjs → init-BPzK5Lnr.mjs} +1 -1
- package/dist/integrations/event-gateway.d.mts +11 -7
- package/dist/integrations/event-gateway.mjs +4 -4
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +18 -5
- package/dist/integrations/mcp/index.d.mts +102 -89
- package/dist/integrations/mcp/index.mjs +19 -4
- package/dist/integrations/mcp/testing.d.mts +8 -9
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.d.mts +85 -144
- package/dist/integrations/streamline.mjs +131 -55
- package/dist/integrations/webhooks.d.mts +83 -143
- package/dist/integrations/webhooks.mjs +36 -80
- package/dist/integrations/websocket-pushref-redis.d.mts +5 -6
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.d.mts +5 -6
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.d.mts +3 -3
- package/dist/integrations/websocket.mjs +2 -2
- package/dist/{interface-DEWNOMza.d.mts → interface-JJzwH4Ro.d.mts} +34 -2
- package/dist/{jsonBody-ELR9lfeU.mjs → jsonBody-YIq-vGLv.mjs} +2 -2
- package/dist/{keys-cpZCtcIE.mjs → keys-CpoiZ8hU.mjs} +7 -18
- package/dist/{loadResources-BPfWiI5s.mjs → loadResources-6jO52-RR.mjs} +3 -3
- package/dist/{loadResourcesFromEntry-ixtfL3J2.mjs → loadResourcesFromEntry-MP8xEppu.mjs} +2 -2
- package/dist/logger/index.d.mts +9 -17
- package/dist/logger/index.mjs +2 -153
- package/dist/logger-D4V1zGLI.mjs +160 -0
- package/dist/{mcpPlugin-BX5PujI0.mjs → mcpPlugin-srPc7ItN.mjs} +446 -170
- package/dist/{memory-Iotz0cCx.mjs → memory-CTa5pOCW.mjs} +36 -34
- package/dist/{metrics-NMsmpRmY.mjs → metrics-DsZrvnpB.mjs} +39 -72
- package/dist/middleware/index.d.mts +5 -5
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.d.mts +13 -13
- package/dist/migrations/index.mjs +2 -2
- package/dist/{module-DpLJG2_N.mjs → module--L0iBIZz.mjs} +8 -8
- package/dist/mongodb-memory-server-CHhYSq5y.mjs +35539 -0
- package/dist/mongoose-CYJCLyi-.mjs +67451 -0
- package/dist/multiTenant-CAtYlW6H.d.mts +104 -0
- package/dist/{multipartBody-DtRWM6_U.mjs → multipartBody-Cc7eZ9cq.mjs} +46 -7
- package/dist/node-D8UZv_8c.mjs +41236 -0
- package/dist/{openapi-CmFf3yq_.mjs → openapi-CMegfsm8.mjs} +48 -10
- package/dist/outbox-admin/index.d.mts +5 -5
- package/dist/outbox-admin/index.mjs +6 -18
- package/dist/{outbox-module-D2z5WkDY.mjs → outbox-module-Ryk270jd.mjs} +203 -33
- package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
- package/dist/permissions/index.d.mts +5 -4
- package/dist/permissions/index.mjs +8 -6
- package/dist/{permissions-D8TBH44E.mjs → permissions-C5ijIz5Q.mjs} +149 -33
- package/dist/{pipe-FMWNheSO.mjs → pipe-D81zMtWs.mjs} +2 -2
- package/dist/pipeline/index.d.mts +7 -7
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plan-CJGMKoui.mjs +565 -0
- package/dist/{BaseController-CYEwjyjN.mjs → plugin-DALd9dcF.mjs} +1269 -346
- package/dist/plugins/index.d.mts +17 -14
- package/dist/plugins/index.mjs +44 -22
- package/dist/plugins/response-cache.d.mts +5 -6
- package/dist/plugins/response-cache.mjs +8 -14
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-CXWZIzTv.mjs → pluralize-COUNYo3d.mjs} +1 -1
- package/dist/presets/filesUpload.d.mts +8 -8
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +35 -40
- package/dist/presets/index.mjs +4 -4
- package/dist/presets/multiTenant.d.mts +2 -107
- package/dist/presets/multiTenant.mjs +22 -162
- package/dist/presets/search.d.mts +9 -10
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-ZJSPgmT2.mjs → presets-CONf2Qem.mjs} +99 -107
- package/dist/{projection-BzIgzoKZ.mjs → projection-wFoLqdss.mjs} +2 -2
- package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
- package/dist/{queryCachePlugin-DZHPOm9p.mjs → queryCachePlugin-BATECpyh.mjs} +12 -14
- package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
- package/dist/{rateLimitKey-BvOvcBDi.mjs → rateLimitKey-DVEZ_UpV.mjs} +1 -1
- package/dist/{realtime-8tIQWZz4.mjs → realtime-xyubMKSB.mjs} +25 -21
- package/dist/{redis-Bzi1y3F9.d.mts → redis-BDgv9Glw.d.mts} +17 -24
- package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
- package/dist/redisShapes-CQksY67q.d.mts +55 -0
- package/dist/registry/index.d.mts +15 -10
- package/dist/registry/index.mjs +4 -4
- package/dist/{registry-DNkgGQcK.mjs → registry-Bdzg-hdm.mjs} +13 -10
- package/dist/{renewingLease-yF8BdW4b.mjs → renewingLease-BFJxGPuh.mjs} +1 -1
- package/dist/{replyHelpers-CNdvMfM4.mjs → replyHelpers-Bnc6lJyy.mjs} +2 -2
- package/dist/{requestContext-cDkAUr-P.mjs → requestContext-C10UeFe5.mjs} +1 -1
- package/dist/requirement-Bu50QALH.mjs +35 -0
- package/dist/requirement-CbiLdQ1n.d.mts +22 -0
- package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
- package/dist/resourceRateLimit-urWPJxrt.mjs +180 -0
- package/dist/rolldown-runtime-MYrLNGnq.mjs +45 -0
- package/dist/routeValidator-DHtpzrzk.mjs +70 -0
- package/dist/{runtimeCapabilities-CkhS6jn6.mjs → runtimeCapabilities-DIMKMV2G.mjs} +1 -1
- package/dist/{schedules-j6uXXAeJ.mjs → schedules-CKTs5ys8.mjs} +46 -37
- package/dist/{schemaConverter-BVA7cFRG.mjs → schemaConverter-BVjkQ5DD.mjs} +2 -2
- package/dist/{schemaIR-CTvPDoPB.mjs → schemaIR-BA0Hb21Y.mjs} +2 -2
- package/dist/schemas/index.d.mts +20 -10
- package/dist/schemas/index.mjs +8 -3
- package/dist/scim/index.d.mts +13 -13
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +4 -4
- package/dist/scope/index.mjs +6 -6
- package/dist/{scope-BUi1xV1I.mjs → scope-DINaj7Ax.mjs} +4 -4
- package/dist/shutdown-LpLMH8T1.mjs +59 -0
- package/dist/{simpleEqualityMatcher-C9bzq2gO.mjs → simpleEqualityMatcher-DbwIM1f1.mjs} +1 -1
- package/dist/{sse-BeqVKQKu.mjs → sse-BzJFPX_1.mjs} +11 -15
- package/dist/{sseStream-Ppzo-WUH.mjs → sseStream-DQChzGTs.mjs} +2 -2
- package/dist/{store-helpers-dW71XVWL.mjs → store-helpers-Coj9RhOZ.mjs} +1 -1
- package/dist/{streaming-IcRFjWQU.mjs → streaming-JzB5CAga.mjs} +1 -1
- package/dist/subscriberIdentity-DeyppIif.mjs +28 -0
- package/dist/tenancy-DxV8OuX2.mjs +43 -0
- package/dist/tenantPreparation-CBvvAcAj.mjs +67 -0
- package/dist/testing/cleanupStoreContract.d.mts +4 -5
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +215 -197
- package/dist/testing/index.mjs +289 -214
- package/dist/testing/outboxStoreContract.d.mts +4 -5
- package/dist/testing/outboxStoreContract.mjs +137 -2
- package/dist/testing/requiredPorts.d.mts +16 -0
- package/dist/testing/requiredPorts.mjs +65 -0
- package/dist/testing/storageContract.d.mts +4 -5
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/timing-CntavTlR.mjs +46 -0
- package/dist/{transactionContext-CPbdlnVw.mjs → transactionContext-orvnGu4F.mjs} +1 -1
- package/dist/{typeGuards-BLjPgVBm.mjs → typeGuards-kEaP_WmO.mjs} +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
- package/dist/{types-CWQn9-IC.d.mts → types-D3Ixsh00.d.mts} +22 -9
- package/dist/{types-CgenB1gv.mjs → types-fvO6Ovzx.mjs} +4 -4
- package/dist/usage/index.d.mts +5 -6
- package/dist/usage/index.mjs +5 -5
- package/dist/{userHelpers-ChRvkuSZ.mjs → userHelpers-C76zD5pa.mjs} +1 -1
- package/dist/utils/index.d.mts +125 -264
- package/dist/utils/index.mjs +13 -12
- package/dist/{utils-CxcctrAh.mjs → utils-BpkVZ8rB.mjs} +315 -404
- package/dist/{validate-DrYWnOzI.mjs → validate-CWp-lsrm.mjs} +6 -14
- package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
- package/dist/{versioning-DKkT4hNJ.mjs → versioning-CHhL9P3o.mjs} +4 -4
- package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
- package/dist/{workScope-CxKqoIFn.mjs → workScope-n9a7d_lZ.mjs} +2 -2
- package/package.json +57 -59
- package/skills/arc/SKILL.md +13 -4
- package/skills/arc/references/auth.md +8 -5
- package/skills/arc/references/integrations.md +1 -1
- package/skills/arc/references/mcp.md +8 -6
- package/skills/arc/references/multi-tenancy.md +19 -14
- package/skills/arc/references/production.md +27 -10
- package/dist/actionPermissions-BoPGQ5-4.mjs +0 -350
- package/dist/index-CFfLKMH4.d.mts +0 -290
- package/dist/interface-YzIbF7Ii.mjs +0 -17
- package/dist/redis-stream-BPKscsTB.d.mts +0 -260
- package/dist/registerRoute-Bsnk6NiZ.mjs +0 -364
- package/dist/rolldown-runtime-eysyzFAF.mjs +0 -15
- package/dist/sync/changelog.d.mts +0 -3
- package/dist/sync/changelog.mjs +0 -3
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { i as RequestScope } from "./types-Ddl9OjmE.mjs";
|
|
3
|
-
import { l as PermissionCheck, t as AnyRecord } from "./base-
|
|
4
|
-
import {
|
|
5
|
-
import "./fastify-augmentation-
|
|
3
|
+
import { l as PermissionCheck, t as AnyRecord } from "./base-CZyixEQR.mjs";
|
|
4
|
+
import { A as RequestWithExtras, Dt as RouteMcpConfig, F as ResourceDefinition, Hn as IRequestContext, I as CrudController, L as ResourceConfig, O as FastifyWithDecorators, St as ActionDefinition, Vn as IControllerResponse, X as RouteSchemaOptions, Z as ArcFieldRule, g as RequestContext, ot as AggregationConfig, v as CrudRouterOptions } from "./index-WH7xgvxS.mjs";
|
|
5
|
+
import "./fastify-augmentation-DRlCIWE9.mjs";
|
|
6
6
|
import { Filter } from "@classytic/repo-core/filter";
|
|
7
7
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
8
8
|
import { z } from "zod";
|
|
@@ -42,6 +42,8 @@ declare const DEFAULT_ID_FIELD: "_id";
|
|
|
42
42
|
declare const DEFAULT_TENANT_FIELD: "organizationId";
|
|
43
43
|
/** Default HTTP method for update routes */
|
|
44
44
|
declare const DEFAULT_UPDATE_METHOD: "PATCH";
|
|
45
|
+
/** Default version field under `concurrency: {}` (optimistic concurrency) */
|
|
46
|
+
declare const DEFAULT_VERSION_FIELD: "__v";
|
|
45
47
|
/** System-managed fields that cannot be set via request body */
|
|
46
48
|
declare const SYSTEM_FIELDS: readonly ["_id", "__v", "createdAt", "updatedAt", "deletedAt"];
|
|
47
49
|
/** Maximum regex pattern length (ReDoS mitigation) */
|
|
@@ -95,9 +97,8 @@ declare function defineAggregation(config: AggregationConfig): AggregationConfig
|
|
|
95
97
|
*/
|
|
96
98
|
declare function createCrudRouter<TDoc = unknown>(fastify: FastifyWithDecorators, controller: CrudController<TDoc> | undefined, options?: CrudRouterOptions): void;
|
|
97
99
|
/**
|
|
98
|
-
* Build a permission middleware from a PermissionCheck
|
|
99
|
-
*
|
|
100
|
-
* evaluate permissions through the shared applicator.
|
|
100
|
+
* Build a permission middleware from a PermissionCheck, for host routes
|
|
101
|
+
* registered outside the resource system.
|
|
101
102
|
*/
|
|
102
103
|
declare function createPermissionMiddleware(permission: PermissionCheck, resourceName: string, action: string): RouteHandlerMethod | null;
|
|
103
104
|
//#endregion
|
|
@@ -123,6 +124,8 @@ interface DefineActionConfig<TSchema extends z.ZodTypeAny | undefined = undefine
|
|
|
123
124
|
id?: boolean;
|
|
124
125
|
/** MCP tool generation flag — `false` to skip, object for explicit overrides. */
|
|
125
126
|
mcp?: boolean | RouteMcpConfig;
|
|
127
|
+
/** `{ required: true }`: a call of this action needs an idempotency key. See `ActionDefinition`. */
|
|
128
|
+
idempotency?: ActionDefinition["idempotency"];
|
|
126
129
|
/**
|
|
127
130
|
* Typed handler. `data` is inferred from `schema` — declare both and
|
|
128
131
|
* the compiler catches `data.stagId` typos at the use site.
|
|
@@ -266,90 +269,33 @@ type VariantsResult<TDoc, V extends VariantsMap<TDoc>> = { [K in keyof V]: Resou
|
|
|
266
269
|
* @returns A record where each key from `variants` maps to a real
|
|
267
270
|
* `ResourceDefinition` ready for `.toPlugin()` registration.
|
|
268
271
|
*/
|
|
269
|
-
declare function defineResourceVariants<TDoc extends
|
|
270
|
-
//#endregion
|
|
271
|
-
//#region src/core/entityHelpers.d.ts
|
|
272
|
-
/**
|
|
273
|
-
* Read the resource's configured `idField` for the current request.
|
|
274
|
-
* Falls back to the framework default (`_id`) when the route hasn't
|
|
275
|
-
* bound an idField — keeps handlers safe to author without checking
|
|
276
|
-
* the resource config.
|
|
277
|
-
*/
|
|
278
|
-
declare function getEntityIdField(req: RequestWithExtras): string;
|
|
279
|
-
/**
|
|
280
|
-
* Read the URL `:id` path param value as the resource handle.
|
|
281
|
-
* Returns `undefined` when the route has no `:id` segment (collection
|
|
282
|
-
* routes) — handlers that need the entity must be on row routes.
|
|
283
|
-
*/
|
|
284
|
-
declare function getEntityId(req: RequestWithExtras): string | undefined;
|
|
285
|
-
/**
|
|
286
|
-
* Compose a `findOne` filter that resolves the current request's
|
|
287
|
-
* entity, regardless of whether the resource binds `_id` or a custom
|
|
288
|
-
* field. Idiomatic shape for arc action handlers.
|
|
289
|
-
*
|
|
290
|
-
* ```ts
|
|
291
|
-
* const doc = await Model.findOne(getEntityQuery(req));
|
|
292
|
-
* ```
|
|
293
|
-
*
|
|
294
|
-
* Returns `{}` when the route has no entity context (collection routes
|
|
295
|
-
* or tests bypassing the router) — caller decides what that means.
|
|
296
|
-
*/
|
|
297
|
-
declare function getEntityQuery(req: RequestWithExtras): Record<string, string>;
|
|
272
|
+
declare function defineResourceVariants<TDoc extends object = AnyRecord, V extends VariantsMap<TDoc> = VariantsMap<TDoc>>(base: Omit<ResourceConfig<TDoc>, "name" | "prefix">, variants: V): VariantsResult<TDoc, V>;
|
|
298
273
|
//#endregion
|
|
299
274
|
//#region src/core/fastifyAdapter.d.ts
|
|
300
275
|
/**
|
|
301
|
-
* Project `FastifyRequest` into the
|
|
302
|
-
*
|
|
303
|
-
* portability boundary — arc is Fastify-only. The projection lifts the
|
|
304
|
-
* fields tenant-scoped controllers reach for (`organizationId`,
|
|
305
|
-
* `teamId`, `scope`, `context`, server accessor) onto a flat, typed
|
|
306
|
-
* surface so handler code doesn't have to dig through Fastify's
|
|
307
|
-
* decorator surface or `req.metadata._scope` internals.
|
|
276
|
+
* Project `FastifyRequest` into the `IRequestContext` controllers receive,
|
|
277
|
+
* lifting scope, context, and a server accessor onto a flat, typed surface.
|
|
308
278
|
*/
|
|
309
279
|
declare function createRequestContext(req: FastifyRequest): IRequestContext;
|
|
310
280
|
/**
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* For org scope, use `getControllerScope(req)` instead.
|
|
281
|
+
* Typed auth context from an IRequestContext, for controller overrides.
|
|
282
|
+
* For org scope, use `getControllerScope(req)`.
|
|
315
283
|
*/
|
|
316
284
|
declare function getControllerContext(req: IRequestContext): RequestContext;
|
|
317
|
-
/**
|
|
318
|
-
* Get request scope from an IRequestContext.
|
|
319
|
-
* Returns the RequestScope set by auth adapters.
|
|
320
|
-
*/
|
|
285
|
+
/** The RequestScope set by auth adapters (`PUBLIC_SCOPE` when absent). */
|
|
321
286
|
declare function getControllerScope(req: IRequestContext): RequestScope;
|
|
322
287
|
/**
|
|
323
|
-
* Send a controller's `IControllerResponse`
|
|
324
|
-
*
|
|
325
|
-
* The `IControllerResponse<T>` envelope is arc's internal pipeline
|
|
326
|
-
* contract — it's how custom `status`, `meta`, `headers`, and field
|
|
327
|
-
* permissions thread from a handler through interceptors to the wire
|
|
328
|
-
* without each step having to touch `reply` directly. Not a portability
|
|
329
|
-
* abstraction (arc is Fastify-only); a pipeline-internal one.
|
|
288
|
+
* Send a controller's `IControllerResponse` envelope (status, meta, headers)
|
|
289
|
+
* through Fastify's reply, applying field masks and field read permissions.
|
|
330
290
|
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
* A handler that returns raw `T` (array, plain object, primitive) used
|
|
335
|
-
* to silently produce a broken response — `response.data` was
|
|
336
|
-
* `undefined`, the body sent was `undefined`, and any declared
|
|
337
|
-
* `fields:` permission map was bypassed (the leak shape mentora
|
|
338
|
-
* flagged). 2.17 detects bare returns and wraps them into
|
|
339
|
-
* `{ data: response, status: 200 }` before the field-permission
|
|
340
|
-
* pipeline runs, so `fields:` applies to ALL custom routes whether the
|
|
341
|
-
* handler envelopes its return value or not. The envelope shape is
|
|
342
|
-
* still the canonical contract — auto-wrapping is a safety net, not
|
|
343
|
-
* an invitation to drop the envelope.
|
|
291
|
+
* A bare return (no `data` key) is wrapped as `{ data, status: 200 }` so
|
|
292
|
+
* `fields:` permissions still apply — otherwise restricted fields would leak.
|
|
293
|
+
* The envelope remains the canonical contract.
|
|
344
294
|
*/
|
|
345
295
|
declare function sendControllerResponse<T>(reply: FastifyReply, response: IControllerResponse<T>, request?: FastifyRequest): void;
|
|
346
296
|
/**
|
|
347
|
-
* Bridge an `IController` method
|
|
348
|
-
*
|
|
349
|
-
* context surface and Fastify's request/reply, and routes the envelope
|
|
350
|
-
* through `sendControllerResponse` so the pipeline applies field
|
|
351
|
-
* permissions, status, and meta uniformly. Internal plumbing, not a
|
|
352
|
-
* portability layer — arc is Fastify-only.
|
|
297
|
+
* Bridge an `IController` method into a Fastify route handler, sending the
|
|
298
|
+
* envelope through `sendControllerResponse`.
|
|
353
299
|
*
|
|
354
300
|
* @example
|
|
355
301
|
* ```typescript
|
|
@@ -359,30 +305,6 @@ declare function sendControllerResponse<T>(reply: FastifyReply, response: IContr
|
|
|
359
305
|
* ```
|
|
360
306
|
*/
|
|
361
307
|
declare function createFastifyHandler<T>(controllerMethod: (req: IRequestContext) => Promise<IControllerResponse<T>>): (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
362
|
-
/**
|
|
363
|
-
* Create Fastify adapters for all CRUD methods of an IController
|
|
364
|
-
*
|
|
365
|
-
* Returns Fastify-compatible handlers for each CRUD operation
|
|
366
|
-
*
|
|
367
|
-
* @example
|
|
368
|
-
* ```typescript
|
|
369
|
-
* const controller = new BaseController(repository);
|
|
370
|
-
* const handlers = createCrudHandlers(controller);
|
|
371
|
-
*
|
|
372
|
-
* fastify.get('/', handlers.list);
|
|
373
|
-
* fastify.get('/:id', handlers.get);
|
|
374
|
-
* fastify.post('/', handlers.create);
|
|
375
|
-
* fastify.patch('/:id', handlers.update);
|
|
376
|
-
* fastify.delete('/:id', handlers.delete);
|
|
377
|
-
* ```
|
|
378
|
-
*/
|
|
379
|
-
declare function createCrudHandlers<TDoc>(controller: IController<TDoc>): {
|
|
380
|
-
list: (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
381
|
-
get: (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
382
|
-
create: (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
383
|
-
update: (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
384
|
-
delete: (req: FastifyRequest, reply: FastifyReply) => Promise<FastifyReply>;
|
|
385
|
-
};
|
|
386
308
|
//#endregion
|
|
387
309
|
//#region src/core/fieldRulePredicates.d.ts
|
|
388
310
|
/**
|
|
@@ -446,4 +368,4 @@ declare function formatValidationErrors(resourceName: string, result: Validation
|
|
|
446
368
|
*/
|
|
447
369
|
declare function assertValidConfig(config: ResourceConfig, options?: ValidateOptions): void;
|
|
448
370
|
//#endregion
|
|
449
|
-
export {
|
|
371
|
+
export { CrudOperation as A, HookOperation as B, mergeResourceConfig as C, createPermissionMiddleware as D, createCrudRouter as E, DEFAULT_TENANT_FIELD as F, MUTATION_OPERATIONS as G, MAX_FILTER_DEPTH as H, DEFAULT_UPDATE_METHOD as I, SYSTEM_FIELDS as J, MutationOperation as K, DEFAULT_VERSION_FIELD as L, DEFAULT_LIMIT as M, DEFAULT_MAX_LIMIT as N, defineAggregation as O, DEFAULT_SORT as P, HOOK_OPERATIONS as R, SeamedResourceConfig as S, defineAction as T, MAX_REGEX_LENGTH as U, HookPhase as V, MAX_SEARCH_LENGTH as W, VariantsMap as _, formatValidationErrors as a, AdapterLike as b, nativePolicyFilter as c, createFastifyHandler as d, createRequestContext as f, VariantOverride as g, sendControllerResponse as h, assertValidConfig as i, DEFAULT_ID_FIELD as j, CRUD_OPERATIONS as k, collectReadBlockedFields as l, getControllerScope as m, ValidateOptions as n, validateResourceConfig as o, getControllerContext as p, RESERVED_QUERY_PARAMS as q, ValidationResult as r, NativePolicyFilter as s, ConfigError as t, isFieldReadable as u, VariantsResult as v, DefineActionConfig as w, ResourceSeams as x, defineResourceVariants as y, HOOK_PHASES as z };
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { Mt as Authenticator } from "./index-WH7xgvxS.mjs";
|
|
3
3
|
import { r as CacheStore } from "./interface-BOk3YnTz.mjs";
|
|
4
|
-
import { n as ElevationOptions } from "./elevation-
|
|
5
|
-
import { a as EventTransport } from "./EventTransport-
|
|
4
|
+
import { n as ElevationOptions } from "./elevation-BW2J3tNj.mjs";
|
|
5
|
+
import { a as EventTransport } from "./EventTransport-CiicKz2Z.mjs";
|
|
6
6
|
import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
|
|
7
|
-
import { r as QueryCachePluginOptions } from "./queryCachePlugin-
|
|
7
|
+
import { r as QueryCachePluginOptions } from "./queryCachePlugin-C2lZjTxk.mjs";
|
|
8
8
|
import { t as ErrorHandlerOptions } from "./errorHandler--4rSMMvq.mjs";
|
|
9
|
-
import {
|
|
10
|
-
import "./index-
|
|
11
|
-
import { t as EventPluginOptions } from "./eventPlugin-
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
9
|
+
import { S as SchedulesPluginOptions, T as HealthOptions, _ as ResourceLike, o as ArcPorts, r as ArcModuleInput } from "./types-BJ-2XqVF.mjs";
|
|
10
|
+
import { H as ModuleGraphOptions } from "./index-CUJvoyw3.mjs";
|
|
11
|
+
import { t as EventPluginOptions } from "./eventPlugin-BtmA4-3P.mjs";
|
|
12
|
+
import { a as MetricsOptions, c as RealtimeOptions, f as CachingOptions, h as GracefulShutdownOptions, t as VersioningOptions, u as SSEOptions } from "./versioning-Bsb51gGT.mjs";
|
|
13
|
+
import { i as IdempotencyStore } from "./interface-JJzwH4Ro.mjs";
|
|
14
14
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
|
|
15
15
|
//#region src/factory/types/assets.d.ts
|
|
16
16
|
/**
|
|
@@ -399,6 +399,8 @@ interface RateLimitPlanConfig {
|
|
|
399
399
|
}
|
|
400
400
|
//#endregion
|
|
401
401
|
//#region src/factory/types/app-options.d.ts
|
|
402
|
+
/** Releases what `beforeBoot` acquired — see `CreateAppOptions.beforeBoot`. */
|
|
403
|
+
type BootDisposer = () => void | Promise<void>;
|
|
402
404
|
/**
|
|
403
405
|
* Configuration for `createApp()`.
|
|
404
406
|
*
|
|
@@ -425,8 +427,9 @@ interface CreateAppOptions {
|
|
|
425
427
|
*/
|
|
426
428
|
mountRoutes?: boolean;
|
|
427
429
|
/**
|
|
428
|
-
* Runtime profile for store backends.
|
|
429
|
-
*
|
|
430
|
+
* Runtime profile for store backends — the deployment's TOPOLOGY. REQUIRED under
|
|
431
|
+
* `preset: 'production'` (boot fails without it); defaults to 'memory' elsewhere.
|
|
432
|
+
* - 'memory': Uses in-memory stores. Correct for exactly ONE instance.
|
|
430
433
|
* - 'distributed': Requires durable adapters for events, and for any enabled
|
|
431
434
|
* shared subsystems such as caching/queryCache/rate limiting.
|
|
432
435
|
* Idempotency remains per-resource opt-in: memory-backed stores are rejected,
|
|
@@ -808,7 +811,7 @@ interface CreateAppOptions {
|
|
|
808
811
|
* - `'number'` — LOSSY above `Number.MAX_SAFE_INTEGER` (2^53-1). Only for
|
|
809
812
|
* an audited, bounded range.
|
|
810
813
|
*/
|
|
811
|
-
serializeBigInt?:
|
|
814
|
+
serializeBigInt?: false | "number" | "string";
|
|
812
815
|
/**
|
|
813
816
|
* Domain modules — one entry per self-contained domain package.
|
|
814
817
|
*
|
|
@@ -819,6 +822,19 @@ interface CreateAppOptions {
|
|
|
819
822
|
* always before the app-level entry for that phase. See [[modules]].
|
|
820
823
|
*/
|
|
821
824
|
modules?: ReadonlyArray<ArcModuleInput>;
|
|
825
|
+
/**
|
|
826
|
+
* Host collaborators modules declare in `requires.ports` (a connection, an outbox, a
|
|
827
|
+
* calendar…). Every `'required'` port of every active module is checked before any module
|
|
828
|
+
* boots — all gaps in one error — and each module's setup phases receive only the ports it
|
|
829
|
+
* declared, as `context.ports`. Nothing is defaulted.
|
|
830
|
+
*/
|
|
831
|
+
ports?: ArcPorts;
|
|
832
|
+
/**
|
|
833
|
+
* The module graph check. `events: 'strict'` fails boot when an event has two owners, is
|
|
834
|
+
* published outside its module's namespace, or is consumed with no active publisher and no
|
|
835
|
+
* `externalEvents` entry. Default `'off'`. The graph is always on `fastify.arc.moduleGraph`.
|
|
836
|
+
*/
|
|
837
|
+
moduleGraph?: ModuleGraphOptions;
|
|
822
838
|
/**
|
|
823
839
|
* Resources to register. An ARRAY is resolved at module import, so every
|
|
824
840
|
* adapter must be constructible synchronously. A FACTORY (sync or async,
|
|
@@ -939,9 +955,15 @@ interface CreateAppOptions {
|
|
|
939
955
|
* ```
|
|
940
956
|
*
|
|
941
957
|
* Runs after option validation (config bugs fail fast without touching
|
|
942
|
-
* the DB).
|
|
958
|
+
* the DB). Return a disposer to hand cleanup to arc: it runs once, on
|
|
959
|
+
* `app.close()` after every plugin's `onClose`, AND on a boot that fails —
|
|
960
|
+
* including one that fails before Fastify exists, where no `onClose` can.
|
|
961
|
+
*
|
|
962
|
+
* ```ts
|
|
963
|
+
* beforeBoot: async () => { await mongoose.connect(uri); return () => mongoose.disconnect(); },
|
|
964
|
+
* ```
|
|
943
965
|
*/
|
|
944
|
-
beforeBoot?: () => void | Promise<void>;
|
|
966
|
+
beforeBoot?: () => void | BootDisposer | Promise<void | BootDisposer>;
|
|
945
967
|
/**
|
|
946
968
|
* Custom plugin registration — runs after Arc core (security, auth, events)
|
|
947
969
|
* but before `bootstrap` and `resources`.
|
|
@@ -987,27 +1009,4 @@ interface CreateAppOptions {
|
|
|
987
1009
|
onClose?: (fastify: FastifyInstance) => void | Promise<void>;
|
|
988
1010
|
}
|
|
989
1011
|
//#endregion
|
|
990
|
-
|
|
991
|
-
/** Eager glob result: `{ '/path/to/file.ts': resourceModule }` */
|
|
992
|
-
type EagerGlobResult = Record<string, unknown>;
|
|
993
|
-
/** Lazy glob result: `{ '/path/to/file.ts': () => Promise<unknown> }` */
|
|
994
|
-
type LazyGlobResult = Record<string, () => Promise<unknown>>;
|
|
995
|
-
/**
|
|
996
|
-
* Normalize an eager `import.meta.glob` result into a `ResourceLike[]`.
|
|
997
|
-
*
|
|
998
|
-
* Accepts either:
|
|
999
|
-
* - `{ import: 'default' }` form: values are the resource directly
|
|
1000
|
-
* - default form: values are the full module — picks first export with `toPlugin()`
|
|
1001
|
-
*
|
|
1002
|
-
* Throws if any module doesn't yield a valid `ResourceLike`.
|
|
1003
|
-
*/
|
|
1004
|
-
declare function preloadResources(globResult: EagerGlobResult): ResourceLike[];
|
|
1005
|
-
/**
|
|
1006
|
-
* Normalize a lazy `import.meta.glob` result into a `Promise<ResourceLike[]>`.
|
|
1007
|
-
*
|
|
1008
|
-
* Use this when resources depend on prior bootstrap (e.g., engine init) and
|
|
1009
|
-
* cannot be evaluated at import time of the preload file.
|
|
1010
|
-
*/
|
|
1011
|
-
declare function preloadResourcesAsync(globResult: LazyGlobResult): Promise<ResourceLike[]>;
|
|
1012
|
-
//#endregion
|
|
1013
|
-
export { RawBodyOptions as a, BetterAuthOption as c, JwtAuthOption as d, MultipartOptions as i, CustomAuthenticatorOption as l, preloadResourcesAsync as n, UnderPressureOptions as o, CreateAppOptions as r, AuthOption as s, preloadResources as t, CustomPluginAuthOption as u };
|
|
1012
|
+
export { UnderPressureOptions as a, CustomAuthenticatorOption as c, RawBodyOptions as i, CustomPluginAuthOption as l, CreateAppOptions as n, AuthOption as o, MultipartOptions as r, BetterAuthOption as s, BootDisposer as t, JwtAuthOption as u };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { i as RequestScope, n as Mandate } from "./types-Ddl9OjmE.mjs";
|
|
3
|
-
import { l as PermissionCheck, s as AuthorizationDecision, u as PermissionContext } from "./base-
|
|
3
|
+
import { c as DataPolicy, l as PermissionCheck, s as AuthorizationDecision, u as PermissionContext } from "./base-CZyixEQR.mjs";
|
|
4
4
|
import { r as CacheStore, t as CacheLogger } from "./interface-BOk3YnTz.mjs";
|
|
5
|
+
import "./resourceRateLimit-Wf6d6FL9.mjs";
|
|
5
6
|
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
|
6
7
|
//#region src/permissions/agent.d.ts
|
|
7
8
|
/**
|
|
@@ -194,16 +195,6 @@ declare function normalizeToDecision(result: PermissionCheckReturn): Authorizati
|
|
|
194
195
|
* nuance lives in {@link evaluateAndApplyPermission}, not here.
|
|
195
196
|
*/
|
|
196
197
|
declare function evaluatePermissionDecision(check: PermissionCheck, context: PermissionContext): Promise<AuthorizationDecision>;
|
|
197
|
-
/**
|
|
198
|
-
* Minimal shape of a Fastify request that can receive permission side-effects.
|
|
199
|
-
* We avoid depending on the full augmented `FastifyRequest` type here because
|
|
200
|
-
* `_policyFilters` / `scope` are declared via ambient module augmentation in
|
|
201
|
-
* multiple places and the unaugmented interface is what the core routers see.
|
|
202
|
-
*/
|
|
203
|
-
type RequestSink = FastifyRequest & {
|
|
204
|
-
_policyFilters?: Record<string, unknown>;
|
|
205
|
-
scope?: RequestScope;
|
|
206
|
-
};
|
|
207
198
|
/**
|
|
208
199
|
* Apply an allowed {@link AuthorizationDecision} to a Fastify request — conjoins
|
|
209
200
|
* the decision's row-level `policy` into `_policyFilters` and conditionally
|
|
@@ -222,7 +213,7 @@ type RequestSink = FastifyRequest & {
|
|
|
222
213
|
* This is the enforcement point (PEP) — the ONE place scope + data policy are
|
|
223
214
|
* installed (and the obligation seam lives).
|
|
224
215
|
*/
|
|
225
|
-
declare function applyAuthorizationDecision(decision: AuthorizationDecision,
|
|
216
|
+
declare function applyAuthorizationDecision(decision: AuthorizationDecision, req: FastifyRequest): void;
|
|
226
217
|
//#endregion
|
|
227
218
|
//#region src/permissions/context.d.ts
|
|
228
219
|
/**
|
|
@@ -251,17 +242,72 @@ declare function allow(extra?: Omit<AuthorizationDecision, "effect">): Authoriza
|
|
|
251
242
|
*/
|
|
252
243
|
declare function deny(reason?: string): AuthorizationDecision;
|
|
253
244
|
/**
|
|
254
|
-
*
|
|
245
|
+
* The row policy an `allowPublic` gate applies to the callers it admits: a
|
|
246
|
+
* filter, or a function of the request that returns one.
|
|
247
|
+
*
|
|
248
|
+
* The function form is the scope-aware one — it sees the caller, so anonymous
|
|
249
|
+
* visitors, the row's author and staff can each get a different filter from ONE
|
|
250
|
+
* gate. Return `{}` to admit a caller unrestricted (e.g. staff); returning
|
|
251
|
+
* nothing is treated as a bug, not as "no filter" (see {@link allowPublic}).
|
|
252
|
+
*/
|
|
253
|
+
type PublicPolicy<TDoc = Record<string, unknown>> = DataPolicy | ((ctx: PermissionContext<TDoc>) => DataPolicy | Promise<DataPolicy>);
|
|
254
|
+
/** Options for {@link allowPublic}. */
|
|
255
|
+
interface AllowPublicOptions<TDoc = Record<string, unknown>> {
|
|
256
|
+
/**
|
|
257
|
+
* Narrow what anyone admitted by this gate can read or write. Enforced where
|
|
258
|
+
* every other row policy is: ANDed into the repository query for `list`, into
|
|
259
|
+
* the compound lookup for `get` / `update` / `delete`, into aggregations, and
|
|
260
|
+
* per event on realtime feeds. A caller cannot widen it with a query
|
|
261
|
+
* parameter — `?status=hidden` is conjoined with the policy, not substituted
|
|
262
|
+
* for it.
|
|
263
|
+
*/
|
|
264
|
+
policy?: PublicPolicy<TDoc>;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Allow public access (no authentication required) — optionally row-filtered.
|
|
268
|
+
*
|
|
269
|
+
* Without options, anyone passes and sees everything the query asks for.
|
|
270
|
+
*
|
|
271
|
+
* With `policy`, anyone still passes, but only the rows the policy admits are
|
|
272
|
+
* readable (or writable). This is the declarative form of a check that returns
|
|
273
|
+
* `allow({ policy })`, and it exists because the hand-written form has a trap:
|
|
274
|
+
* a check function is treated as PROTECTED unless it carries `_isPublic`, so a
|
|
275
|
+
* custom "public, but only published rows" check that forgets to set the flag
|
|
276
|
+
* answers every anonymous visitor with a 401 — the public page silently
|
|
277
|
+
* becomes a login wall. `allowPublic({ policy })` sets it for you.
|
|
278
|
+
*
|
|
279
|
+
* Fail-closed on both ends:
|
|
280
|
+
* - a STATIC policy must be a non-empty object — `{}` filters nothing and is
|
|
281
|
+
* almost certainly a mistake, so it throws at definition time (use
|
|
282
|
+
* `allowPublic()` for an unrestricted gate);
|
|
283
|
+
* - a RESOLVER that returns anything but an object throws per request, which
|
|
284
|
+
* arc answers as a 403 for everyone. A forgotten branch that falls off the
|
|
285
|
+
* end of the function must not quietly mean "no filter". Return `{}` when a
|
|
286
|
+
* caller genuinely should be unrestricted.
|
|
287
|
+
*
|
|
288
|
+
* Composing: inside `anyOf`, the FIRST granting branch wins, and a public
|
|
289
|
+
* branch grants everyone — so `anyOf(allowPublic({ policy }), requireRoles("admin"))`
|
|
290
|
+
* filters admins too. Put the privileged branch first, or use the resolver
|
|
291
|
+
* form and return `{}` for staff.
|
|
255
292
|
*
|
|
256
293
|
* @example
|
|
257
294
|
* ```typescript
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
*
|
|
295
|
+
* // Strangers see only published reviews, whatever filter they send.
|
|
296
|
+
* list: allowPublic({ policy: { status: { $in: ["published", "flagged"] } } }),
|
|
297
|
+
*
|
|
298
|
+
* // Scope-aware: the author also sees their own pending review; staff see all.
|
|
299
|
+
* list: allowPublic({
|
|
300
|
+
* policy: (ctx) => {
|
|
301
|
+
* const scope = scopeOf(ctx);
|
|
302
|
+
* if (isElevated(scope)) return {};
|
|
303
|
+
* const visible = { status: { $in: ["published", "flagged"] } };
|
|
304
|
+
* const userId = getUserId(scope);
|
|
305
|
+
* return userId ? { $or: [visible, { authorId: userId }] } : visible;
|
|
306
|
+
* },
|
|
307
|
+
* }),
|
|
262
308
|
* ```
|
|
263
309
|
*/
|
|
264
|
-
declare function allowPublic(): PermissionCheck
|
|
310
|
+
declare function allowPublic<TDoc = Record<string, unknown>>(options?: AllowPublicOptions<TDoc>): PermissionCheck<TDoc>;
|
|
265
311
|
/**
|
|
266
312
|
* Require authentication (any authenticated user).
|
|
267
313
|
*
|
|
@@ -549,12 +595,23 @@ declare function createDynamicPermissionMatrix(config: DynamicPermissionMatrixCo
|
|
|
549
595
|
* aren't, so a consumer that holds the caller's scope (a FE that knows the
|
|
550
596
|
* active branch's role) can decide it client-side — the piece a flat `roles`
|
|
551
597
|
* requirement could not express.
|
|
598
|
+
* - `member` — any MEMBER of the caller's active organization passes
|
|
599
|
+
* (`requireOrgMembership()`), or a holder of one of `roles` when it is an `anyOf`
|
|
600
|
+
* with role branches. Membership is a fact the client holds, so it is decidable.
|
|
552
601
|
* - `authenticated` — the check reads request-time facts (custom auth, service
|
|
553
602
|
* scope, ownership, grants) that no static analysis can decide; the definitive
|
|
554
603
|
* answer is computed per request. Treat as "server decides".
|
|
555
604
|
*/
|
|
556
605
|
type PermissionRequirement = {
|
|
557
606
|
readonly kind: "public";
|
|
607
|
+
/**
|
|
608
|
+
* `true` for `allowPublic({ policy })`: anyone passes the gate, but a row
|
|
609
|
+
* policy narrows what they can read or write. Absent for a plain
|
|
610
|
+
* `allowPublic()`, which exposes every row the query asks for. The access
|
|
611
|
+
* DECISION is the same (allow); the exposure is not, and an audit of the
|
|
612
|
+
* public surface needs to tell them apart.
|
|
613
|
+
*/
|
|
614
|
+
readonly rowFiltered?: true;
|
|
558
615
|
} | {
|
|
559
616
|
readonly kind: "roles";
|
|
560
617
|
readonly roles: readonly string[];
|
|
@@ -573,6 +630,10 @@ type PermissionRequirement = {
|
|
|
573
630
|
readonly roles?: readonly string[];
|
|
574
631
|
/** See `roles.conditional` — the composite also has an opaque/contradictory branch. */
|
|
575
632
|
readonly conditional?: boolean;
|
|
633
|
+
} | {
|
|
634
|
+
readonly kind: "member";
|
|
635
|
+
/** Roles that ALSO grant without membership (the role branches of an `anyOf`). */
|
|
636
|
+
readonly roles?: readonly string[];
|
|
576
637
|
} | {
|
|
577
638
|
readonly kind: "authenticated";
|
|
578
639
|
} |
|
|
@@ -620,6 +681,8 @@ declare function explainAccess(check: PermissionCheck, principal?: {
|
|
|
620
681
|
orgRoles?: readonly string[];
|
|
621
682
|
/** The caller's scope-context values (e.g. `{ branchRole: "head_office" }`) — supply to decide a `scoped` gate. */
|
|
622
683
|
scope?: Readonly<Record<string, string | undefined>>;
|
|
684
|
+
/** Whether the caller is a member of the active organization — supply to decide a `member` gate. */
|
|
685
|
+
member?: boolean;
|
|
623
686
|
}): AccessExplanation;
|
|
624
687
|
/**
|
|
625
688
|
* Introspect a whole permission map (`{ list, get, create, ... }` or any
|
|
@@ -922,7 +985,7 @@ declare function requireOrgInScope<TDoc = Record<string, unknown>>(target: strin
|
|
|
922
985
|
*/
|
|
923
986
|
declare function requireTeamMembership<TDoc = Record<string, unknown>>(): PermissionCheck<TDoc>;
|
|
924
987
|
declare namespace presets_d_exports {
|
|
925
|
-
export { adminOnly, authenticated, fullPublic, ownerWithAdminBypass, permissionMatrix, publicRead, publicReadAdminWrite, readOnly };
|
|
988
|
+
export { PermissionOverrides, adminOnly, authenticated, fullPublic, ownerWithAdminBypass, permissionMatrix, publicRead, publicReadAdminWrite, readOnly };
|
|
926
989
|
}
|
|
927
990
|
/**
|
|
928
991
|
* ResourcePermissions shape — matches the type in types/index.ts
|
|
@@ -1017,7 +1080,7 @@ declare function readOnly<TDoc = Record<string, unknown>>(overrides?: Permission
|
|
|
1017
1080
|
* A CLIENT MUST treat an unrecognised type as DENIED, never as permitted — the
|
|
1018
1081
|
* next type added here will otherwise read as "allowed" on every older client.
|
|
1019
1082
|
*/
|
|
1020
|
-
type PermissionEntryType = "public" | "authenticated" | "roles" | "scoped" | "denied";
|
|
1083
|
+
type PermissionEntryType = "public" | "authenticated" | "roles" | "scoped" | "member" | "denied";
|
|
1021
1084
|
interface PermissionEntry {
|
|
1022
1085
|
type: PermissionEntryType;
|
|
1023
1086
|
roles: string[];
|
|
@@ -1095,4 +1158,4 @@ declare function introspectModule(mod: Record<string, unknown>): Record<string,
|
|
|
1095
1158
|
declare function introspectRegistry(registry: PermissionMatrixRegistry): Record<string, Record<string, PermissionEntry>>;
|
|
1096
1159
|
declare function buildPermissionMatrix(options?: PermissionMatrixOptions): PermissionMatrix;
|
|
1097
1160
|
//#endregion
|
|
1098
|
-
export {
|
|
1161
|
+
export { deny as $, GrantResolution as A, explainAccess as B, requireScopeContext as C, createRoleHierarchy as D, RoleHierarchy as E, AccessExplanation as F, createDynamicPermissionMatrix as G, DynamicPermissionMatrix as H, PermissionRequirement as I, PublicPolicy as J, createOrgPermissions as K, collectPublicSurface as L, modeSatisfies as M, requireGrant as N, GRANT_MODES as O, conjoinPolicyFilters as P, anyOf as Q, describePermission as R, requireOrgRole as S, requireTeamMembership as T, DynamicPermissionMatrixConfig as U, ConnectEventsOptions as V, PermissionEventBus as W, allow as X, allOf as Y, allowPublic as Z, publicRead as _, requireMandate as _t, PermissionMatrixRegistry as a, requireRoles as at, requireOrgInScope as b, introspectModule as c, scopeOf as ct, adminOnly as d, evaluatePermissionDecision as dt, denyAll as et, authenticated as f, normalizeToDecision as ft, presets_d_exports as g, requireDPoP as gt, permissionMatrix as h, requireAgentScope as ht, PermissionMatrixOptions as i, requirePlatformRole as it, RequireGrantOptions as j, GrantMode as k, introspectRegistry as l, PermissionCheckReturn as lt, ownerWithAdminBypass as m, RequireMandateOptions as mt, PermissionEntryType as n, requireAuth as nt, buildPermissionMatrix as o, roles as ot, fullPublic as p, RequireAgentScopeOptions as pt, AllowPublicOptions as q, PermissionMatrix as r, requireOwnership as rt, introspectCheck as s, when as st, PermissionEntry as t, not as tt, PermissionOverrides as u, applyAuthorizationDecision as ut, publicReadAdminWrite as v, requireServiceScope as w, requireOrgMembership as x, readOnly as y, describePermissionMap as z };
|