@classytic/arc 2.34.0 → 2.36.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/{BaseController-CbkuhNI2.mjs → BaseController-CTJKm6Cb.mjs} +95 -14
- package/dist/{EventTransport-tq4CEB-q.mjs → EventTransport-D23Uvhg4.mjs} +1 -1
- package/dist/{HookSystem-DqXkMXkB.mjs → HookSystem-DgwxNZTx.mjs} +6 -4
- package/dist/{ResourceRegistry-DoALUlOO.mjs → ResourceRegistry-DNuYVbmv.mjs} +2 -2
- package/dist/{pipeline-q69DZzgG.mjs → actionPermissions-D97DniUQ.mjs} +30 -7
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +2 -2
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +6 -6
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-CMMLWmuZ.mjs → authorizationDecision-EsiY3nUu.mjs} +2 -2
- package/dist/{base-Csjc2oF-.d.mts → base-C-NL2fTi.d.mts} +16 -1
- package/dist/{buildHandler-BrdYrG_1.mjs → buildHandler-Dohd2JuY.mjs} +4 -4
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-BcGmvnHh.mjs → caching-CP3GLJ7U.mjs} +2 -2
- package/dist/cleanup/index.d.mts +2 -2
- package/dist/cleanup/index.mjs +4 -4
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +3 -3
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -2
- package/dist/cli/commands/init.mjs +2 -2
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-BxCoxmiN.mjs → constants-DUoKAGYD.mjs} +1 -1
- package/dist/context/index.d.mts +16 -1
- package/dist/context/index.mjs +64 -4
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +7 -8
- package/dist/{core-BYKa8wHu.mjs → core-DTXsiNTJ.mjs} +3 -3
- package/dist/{createActionRouter-D6T0jWhS.mjs → createActionRouter-CZz6JO93.mjs} +27 -64
- package/dist/{createAggregationRouter-QLV2PrWP.mjs → createAggregationRouter-DKrGv_EC.mjs} +7 -7
- package/dist/defineAggregation-CpQfcM8R.mjs +25 -0
- package/dist/{defineResource-ZhuLonLm.mjs → defineResource-DWzjyxb2.mjs} +62 -66
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +3 -3
- package/dist/{elevation-B0tlY8y1.mjs → elevation-D_cmo80j.mjs} +4 -4
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-C7xBqHsI.mjs → errorHandler-2RT0hLSI.mjs} +3 -3
- package/dist/{errors-Cd_yy7aW.mjs → errors-DDKni6Tz.mjs} +1 -1
- package/dist/{eventPlugin-DSNEZWfV.d.mts → eventPlugin-B47sfCJ8.d.mts} +1 -1
- package/dist/{eventPlugin-Dar8qRaj.mjs → eventPlugin-c3YwGzz9.mjs} +5 -5
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +5 -5
- package/dist/events/transports/redis-stream-entry.mjs +1 -1
- package/dist/events/transports/redis.mjs +1 -1
- package/dist/factory/index.d.mts +5 -5
- package/dist/factory/index.mjs +5 -6
- package/dist/{fastify-augmentation-DVsTAy6X.d.mts → fastify-augmentation-Bk_9PoiV.d.mts} +3 -3
- package/dist/{fields-CojeUkS4.mjs → fields-DdP225wt.mjs} +1 -1
- package/dist/{generate-DiB0nHPR.mjs → generate-B1bKdcV9.mjs} +2 -2
- package/dist/{headers-CveNO9gR.mjs → headers-DKslnhey.mjs} +2 -2
- package/dist/{health-CasG2A28.mjs → health-k6NODS8f.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.mjs +22 -56
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-B-DvUzsr.d.mts → index-BtYoMip1.d.mts} +21 -3
- package/dist/{index-BcR2bFZQ.d.mts → index-C01wWGJt.d.mts} +33 -105
- package/dist/{index-C5NnMEKF.d.mts → index-C50BUxKs.d.mts} +1 -1
- package/dist/{index-CFAJEWCX.d.mts → index-RdpLP71b.d.mts} +7 -30
- package/dist/{index-ugr1tQlW.d.mts → index-eyg5WEcy.d.mts} +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +11 -12
- package/dist/{init-mdJ-v4Xp.mjs → init-LuGxIbQ_.mjs} +1 -1
- package/dist/integrations/event-gateway.mjs +2 -2
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +2 -2
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +2 -2
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +3 -3
- package/dist/integrations/streamline.mjs +3 -3
- package/dist/integrations/webhooks.d.mts +4 -2
- package/dist/integrations/webhooks.mjs +28 -27
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.mjs +1 -1
- package/dist/{interface-DznJrm9R.mjs → interface-B7awDx3b.mjs} +1 -1
- package/dist/{jsonBody-CfGH-GxO.mjs → jsonBody-CiHih3ZU.mjs} +2 -2
- package/dist/{keys-WeKvY1dE.mjs → keys-BcNl12HN.mjs} +1 -1
- package/dist/{loadResources-Bj-aSsXi.mjs → loadResources-DGlfRQc9.mjs} +2 -2
- package/dist/{loadResourcesFromEntry-DwaxNcE2.mjs → loadResourcesFromEntry-VYPGSas8.mjs} +2 -2
- package/dist/logger/index.d.mts +23 -4
- package/dist/logger/index.mjs +50 -7
- package/dist/{mcpPlugin-DX3PHD7K.mjs → mcpPlugin-NxSlc-Ks.mjs} +15 -16
- package/dist/{memory-qYSB7rMQ.mjs → memory-BU-C-MV3.mjs} +2 -2
- package/dist/{metrics-D7uchLjN.mjs → metrics-7_1GbJpl.mjs} +2 -2
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.mjs +7 -4
- package/dist/{module-CwKsgZXp.mjs → module-CQNHzE7g.mjs} +1 -1
- package/dist/{multipartBody-4w-S3-PU.mjs → multipartBody-Bi5yqW0M.mjs} +1 -1
- package/dist/{openapi-CkV5mQ53.mjs → openapi-RpNbPBL-.mjs} +6 -6
- package/dist/outbox-admin/index.d.mts +2 -2
- package/dist/outbox-admin/index.mjs +4 -4
- package/dist/{outbox-module-D1QfHqO4.mjs → outbox-module-ClcFrq98.mjs} +6 -4
- package/dist/{outbox-module-C1Bs_FXF.d.mts → outbox-module-b1TyDGGi.d.mts} +24 -1
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-CP47jdi7.mjs → permissions-DgPrZsJh.mjs} +36 -9
- package/dist/{pipe-BzzoEhHj.mjs → pipe-Cjy1UiXX.mjs} +2 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plugins/index.d.mts +92 -7
- package/dist/plugins/index.mjs +168 -17
- package/dist/plugins/response-cache.mjs +2 -2
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-B7xf8qZF.mjs → pluralize-B7m0dPm8.mjs} +1 -1
- package/dist/{preloadResources-g07ldtzh.d.mts → preloadResources-BuutdWgr.d.mts} +54 -270
- package/dist/{createApp-zR-DEesr.mjs → preloadResources-CjnW4iIX.mjs} +170 -34
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +2 -2
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +3 -3
- package/dist/presets/search.d.mts +9 -47
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-BAPijK_A.mjs → presets-CsGg8B58.mjs} +4 -4
- package/dist/{projection-BKM0Ui-s.mjs → projection-koISNyQo.mjs} +2 -2
- package/dist/{queryCachePlugin-DhsZ0ZIc.mjs → queryCachePlugin-DHueQT9O.mjs} +5 -5
- package/dist/{rateLimitKey-XngqVNEV.mjs → rateLimitKey-Bma8VXDO.mjs} +1 -1
- package/dist/{realtime-G1TC6Yzc.mjs → realtime-BBoC91Bz.mjs} +9 -9
- package/dist/{rateLimit-D4-ASwsI.mjs → registerRoute-BTgORTlR.mjs} +114 -3
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +3 -3
- package/dist/{registry-CLxCR5LF.mjs → registry-BzvRCYS6.mjs} +15 -56
- package/dist/{renewingLease-BnWtbA2U.mjs → renewingLease-CgIGh0Ab.mjs} +14 -2
- package/dist/{replyHelpers-BSBVCwL3.mjs → replyHelpers-BN16KPHr.mjs} +2 -2
- package/dist/{requestContext-uYE35JxI.mjs → requestContext-B93dmpf0.mjs} +1 -1
- package/dist/{rolldown-runtime-DNg-KNCk.mjs → rolldown-runtime-JJWfp8rp.mjs} +1 -1
- package/dist/{runtimeCapabilities-Dm88DaTW.mjs → runtimeCapabilities-jK99Ciw_.mjs} +1 -1
- package/dist/{schedules-CAcZgia0.mjs → schedules-CKKEL21P.mjs} +6 -4
- package/dist/{schemaConverter-XH1RZRyu.mjs → schemaConverter-gg0_aUPF.mjs} +19 -32
- package/dist/{schemaIR-CDvclAew.mjs → schemaIR-CngYvpCF.mjs} +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +5 -5
- package/dist/{scope-BaWcqBvr.mjs → scope-B1RsHdjF.mjs} +4 -4
- package/dist/simpleEqualityMatcher-_9NAMHUD.mjs +43 -0
- package/dist/{sse-Cf0jUHsh.mjs → sse-Bxt03Hk5.mjs} +5 -5
- package/dist/{sseStream-Bvpi-UXQ.mjs → sseStream-BMHTLlhR.mjs} +2 -2
- package/dist/{store-helpers-B88p99Z2.mjs → store-helpers-Brt8OxWZ.mjs} +1 -1
- package/dist/{streaming-DsT1B5zJ.mjs → streaming-CiTJW8kZ.mjs} +1 -1
- package/dist/{subscribe-helpers-CLIOHsOK.mjs → subscribe-helpers-B4fNHRNc.mjs} +21 -49
- package/dist/sync/changelog.mjs +1 -1
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +6 -6
- package/dist/testing/index.mjs +10 -11
- package/dist/testing/outboxStoreContract.mjs +1 -1
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/{transactionContext-BYtWnwAS.mjs → transactionContext-D2HwJM2z.mjs} +1 -1
- package/dist/{typeGuards-jjKJDN13.mjs → typeGuards-IE1laMDf.mjs} +1 -1
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-CoqIRrkY.mjs → types-B8lwJv9Q.mjs} +10 -53
- package/dist/{types-BfC83KsP.d.mts → types-BXnTOsXP.d.mts} +1 -1
- package/dist/{types-BcTumAz_.d.mts → types-DDD5RKTu.d.mts} +30 -87
- package/dist/{types-ChuShpCP.d.mts → types-Ddl9OjmE.d.mts} +18 -121
- package/dist/usage/index.d.mts +2 -2
- package/dist/usage/index.mjs +0 -0
- package/dist/{userHelpers-CWF5pbZD.mjs → userHelpers-xQAi5bPF.mjs} +1 -1
- package/dist/utils/index.d.mts +16 -42
- package/dist/utils/index.mjs +11 -11
- package/dist/{utils-h1V_sT-t.mjs → utils-DgNFsJ2c.mjs} +3 -3
- package/dist/{validate-CdQlz52F.mjs → validate-DI3L5V9w.mjs} +2 -2
- package/dist/{versioning-rZbyLVD-.mjs → versioning-COpAyfpZ.mjs} +3 -3
- package/package.json +8 -8
- package/dist/actionPermissions-CUeCmpUd.mjs +0 -25
- package/dist/defineAggregation-Nv-DwfOf.mjs +0 -48
- package/dist/preloadResources-BkyqeTDz.mjs +0 -46
- package/dist/registerRoute-Ba8v0PCa.mjs +0 -113
- package/dist/repositoryFilter-BANpz6BX.mjs +0 -78
- package/dist/simpleEqualityMatcher-Se8VrsaP.mjs +0 -69
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as requireSingleHeaderValue } from "../headers-
|
|
3
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
4
|
-
import { t as createIdempotencyResult } from "../interface-
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as requireSingleHeaderValue } from "../headers-DKslnhey.mjs";
|
|
3
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-Brt8OxWZ.mjs";
|
|
4
|
+
import { t as createIdempotencyResult } from "../interface-B7awDx3b.mjs";
|
|
5
5
|
import { and, eq, exists, gt, lt, or, startsWith } from "@classytic/repo-core/filter";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import fp from "fastify-plugin";
|
|
@@ -266,61 +266,27 @@ var MemoryIdempotencyStore = class {
|
|
|
266
266
|
//#endregion
|
|
267
267
|
//#region src/idempotency/idempotencyPlugin.ts
|
|
268
268
|
/**
|
|
269
|
-
* Idempotency
|
|
269
|
+
* Idempotency — duplicate-request protection for mutations.
|
|
270
270
|
*
|
|
271
|
-
*
|
|
272
|
-
*
|
|
271
|
+
* AUTH ORDER MATTERS: `idempotency.middleware` must run AFTER authentication
|
|
272
|
+
* in the preHandler chain, so the fingerprint includes the real caller and a
|
|
273
|
+
* key cannot replay another user's response. `createCrudRouter` wires this for
|
|
274
|
+
* mutation routes; custom routes do it themselves:
|
|
275
|
+
* `preHandler: [fastify.authenticate, fastify.idempotency.middleware]`.
|
|
273
276
|
*
|
|
274
|
-
*
|
|
277
|
+
* GUARANTEE — best-effort effectively-once, NOT exactly-once. A distributed
|
|
278
|
+
* lock makes concurrent same-key requests 409, the key includes a body+caller
|
|
279
|
+
* fingerprint (a different body under one key is its own operation), and a
|
|
280
|
+
* completed result replays. The business effect is not exactly-once, because
|
|
281
|
+
* the domain write and the idempotency record are different systems:
|
|
282
|
+
* - a crash after the DB write but before the record (preSerialization) lets a
|
|
283
|
+
* retry re-execute;
|
|
284
|
+
* - a handler outrunning `lockTimeoutMs` can overlap its own retry — size that
|
|
285
|
+
* above the slowest protected handler.
|
|
275
286
|
*
|
|
276
|
-
*
|
|
277
|
-
* (
|
|
278
|
-
*
|
|
279
|
-
* identity, preventing cross-user replay attacks.
|
|
280
|
-
*
|
|
281
|
-
* Arc's `createCrudRouter` does this automatically for mutation routes.
|
|
282
|
-
* For custom routes, wire it manually:
|
|
283
|
-
*
|
|
284
|
-
* ```typescript
|
|
285
|
-
* fastify.post('/orders', {
|
|
286
|
-
* preHandler: [fastify.authenticate, fastify.idempotency.middleware],
|
|
287
|
-
* }, handler);
|
|
288
|
-
* ```
|
|
289
|
-
*
|
|
290
|
-
* @example
|
|
291
|
-
* import { idempotencyPlugin } from '@classytic/arc/idempotency';
|
|
292
|
-
*
|
|
293
|
-
* await fastify.register(idempotencyPlugin, {
|
|
294
|
-
* enabled: true,
|
|
295
|
-
* headerName: 'idempotency-key',
|
|
296
|
-
* ttlMs: 86400000, // 24 hours
|
|
297
|
-
* });
|
|
298
|
-
*
|
|
299
|
-
* // Client sends:
|
|
300
|
-
* // POST /api/orders
|
|
301
|
-
* // Idempotency-Key: order-123-abc
|
|
302
|
-
*
|
|
303
|
-
* // If same key sent again within TTL, returns cached response
|
|
304
|
-
*
|
|
305
|
-
* ## Guarantee: best-effort effectively-once, NOT exactly-once
|
|
306
|
-
*
|
|
307
|
-
* The plugin gives strong request replay + overlap protection: a
|
|
308
|
-
* distributed lock guards execution (concurrent same-key requests get
|
|
309
|
-
* 409), the store key includes a body/caller fingerprint (a different
|
|
310
|
-
* body under the same key executes as its own operation instead of
|
|
311
|
-
* replaying someone else's response), and a completed result replays on
|
|
312
|
-
* hit. It does NOT make the business effect exactly-once, because the
|
|
313
|
-
* domain write and the idempotency record live in different systems:
|
|
314
|
-
*
|
|
315
|
-
* - a crash after the DB mutation but before the result is recorded
|
|
316
|
-
* (preSerialization) lets a retry re-execute the mutation;
|
|
317
|
-
* - a handler that outruns `lockTimeoutMs` can overlap its own retry —
|
|
318
|
-
* size the lock timeout above the slowest protected handler.
|
|
319
|
-
*
|
|
320
|
-
* For mutations where re-execution is unacceptable, write the idempotency
|
|
321
|
-
* record in the SAME transaction as the business write inside the handler
|
|
322
|
-
* (the store contract is public — `@classytic/arc/idempotency` exports it),
|
|
323
|
-
* or make the handler naturally idempotent (upserts, compare-and-set).
|
|
287
|
+
* Where re-execution is unacceptable: write the record in the SAME transaction
|
|
288
|
+
* as the business write (the store contract is exported), or make the handler
|
|
289
|
+
* naturally idempotent (upsert, compare-and-set).
|
|
324
290
|
*/
|
|
325
291
|
const HEADER_IDEMPOTENCY_REPLAYED = "x-idempotency-replayed";
|
|
326
292
|
const HEADER_IDEMPOTENCY_KEY = "x-idempotency-key";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as RequestScope, n as Mandate } from "./types-
|
|
3
|
-
import { l as PermissionCheck, s as AuthorizationDecision, u as PermissionContext } from "./base-
|
|
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-C-NL2fTi.mjs";
|
|
4
4
|
import { r as CacheStore, t as CacheLogger } from "./interface-BOk3YnTz.mjs";
|
|
5
5
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
6
6
|
//#region src/permissions/agent.d.ts
|
|
@@ -567,6 +567,14 @@ type PermissionRequirement = {
|
|
|
567
567
|
readonly conditional?: boolean;
|
|
568
568
|
} | {
|
|
569
569
|
readonly kind: "authenticated";
|
|
570
|
+
} |
|
|
571
|
+
/**
|
|
572
|
+
* Nobody passes — an explicit `denyAll()`. Distinct from "no rule found",
|
|
573
|
+
* which is `public` (public-by-omission): one is a closed door, the other is
|
|
574
|
+
* an open one, and before this existed both were reported as `authenticated`.
|
|
575
|
+
*/
|
|
576
|
+
{
|
|
577
|
+
readonly kind: "denied";
|
|
570
578
|
};
|
|
571
579
|
/**
|
|
572
580
|
* Extract a check's static requirement from its `PermissionCheckMeta`. Public
|
|
@@ -991,7 +999,17 @@ declare function fullPublic<TDoc = Record<string, unknown>>(overrides?: Permissi
|
|
|
991
999
|
declare function readOnly<TDoc = Record<string, unknown>>(overrides?: PermissionOverrides<TDoc>): ResourcePermissions<TDoc>;
|
|
992
1000
|
//#endregion
|
|
993
1001
|
//#region src/permissions/matrix.d.ts
|
|
994
|
-
|
|
1002
|
+
/**
|
|
1003
|
+
* `denied` is a CLOSED door — an explicit `denyAll()`. It is not the same as
|
|
1004
|
+
* "no rule found", which surfaces as `public` (public-by-omission). Before it
|
|
1005
|
+
* existed a denyAll gate was reported as `authenticated`, so a permission UI
|
|
1006
|
+
* rendered the action for every signed-in user and the server refused every
|
|
1007
|
+
* attempt.
|
|
1008
|
+
*
|
|
1009
|
+
* A CLIENT MUST treat an unrecognised type as DENIED, never as permitted — the
|
|
1010
|
+
* next type added here will otherwise read as "allowed" on every older client.
|
|
1011
|
+
*/
|
|
1012
|
+
type PermissionEntryType = "public" | "authenticated" | "roles" | "scoped" | "denied";
|
|
995
1013
|
interface PermissionEntry {
|
|
996
1014
|
type: PermissionEntryType;
|
|
997
1015
|
roles: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { P as ArcHeaders, i as RequestScope } from "./types-
|
|
3
|
-
import { d as UserBase, l as PermissionCheck, t as AnyRecord } from "./base-
|
|
2
|
+
import { P as ArcHeaders, i as RequestScope } from "./types-Ddl9OjmE.mjs";
|
|
3
|
+
import { d as UserBase, l as PermissionCheck, t as AnyRecord } from "./base-C-NL2fTi.mjs";
|
|
4
4
|
import { a as QueryCacheConfig } from "./QueryCache-DFA-QrU9.mjs";
|
|
5
5
|
import "./elevation-BXCfVcNG.mjs";
|
|
6
6
|
import { n as FieldPermissionMap } from "./fields-I_EeRWND.mjs";
|
|
@@ -1343,7 +1343,7 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
|
|
|
1343
1343
|
* wants downstream after-handlers to receive — typically the result for
|
|
1344
1344
|
* create/update, the original input (`existing`) for delete.
|
|
1345
1345
|
*/
|
|
1346
|
-
protected runAfterHook(req: IRequestContext, op: "create" | "update" | "delete", data: AnyRecord, meta?: Record<string, unknown>): Promise<void>;
|
|
1346
|
+
protected runAfterHook(req: IRequestContext, op: "create" | "update" | "delete" | "list" | "read", data: AnyRecord, meta?: Record<string, unknown>): Promise<void>;
|
|
1347
1347
|
/**
|
|
1348
1348
|
* Per-instance single-flight for cache fills — concurrent requests for
|
|
1349
1349
|
* the SAME cache key coalesce onto one repository query instead of each
|
|
@@ -1470,70 +1470,28 @@ declare function SoftDeleteMixin<TBase extends Constructor<BaseCrudController>>(
|
|
|
1470
1470
|
* Fully-composed controller shape: all CRUD methods + every preset method
|
|
1471
1471
|
* (SoftDelete / Tree / Slug / Bulk) typed over the caller-supplied `TDoc`.
|
|
1472
1472
|
*
|
|
1473
|
-
*
|
|
1474
|
-
*
|
|
1473
|
+
* Composes `BaseCrudController` (list/get/create/update/delete) → `BulkMixin`
|
|
1474
|
+
* (bulk*) → `SlugMixin` (getBySlug) → `TreeMixin` (getTree/getChildren) →
|
|
1475
|
+
* `SoftDeleteMixin` (getDeleted/restore). CRUD-only hosts extend
|
|
1476
|
+
* `BaseCrudController` for a smaller surface; others compose mixins by hand.
|
|
1475
1477
|
*
|
|
1476
|
-
*
|
|
1477
|
-
*
|
|
1478
|
+
* DECLARATION MERGING, not a generic mixin chain: TypeScript cannot thread one
|
|
1479
|
+
* `TDoc` through four chained mixin factories without losing the
|
|
1480
|
+
* `extends Constructor<Base>` constraint. So the runtime pins the chain base to
|
|
1481
|
+
* `AnyRecord` while the TYPE surface threads `TDoc`, and merging bridges them.
|
|
1478
1482
|
*
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1483
|
+
* `TDoc extends AnyRecord` is LOAD-BEARING: inherited methods return
|
|
1484
|
+
* `ListResult<AnyRecord>` and the merged interface returns `ListResult<TDoc>`,
|
|
1485
|
+
* so TS's derived-assignable-to-base check needs the bound. Without it the
|
|
1486
|
+
* class declaration fails with `Type 'TDoc[]' is not assignable to type
|
|
1487
|
+
* 'AnyRecord[]'`. Hosts pick one of:
|
|
1488
|
+
* (a) drop the generic — lose return narrowing;
|
|
1489
|
+
* (b) `interface IUser extends AnyRecord` — preferred when you own the type;
|
|
1490
|
+
* (c) `ArcListResult<typeof this>` etc. when overriding — reads the return
|
|
1491
|
+
* type off the class, so the bound never applies.
|
|
1484
1492
|
*
|
|
1485
|
-
*
|
|
1486
|
-
*
|
|
1487
|
-
* (e.g. `class X extends SoftDeleteMixin(BaseCrudController<Doc>)`).
|
|
1488
|
-
*
|
|
1489
|
-
* ──────────────────────────────────────────────────────────────────────────
|
|
1490
|
-
* ADR — why declaration merging + why `TDoc` carries `extends AnyRecord`
|
|
1491
|
-
* ──────────────────────────────────────────────────────────────────────────
|
|
1492
|
-
* The natural reflex is:
|
|
1493
|
-
*
|
|
1494
|
-
* class BaseController<TDoc> extends SoftDelete(Tree(Slug(Bulk(BaseCrud<TDoc>)))) {}
|
|
1495
|
-
*
|
|
1496
|
-
* TypeScript rejects this. Mixin factories can't receive a generic type
|
|
1497
|
-
* parameter from the derived class (TS4.0 added limited support, but
|
|
1498
|
-
* chained mixins over 4 levels deep still break because each factory
|
|
1499
|
-
* would need its own TDoc binding — TS can't infer a shared `TDoc` across
|
|
1500
|
-
* the chain without losing the base `extends Constructor<Base>` constraint).
|
|
1501
|
-
*
|
|
1502
|
-
* The composed runtime pins `BaseCrudController` to `AnyRecord` at the
|
|
1503
|
-
* mixin-chain base; the TYPE surface hosts interact with threads `TDoc` so
|
|
1504
|
-
* `new BaseController<Product>().list(req)` returns
|
|
1505
|
-
* `Promise<IControllerResponse<ListResult<Product>>>` and not
|
|
1506
|
-
* `ListResult<AnyRecord>`. Declaration merging bridges the two.
|
|
1507
|
-
*
|
|
1508
|
-
* **Why `TDoc extends AnyRecord` IS load-bearing:** the derived class
|
|
1509
|
-
* inherits the mixin-composed base which is pinned to `AnyRecord`.
|
|
1510
|
-
* Inherited methods return `ListResult<AnyRecord>` and the derived
|
|
1511
|
-
* interface returns `ListResult<TDoc>`. For TS's "derived is assignable
|
|
1512
|
-
* to base" check to pass, `TDoc` must be assignable to `AnyRecord` —
|
|
1513
|
-
* which requires the `extends AnyRecord` bound. Dropping the bound fails
|
|
1514
|
-
* with `Type 'TDoc[]' is not assignable to type 'AnyRecord[]'` at the
|
|
1515
|
-
* class declaration. Hosts therefore need one of:
|
|
1516
|
-
* (a) `class X extends BaseController { ... }` — drop the generic,
|
|
1517
|
-
* lose return-type narrowing for `list` / `get` / etc.
|
|
1518
|
-
* (b) `interface IUser extends AnyRecord { ... }` — add an index
|
|
1519
|
-
* signature to the domain interface (preferred when you own it).
|
|
1520
|
-
* (c) Use the utility types (`ArcListResult<typeof this>`,
|
|
1521
|
-
* `ArcCreateResult<typeof this>`) when overriding methods — they
|
|
1522
|
-
* read the return type from the class, sidestepping the bound
|
|
1523
|
-
* for method bodies even when `TDoc` is unbound elsewhere.
|
|
1524
|
-
*
|
|
1525
|
-
* **Why `TRepository` defaults to `RepositoryLike<TDoc>`:** keeps
|
|
1526
|
-
* diagnostics symmetric. With the older `RepositoryLike = RepositoryLike<unknown>`
|
|
1527
|
-
* default, error messages mixed `AnyRecord` and `unknown` in the same
|
|
1528
|
-
* signature, which confused the reader about where the mismatch was.
|
|
1529
|
-
*
|
|
1530
|
-
* **Cost this pays:** every method that participates in the `TDoc`
|
|
1531
|
-
* narrowing is redeclared on the interface. Adding a new method to a
|
|
1532
|
-
* mixin means updating this interface too. The alternative (losing
|
|
1533
|
-
* host-side generics OR rewriting mixins as a non-generic union) is
|
|
1534
|
-
* strictly worse.
|
|
1535
|
-
*
|
|
1536
|
-
* Spec reference: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-classes-with-other-types
|
|
1493
|
+
* COST: every `TDoc`-narrowed method is redeclared on the interface, so a new
|
|
1494
|
+
* mixin method must be added here too.
|
|
1537
1495
|
*/
|
|
1538
1496
|
interface BaseController<TDoc extends AnyRecord = AnyRecord, _TRepository extends RepositoryLike = RepositoryLike<TDoc>> {
|
|
1539
1497
|
accessControl: AccessControl;
|
|
@@ -3333,47 +3291,17 @@ interface ResourceConfig<TDoc = AnyRecord> {
|
|
|
3333
3291
|
*/
|
|
3334
3292
|
tenantField?: string | false;
|
|
3335
3293
|
/**
|
|
3336
|
-
*
|
|
3337
|
-
*
|
|
3338
|
-
*
|
|
3339
|
-
*
|
|
3340
|
-
*
|
|
3341
|
-
*
|
|
3342
|
-
*
|
|
3343
|
-
*
|
|
3344
|
-
*
|
|
3345
|
-
*
|
|
3346
|
-
*
|
|
3347
|
-
* value` for derived patches (hashes, etc.).
|
|
3348
|
-
* - `{ strategy: { type: 'skip', reason: 'audit-retained-per-SOX' } }`
|
|
3349
|
-
* — explicit opt-out with **mandatory** reason. Surfaces in audit reports.
|
|
3350
|
-
*
|
|
3351
|
-
* **Priority** — lower runs first. Default `100`. Use to land leaf data
|
|
3352
|
-
* before aggregate references:
|
|
3353
|
-
* - `10` : bulk leaf data (events, logs)
|
|
3354
|
-
* - `50` : business entities (orders, invoices)
|
|
3355
|
-
* - `100` : default
|
|
3356
|
-
*
|
|
3357
|
-
* Priority groups are barriers even under concurrency — all
|
|
3358
|
-
* priority-10 resources finish before any priority-50 starts.
|
|
3359
|
-
*
|
|
3360
|
-
* **Batch size** — rows per chunk for the underlying `purgeByField`
|
|
3361
|
-
* call. Default kit-specific (~1000). Tune for very large tenants.
|
|
3362
|
-
*
|
|
3363
|
-
* @example Compliance-retained financial ledger
|
|
3364
|
-
* ```ts
|
|
3365
|
-
* defineResource({
|
|
3366
|
-
* name: 'invoice',
|
|
3367
|
-
* tenantField: 'organizationId',
|
|
3368
|
-
* onTenantDelete: {
|
|
3369
|
-
* strategy: {
|
|
3370
|
-
* type: 'anonymize',
|
|
3371
|
-
* fields: { customerName: '[REDACTED]', customerEmail: null },
|
|
3372
|
-
* },
|
|
3373
|
-
* priority: 50,
|
|
3374
|
-
* },
|
|
3375
|
-
* });
|
|
3376
|
-
* ```
|
|
3294
|
+
* How `cascadeDeleteForOrganization` treats this resource's rows. Absent
|
|
3295
|
+
* means the resource is NEVER touched by the cascade — participation is
|
|
3296
|
+
* opt-in. Strategies: `hard` (GDPR erase) · `soft` (`deleted`+`deletedAt`,
|
|
3297
|
+
* pair with a TTL) · `anonymize` (keep the row for legal retention, clear
|
|
3298
|
+
* PII; values static or `(doc) => value`) · `skip` (explicit opt-out,
|
|
3299
|
+
* `reason` MANDATORY and surfaced in audit reports).
|
|
3300
|
+
*
|
|
3301
|
+
* `priority` (default 100) orders leaf data before aggregates — 10 bulk
|
|
3302
|
+
* logs, 50 business entities. Groups are BARRIERS: every priority-10
|
|
3303
|
+
* resource finishes before any priority-50 starts. `batchSize` chunks the
|
|
3304
|
+
* underlying `purgeByField` (kit default ~1000).
|
|
3377
3305
|
*/
|
|
3378
3306
|
onTenantDelete?: OnTenantDeleteConfig;
|
|
3379
3307
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { _ as HealthCheck, a as ModuleContribution, f as ScheduleDefinition, n as ArcModuleInput, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule } from "./types-
|
|
2
|
+
import { _ as HealthCheck, a as ModuleContribution, f as ScheduleDefinition, n as ArcModuleInput, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule } from "./types-DDD5RKTu.mjs";
|
|
3
3
|
import { FastifyInstance } from "fastify";
|
|
4
4
|
//#region src/factory/module/contributions.d.ts
|
|
5
5
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as RequestScope } from "./types-
|
|
3
|
-
import { l as PermissionCheck, t as AnyRecord } from "./base-
|
|
4
|
-
import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, Fn as IControllerResponse, H as CrudController, In as IRequestContext, L as RequestWithExtras, Pn as IController, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig } from "./index-
|
|
5
|
-
import "./fastify-augmentation-
|
|
2
|
+
import { i as RequestScope } from "./types-Ddl9OjmE.mjs";
|
|
3
|
+
import { l as PermissionCheck, t as AnyRecord } from "./base-C-NL2fTi.mjs";
|
|
4
|
+
import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, Fn as IControllerResponse, H as CrudController, In as IRequestContext, L as RequestWithExtras, Pn as IController, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig } from "./index-C01wWGJt.mjs";
|
|
5
|
+
import "./fastify-augmentation-Bk_9PoiV.mjs";
|
|
6
6
|
import { Filter } from "@classytic/repo-core/filter";
|
|
7
7
|
import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
|
|
8
8
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
@@ -70,40 +70,17 @@ declare const RESERVED_QUERY_PARAMS: Readonly<Set<string>>;
|
|
|
70
70
|
* `defineResource({ aggregations: { ... } })` either as named keys or
|
|
71
71
|
* via auto-discovery patterns (loadAggregations — future).
|
|
72
72
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* defineResource({
|
|
76
|
-
* name: 'order',
|
|
77
|
-
* aggregations: {
|
|
78
|
-
* revenueByStatus: defineAggregation({
|
|
79
|
-
* groupBy: 'status',
|
|
80
|
-
* measures: { count: 'count', revenue: 'sum:totalPrice' },
|
|
81
|
-
* permissions: requireRoles(['admin']),
|
|
82
|
-
* }),
|
|
83
|
-
* },
|
|
84
|
-
* });
|
|
85
|
-
* ```
|
|
73
|
+
* A namespace import lets many live in their own files and flow in at once
|
|
74
|
+
* (`import * as aggregations` → `defineResource({ aggregations })`).
|
|
86
75
|
*
|
|
87
|
-
* @example
|
|
76
|
+
* @example
|
|
88
77
|
* ```ts
|
|
89
|
-
* // orders/aggregations/revenue-by-status.ts
|
|
90
|
-
* import { defineAggregation } from '@classytic/arc';
|
|
91
|
-
*
|
|
92
78
|
* export const revenueByStatus = defineAggregation({
|
|
93
79
|
* groupBy: 'status',
|
|
94
80
|
* measures: { count: 'count', revenue: 'sum:totalPrice' },
|
|
95
81
|
* permissions: requireRoles(['admin']),
|
|
96
|
-
* timeout: 5000,
|
|
97
82
|
* cache: { staleTime: 60 },
|
|
98
83
|
* });
|
|
99
|
-
*
|
|
100
|
-
* // orders/order.resource.ts
|
|
101
|
-
* import * as aggregations from './aggregations/index.js';
|
|
102
|
-
*
|
|
103
|
-
* defineResource({
|
|
104
|
-
* name: 'order',
|
|
105
|
-
* aggregations, // 30+ entries flow in
|
|
106
|
-
* });
|
|
107
84
|
* ```
|
|
108
85
|
*/
|
|
109
86
|
declare function defineAggregation(config: AggregationConfig): AggregationConfig;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
import { c as DataPolicy, d as UserBase, l as PermissionCheck, n as ArcRequest, o as UserOrganization, r as JWTPayload, s as AuthorizationDecision, t as AnyRecord, u as PermissionContext } from "./base-
|
|
3
|
-
import { A as RequestIdOptions, An as WriteVerbKey, B as defineResource, Bt as BaseController, C as RequestContext, Cn as ControllerConstructionOptions, D as HealthCheck, Dn as MutationWriteContext, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as IControllerResponse, Ft as AuthPluginOptions, Gt as SlugExt, H as CrudController, Ht as SoftDeleteMixin, In as IRequestContext, Jt as BulkMixin, Kt as SlugMixin, L as RequestWithExtras, Ln as RawRouteHandler, Mn as ControllerLike, N as FastifyRequestExtras, Nt as RateLimitConfig, O as HealthOptions, On as ResourceWrites, P as FastifyWithAuth, Pn as IController, Q as MiddlewareConfig, Rn as RouteHandler, S as QueryParserInterface, Sn as ControllerConfigurableOptions, T as CrudRouterOptions, U as ResourceConfig, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, X as CrudRouteKey, Y as PresetResult, Yt as BaseCrudController, Z as CrudSchemas, _n as ArcDeleteResult, a as InferAdapterDoc, bn as ArcUpdateResult, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gn as ArcCreateResult, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, k as IntrospectionPluginOptions, kn as WriteContext, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, qt as BulkExt, r as ValidateOptions, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, u as TypedResourceConfig, ut as AggregationConfig, vn as ArcGetResult, w as ServiceContext, wn as ListResult, xn as BaseControllerOptions, y as OwnershipCheck, yn as ArcListResult } from "./index-
|
|
2
|
+
import { c as DataPolicy, d as UserBase, l as PermissionCheck, n as ArcRequest, o as UserOrganization, r as JWTPayload, s as AuthorizationDecision, t as AnyRecord, u as PermissionContext } from "./base-C-NL2fTi.mjs";
|
|
3
|
+
import { A as RequestIdOptions, An as WriteVerbKey, B as defineResource, Bt as BaseController, C as RequestContext, Cn as ControllerConstructionOptions, D as HealthCheck, Dn as MutationWriteContext, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as IControllerResponse, Ft as AuthPluginOptions, Gt as SlugExt, H as CrudController, Ht as SoftDeleteMixin, In as IRequestContext, Jt as BulkMixin, Kt as SlugMixin, L as RequestWithExtras, Ln as RawRouteHandler, Mn as ControllerLike, N as FastifyRequestExtras, Nt as RateLimitConfig, O as HealthOptions, On as ResourceWrites, P as FastifyWithAuth, Pn as IController, Q as MiddlewareConfig, Rn as RouteHandler, S as QueryParserInterface, Sn as ControllerConfigurableOptions, T as CrudRouterOptions, U as ResourceConfig, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, X as CrudRouteKey, Y as PresetResult, Yt as BaseCrudController, Z as CrudSchemas, _n as ArcDeleteResult, a as InferAdapterDoc, bn as ArcUpdateResult, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gn as ArcCreateResult, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, k as IntrospectionPluginOptions, kn as WriteContext, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, qt as BulkExt, r as ValidateOptions, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, u as TypedResourceConfig, ut as AggregationConfig, vn as ArcGetResult, w as ServiceContext, wn as ListResult, xn as BaseControllerOptions, y as OwnershipCheck, yn as ArcListResult } from "./index-C01wWGJt.mjs";
|
|
4
4
|
import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-I_EeRWND.mjs";
|
|
5
|
-
import "./fastify-augmentation-
|
|
6
|
-
import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, b as defineResourceVariants, c as nativePolicyFilter, h as getControllerScope, j as CrudOperation, k as defineAggregation, q as RESERVED_QUERY_PARAMS, s as NativePolicyFilter, w as mergeResourceConfig, x as AdapterLike, z as HOOK_PHASES } from "./index-
|
|
7
|
-
import { $ as requireAuth, C as requireServiceScope, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, J as allowPublic, K as allOf, S as requireScopeContext, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, b as requireOrgMembership, d as authenticated, et as requireOwnership, f as fullPublic, g as publicRead, h as presets_d_exports, it as when, nt as requireRoles, p as ownerWithAdminBypass, u as adminOnly, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope } from "./index-
|
|
5
|
+
import "./fastify-augmentation-Bk_9PoiV.mjs";
|
|
6
|
+
import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, b as defineResourceVariants, c as nativePolicyFilter, h as getControllerScope, j as CrudOperation, k as defineAggregation, q as RESERVED_QUERY_PARAMS, s as NativePolicyFilter, w as mergeResourceConfig, x as AdapterLike, z as HOOK_PHASES } from "./index-RdpLP71b.mjs";
|
|
7
|
+
import { $ as requireAuth, C as requireServiceScope, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, J as allowPublic, K as allOf, S as requireScopeContext, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, b as requireOrgMembership, d as authenticated, et as requireOwnership, f as fullPublic, g as publicRead, h as presets_d_exports, it as when, nt as requireRoles, p as ownerWithAdminBypass, u as adminOnly, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope } from "./index-BtYoMip1.mjs";
|
|
8
8
|
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-BGdVwP25.mjs";
|
|
9
9
|
//#region src/index.d.ts
|
|
10
10
|
declare const version: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-
|
|
3
|
-
import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { a as
|
|
11
|
-
import { B as requireAuth, C as createOrgPermissions, D as requireScopeContext, E as requireOrgRole, F as allowPublic, G as when, I as anyOf, N as allOf, O as requireServiceScope, R as denyAll, S as createDynamicPermissionMatrix, T as requireOrgMembership, U as requireRoles, V as requireOwnership, a as adminOnly, c as ownerWithAdminBypass, d as publicRead, f as publicReadAdminWrite, k as requireTeamMembership, o as authenticated, p as readOnly, s as fullPublic, u as presets_exports, w as requireOrgInScope } from "./permissions-CP47jdi7.mjs";
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-DUoKAGYD.mjs";
|
|
3
|
+
import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DDKni6Tz.mjs";
|
|
4
|
+
import { a as BulkMixin, h as nativePolicyFilter, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-CTJKm6Cb.mjs";
|
|
5
|
+
import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-DdP225wt.mjs";
|
|
6
|
+
import { a as ResourceDefinition, t as defineResource } from "./defineResource-DWzjyxb2.mjs";
|
|
7
|
+
import { l as getControllerScope } from "./actionPermissions-D97DniUQ.mjs";
|
|
8
|
+
import { t as defineAggregation } from "./defineAggregation-CpQfcM8R.mjs";
|
|
9
|
+
import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-DTXsiNTJ.mjs";
|
|
10
|
+
import { B as requireAuth, C as createOrgPermissions, D as requireScopeContext, E as requireOrgRole, F as allowPublic, G as when, I as anyOf, N as allOf, O as requireServiceScope, R as denyAll, S as createDynamicPermissionMatrix, T as requireOrgMembership, U as requireRoles, V as requireOwnership, a as adminOnly, c as ownerWithAdminBypass, d as publicRead, f as publicReadAdminWrite, k as requireTeamMembership, o as authenticated, p as readOnly, s as fullPublic, u as presets_exports, w as requireOrgInScope } from "./permissions-DgPrZsJh.mjs";
|
|
12
11
|
//#region src/index.ts
|
|
13
|
-
const version = "2.
|
|
12
|
+
const version = "2.36.0";
|
|
14
13
|
//#endregion
|
|
15
14
|
export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, nativePolicyFilter, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
2
|
import fp from "fastify-plugin";
|
|
3
3
|
//#region src/integrations/event-gateway.ts
|
|
4
4
|
const eventGatewayPluginImpl = async (fastify, opts = {}) => {
|
|
5
5
|
const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
|
|
6
6
|
if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
|
|
7
7
|
if (opts.sse !== false) {
|
|
8
|
-
const { default: ssePlugin } = await import("../sse-
|
|
8
|
+
const { default: ssePlugin } = await import("../sse-Bxt03Hk5.mjs").then((n) => n.r);
|
|
9
9
|
await fastify.register(ssePlugin, {
|
|
10
10
|
path: opts.sse?.path ?? "/events/stream",
|
|
11
11
|
requireAuth: auth,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-BOXVggMf.mjs";
|
|
3
3
|
import { EventGatewayOptions } from "./event-gateway.mjs";
|
|
4
|
-
import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-
|
|
5
|
-
import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-
|
|
4
|
+
import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-eyg5WEcy.mjs";
|
|
5
|
+
import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-BXnTOsXP.mjs";
|
|
6
6
|
import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
|
|
7
7
|
import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
|
|
8
8
|
export type { BetterAuthHandler, CallToolResult, CreateMcpServerConfig, CrudOperation, EventGatewayOptions, JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, McpAuthResult, McpPluginOptions, McpResourceConfig, PromptDefinition, QueueStats, StreamlinePluginOptions, ToolAnnotations, ToolContext, ToolDefinition, WebSocketClient, WebSocketMessage, WebSocketPluginOptions, WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription, WorkflowLike, WorkflowRunLike };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
2
|
export {};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-
|
|
2
|
+
import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-eyg5WEcy.mjs";
|
|
3
3
|
export { type ExecuteTimedHandlerOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobRepeatOptions, type JobStatus, type JobsPluginOptions, type QueueStats, type TimedHandlerLogger, defineJob, executeTimedHandler, jobsPlugin };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as evaluateAndApplyPermission } from "../../authorizationDecision-
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as evaluateAndApplyPermission } from "../../authorizationDecision-EsiY3nUu.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/integrations/jobs/execution.ts
|
|
5
5
|
async function executeTimedHandler(options) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as RequestScope } from "../../types-
|
|
3
|
-
import { l as PermissionCheck } from "../../base-
|
|
4
|
-
import { Fn as IControllerResponse, In as IRequestContext, V as ResourceDefinition, zn as ServerAccessor } from "../../index-
|
|
2
|
+
import { i as RequestScope } from "../../types-Ddl9OjmE.mjs";
|
|
3
|
+
import { l as PermissionCheck } from "../../base-C-NL2fTi.mjs";
|
|
4
|
+
import { Fn as IControllerResponse, In as IRequestContext, V as ResourceDefinition, zn as ServerAccessor } from "../../index-C01wWGJt.mjs";
|
|
5
5
|
import { n as FieldPermissionMap } from "../../fields-I_EeRWND.mjs";
|
|
6
|
-
import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-
|
|
6
|
+
import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-BXnTOsXP.mjs";
|
|
7
7
|
import { ErrorContract } from "@classytic/repo-core/errors";
|
|
8
8
|
import { FastifyPluginAsync } from "fastify";
|
|
9
9
|
import { z } from "zod";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-NxSlc-Ks.mjs";
|
|
3
3
|
//#region src/integrations/mcp/defineTool.ts
|
|
4
4
|
/**
|
|
5
5
|
* Define a type-safe MCP tool.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { c as McpAuthResult, u as McpPluginOptions } from "../../types-
|
|
2
|
+
import { c as McpAuthResult, u as McpPluginOptions } from "../../types-BXnTOsXP.mjs";
|
|
3
3
|
//#region src/integrations/mcp/testing.d.ts
|
|
4
4
|
interface TestMcpClientOptions {
|
|
5
5
|
/** MCP plugin options (resources, overrides, etc.) — same as mcpPlugin config */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-NxSlc-Ks.mjs";
|
|
3
3
|
//#region src/integrations/mcp/testing.ts
|
|
4
4
|
/**
|
|
5
5
|
* @classytic/arc/mcp/testing — MCP Test Utilities
|
|
@@ -50,7 +50,7 @@ async function createTestMcpClient(options = {}) {
|
|
|
50
50
|
resources: [],
|
|
51
51
|
...options.pluginOptions
|
|
52
52
|
};
|
|
53
|
-
const auth = options.auth
|
|
53
|
+
const auth = options.auth === void 0 ? { userId: "test-user" } : options.auth;
|
|
54
54
|
const serverName = options.serverName ?? "test-mcp";
|
|
55
55
|
const overrides = pluginOpts.overrides ?? {};
|
|
56
56
|
const tools = filterResourcesForMcp(pluginOpts.resources ?? [], {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-
|
|
3
|
-
import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-
|
|
1
|
+
/*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
|
|
2
|
+
import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-DDKni6Tz.mjs";
|
|
3
|
+
import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-CiTJW8kZ.mjs";
|
|
4
4
|
import fp from "fastify-plugin";
|
|
5
5
|
//#region src/integrations/streamline.ts
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { a as EventTransport, n as DomainEvent } from "../EventTransport-BEVP50ka.mjs";
|
|
3
|
-
import { n as OutboxModuleOptions, r as createOutboxModule } from "../outbox-module-
|
|
3
|
+
import { n as OutboxModuleOptions, r as createOutboxModule } from "../outbox-module-b1TyDGGi.mjs";
|
|
4
4
|
import { FastifyPluginAsync } from "fastify";
|
|
5
5
|
import { OutboxFailurePolicy, OutboxStore } from "@classytic/primitives/outbox";
|
|
6
6
|
//#region src/integrations/webhooks.d.ts
|
|
@@ -310,6 +310,8 @@ interface WebhookDeliveryTransportOptions {
|
|
|
310
310
|
* an allowed URL can't 302 into a blocked target; a rejection is permanent.
|
|
311
311
|
*/
|
|
312
312
|
validateUrl?: (url: URL, subscription: WebhookSubscription) => void | Promise<void>;
|
|
313
|
+
/** Resolve private auth headers at delivery time; reserved Arc headers cannot be replaced. */
|
|
314
|
+
resolveHeaders?: (subscription: WebhookSubscription, event: WebhookDeliveryPayload["event"]) => Record<string, string> | Promise<Record<string, string>>;
|
|
313
315
|
}
|
|
314
316
|
/**
|
|
315
317
|
* Publish-only `EventTransport` whose `publish()` IS the webhook POST —
|
|
@@ -338,7 +340,7 @@ interface WebhookDeliveryPolicyOptions {
|
|
|
338
340
|
* retry on exponential backoff until `maxAttempts`, then dead-letter.
|
|
339
341
|
*/
|
|
340
342
|
declare function webhookDeliveryFailurePolicy(options?: WebhookDeliveryPolicyOptions): OutboxFailurePolicy;
|
|
341
|
-
interface DurableWebhookModuleOptions extends Omit<OutboxModuleOptions, "name" | "transport" | "failurePolicy">, Pick<WebhookDeliveryTransportOptions, "fetch" | "timeout" | "validateUrl"> {
|
|
343
|
+
interface DurableWebhookModuleOptions extends Omit<OutboxModuleOptions, "name" | "transport" | "failurePolicy">, Pick<WebhookDeliveryTransportOptions, "fetch" | "timeout" | "validateUrl" | "resolveHeaders"> {
|
|
342
344
|
/** Module name / `dependsOn` key. Default `'webhook-delivery'`. */
|
|
343
345
|
name?: string;
|
|
344
346
|
/** Retry/backoff tuning for the default failure policy. */
|