@classytic/arc 2.23.0 → 2.28.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/README.md +2 -0
- package/dist/{BaseController-BQ8KNvWC.mjs → BaseController-B65zbz9m.mjs} +94 -23
- package/dist/QueryCache-DOMT_iq7.d.mts +72 -0
- package/dist/actionPermissions-CAphcmUG.mjs +24 -0
- package/dist/{applyPermissionResult-Tw4iXtlf.mjs → applyPermissionResult-BnyVE9eD.mjs} +10 -0
- package/dist/audit/index.d.mts +32 -3
- package/dist/audit/index.mjs +7 -4
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +263 -259
- package/dist/{buildHandler-D_2ULWxZ.mjs → buildHandler-Dtwd8fdz.mjs} +1 -1
- package/dist/cache/index.d.mts +41 -3
- package/dist/cache/index.mjs +33 -4
- package/dist/cleanup/index.d.mts +313 -0
- package/dist/cleanup/index.mjs +1267 -0
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/docs.mjs +1 -1
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/index.mjs +2 -2
- package/dist/context/index.mjs +2 -64
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +5 -4
- package/dist/core-BGa8TXJR.mjs +221 -0
- package/dist/{createActionRouter-BuOv-m4Y.mjs → createActionRouter-C-N7z2EL.mjs} +3 -2
- package/dist/{createAggregationRouter-CgJv_BU_.mjs → createAggregationRouter-wzwFa_dW.mjs} +3 -3
- package/dist/{createApp-CjOeWJ9_.mjs → createApp-Du5G54TM.mjs} +187 -96
- package/dist/{core-DQ6rDTyH.mjs → defineResource-2zvVVpxg.mjs} +297 -230
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-COpYKt2h.mjs → elevation-CIz1GjGm.mjs} +4 -3
- package/dist/{eventPlugin-A6EbthXR.d.mts → eventPlugin-Bg3cP2_u.d.mts} +38 -3
- package/dist/{eventPlugin-DJG2D7sy.mjs → eventPlugin-DrQ_FesK.mjs} +22 -4
- package/dist/events/index.d.mts +83 -314
- package/dist/events/index.mjs +183 -95
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +24 -2
- package/dist/factory/index.d.mts +5 -5
- package/dist/factory/index.mjs +30 -8
- package/dist/{fastify-augmentation-g_f9omSc.d.mts → fastify-augmentation-OzYGIiU1.d.mts} +26 -2
- package/dist/{generate-usRSdQmP.mjs → generate-D0wZupBg.mjs} +1 -1
- package/dist/headers-BvlQSDMB.mjs +45 -0
- package/dist/health-CB_m4S32.mjs +377 -0
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.mjs +27 -3
- package/dist/{index-wMoWBLkn.d.mts → index-BMnbzvtO.d.mts} +3 -3
- package/dist/{integrations/jobs.d.mts → index-CG4yqMDB.d.mts} +82 -2
- package/dist/index-CZY4EGga.d.mts +107 -0
- package/dist/{index-CC5ruDGh.d.mts → index-CjVg-Epg.d.mts} +37 -5
- package/dist/{index-BBsvQt7U.d.mts → index-DPRH0Cme.d.mts} +36 -106
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +7 -6
- package/dist/{init-CjO4p_q1.mjs → init-tlRSt667.mjs} +206 -208
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/jobs/index.d.mts +2 -0
- package/dist/integrations/{jobs.mjs → jobs/index.mjs} +110 -67
- 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 +1 -1
- package/dist/integrations/webhooks.d.mts +37 -30
- package/dist/integrations/webhooks.mjs +51 -62
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +1 -1
- package/dist/integrations/websocket.mjs +41 -14
- package/dist/{interface-C1_WLTMK.d.mts → interface-BGZCzOGL.d.mts} +24 -31
- package/dist/{mcpPlugin-BtzIL_kM.mjs → mcpPlugin-Cs6nRGCt.mjs} +12 -10
- package/dist/{memory-CLXA2VeJ.mjs → memory-CmnzXE5Z.mjs} +29 -0
- package/dist/middleware/index.d.mts +17 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/migrations/index.d.mts +94 -44
- package/dist/migrations/index.mjs +196 -44
- package/dist/module-_-M7C5ES.mjs +29 -0
- package/dist/{multipartBody-CHEQSZ6G.mjs → multipartBody-D0eBvkeq.mjs} +17 -0
- package/dist/{openapi-jSDx-VDv.mjs → openapi-BLV4OMXb.mjs} +3 -3
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +3 -3
- package/dist/{permissions-tbxFHxjZ.mjs → permissions-BrtiBKGs.mjs} +229 -229
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/{actionPermissions-lszoJle1.mjs → pipeline-BGRnV-To.mjs} +4 -27
- package/dist/plugins/index.d.mts +6 -77
- package/dist/plugins/index.mjs +11 -95
- package/dist/plugins/response-cache.mjs +1 -0
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/{index-Ba10fdKp.d.mts → preloadResources-CM4uUaFv.d.mts} +51 -50
- package/dist/preloadResources-DSY5HGpS.mjs +45 -0
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +3 -3
- package/dist/presets/index.d.mts +2 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-BOe4Ugkl.mjs → presets-DwFDVKP0.mjs} +2 -2
- package/dist/{queryCachePlugin-DzqLN904.mjs → queryCachePlugin-DSGuSVLW.mjs} +39 -8
- package/dist/{queryCachePlugin-CfYWq-Ak.d.mts → queryCachePlugin-br4otiqF.d.mts} +2 -2
- package/dist/{registerRoute-CWO6mdYe.mjs → rateLimit-DrED-C4v.mjs} +2 -109
- package/dist/{realtime-I8OrfnMR.mjs → realtime-DEuDu9io.mjs} +3 -3
- package/dist/{redis-stream-iVR2l7aS.d.mts → redis-stream-uIaauNpZ.d.mts} +22 -0
- package/dist/registerRoute-DTp18Ah_.mjs +108 -0
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +1 -1
- package/dist/{registry-vcOCtPij.mjs → registry-9km_w1aP.mjs} +15 -0
- package/dist/renewingLease-3cuQH7h8.mjs +44 -0
- package/dist/{requestContext-BZKOr13H.mjs → requestContext-MrlJwECf.mjs} +2 -2
- package/dist/schedules-CjOd2MG9.mjs +113 -0
- package/dist/schemas/index.d.mts +67 -67
- package/dist/schemas/index.mjs +2 -3
- package/dist/scim/index.mjs +1 -2
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +4 -4
- package/dist/{scope-LONQ3mfZ.mjs → scope-DfaPntpo.mjs} +4 -5
- package/dist/{sse-0u4P4-OI.mjs → sse-BQ1w0dfl.mjs} +1 -1
- package/dist/testing/cleanupStoreContract.d.mts +10 -0
- package/dist/testing/cleanupStoreContract.mjs +375 -0
- package/dist/testing/index.d.mts +5 -3
- package/dist/testing/index.mjs +4 -2
- package/dist/testing/outboxStoreContract.d.mts +13 -0
- package/dist/testing/outboxStoreContract.mjs +247 -0
- package/dist/transactionContext-PNdoyLLm.mjs +64 -0
- package/dist/types/index.d.mts +4 -4
- package/dist/{types-bHblZ9YN.mjs → types-CSyCxl2V.mjs} +38 -7
- package/dist/types-C_ZZRcD6.d.mts +450 -0
- package/dist/{module-B4u10iOJ.d.mts → types-Cu6vVJmh.d.mts} +196 -60
- package/dist/{types-DH0GupI7.d.mts → types-DjC-KUCz.d.mts} +118 -20
- package/dist/{types-Csxga7d3.d.mts → types-Dmw-6Qeo.d.mts} +96 -4
- package/dist/{types-5OuqeTDX.d.mts → types-QFGc3Cjv.d.mts} +1 -1
- package/dist/usage/index.d.mts +3 -52
- package/dist/usage/index.mjs +0 -0
- package/dist/userHelpers-Cg_y3fBz.mjs +29 -0
- package/dist/utils/index.d.mts +58 -85
- package/dist/utils/index.mjs +4 -2
- package/dist/{utils-CZyeRXTh.mjs → utils-taUVD4p3.mjs} +47 -337
- package/dist/{validate-C2mGgSXg.mjs → validate-Bk44F2yT.mjs} +1 -1
- package/dist/{versioning-D6PvCwpq.d.mts → versioning-DXgY5BUm.d.mts} +11 -29
- package/dist/{versioning-Dk-71iIz.mjs → versioning-gKWyryT3.mjs} +8 -1
- package/dist/{websocket-uuWqM6UY.d.mts → websocket-_Pd0CgR0.d.mts} +15 -1
- package/package.json +541 -513
- package/skills/arc/references/api-reference.md +3 -1
- package/skills/arc/references/integrations.md +20 -11
- package/dist/QueryCache-Z1B38koh.d.mts +0 -40
- package/dist/betterAuthOpenApi-CV1lxpRX.mjs +0 -2
- package/dist/health-ScyjIVo5.mjs +0 -202
- package/dist/requestId-5BhTVzBv.mjs +0 -113
- package/dist/types-XTApa8b6.mjs +0 -24
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-
|
|
1
|
+
import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-DPRH0Cme.mjs";
|
|
2
2
|
//#region src/cli/commands/describe.d.ts
|
|
3
3
|
interface DescribedResource {
|
|
4
4
|
name: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as buildOpenApiSpec } from "../../openapi-
|
|
1
|
+
import { t as buildOpenApiSpec } from "../../openapi-BLV4OMXb.mjs";
|
|
2
2
|
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-kvGT6EcO.mjs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as generate } from "../../generate-
|
|
1
|
+
import { t as generate } from "../../generate-D0wZupBg.mjs";
|
|
2
2
|
export { generate };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as init } from "../../init-
|
|
1
|
+
import { t as init } from "../../init-tlRSt667.mjs";
|
|
2
2
|
export { init };
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe } from "./commands/describe.mjs";
|
|
2
2
|
import { exportDocs } from "./commands/docs.mjs";
|
|
3
3
|
import { doctor } from "./commands/doctor.mjs";
|
|
4
|
-
import { t as generate } from "../generate-
|
|
5
|
-
import { t as init } from "../init-
|
|
4
|
+
import { t as generate } from "../generate-D0wZupBg.mjs";
|
|
5
|
+
import { t as init } from "../init-tlRSt667.mjs";
|
|
6
6
|
import { introspect } from "./commands/introspect.mjs";
|
|
7
7
|
export { describe, doctor, exportDocs, generate, init, introspect };
|
package/dist/context/index.mjs
CHANGED
|
@@ -1,65 +1,3 @@
|
|
|
1
|
-
import { n as requestContext, t as getTraceHeaders } from "../requestContext-
|
|
2
|
-
import {
|
|
3
|
-
//#region src/context/transactionContext.ts
|
|
4
|
-
/**
|
|
5
|
-
* Transaction Context via AsyncLocalStorage
|
|
6
|
-
*
|
|
7
|
-
* Provides a Unit-of-Work (UoW) hook so any code in the call stack can
|
|
8
|
-
* retrieve the active database session/transaction without it being threaded
|
|
9
|
-
* through every function parameter.
|
|
10
|
-
*
|
|
11
|
-
* Arc is DB-agnostic — the session type is `unknown` so any backend
|
|
12
|
-
* (Mongoose session, Prisma transaction, pg client, Drizzle client) can
|
|
13
|
-
* participate. Kit adapters call `runInTransaction(session, fn)` to install
|
|
14
|
-
* the active context; the outbox's `store()` reads it automatically when no
|
|
15
|
-
* explicit `options.session` is passed.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* // In a Mongoose-backed service (mongokit adapter)
|
|
20
|
-
* import { transactionContext } from '@classytic/arc/context';
|
|
21
|
-
*
|
|
22
|
-
* await mongoose.connection.withSession(async (session) => {
|
|
23
|
-
* await session.withTransaction(async () => {
|
|
24
|
-
* await transactionContext.run(session, async () => {
|
|
25
|
-
* await orders.insertOne(order, { session });
|
|
26
|
-
* // outbox.store() auto-picks up `session` — no manual threading
|
|
27
|
-
* await outbox.store(orderCreatedEvent);
|
|
28
|
-
* });
|
|
29
|
-
* });
|
|
30
|
-
* });
|
|
31
|
-
* ```
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```typescript
|
|
35
|
-
* // Opt-out: explicit session always wins over the ALS context
|
|
36
|
-
* await outbox.store(event, { session: explicitSession });
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
const storage = new AsyncLocalStorage();
|
|
40
|
-
/**
|
|
41
|
-
* Transaction context API.
|
|
42
|
-
*
|
|
43
|
-
* - `run(session, fn)` — install an active DB session for the duration of `fn`
|
|
44
|
-
* - `get()` — read the current session (undefined if outside a transaction scope)
|
|
45
|
-
*/
|
|
46
|
-
const transactionContext = {
|
|
47
|
-
/**
|
|
48
|
-
* Run `fn` with `session` as the active DB transaction context.
|
|
49
|
-
* Any call to `get()` within `fn`'s async call stack returns `session`.
|
|
50
|
-
*/
|
|
51
|
-
run(session, fn) {
|
|
52
|
-
return storage.run(session, fn);
|
|
53
|
-
},
|
|
54
|
-
/**
|
|
55
|
-
* Get the current DB session, or `undefined` if not inside a
|
|
56
|
-
* `transactionContext.run(...)` scope.
|
|
57
|
-
*/
|
|
58
|
-
get() {
|
|
59
|
-
return storage.getStore();
|
|
60
|
-
},
|
|
61
|
-
/** The underlying AsyncLocalStorage instance. Exposed for advanced integrations. */
|
|
62
|
-
storage
|
|
63
|
-
};
|
|
64
|
-
//#endregion
|
|
1
|
+
import { n as requestContext, t as getTraceHeaders } from "../requestContext-MrlJwECf.mjs";
|
|
2
|
+
import { t as transactionContext } from "../transactionContext-PNdoyLLm.mjs";
|
|
65
3
|
export { getTraceHeaders, requestContext, transactionContext };
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { B as defineResource,
|
|
2
|
-
import { A as
|
|
3
|
-
export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, sendControllerResponse };
|
|
1
|
+
import { $t as SlugExt, An as ControllerConfigurableOptions, B as defineResource, Jt as BaseController, Mn as ListResult, Nn as BodySanitizer, Pn as BodySanitizerConfig, Qt as TreeMixin, V as ResourceDefinition, Xt as SoftDeleteMixin, Yt as SoftDeleteExt, Zt as TreeExt, an as QueryResolverConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, en as SlugMixin, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, in as QueryResolver, jn as ControllerConstructionOptions, kn as BaseControllerOptions, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, nn as BulkMixin, on as AccessControl, pt as AggregationMaterializedContext, rn as BaseCrudController, sn as AccessControlConfig, st as AggMeasureInput, tn as BulkExt, ut as AggregationConfig } from "../index-DPRH0Cme.mjs";
|
|
2
|
+
import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, C as DefineActionConfig, D as defineAggregation, E as createPermissionMiddleware, F as DEFAULT_UPDATE_METHOD, G as RESERVED_QUERY_PARAMS, H as MAX_SEARCH_LENGTH, I as HOOK_OPERATIONS, K as SYSTEM_FIELDS, L as HOOK_PHASES, M as DEFAULT_MAX_LIMIT, N as DEFAULT_SORT, O as CRUD_OPERATIONS, P as DEFAULT_TENANT_FIELD, R as HookOperation, S as mergeResourceConfig, T as createCrudRouter, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, _ as getEntityQuery, a as formatValidationErrors, b as ResourceSeams, c as isFieldReadable, d as createRequestContext, f as getControllerContext, g as getEntityIdField, h as getEntityId, i as assertValidConfig, j as DEFAULT_LIMIT, k as CrudOperation, l as createCrudHandlers, m as sendControllerResponse, n as ValidateOptions, o as validateResourceConfig, p as getControllerScope, r as ValidationResult, s as collectReadBlockedFields, t as ConfigError, u as createFastifyHandler, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "../index-CjVg-Epg.mjs";
|
|
3
|
+
export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type ValidateOptions, type ValidationResult, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, sendControllerResponse, validateResourceConfig };
|
package/dist/core/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "../constants-DNre0wRg.mjs";
|
|
2
|
-
import { a as BulkMixin, c as collectReadBlockedFields, f as AccessControl, i as SlugMixin, l as isFieldReadable, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController, u as BodySanitizer } from "../BaseController-
|
|
3
|
-
import { a as
|
|
4
|
-
import { a as
|
|
5
|
-
|
|
2
|
+
import { a as BulkMixin, c as collectReadBlockedFields, f as AccessControl, i as SlugMixin, l as isFieldReadable, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController, u as BodySanitizer } from "../BaseController-B65zbz9m.mjs";
|
|
3
|
+
import { a as ResourceDefinition, i as validateResourceConfig, n as assertValidConfig, o as createCrudRouter, r as formatValidationErrors, s as createPermissionMiddleware, t as defineResource } from "../defineResource-2zvVVpxg.mjs";
|
|
4
|
+
import { a as createFastifyHandler, c as getControllerScope, i as createCrudHandlers, l as sendControllerResponse, o as createRequestContext, s as getControllerContext } from "../pipeline-BGRnV-To.mjs";
|
|
5
|
+
import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, s as defineAggregation, t as getEntityId } from "../core-BGa8TXJR.mjs";
|
|
6
|
+
export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, sendControllerResponse, validateResourceConfig };
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import "./constants-DNre0wRg.mjs";
|
|
2
|
+
import { t as defineResource } from "./defineResource-2zvVVpxg.mjs";
|
|
3
|
+
//#region src/core/aggregation/defineAggregation.ts
|
|
4
|
+
/**
|
|
5
|
+
* Declare a single resource aggregation. Exported configs flow into
|
|
6
|
+
* `defineResource({ aggregations: { ... } })` either as named keys or
|
|
7
|
+
* via auto-discovery patterns (loadAggregations — future).
|
|
8
|
+
*
|
|
9
|
+
* @example Inline
|
|
10
|
+
* ```ts
|
|
11
|
+
* defineResource({
|
|
12
|
+
* name: 'order',
|
|
13
|
+
* aggregations: {
|
|
14
|
+
* revenueByStatus: defineAggregation({
|
|
15
|
+
* groupBy: 'status',
|
|
16
|
+
* measures: { count: 'count', revenue: 'sum:totalPrice' },
|
|
17
|
+
* permissions: requireRoles(['admin']),
|
|
18
|
+
* }),
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example Multi-file
|
|
24
|
+
* ```ts
|
|
25
|
+
* // orders/aggregations/revenue-by-status.ts
|
|
26
|
+
* import { defineAggregation } from '@classytic/arc';
|
|
27
|
+
*
|
|
28
|
+
* export const revenueByStatus = defineAggregation({
|
|
29
|
+
* groupBy: 'status',
|
|
30
|
+
* measures: { count: 'count', revenue: 'sum:totalPrice' },
|
|
31
|
+
* permissions: requireRoles(['admin']),
|
|
32
|
+
* timeout: 5000,
|
|
33
|
+
* cache: { staleTime: 60 },
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // orders/order.resource.ts
|
|
37
|
+
* import * as aggregations from './aggregations/index.js';
|
|
38
|
+
*
|
|
39
|
+
* defineResource({
|
|
40
|
+
* name: 'order',
|
|
41
|
+
* aggregations, // 30+ entries flow in
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function defineAggregation(config) {
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/core/defineAction.ts
|
|
50
|
+
/**
|
|
51
|
+
* Build an `ActionDefinition` with a typed handler. The literal schema
|
|
52
|
+
* type captured here flows into `data`, so `defineAction({ schema:
|
|
53
|
+
* z.object({...}), handler })` produces fully-typed code with no
|
|
54
|
+
* `as MyShape` cast.
|
|
55
|
+
*
|
|
56
|
+
* Behaviorally identical to a bare `ActionDefinition` object — same
|
|
57
|
+
* validation path (AJV), same permission resolution, same MCP wiring.
|
|
58
|
+
* The runtime shape is unchanged; only the type-level inference is new.
|
|
59
|
+
*/
|
|
60
|
+
function defineAction(config) {
|
|
61
|
+
return {
|
|
62
|
+
handler: config.handler,
|
|
63
|
+
permissions: config.permissions,
|
|
64
|
+
schema: config.schema,
|
|
65
|
+
description: config.description,
|
|
66
|
+
id: config.id,
|
|
67
|
+
mcp: config.mcp
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/core/defineResource/seams.ts
|
|
72
|
+
/** Plain object test — literals only; class instances must replace, not merge. */
|
|
73
|
+
function isPlainObject(value) {
|
|
74
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
75
|
+
const proto = Object.getPrototypeOf(value);
|
|
76
|
+
return proto === Object.prototype || proto === null;
|
|
77
|
+
}
|
|
78
|
+
/** Recursive plain-object merge; nested arrays REPLACE (they're value lists). */
|
|
79
|
+
function mergePlain(base, next) {
|
|
80
|
+
const out = { ...base };
|
|
81
|
+
for (const [key, value] of Object.entries(next)) {
|
|
82
|
+
if (value === void 0) continue;
|
|
83
|
+
const existing = out[key];
|
|
84
|
+
out[key] = isPlainObject(existing) && isPlainObject(value) ? mergePlain(existing, value) : value;
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Canonical slot-aware merge of a base resource config with host seams.
|
|
90
|
+
* Later seams win over earlier ones; `undefined` values never clobber.
|
|
91
|
+
*
|
|
92
|
+
* Merge semantics (value-driven — no per-slot registry to drift):
|
|
93
|
+
*
|
|
94
|
+
* - **Top-level arrays CONCAT** — `routes`, `middlewares`, `presets`,
|
|
95
|
+
* `routeGuards`, `disabledRoutes`: additive collections, base first.
|
|
96
|
+
* - **Plain objects merge recursively** — `permissions`, `actions`,
|
|
97
|
+
* `schemaOptions` (incl. `fieldRules`), `aggregations`, `customSchemas`,
|
|
98
|
+
* `fields`, `cache`, `events`: per-key composition. Arrays NESTED inside
|
|
99
|
+
* them replace (they're value lists — enums, sort specs), not concat.
|
|
100
|
+
* - **Everything else last-wins** — class instances (`adapter`,
|
|
101
|
+
* `controller`, `queryParser`), functions, scalars.
|
|
102
|
+
*
|
|
103
|
+
* The single `as` at the return is the one documented erasure for the
|
|
104
|
+
* {@link AdapterLike}-widened seam slots — inside the helper so no module
|
|
105
|
+
* author ever writes one (mirrors mongokit's one-cast-at-the-boundary rule).
|
|
106
|
+
*/
|
|
107
|
+
function mergeResourceConfig(base, ...seams) {
|
|
108
|
+
const out = { ...base };
|
|
109
|
+
for (const seam of seams) {
|
|
110
|
+
if (!seam) continue;
|
|
111
|
+
for (const [key, value] of Object.entries(seam)) {
|
|
112
|
+
if (value === void 0) continue;
|
|
113
|
+
const existing = out[key];
|
|
114
|
+
if (Array.isArray(existing) && Array.isArray(value)) out[key] = [...existing, ...value];
|
|
115
|
+
else if (isPlainObject(existing) && isPlainObject(value)) out[key] = mergePlain(existing, value);
|
|
116
|
+
else if (Array.isArray(value)) out[key] = [...value];
|
|
117
|
+
else out[key] = value;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/core/defineResourceVariants.ts
|
|
124
|
+
/**
|
|
125
|
+
* Define multiple resources from a shared base config and per-variant overrides.
|
|
126
|
+
*
|
|
127
|
+
* Each variant is independently passed through `defineResource()` — the
|
|
128
|
+
* returned `ResourceDefinition`s are real, fully-registered resources.
|
|
129
|
+
* Register each one's plugin in your app:
|
|
130
|
+
*
|
|
131
|
+
* ```typescript
|
|
132
|
+
* await app.register(articlePublic.toPlugin());
|
|
133
|
+
* await app.register(articleAdmin.toPlugin());
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @param base Shared config — adapter, queryParser, schemaOptions, hooks, etc.
|
|
137
|
+
* Must NOT include `name` or `prefix` (those are per-variant).
|
|
138
|
+
* @param variants Map of variant key → override. Each variant must declare
|
|
139
|
+
* its own `name` and `prefix`. Other fields override the base.
|
|
140
|
+
* @returns A record where each key from `variants` maps to a real
|
|
141
|
+
* `ResourceDefinition` ready for `.toPlugin()` registration.
|
|
142
|
+
*/
|
|
143
|
+
function defineResourceVariants(base, variants) {
|
|
144
|
+
const out = {};
|
|
145
|
+
for (const key of Object.keys(variants)) {
|
|
146
|
+
const override = variants[key];
|
|
147
|
+
out[key] = defineResource({
|
|
148
|
+
...base,
|
|
149
|
+
...override
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
return out;
|
|
153
|
+
}
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/core/entityHelpers.ts
|
|
156
|
+
/**
|
|
157
|
+
* Per-request entity helpers — read the resource binding (idField + the
|
|
158
|
+
* URL `:id` value) off `req.arc`.
|
|
159
|
+
*
|
|
160
|
+
* Action handlers receive their `id` argument as the raw URL `:id` value.
|
|
161
|
+
* When the resource declares a custom `idField` (`slug`, `reportId`, …)
|
|
162
|
+
* that's NOT the document `_id`, a naive `Model.findById(id)` silently
|
|
163
|
+
* returns null. The historical footgun was a `findById(id)` typo where
|
|
164
|
+
* the handler author hadn't realised that `:id` resolves to the friendly
|
|
165
|
+
* handle.
|
|
166
|
+
*
|
|
167
|
+
* `getEntityQuery(req)` produces the canonical filter shape so handlers
|
|
168
|
+
* compose lookups with no resource-config recall:
|
|
169
|
+
*
|
|
170
|
+
* ```ts
|
|
171
|
+
* actions: {
|
|
172
|
+
* archive: {
|
|
173
|
+
* handler: async (id, data, req) => {
|
|
174
|
+
* const doc = await Model.findOne(getEntityQuery(req));
|
|
175
|
+
* if (!doc) throw new NotFoundError("Order");
|
|
176
|
+
* // ...
|
|
177
|
+
* },
|
|
178
|
+
* },
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* The router populates `req.arc.idField` and `req.arc.entityId` before
|
|
183
|
+
* invoking the handler — these helpers are zero-cost reads.
|
|
184
|
+
*/
|
|
185
|
+
/**
|
|
186
|
+
* Read the resource's configured `idField` for the current request.
|
|
187
|
+
* Falls back to the framework default (`_id`) when the route hasn't
|
|
188
|
+
* bound an idField — keeps handlers safe to author without checking
|
|
189
|
+
* the resource config.
|
|
190
|
+
*/
|
|
191
|
+
function getEntityIdField(req) {
|
|
192
|
+
return req.arc?.idField ?? "_id";
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Read the URL `:id` path param value as the resource handle.
|
|
196
|
+
* Returns `undefined` when the route has no `:id` segment (collection
|
|
197
|
+
* routes) — handlers that need the entity must be on row routes.
|
|
198
|
+
*/
|
|
199
|
+
function getEntityId(req) {
|
|
200
|
+
if (req.arc?.entityId !== void 0) return req.arc.entityId;
|
|
201
|
+
return req.params?.id;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Compose a `findOne` filter that resolves the current request's
|
|
205
|
+
* entity, regardless of whether the resource binds `_id` or a custom
|
|
206
|
+
* field. Idiomatic shape for arc action handlers.
|
|
207
|
+
*
|
|
208
|
+
* ```ts
|
|
209
|
+
* const doc = await Model.findOne(getEntityQuery(req));
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
212
|
+
* Returns `{}` when the route has no entity context (collection routes
|
|
213
|
+
* or tests bypassing the router) — caller decides what that means.
|
|
214
|
+
*/
|
|
215
|
+
function getEntityQuery(req) {
|
|
216
|
+
const id = getEntityId(req);
|
|
217
|
+
if (id === void 0) return {};
|
|
218
|
+
return { [getEntityIdField(req)]: id };
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
export { mergeResourceConfig as a, defineResourceVariants as i, getEntityIdField as n, defineAction as o, getEntityQuery as r, defineAggregation as s, getEntityId as t };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
2
|
import "./constants-DNre0wRg.mjs";
|
|
3
3
|
import { f as createError } from "./errors-DkO8Nk6-.mjs";
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
4
|
+
import { a as buildRouteHooks, i as selectPluginMw, l as buildAuthMiddlewareForPermissions, n as buildRouteConfig, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-DrED-C4v.mjs";
|
|
5
|
+
import { n as buildActionPermissionMw, t as tryRegisterRoute } from "./registerRoute-DTp18Ah_.mjs";
|
|
6
|
+
import { l as sendControllerResponse, r as resolvePipelineSteps, t as buildActionPipelineHandler } from "./pipeline-BGRnV-To.mjs";
|
|
6
7
|
import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-Ca7ySNPx.mjs";
|
|
7
8
|
//#region src/core/createActionRouter.ts
|
|
8
9
|
var createActionRouter_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { f as createError, l as UnauthorizedError, r as ForbiddenError } from "./errors-DkO8Nk6-.mjs";
|
|
2
|
-
import { a as
|
|
3
|
-
import { n as validateAggregations } from "./validate-
|
|
4
|
-
import { t as buildAggregationHandler } from "./buildHandler-
|
|
2
|
+
import { a as buildRouteHooks, c as buildAuthMiddleware, i as selectPluginMw, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-DrED-C4v.mjs";
|
|
3
|
+
import { n as validateAggregations } from "./validate-Bk44F2yT.mjs";
|
|
4
|
+
import { t as buildAggregationHandler } from "./buildHandler-Dtwd8fdz.mjs";
|
|
5
5
|
//#region src/core/aggregation/createAggregationRouter.ts
|
|
6
6
|
/**
|
|
7
7
|
* Register one Fastify route per aggregation. No-op when the map is
|