@classytic/arc 2.16.0 → 2.17.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 +22 -2
- package/dist/{BaseController-DlCCTIxJ.mjs → BaseController-Dmeh4Y_y.mjs} +5 -47
- package/dist/{QueryCache-SvmT_9ti.d.mts → QueryCache-8YmAQ-zW.d.mts} +1 -1
- package/dist/{ResourceRegistry-f48hFk3m.mjs → ResourceRegistry-CzSzVK1m.mjs} +3 -0
- package/dist/audit/index.d.mts +1 -1
- package/dist/audit/index.mjs +2 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +2 -2
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/auth/redis-session.mjs +28 -2
- package/dist/{buildHandler-BZX6zzDM.mjs → buildHandler-C_SkBNF3.mjs} +6 -4
- package/dist/cache/index.d.mts +3 -3
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.d.mts +1 -1
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.d.mts +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.mjs +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -3
- package/dist/{core-DBJ_j6rX.mjs → core-DYJvu7aI.mjs} +174 -31
- package/dist/{createActionRouter-DUpN3Dd1.mjs → createActionRouter-BHUMb1-y.mjs} +6 -3
- package/dist/{createAggregationRouter-Dq-TUCuY.mjs → createAggregationRouter-BYVvhfc5.mjs} +3 -3
- package/dist/{createApp-DNccuhyI.mjs → createApp-CzCEEsEm.mjs} +9 -9
- package/dist/{defineEvent-DRwY0fYm.mjs → defineEvent-NPKUJRt8.mjs} +1 -1
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-Dci0AYLT.mjs → elevation-6mfTLBC-.mjs} +1 -1
- package/dist/{errorHandler-DpoXQHZ9.mjs → errorHandler-wQejMBT3.mjs} +45 -4
- package/dist/{eventPlugin-C2cGqtRO.mjs → eventPlugin-CnJCUyM0.mjs} +1 -1
- package/dist/{eventPlugin-CtHC_av1.d.mts → eventPlugin-DjEx_J3j.d.mts} +1 -1
- package/dist/events/index.d.mts +3 -3
- package/dist/events/index.mjs +5 -5
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +34 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/events/transports/redis.mjs +17 -1
- package/dist/factory/index.d.mts +2 -2
- package/dist/factory/index.mjs +4 -3
- package/dist/fastify-augmentation-7LIR0nDv.d.mts +42 -0
- package/dist/{fields-Anj0xdih.d.mts → fields-DqZLp5d6.d.mts} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.d.mts +2 -2
- package/dist/idempotency/index.mjs +21 -5
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-3oIimXQn.d.mts → index-3L-adFJO.d.mts} +3 -3
- package/dist/{index-CkW0flkU.d.mts → index-C1JSBan-.d.mts} +256 -8
- package/dist/{index-B-ulKx5P.d.mts → index-CruZir1o.d.mts} +36 -16
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +5 -5
- package/dist/integrations/event-gateway.d.mts +2 -2
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/jobs.d.mts +36 -1
- package/dist/integrations/jobs.mjs +82 -9
- package/dist/integrations/mcp/index.d.mts +67 -5
- package/dist/integrations/mcp/index.mjs +93 -2
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +1 -1
- package/dist/integrations/websocket.mjs +2 -1
- package/dist/{loadResourcesFromEntry-BLMEI2Xa.mjs → loadResourcesFromEntry-DCjYMgfC.mjs} +1 -1
- package/dist/{mcpPlugin-7vGV51ED.mjs → mcpPlugin-hZE00H74.mjs} +114 -11
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/{multipartBody-BOvVSVCD.mjs → multipartBody-VjVWmZl8.mjs} +2 -1
- package/dist/{openapi-34T9yNwd.mjs → openapi-DKDs9NfD.mjs} +37 -10
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +2 -2
- package/dist/{permissions-CTxMrreC.mjs → permissions-B1Qy55fg.mjs} +169 -169
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/plugins/index.d.mts +5 -59
- package/dist/plugins/index.mjs +7 -7
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/preloadResources-BOXzPhKU.mjs +45 -0
- package/dist/presets/filesUpload.d.mts +4 -4
- package/dist/presets/filesUpload.mjs +2 -2
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-C9BE6WaZ.mjs → presets-BYbPobbF.mjs} +5 -3
- package/dist/{queryCachePlugin-Biqzfbi5.d.mts → queryCachePlugin-Do4P_WBC.d.mts} +2 -2
- package/dist/{redis-Cyzrz6SX.d.mts → redis-cpqVb85w.d.mts} +1 -1
- package/dist/{redis-stream-DT-YjzrB.d.mts → redis-stream-BuiAS3aE.d.mts} +1 -1
- package/dist/registry/index.d.mts +30 -8
- package/dist/registry/index.mjs +2 -2
- package/dist/{registry-BBE23CDj.mjs → registry-BrlHkrRS.mjs} +14 -8
- package/dist/{routerShared-CZV5aabX.mjs → routerShared-nCyJGOKX.mjs} +164 -17
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +2 -2
- package/dist/testing/index.d.mts +2 -25
- package/dist/testing/index.mjs +2 -45
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-D-fYtKjb.d.mts → types-BRmS8TNa.d.mts} +34 -11
- package/dist/{types-BsJMEQ4D.d.mts → types-CoMjNmkF.d.mts} +12 -1
- package/dist/utils/index.d.mts +83 -5
- package/dist/utils/index.mjs +2 -2
- package/dist/{utils-DC5ycPfr.mjs → utils-CvD3glpM.mjs} +168 -3
- package/dist/{validate-By96rH0r.mjs → validate-DFIP2VrM.mjs} +65 -3
- package/dist/{versioning-ZwX9tmbS.d.mts → versioning-5H4930tj.d.mts} +1 -1
- package/package.json +3 -3
- package/skills/arc/SKILL.md +43 -1
- package/skills/arc/references/api-reference.md +2 -0
- package/skills/arc/references/mcp.md +30 -1
- /package/dist/{EventTransport-C-2oAHtw.d.mts → EventTransport-B1GFiYUy.d.mts} +0 -0
- /package/dist/{EventTransport-Hxvv5QQz.mjs → EventTransport-ClEDfiMS.mjs} +0 -0
- /package/dist/{caching-TeHE8G-v.mjs → caching-8MfrrUYU.mjs} +0 -0
- /package/dist/{elevation-0YBpa663.d.mts → elevation-DvwtjDwu.d.mts} +0 -0
- /package/dist/{errorHandler-mHuyWzZE.d.mts → errorHandler-DuqTqeqn.d.mts} +0 -0
- /package/dist/{errors-C1lX_jlm.d.mts → errors-4ZloYFvm.d.mts} +0 -0
- /package/dist/{externalPaths-DFg-2KTp.d.mts → externalPaths-ClykOQqa.d.mts} +0 -0
- /package/dist/{generate-CYac-OLv.mjs → generate-CcM24hoq.mjs} +0 -0
- /package/dist/{generate-BWFwgcCM.d.mts → generate-cRnsafMS.d.mts} +0 -0
- /package/dist/{init-Dv71MsJr.d.mts → init-D-vrTZ1G.d.mts} +0 -0
- /package/dist/{init-HDvoO9L5.mjs → init-DYzfniuX.mjs} +0 -0
- /package/dist/{interface-CH0OQudo.d.mts → interface-BVkZsvEe.d.mts} +0 -0
- /package/dist/{interface-NwJ_qPlY.d.mts → interface-DoE6UoC2.d.mts} +0 -0
- /package/dist/{loadResources-ChQEj8ih.mjs → loadResources-fol6JuvW.mjs} +0 -0
- /package/dist/{metrics-TuOmguhi.mjs → metrics-B-PU4-Yu.mjs} +0 -0
- /package/dist/{replyHelpers-C-gD32oF.mjs → replyHelpers-boS5Rx26.mjs} +0 -0
- /package/dist/{schemaIR-Ctc89DSn.mjs → schemaIR-DAOvBWgT.mjs} +0 -0
- /package/dist/{sessionManager-BqFegc0W.d.mts → sessionManager-DlmaHUAl.d.mts} +0 -0
- /package/dist/{sse-BY6sTy4P.mjs → sse-jh5OqFjR.mjs} +0 -0
- /package/dist/{storage-D2KZJAmn.d.mts → storage-HcAgP5Ni.d.mts} +0 -0
- /package/dist/{store-helpers-B0sunfZZ.mjs → store-helpers-5JgaxieH.mjs} +0 -0
- /package/dist/{tracing-Dm8n7Cnn.d.mts → tracing-bRqqUxFO.d.mts} +0 -0
- /package/dist/{types-DVfpSfx2.d.mts → types-CfapW2t8.d.mts} +0 -0
- /package/dist/{types-D57iXYb8.mjs → types-DV9WDfeg.mjs} +0 -0
- /package/dist/{versioning-B6mimogM.mjs → versioning-CuIwUQZ2.mjs} +0 -0
- /package/dist/{websocket-BkjeGZRn.d.mts → websocket-BJ0w-3Dt.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -122,12 +122,31 @@ export default defineResource({
|
|
|
122
122
|
actions: {
|
|
123
123
|
approve: { handler: approveOrder, permissions: requireRoles(['admin']) },
|
|
124
124
|
},
|
|
125
|
-
// mcp: false, // opt out of MCP tool generation for this resource
|
|
125
|
+
// mcp: false, // opt out of MCP tool generation for this resource
|
|
126
126
|
});
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
Auto-generates: `GET /products`, `GET /products/:id`, `POST /products`, `PATCH /products/:id`, `DELETE /products/:id` + softDelete adds `GET /products/deleted`, `POST /products/:id/restore` + slugLookup adds `GET /products/by-slug/:slug` + custom routes + `POST /products/:id/action`.
|
|
130
130
|
|
|
131
|
+
### Resource shorthands
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Reference data — read-only list+get, fetch-all limits (1000), 5min/10min cache.
|
|
135
|
+
defineResource({ name: 'currency', adapter, referenceData: true });
|
|
136
|
+
|
|
137
|
+
// Service resource — custom routes only, no adapter, no auto-CRUD, no registry entry.
|
|
138
|
+
defineResource({
|
|
139
|
+
name: 'health',
|
|
140
|
+
customRoutesOnly: true,
|
|
141
|
+
routes: [{ method: 'GET', path: '/ping', permissions: allowPublic(), handler: () => ({ ok: true }) }],
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Tune pagination caps inline (no custom queryParser needed).
|
|
145
|
+
defineResource({ name: 'pipeline', adapter, defaultLimit: 200, maxLimit: 500 });
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`?limit=` violations respond 400 with a cap-aware envelope: `message: "Query parameter 'limit' must be <= 500 (got 800) (cap is 500)"` plus `meta: { field: 'limit', cap: 500 }` so callers can self-correct without scraping the message.
|
|
149
|
+
|
|
131
150
|
---
|
|
132
151
|
|
|
133
152
|
## Permissions
|
|
@@ -243,7 +262,8 @@ Tree-shake by importing only the subpath you need:
|
|
|
243
262
|
| `@classytic/arc/plugins` | Health, request-id, versioning, tracing, response-cache |
|
|
244
263
|
| `@classytic/arc/integrations/jobs` | BullMQ job dispatcher |
|
|
245
264
|
| `@classytic/arc/integrations/websocket` | WebSocket integration |
|
|
246
|
-
| `@classytic/arc/mcp` | Model Context Protocol tools |
|
|
265
|
+
| `@classytic/arc/mcp` | Model Context Protocol tools + `createMcpAuthFromBetterAuthApiKey` (Better Auth API-key resolver), `resolveToolCollisions` |
|
|
266
|
+
| `@classytic/arc/utils` | `pipeUIMessageStreamToReply`, `UI_MESSAGE_STREAM_HEADERS` (Vercel AI SDK → Fastify reply); errors, query parser, circuit breaker |
|
|
247
267
|
| `@classytic/arc/testing` | `createTestApp`, `expectArc`, `TestAuthProvider`, `createTestFixtures` |
|
|
248
268
|
| `@classytic/arc/types` | Type-only barrel (zero runtime cost) |
|
|
249
269
|
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as DEFAULT_TENANT_FIELD } from "./constants-TrJVIJl0.mjs";
|
|
2
2
|
import { arcLog } from "./logger/index.mjs";
|
|
3
3
|
import { d as createDomainError, f as createError, i as NotFoundError, r as ForbiddenError } from "./errors-j4aJm1Wg.mjs";
|
|
4
|
-
import { b as isElevated, c as getOrgId
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { t as getUserRoles } from "./types-D57iXYb8.mjs";
|
|
4
|
+
import { b as isElevated, c as getOrgId } from "./types-Bi0r0vjG.mjs";
|
|
5
|
+
import { I as simpleEqualityMatcher, b as ArcQueryParser, o as scheduleBackground, t as getUserId } from "./utils-CvD3glpM.mjs";
|
|
6
|
+
import { w as BodySanitizer } from "./routerShared-nCyJGOKX.mjs";
|
|
8
7
|
import { t as buildQueryKey } from "./keys-DopsCuyQ.mjs";
|
|
9
8
|
//#region src/core/AccessControl.ts
|
|
10
9
|
const log = arcLog("access-control");
|
|
@@ -241,47 +240,6 @@ var AccessControl = class {
|
|
|
241
240
|
return req.metadata;
|
|
242
241
|
}
|
|
243
242
|
};
|
|
244
|
-
var BodySanitizer = class {
|
|
245
|
-
schemaOptions;
|
|
246
|
-
onFieldWriteDenied;
|
|
247
|
-
constructor(config) {
|
|
248
|
-
this.schemaOptions = config.schemaOptions;
|
|
249
|
-
this.onFieldWriteDenied = config.onFieldWriteDenied ?? "reject";
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Strip readonly and system-managed fields from request body.
|
|
253
|
-
* Prevents clients from overwriting _id, timestamps, __v, etc.
|
|
254
|
-
*
|
|
255
|
-
* Also applies field-level write permissions when the request has
|
|
256
|
-
* field permission metadata.
|
|
257
|
-
*/
|
|
258
|
-
sanitize(body, _operation, req, meta) {
|
|
259
|
-
let sanitized = { ...body };
|
|
260
|
-
for (const field of SYSTEM_FIELDS) delete sanitized[field];
|
|
261
|
-
const scopeForRules = req ? (meta ?? req.metadata)?._scope ?? PUBLIC_SCOPE : void 0;
|
|
262
|
-
const scopeIsElevated = scopeForRules ? isElevated(scopeForRules) : false;
|
|
263
|
-
const fieldRules = this.schemaOptions.fieldRules ?? {};
|
|
264
|
-
for (const [field, rules] of Object.entries(fieldRules)) {
|
|
265
|
-
const bypass = Boolean(rules.preserveForElevated) && scopeIsElevated;
|
|
266
|
-
if ((rules.systemManaged || rules.readonly) && !bypass) delete sanitized[field];
|
|
267
|
-
if (_operation === "update" && (rules.immutable || rules.immutableAfterCreate) && !bypass) delete sanitized[field];
|
|
268
|
-
}
|
|
269
|
-
if (req) {
|
|
270
|
-
const arcContext = meta ?? req.metadata;
|
|
271
|
-
const scope = arcContext?._scope ?? PUBLIC_SCOPE;
|
|
272
|
-
if (!isElevated(scope)) {
|
|
273
|
-
const fieldPerms = arcContext?.arc?.fields;
|
|
274
|
-
if (fieldPerms) {
|
|
275
|
-
const effectiveRoles = resolveEffectiveRoles(getUserRoles(req.user), isMember(scope) ? scope.orgRoles : []);
|
|
276
|
-
const { body: filtered, deniedFields } = applyFieldWritePermissions(sanitized, fieldPerms, effectiveRoles);
|
|
277
|
-
if (deniedFields.length > 0 && this.onFieldWriteDenied === "reject") throw new ForbiddenError(`Not permitted to write field${deniedFields.length === 1 ? "" : "s"}: ${deniedFields.join(", ")}`);
|
|
278
|
-
sanitized = filtered;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return sanitized;
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
243
|
//#endregion
|
|
286
244
|
//#region src/core/fieldRulePredicates.ts
|
|
287
245
|
/**
|
|
@@ -1531,4 +1489,4 @@ function TreeMixin(Base) {
|
|
|
1531
1489
|
*/
|
|
1532
1490
|
var BaseController = class extends SoftDeleteMixin(TreeMixin(SlugMixin(BulkMixin(BaseCrudController)))) {};
|
|
1533
1491
|
//#endregion
|
|
1534
|
-
export { BulkMixin as a, collectReadBlockedFields as c,
|
|
1492
|
+
export { BulkMixin as a, collectReadBlockedFields as c, SlugMixin as i, isFieldReadable as l, TreeMixin as n, BaseCrudController as o, SoftDeleteMixin as r, QueryResolver as s, BaseController as t, AccessControl as u };
|
|
@@ -96,6 +96,9 @@ var ResourceRegistry = class {
|
|
|
96
96
|
lookupAliases: (entry.lookups ?? []).map((l) => l.as ?? l.from),
|
|
97
97
|
requireDateRange: entry.requireDateRange,
|
|
98
98
|
requireFilters: entry.requireFilters,
|
|
99
|
+
limit: entry.limit,
|
|
100
|
+
defaultLimit: entry.defaultLimit,
|
|
101
|
+
maxLimit: entry.maxLimit,
|
|
99
102
|
mcp: entry.mcp
|
|
100
103
|
})) : void 0,
|
|
101
104
|
plugin: resource.toPlugin()
|
package/dist/audit/index.d.mts
CHANGED
package/dist/audit/index.mjs
CHANGED
package/dist/auth/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Bt as AuthHelpers, Vt as AuthPluginOptions } from "../index-
|
|
2
|
-
import { c as PermissionCheck } from "../fields-
|
|
3
|
-
import { t as ExternalOpenApiPaths } from "../externalPaths-
|
|
4
|
-
import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-
|
|
1
|
+
import { Bt as AuthHelpers, Vt as AuthPluginOptions } from "../index-C1JSBan-.mjs";
|
|
2
|
+
import { c as PermissionCheck } from "../fields-DqZLp5d6.mjs";
|
|
3
|
+
import { t as ExternalOpenApiPaths } from "../externalPaths-ClykOQqa.mjs";
|
|
4
|
+
import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-DlmaHUAl.mjs";
|
|
5
5
|
import { FastifyPluginAsync, FastifyReply as FastifyReply$1, FastifyRequest } from "fastify";
|
|
6
6
|
|
|
7
7
|
//#region src/auth/authPlugin.d.ts
|
package/dist/auth/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as createDomainError, l as UnauthorizedError, p as isArcError, t as ArcError } from "../errors-j4aJm1Wg.mjs";
|
|
2
|
-
import { _ as
|
|
3
|
-
import { n as normalizeRoles, t as getUserRoles } from "../types-
|
|
2
|
+
import { _ as requireTeamMembership, m as requireOrgRole, p as requireOrgMembership } from "../permissions-B1Qy55fg.mjs";
|
|
3
|
+
import { n as normalizeRoles, t as getUserRoles } from "../types-DV9WDfeg.mjs";
|
|
4
4
|
import { n as extractBetterAuthOpenApi } from "../betterAuthOpenApi-ClWxaceA.mjs";
|
|
5
5
|
import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
6
6
|
import fp from "fastify-plugin";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as SessionData, s as SessionStore } from "../sessionManager-
|
|
1
|
+
import { i as SessionData, s as SessionStore } from "../sessionManager-DlmaHUAl.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/auth/redis-session.d.ts
|
|
4
4
|
/** Minimal Redis client interface — compatible with ioredis */
|
|
@@ -1,5 +1,31 @@
|
|
|
1
|
+
import sjson from "secure-json-parse";
|
|
1
2
|
//#region src/auth/redis-session.ts
|
|
2
3
|
/**
|
|
4
|
+
* Redis Session Store for Arc
|
|
5
|
+
*
|
|
6
|
+
* Implements the SessionStore interface using Redis for distributed session storage.
|
|
7
|
+
* Use this in multi-instance/clustered deployments where MemorySessionStore won't work.
|
|
8
|
+
*
|
|
9
|
+
* This is a SEPARATE subpath import — only loaded when explicitly used:
|
|
10
|
+
* import { RedisSessionStore } from '@classytic/arc/auth/redis';
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { createSessionManager } from '@classytic/arc/auth';
|
|
15
|
+
* import { RedisSessionStore } from '@classytic/arc/auth/redis';
|
|
16
|
+
* import Redis from 'ioredis';
|
|
17
|
+
*
|
|
18
|
+
* const redis = new Redis(process.env.REDIS_URL);
|
|
19
|
+
*
|
|
20
|
+
* const sessions = createSessionManager({
|
|
21
|
+
* store: new RedisSessionStore({ redis }),
|
|
22
|
+
* secret: process.env.SESSION_SECRET!,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* await fastify.register(sessions.plugin);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
3
29
|
* Redis-backed session store for distributed deployments.
|
|
4
30
|
*
|
|
5
31
|
* Uses two key patterns:
|
|
@@ -22,7 +48,7 @@ var RedisSessionStore = class {
|
|
|
22
48
|
if (!raw) return null;
|
|
23
49
|
let session;
|
|
24
50
|
try {
|
|
25
|
-
session =
|
|
51
|
+
session = sjson.parse(raw);
|
|
26
52
|
} catch {
|
|
27
53
|
await this.delete(sessionId);
|
|
28
54
|
return null;
|
|
@@ -46,7 +72,7 @@ var RedisSessionStore = class {
|
|
|
46
72
|
async delete(sessionId) {
|
|
47
73
|
const raw = await this.redis.get(this.prefix + sessionId);
|
|
48
74
|
if (raw) try {
|
|
49
|
-
const session =
|
|
75
|
+
const session = sjson.parse(raw);
|
|
50
76
|
await this.redis.srem(this.userPrefix + session.userId, sessionId);
|
|
51
77
|
} catch {}
|
|
52
78
|
await this.redis.del(this.prefix + sessionId);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as compileAggRequest, t as adapterSupportsAggregate } from "./validate-
|
|
1
|
+
import { n as compileAggRequest, t as adapterSupportsAggregate } from "./validate-DFIP2VrM.mjs";
|
|
2
2
|
//#region src/core/aggregation/buildHandler.ts
|
|
3
3
|
/**
|
|
4
4
|
* Framework-agnostic aggregation execution. Runs safety guards,
|
|
@@ -24,7 +24,7 @@ async function executeAggregation(normalized, deps, ctx) {
|
|
|
24
24
|
status: 400,
|
|
25
25
|
body: guardError
|
|
26
26
|
};
|
|
27
|
-
const aggReq = compileAggRequest(normalized, extractCallerFilter(query), tenantOptions);
|
|
27
|
+
const aggReq = compileAggRequest(normalized, extractCallerFilter(query), tenantOptions, query);
|
|
28
28
|
if (config.materialized) {
|
|
29
29
|
const matCtx = {
|
|
30
30
|
filter: aggReq.filter,
|
|
@@ -259,8 +259,10 @@ function extractCallerFilter(query) {
|
|
|
259
259
|
return out;
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
262
|
-
* Map a kit-thrown error to the
|
|
263
|
-
*
|
|
262
|
+
* Map a kit-thrown error to the canonical `AggregationExecuteResponse`
|
|
263
|
+
* shape so the aggregation router can surface a structured failure
|
|
264
|
+
* (status + code + message) instead of leaking raw kit errors.
|
|
265
|
+
* Detects three signals:
|
|
264
266
|
* - "unsupported" / "not implemented" → 501 with upgrade hint
|
|
265
267
|
* - timeout markers → 504
|
|
266
268
|
* - everything else → 500
|
package/dist/cache/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-
|
|
2
|
-
import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-
|
|
3
|
-
import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-
|
|
1
|
+
import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-BVkZsvEe.mjs";
|
|
2
|
+
import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-8YmAQ-zW.mjs";
|
|
3
|
+
import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-Do4P_WBC.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/cache/keys.d.ts
|
|
6
6
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as ResourceDefinition, it as RateLimitConfig, mt as RouteSchemaOptions } from "../../index-
|
|
1
|
+
import { V as ResourceDefinition, it as RateLimitConfig, mt as RouteSchemaOptions } from "../../index-C1JSBan-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/cli/commands/describe.d.ts
|
|
4
4
|
interface DescribedResource {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as CRUD_OPERATIONS } from "../../constants-TrJVIJl0.mjs";
|
|
2
|
-
import { n as stringifyMeasureMap } from "../../ResourceRegistry-
|
|
2
|
+
import { n as stringifyMeasureMap } from "../../ResourceRegistry-CzSzVK1m.mjs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
//#region src/cli/commands/describe.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as buildOpenApiSpec } from "../../openapi-
|
|
2
|
-
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-
|
|
1
|
+
import { t as buildOpenApiSpec } from "../../openapi-DKDs9NfD.mjs";
|
|
2
|
+
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DCjYMgfC.mjs";
|
|
3
3
|
import { dirname, resolve } from "node:path";
|
|
4
4
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/cli/commands/docs.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as generate, t as ArcProjectConfig } from "../../generate-
|
|
1
|
+
import { n as generate, t as ArcProjectConfig } from "../../generate-cRnsafMS.mjs";
|
|
2
2
|
export { ArcProjectConfig, generate };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as generate } from "../../generate-
|
|
1
|
+
import { t as generate } from "../../generate-CcM24hoq.mjs";
|
|
2
2
|
export { generate };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-
|
|
1
|
+
import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-D-vrTZ1G.mjs";
|
|
2
2
|
export { DependencyManifest, InitOptions, PackageManager, ProjectConfig, init };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as init } from "../../init-
|
|
1
|
+
import { t as init } from "../../init-DYzfniuX.mjs";
|
|
2
2
|
export { init };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-
|
|
1
|
+
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DCjYMgfC.mjs";
|
|
2
2
|
//#region src/cli/commands/introspect.ts
|
|
3
3
|
function describePermission(value) {
|
|
4
4
|
if (!value) return "none";
|
package/dist/cli/index.d.mts
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 { n as generate } from "../generate-
|
|
5
|
-
import { t as init } from "../init-
|
|
4
|
+
import { n as generate } from "../generate-cRnsafMS.mjs";
|
|
5
|
+
import { t as init } from "../init-D-vrTZ1G.mjs";
|
|
6
6
|
import { introspect } from "./commands/introspect.mjs";
|
|
7
7
|
export { describe, doctor, exportDocs, generate, init, introspect };
|
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-CcM24hoq.mjs";
|
|
5
|
+
import { t as init } from "../init-DYzfniuX.mjs";
|
|
6
6
|
import { introspect } from "./commands/introspect.mjs";
|
|
7
7
|
export { describe, doctor, exportDocs, generate, init, introspect };
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $t as BaseController, At as AggregationRateLimit, B as defineResource, Cn as AccessControlConfig, Ct as AggMeasureShorthand, Dt as AggregationIndexHint, Et as AggregationDateRangeRequirement, Ot as AggregationMaterializedContext, Sn as AccessControl, St as AggMeasureInput, Tt as AggregationConfig, V as ResourceDefinition, an as SlugMixin, bn as BodySanitizer, cn as BaseControllerOptions, dn as ControllerConstructionOptions, en as SoftDeleteExt, fn as QueryResolver, in as SlugExt, jt as AggregationsMap, kt as AggregationMaterializedResult, ln as BaseCrudController, nn as TreeExt, on as BulkExt, pn as QueryResolverConfig, rn as TreeMixin, sn as BulkMixin, tn as SoftDeleteMixin, un as ControllerConfigurableOptions, wt as AggregationCacheConfig, xn as BodySanitizerConfig, yn as ListResult } from "../index-
|
|
2
|
-
import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, a as createRequestContext, b as DEFAULT_ID_FIELD, c as sendControllerResponse, d as getEntityQuery, f as defineResourceVariants, g as createPermissionMiddleware, h as createCrudRouter, i as createFastifyHandler, j as MAX_REGEX_LENGTH, k as HookPhase, l as getEntityId, m as defineAction, n as isFieldReadable, o as getControllerContext, p as DefineActionConfig, r as createCrudHandlers, s as getControllerScope, t as collectReadBlockedFields, u as getEntityIdField, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "../index-
|
|
1
|
+
import { $t as BaseController, At as AggregationRateLimit, B as defineResource, Cn as AccessControlConfig, Ct as AggMeasureShorthand, Dt as AggregationIndexHint, Et as AggregationDateRangeRequirement, Ot as AggregationMaterializedContext, Sn as AccessControl, St as AggMeasureInput, Tt as AggregationConfig, V as ResourceDefinition, an as SlugMixin, bn as BodySanitizer, cn as BaseControllerOptions, dn as ControllerConstructionOptions, en as SoftDeleteExt, fn as QueryResolver, in as SlugExt, jt as AggregationsMap, kt as AggregationMaterializedResult, ln as BaseCrudController, nn as TreeExt, on as BulkExt, pn as QueryResolverConfig, rn as TreeMixin, sn as BulkMixin, tn as SoftDeleteMixin, un as ControllerConfigurableOptions, wt as AggregationCacheConfig, xn as BodySanitizerConfig, yn as ListResult } from "../index-C1JSBan-.mjs";
|
|
2
|
+
import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, a as createRequestContext, b as DEFAULT_ID_FIELD, c as sendControllerResponse, d as getEntityQuery, f as defineResourceVariants, g as createPermissionMiddleware, h as createCrudRouter, i as createFastifyHandler, j as MAX_REGEX_LENGTH, k as HookPhase, l as getEntityId, m as defineAction, n as isFieldReadable, o as getControllerContext, p as DefineActionConfig, r as createCrudHandlers, s as getControllerScope, t as collectReadBlockedFields, u as getEntityIdField, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "../index-CruZir1o.mjs";
|
|
3
3
|
export { AccessControl, AccessControlConfig, AggMeasureInput, AggMeasureShorthand, AggregationCacheConfig, AggregationConfig, AggregationDateRangeRequirement, AggregationIndexHint, AggregationMaterializedContext, AggregationMaterializedResult, AggregationRateLimit, AggregationsMap, BaseController, BaseControllerOptions, BaseCrudController, BodySanitizer, BodySanitizerConfig, BulkExt, BulkMixin, CRUD_OPERATIONS, ControllerConfigurableOptions, ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugExt, SlugMixin, SoftDeleteExt, SoftDeleteMixin, TreeExt, TreeMixin, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, sendControllerResponse };
|
package/dist/core/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "../constants-TrJVIJl0.mjs";
|
|
2
|
-
import { a as BulkMixin, c as collectReadBlockedFields,
|
|
3
|
-
import { _ as
|
|
4
|
-
import { a as defineResource, c as createCrudRouter, i as defineResourceVariants, l as createPermissionMiddleware, n as getEntityIdField, o as ResourceDefinition, r as getEntityQuery, s as defineAction, t as getEntityId, u as defineAggregation } from "../core-
|
|
2
|
+
import { a as BulkMixin, c as collectReadBlockedFields, i as SlugMixin, l as isFieldReadable, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController, u as AccessControl } from "../BaseController-Dmeh4Y_y.mjs";
|
|
3
|
+
import { S as sendControllerResponse, _ as createCrudHandlers, b as getControllerContext, v as createFastifyHandler, w as BodySanitizer, x as getControllerScope, y as createRequestContext } from "../routerShared-nCyJGOKX.mjs";
|
|
4
|
+
import { a as defineResource, c as createCrudRouter, i as defineResourceVariants, l as createPermissionMiddleware, n as getEntityIdField, o as ResourceDefinition, r as getEntityQuery, s as defineAction, t as getEntityId, u as defineAggregation } from "../core-DYJvu7aI.mjs";
|
|
5
5
|
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, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, sendControllerResponse };
|