@classytic/arc 2.11.3 → 2.13.1
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 +27 -18
- package/dist/{BaseController-swXruJ2_.mjs → BaseController-DX_T-bDB.mjs} +388 -423
- package/dist/EventTransport-CT_52aWU.d.mts +34 -0
- package/dist/EventTransport-DLWoUMHy.mjs +103 -0
- package/dist/{QueryCache-DOBNHBE0.d.mts → QueryCache-D41bfdBB.d.mts} +1 -1
- package/dist/{ResourceRegistry-DkAeAuTX.mjs → ResourceRegistry-CTERg_2x.mjs} +139 -66
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +1 -1
- package/dist/auth/audit.d.mts +199 -0
- package/dist/auth/audit.mjs +288 -0
- package/dist/auth/index.d.mts +5 -5
- package/dist/auth/index.mjs +117 -191
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-DwxtK3uG.mjs → betterAuthOpenApi--M_i87dQ.mjs} +1 -1
- package/dist/buildHandler-olo-gt94.mjs +610 -0
- package/dist/cache/index.d.mts +3 -3
- package/dist/cache/index.mjs +3 -3
- package/dist/cli/commands/describe.d.mts +89 -13
- package/dist/cli/commands/describe.mjs +56 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +147 -48
- package/dist/cli/commands/init.d.mts +13 -0
- package/dist/cli/commands/init.mjs +237 -112
- package/dist/cli/commands/introspect.mjs +8 -1
- package/dist/context/index.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +5 -5
- package/dist/core-D72ia0EH.mjs +1399 -0
- package/dist/{createActionRouter-u3ql2EDo.mjs → createActionRouter-CEvzKcy8.mjs} +7 -20
- package/dist/createAggregationRouter-CyecOxnO.mjs +114 -0
- package/dist/{createApp-BFxtdKy6.mjs → createApp-XX2-N0Yd.mjs} +31 -27
- package/dist/defineEvent-D5h7EvAx.mjs +188 -0
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-DOFoxoDs.mjs → elevation-DgoeTyfX.mjs} +1 -1
- package/dist/errorHandler-Bk-AGhkU.mjs +174 -0
- package/dist/errorHandler-DFr45ZG4.d.mts +45 -0
- package/dist/errors-j4aJm1Wg.mjs +184 -0
- package/dist/{eventPlugin-KrFIQ097.mjs → eventPlugin-CaKTYkYM.mjs} +35 -137
- package/dist/{eventPlugin-CUNjYYRY.d.mts → eventPlugin-qXpqTebY.d.mts} +57 -7
- package/dist/events/index.d.mts +164 -5
- package/dist/events/index.mjs +133 -209
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +204 -31
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +2 -2
- package/dist/factory/index.mjs +2 -2
- package/dist/{fields-C8Y0XLAu.d.mts → fields-COhcH3fk.d.mts} +23 -2
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +3 -3
- package/dist/idempotency/index.mjs +1 -20
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-BYCqHCVu.d.mts → index-BTqLEvhu.d.mts} +164 -4
- package/dist/{index-6u4_Gg6G.d.mts → index-BtW7qYwa.d.mts} +661 -281
- package/dist/{index-BdXnTPRj.d.mts → index-Ds61mrJE.d.mts} +50 -4
- package/dist/{index-DdQ3O9Pg.d.mts → index-Dz5IKsrE.d.mts} +360 -219
- package/dist/index.d.mts +6 -7
- package/dist/index.mjs +9 -10
- 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/mcp/index.d.mts +2 -2
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.d.mts +60 -11
- package/dist/integrations/streamline.mjs +75 -85
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +1 -1
- package/dist/integrations/websocket.mjs +2 -8
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +2 -2
- package/dist/migrations/index.d.mts +23 -3
- package/dist/migrations/index.mjs +0 -7
- package/dist/{multipartBody-CvTR1Un6.mjs → multipartBody-BOvVSVCD.mjs} +11 -8
- package/dist/{openapi-BGUn7Ki1.mjs → openapi-CiOMVW1p.mjs} +143 -13
- package/dist/org/index.d.mts +2 -2
- package/dist/org/index.mjs +1 -1
- package/dist/permissions/index.d.mts +3 -3
- package/dist/permissions/index.mjs +3 -3
- package/dist/{permissions-gd_aUWrR.mjs → permissions-ohQyv50e.mjs} +404 -176
- package/dist/{pipe-DVoIheVC.mjs → pipe-Zr0KXjQe.mjs} +1 -1
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +1 -1
- package/dist/plugins/index.d.mts +18 -33
- package/dist/plugins/index.mjs +33 -13
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +5 -5
- package/dist/presets/filesUpload.mjs +6 -9
- 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/multiTenant.mjs +2 -2
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +6 -8
- package/dist/{presets-Z7P5w4gF.mjs → presets-BbkjdPeH.mjs} +6 -28
- package/dist/{queryCachePlugin-BUXBSm4F.d.mts → queryCachePlugin-CqMdLI2-.d.mts} +2 -2
- package/dist/{queryCachePlugin-Bq6bO6vc.mjs → queryCachePlugin-m1XsgAIJ.mjs} +3 -3
- package/dist/{redis-Cm1gnRDf.d.mts → redis-DiMkdHEl.d.mts} +1 -1
- package/dist/redis-stream-D6HzR1Z_.d.mts +232 -0
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{replyHelpers-ByllIXXV.mjs → replyHelpers-CK-FNO8E.mjs} +3 -21
- package/dist/{resourceToTools-ByZpgjeH.mjs → resourceToTools-C5coh64w.mjs} +224 -71
- package/dist/{routerShared-BqLRb5l7.mjs → routerShared-D6_fEGHh.mjs} +40 -36
- package/dist/{schemaIR-BlG9bY7v.mjs → schemaIR-7Vl611Qs.mjs} +1 -1
- package/dist/schemas/index.d.mts +100 -30
- package/dist/schemas/index.mjs +86 -29
- package/dist/scim/index.d.mts +264 -0
- package/dist/scim/index.mjs +963 -0
- package/dist/scope/index.d.mts +3 -3
- package/dist/scope/index.mjs +4 -4
- package/dist/{sse-V7aXc3bW.mjs → sse-Bz-5ZeTt.mjs} +1 -1
- package/dist/{store-helpers-BhrzxvyQ.mjs → store-helpers-BkIN9-vu.mjs} +1 -1
- package/dist/testing/index.d.mts +2 -8
- package/dist/testing/index.mjs +16 -24
- 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-BH7dEGvU.d.mts → types-BvqwCCSx.d.mts} +77 -29
- package/dist/{types-tgR4Pt8F.d.mts → types-CTYvcwHe.d.mts} +195 -1
- package/dist/{types-AOD8fxIw.mjs → types-C_s5moIu.mjs} +117 -1
- package/dist/{types-9beEMe25.d.mts → types-DQHFc8PM.d.mts} +1 -1
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.mjs +5 -5
- package/dist/{utils-CcYTj09l.mjs → utils-_h9B3c57.mjs} +1269 -1334
- package/dist/{versioning-M9lNLhO8.d.mts → versioning-DTTvc80y.d.mts} +1 -1
- package/package.json +24 -34
- package/skills/arc/SKILL.md +521 -785
- package/skills/arc/references/agent-auth.md +238 -0
- package/skills/arc/references/api-reference.md +187 -0
- package/skills/arc/references/auth.md +354 -7
- package/skills/arc/references/enterprise-auth.md +94 -0
- package/skills/arc/references/events.md +8 -6
- package/skills/arc/references/mcp.md +2 -2
- package/skills/arc/references/multi-tenancy.md +11 -2
- package/skills/arc/references/production.md +10 -9
- package/skills/arc/references/scim.md +247 -0
- package/skills/arc/references/testing.md +1 -1
- package/skills/arc-code-review/SKILL.md +141 -0
- package/skills/arc-code-review/references/anti-patterns.md +911 -0
- package/skills/arc-code-review/references/arc-cheatsheet.md +380 -0
- package/skills/arc-code-review/references/migration-recipes.md +700 -0
- package/skills/arc-code-review/references/mongokit-migration.md +386 -0
- package/skills/arc-code-review/references/scaffolding.md +230 -0
- package/skills/arc-code-review/references/severity.md +127 -0
- package/dist/EventTransport-CfVEGaEl.d.mts +0 -293
- package/dist/adapters/index.d.mts +0 -3
- package/dist/adapters/index.mjs +0 -2
- package/dist/adapters-D0tT2Tyo.mjs +0 -949
- package/dist/auth/mongoose.d.mts +0 -191
- package/dist/auth/mongoose.mjs +0 -73
- package/dist/core-DnUsRpuX.mjs +0 -1049
- package/dist/errorHandler-BQm8ZxTK.mjs +0 -173
- package/dist/errorHandler-Co3lnVmJ.d.mts +0 -114
- package/dist/errors-D5c-5BJL.mjs +0 -232
- package/dist/index-BbMrcvGp.d.mts +0 -362
- package/dist/redis-stream-CM8TXTix.d.mts +0 -110
- /package/dist/{HookSystem-CGsMd6oK.mjs → HookSystem-Iiebom92.mjs} +0 -0
- /package/dist/{actionPermissions-sUUKDhtP.mjs → actionPermissions-CyUkQu6O.mjs} +0 -0
- /package/dist/{caching-CheW3m-S.mjs → caching-SM8gghN6.mjs} +0 -0
- /package/dist/{constants-BhY1OHoH.mjs → constants-Cxde4rpC.mjs} +0 -0
- /package/dist/{elevation-s5ykdNHr.d.mts → elevation-BXOWoGCF.d.mts} +0 -0
- /package/dist/{externalPaths-Bapitwvd.d.mts → externalPaths-BD5nw6St.d.mts} +0 -0
- /package/dist/{interface-CkkWm5uR.d.mts → interface-DfLGcus7.d.mts} +0 -0
- /package/dist/{interface-Da0r7Lna.d.mts → interface-beEtJyWM.d.mts} +0 -0
- /package/dist/{keys-CARyUjiR.mjs → keys-CGcCbNyu.mjs} +0 -0
- /package/dist/{loadResources-CPpkyKfM.mjs → loadResources-DBMQg_Aj.mjs} +0 -0
- /package/dist/{memory-DikHSvWa.mjs → memory-UBydS5ku.mjs} +0 -0
- /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
- /package/dist/{pluralize-BneOJkpi.mjs → pluralize-DQgqgifU.mjs} +0 -0
- /package/dist/{registry-D63ee7fl.mjs → registry-I-ogLgL9.mjs} +0 -0
- /package/dist/{requestContext-C5XeK3VA.mjs → requestContext-SSaaTgW8.mjs} +0 -0
- /package/dist/{schemaConverter-B0oKLuqI.mjs → schemaConverter-De34B1ZG.mjs} +0 -0
- /package/dist/{sessionManager-D-oNWHz3.d.mts → sessionManager-C4Le_UB3.d.mts} +0 -0
- /package/dist/{storage-BwGQXUpd.d.mts → storage-Dfzt4VTl.d.mts} +0 -0
- /package/dist/{tracing-DokiEsuz.d.mts → tracing-QJVprktp.d.mts} +0 -0
- /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-BzkXkvVv.mjs} +0 -0
- /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
- /package/dist/{versioning-CGPjkqAg.mjs → versioning-BUrT5aP4.mjs} +0 -0
- /package/dist/{websocket-CyJ1VIFI.d.mts → websocket-ChC2rqe1.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
# @classytic/arc
|
|
2
2
|
|
|
3
|
-
Database-agnostic resource framework for Fastify. One `defineResource()` call
|
|
3
|
+
Database-agnostic resource framework for Fastify. One `defineResource()` call -> REST + auth + permissions + events + caching + OpenAPI + MCP tools.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Fastify 5+ | Node.js 22+ | ESM only
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
# Core
|
|
9
8
|
npm install @classytic/arc fastify
|
|
10
9
|
|
|
11
|
-
# Security defaults
|
|
10
|
+
# Security defaults createApp() loads (each opt-out via `cors: false` etc.)
|
|
12
11
|
npm install @fastify/cors @fastify/helmet @fastify/rate-limit @fastify/under-pressure @fastify/sensible
|
|
13
|
-
# (each is opt-out via `cors: false` / `helmet: false` / etc.)
|
|
14
12
|
|
|
15
|
-
#
|
|
16
|
-
npm install @classytic/mongokit mongoose
|
|
17
|
-
# OR @classytic/sqlitekit drizzle-orm better-sqlite3
|
|
18
|
-
# OR
|
|
13
|
+
# Storage adapter — pick one (kits ship their own adapters under `/adapter`)
|
|
14
|
+
npm install @classytic/mongokit mongoose # MongoDB → @classytic/mongokit/adapter
|
|
15
|
+
# OR @classytic/sqlitekit drizzle-orm better-sqlite3 # → @classytic/sqlitekit/adapter
|
|
16
|
+
# OR @classytic/prismakit @prisma/client # → @classytic/prismakit/adapter
|
|
17
|
+
# OR implement DataAdapter / RepositoryLike from @classytic/repo-core/adapter
|
|
19
18
|
```
|
|
20
19
|
|
|
21
20
|
---
|
|
@@ -25,7 +24,7 @@ npm install @classytic/mongokit mongoose # MongoDB (most common)
|
|
|
25
24
|
| | |
|
|
26
25
|
|---|---|
|
|
27
26
|
| **One call, full REST** | `defineResource({ name, adapter, presets, permissions })` → `GET /`, `GET /:id`, `POST /`, `PATCH /:id`, `DELETE /:id` + custom routes + actions |
|
|
28
|
-
| **DB-agnostic** | Mongoose, Drizzle/sqlitekit, or any `RepositoryLike` impl — swap backends without rewriting routes.
|
|
27
|
+
| **DB-agnostic** | Mongoose (`@classytic/mongokit/adapter`), Drizzle/SQLite (`@classytic/sqlitekit/adapter`), Prisma (`@classytic/prismakit/adapter`), or any `RepositoryLike` impl — swap backends without rewriting routes. Adapter contract lives in `@classytic/repo-core/adapter`; arc 2.12 ships zero kit-specific adapters. |
|
|
29
28
|
| **Multi-tenant by default** | Tenant-field auto-injected, scope-aware queries, per-org cache keys, elevation events. |
|
|
30
29
|
| **Tree-shakable subpaths** | `@classytic/arc/auth`, `/events`, `/cache`, `/mcp`, `/integrations/jobs` — pay only for what you import. |
|
|
31
30
|
| **MCP tools, free** | Resources auto-generate Model Context Protocol tools for AI agents. Same permissions, same field rules. |
|
|
@@ -40,12 +39,19 @@ import { createApp, loadResources } from '@classytic/arc/factory';
|
|
|
40
39
|
|
|
41
40
|
await mongoose.connect(process.env.DB_URI);
|
|
42
41
|
|
|
42
|
+
// Fail fast on missing CORS env — silent `undefined` here drops to surprising
|
|
43
|
+
// browser defaults. Browser apps: declare an explicit allowlist (below).
|
|
44
|
+
// Server-to-server / API-key services: `cors: { origin: '*', credentials: false }`
|
|
45
|
+
// or `cors: false` to disable entirely (CORS is a browser-only concern).
|
|
46
|
+
const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS;
|
|
47
|
+
if (!ALLOWED_ORIGINS) throw new Error('ALLOWED_ORIGINS env is required');
|
|
48
|
+
|
|
43
49
|
const app = await createApp({
|
|
44
50
|
preset: 'production',
|
|
45
51
|
resourcePrefix: '/api/v1',
|
|
46
52
|
resources: await loadResources(import.meta.url), // auto-discover *.resource.ts
|
|
47
53
|
auth: { type: 'jwt', jwt: { secret: process.env.JWT_SECRET } },
|
|
48
|
-
cors: { origin:
|
|
54
|
+
cors: { origin: ALLOWED_ORIGINS.split(','), credentials: true },
|
|
49
55
|
});
|
|
50
56
|
|
|
51
57
|
await app.listen({ port: 8040, host: '0.0.0.0' });
|
|
@@ -67,15 +73,16 @@ resources: async () => {
|
|
|
67
73
|
},
|
|
68
74
|
```
|
|
69
75
|
|
|
70
|
-
`loadResources({ context })`
|
|
76
|
+
`loadResources({ context })` threads engine handles into resources whose default export is `(ctx) => defineResource(...)`. No parallel factory files, no `exclude: [...]` bookkeeping.
|
|
71
77
|
|
|
72
78
|
---
|
|
73
79
|
|
|
74
80
|
## Define a resource
|
|
75
81
|
|
|
76
82
|
```typescript
|
|
77
|
-
import { defineResource
|
|
83
|
+
import { defineResource } from '@classytic/arc';
|
|
78
84
|
import { allowPublic, requireRoles, requireAuth } from '@classytic/arc/permissions';
|
|
85
|
+
import { createMongooseAdapter } from '@classytic/mongokit/adapter';
|
|
79
86
|
import { buildCrudSchemasFromModel } from '@classytic/mongokit';
|
|
80
87
|
import ProductModel from './product.model.js';
|
|
81
88
|
import productRepository from './product.repository.js';
|
|
@@ -167,7 +174,7 @@ auth: { type: 'custom', plugin: myAuthPlugin }
|
|
|
167
174
|
auth: false
|
|
168
175
|
```
|
|
169
176
|
|
|
170
|
-
Better Auth +
|
|
177
|
+
Better Auth + arc resources over BA tables: the kit owns the bridge. `@classytic/mongokit/better-auth` ships `createBetterAuthOverlay()` (per-collection `DataAdapter` for `defineResource`) and `registerBetterAuthStubs()` (bulk stub models for `populate()`). Sqlitekit users hand-roll the Drizzle table — see [auth.md](skills/arc/references/auth.md).
|
|
171
178
|
|
|
172
179
|
---
|
|
173
180
|
|
|
@@ -177,14 +184,16 @@ Tree-shake by importing only the subpath you need:
|
|
|
177
184
|
|
|
178
185
|
| Subpath | Purpose |
|
|
179
186
|
|---|---|
|
|
180
|
-
| `@classytic/arc` | `defineResource`, `BaseController`,
|
|
187
|
+
| `@classytic/arc` | `defineResource`, `BaseController`, error classes |
|
|
188
|
+
| `@classytic/repo-core/adapter` | Adapter contract types: `DataAdapter`, `RepositoryLike`, `AdapterRepositoryInput`, `asRepositoryLike`, `isRepository`. **Imported from repo-core directly** — arc deliberately does not re-export the contract to keep one source of truth. |
|
|
181
189
|
| `@classytic/arc/factory` | `createApp`, `loadResources`, presets |
|
|
182
190
|
| `@classytic/arc/auth` | JWT + Better Auth adapters |
|
|
183
|
-
| `@classytic/
|
|
191
|
+
| `@classytic/mongokit/better-auth` | BA overlay for Mongoose: `createBetterAuthOverlay`, `registerBetterAuthStubs` (kit-owned) |
|
|
192
|
+
| `@classytic/repo-core/better-auth` | BA collection registry shared by every kit's overlay |
|
|
184
193
|
| `@classytic/arc/permissions` | All permission helpers |
|
|
185
194
|
| `@classytic/arc/scope` | `RequestScope` accessors (`isMember`, `isElevated`, `getOrgId`, …) |
|
|
186
195
|
| `@classytic/arc/cache` | `QueryCache`, transports, plugin |
|
|
187
|
-
| `@classytic/arc/events` | Event plugin,
|
|
196
|
+
| `@classytic/arc/events` | Event plugin, `MemoryEventTransport`, outbox (event types live in `@classytic/primitives/events`) |
|
|
188
197
|
| `@classytic/arc/events/redis` · `/redis-stream` | Redis Pub/Sub + Streams transports (opt-in) |
|
|
189
198
|
| `@classytic/arc/plugins` | Health, request-id, versioning, tracing, response-cache |
|
|
190
199
|
| `@classytic/arc/integrations/jobs` | BullMQ job dispatcher |
|
|
@@ -206,7 +215,7 @@ const ctx = await createTestApp({
|
|
|
206
215
|
authMode: 'jwt',
|
|
207
216
|
connectMongoose: true, // in-memory Mongo + Mongoose connect
|
|
208
217
|
});
|
|
209
|
-
ctx.auth.register('admin', { user: { id: '1',
|
|
218
|
+
ctx.auth.register('admin', { user: { id: '1', role: 'admin' }, orgId: 'org-1' });
|
|
210
219
|
|
|
211
220
|
const res = await ctx.app.inject({
|
|
212
221
|
method: 'POST',
|