@classytic/arc 2.10.3 → 2.11.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 +1 -1
- package/dist/{BaseController-CbKKIflT.mjs → BaseController-JNV08qOT.mjs} +595 -537
- package/dist/{queryCachePlugin-BKbWjgDG.d.mts → QueryCache-DOBNHBE0.d.mts} +2 -32
- package/dist/actionPermissions-C8YYU92K.mjs +22 -0
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +1 -1
- package/dist/{adapters-BXY4i-hw.mjs → adapters-D0tT2Tyo.mjs} +54 -0
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +15 -17
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +3 -3
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-BBRVhjQN.mjs → betterAuthOpenApi-DwxtK3uG.mjs} +1 -1
- package/dist/cache/index.d.mts +3 -2
- package/dist/cache/index.mjs +3 -3
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +37 -27
- package/dist/cli/commands/init.mjs +47 -34
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/context/index.d.mts +58 -0
- package/dist/context/index.mjs +2 -0
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -3
- package/dist/core-DXdSSFW-.mjs +1037 -0
- package/dist/createActionRouter-BwaSM0No.mjs +166 -0
- package/dist/{createApp-BuvPma24.mjs → createApp-DvNYEhpb.mjs} +118 -36
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/{elevation-C7hgL_aI.mjs → elevation-DOFoxoDs.mjs} +1 -1
- package/dist/errorHandler-Co3lnVmJ.d.mts +114 -0
- package/dist/{eventPlugin-DCUjuiQT.mjs → eventPlugin--5HIkdPU.mjs} +1 -1
- package/dist/{eventPlugin-CxWgpd6K.d.mts → eventPlugin-CUNjYYRY.d.mts} +1 -1
- package/dist/events/index.d.mts +4 -4
- package/dist/events/index.mjs +69 -51
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -2
- package/dist/{fields-Lo1VUDpt.d.mts → fields-C8Y0XLAu.d.mts} +1 -1
- 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 +38 -27
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-ChIw3776.d.mts → index-BYCqHCVu.d.mts} +4 -4
- package/dist/{index-Cl0uoKd5.d.mts → index-Cm0vUrr_.d.mts} +2100 -1688
- package/dist/{index-DStwgFUK.d.mts → index-DAushRTt.d.mts} +29 -10
- package/dist/index-DsJ1MNfC.d.mts +1179 -0
- package/dist/{index-8qw4y6ff.d.mts → index-t8pLpPFW.d.mts} +13 -10
- package/dist/index.d.mts +7 -251
- package/dist/index.mjs +8 -128
- 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 +46 -5
- package/dist/integrations/streamline.mjs +50 -21
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket.d.mts +2 -154
- package/dist/integrations/websocket.mjs +292 -224
- package/dist/{keys-qcD-TVJl.mjs → keys-CARyUjiR.mjs} +2 -0
- package/dist/{loadResources-BAzJItAJ.mjs → loadResources-YNwKHvRA.mjs} +3 -1
- package/dist/logger/index.d.mts +81 -0
- package/dist/{logger-DLg8-Ueg.mjs → logger/index.mjs} +1 -6
- package/dist/middleware/index.d.mts +109 -0
- package/dist/middleware/index.mjs +70 -0
- package/dist/multipartBody-CvTR1Un6.mjs +123 -0
- package/dist/{openapi-B5F8AddX.mjs → openapi-C0L9ar7m.mjs} +9 -7
- package/dist/org/index.d.mts +2 -2
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +1 -3
- package/dist/{permissions-Dk6mshja.mjs → permissions-B4vU9L0Q.mjs} +220 -2
- package/dist/pipe-DVoIheVC.mjs +62 -0
- package/dist/pipeline/index.d.mts +62 -0
- package/dist/pipeline/index.mjs +53 -0
- package/dist/plugins/index.d.mts +25 -5
- package/dist/plugins/index.mjs +10 -10
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +42 -24
- package/dist/presets/filesUpload.d.mts +4 -4
- package/dist/presets/filesUpload.mjs +255 -1
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +48 -8
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-fLJVXdVn.mjs → presets-k604Lj99.mjs} +1 -1
- package/dist/queryCachePlugin-BUXBSm4F.d.mts +34 -0
- package/dist/{queryCachePlugin-DQCEfJis.mjs → queryCachePlugin-Bq6bO6vc.mjs} +3 -3
- package/dist/{redis-DqyeggCa.d.mts → redis-Cm1gnRDf.d.mts} +1 -1
- package/dist/{redis-stream-CakIQmwR.d.mts → redis-stream-CM8TXTix.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{requestContext-xHIKedG6.mjs → requestContext-CfRkaxwf.mjs} +1 -1
- package/dist/{resourceToTools-BElv3xPT.mjs → resourceToTools--okX6QBr.mjs} +534 -415
- package/dist/routerShared-DeESFp4a.mjs +515 -0
- package/dist/schemaIR-BlG9bY7v.mjs +137 -0
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +1 -1
- package/dist/{sse-yBCgOLGu.mjs → sse-V7aXc3bW.mjs} +1 -1
- package/dist/{store-helpers-ZCSMJJAX.mjs → store-helpers-BhrzxvyQ.mjs} +4 -0
- package/dist/testing/index.d.mts +367 -711
- package/dist/testing/index.mjs +646 -1434
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/{tracing-65B51Dw3.d.mts → tracing-DokiEsuz.d.mts} +9 -4
- package/dist/types/index.d.mts +5 -5
- package/dist/types/index.mjs +1 -3
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-Co8k3NyS.d.mts → types-CgikqKAj.d.mts} +133 -21
- package/dist/{types-Btdda02s.d.mts → types-D9NqiYIw.d.mts} +1 -1
- package/dist/utils/index.d.mts +2 -898
- package/dist/utils/index.mjs +4 -5
- package/dist/utils-D3Yxnrwr.mjs +1639 -0
- package/dist/versioning-M9lNLhO8.d.mts +117 -0
- package/dist/websocket-CyJ1VIFI.d.mts +186 -0
- package/package.json +26 -8
- package/skills/arc/SKILL.md +124 -39
- package/skills/arc/references/testing.md +212 -183
- package/dist/applyPermissionResult-QhV1Pa-g.mjs +0 -37
- package/dist/core-CcR01lup.mjs +0 -1411
- package/dist/createActionRouter-Bp_5c_2b.mjs +0 -249
- package/dist/errorHandler-DRQ3EqfL.d.mts +0 -218
- package/dist/errors-CCSsMpXE.d.mts +0 -140
- package/dist/fields-bxkeltzz.mjs +0 -126
- package/dist/filesUpload-t21LS-py.mjs +0 -377
- package/dist/queryParser-DBqBB6AC.mjs +0 -352
- package/dist/types-Csi3FLfq.mjs +0 -27
- package/dist/utils-B2fNOD_i.mjs +0 -929
- /package/dist/{EventTransport-CUw5NNWe.d.mts → EventTransport-CfVEGaEl.d.mts} +0 -0
- /package/dist/{HookSystem-BNYKnrXF.mjs → HookSystem-CGsMd6oK.mjs} +0 -0
- /package/dist/{ResourceRegistry-BPd6NQDm.mjs → ResourceRegistry-DkAeAuTX.mjs} +0 -0
- /package/dist/{caching-CBpK_SCM.mjs → caching-CheW3m-S.mjs} +0 -0
- /package/dist/{elevation-C5SwtkAn.d.mts → elevation-s5ykdNHr.d.mts} +0 -0
- /package/dist/{errorHandler-Bb49BvPD.mjs → errorHandler-BQm8ZxTK.mjs} +0 -0
- /package/dist/{externalPaths-BQ8QijNH.d.mts → externalPaths-Bapitwvd.d.mts} +0 -0
- /package/dist/{interface-CSbZdv_3.d.mts → interface-CkkWm5uR.d.mts} +0 -0
- /package/dist/{interface-D218ikEo.d.mts → interface-Da0r7Lna.d.mts} +0 -0
- /package/dist/{memory-B5Amv9A1.mjs → memory-DikHSvWa.mjs} +0 -0
- /package/dist/{metrics-DuhiSEZI.mjs → metrics-Csh4nsvv.mjs} +0 -0
- /package/dist/{pluralize-A0tWEl1K.mjs → pluralize-BneOJkpi.mjs} +0 -0
- /package/dist/{registry-B3lRFBWo.mjs → registry-D63ee7fl.mjs} +0 -0
- /package/dist/{replyHelpers-CXtJDAZ0.mjs → replyHelpers-ByllIXXV.mjs} +0 -0
- /package/dist/{schemaConverter-BxFDdtXu.mjs → schemaConverter-B0oKLuqI.mjs} +0 -0
- /package/dist/{sessionManager-BkzVU8h2.d.mts → sessionManager-D-oNWHz3.d.mts} +0 -0
- /package/dist/{storage-CVk_SEn2.d.mts → storage-BwGQXUpd.d.mts} +0 -0
- /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{types-BD85MlEK.d.mts → types-tgR4Pt8F.d.mts} +0 -0
- /package/dist/{versioning-C2U_bLY0.mjs → versioning-CGPjkqAg.mjs} +0 -0
|
@@ -10,6 +10,20 @@ function resolveSpec(scope, spec) {
|
|
|
10
10
|
if (spec.type === "org") return getOrgId(scope);
|
|
11
11
|
if (spec.type === "team") return getTeamId(scope);
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* Stash the resolved tenant field map on the request so `BaseController`
|
|
15
|
+
* can forward it to the repository layer as top-level options. Needed by
|
|
16
|
+
* plugin-scoped repos (mongokit's `multiTenantPlugin`) that read tenant
|
|
17
|
+
* from `context.<field>` rather than from filter/query/data stamping.
|
|
18
|
+
*/
|
|
19
|
+
function stashTenantFields(request, resolved) {
|
|
20
|
+
if (Object.keys(resolved).length === 0) return;
|
|
21
|
+
const target = request;
|
|
22
|
+
target._tenantFields = {
|
|
23
|
+
...target._tenantFields ?? {},
|
|
24
|
+
...resolved
|
|
25
|
+
};
|
|
26
|
+
}
|
|
13
27
|
/** Resolve every spec — returns the partial map of fields that have a value. */
|
|
14
28
|
function resolveAll(scope, specs) {
|
|
15
29
|
const resolved = {};
|
|
@@ -34,10 +48,13 @@ function createTenantFilter(specs) {
|
|
|
34
48
|
const scope = getRequestScope(request);
|
|
35
49
|
if (isElevated(scope)) {
|
|
36
50
|
const { resolved } = resolveAll(scope, specs);
|
|
37
|
-
if (Object.keys(resolved).length > 0)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
if (Object.keys(resolved).length > 0) {
|
|
52
|
+
request._policyFilters = {
|
|
53
|
+
...request._policyFilters ?? {},
|
|
54
|
+
...resolved
|
|
55
|
+
};
|
|
56
|
+
stashTenantFields(request, resolved);
|
|
57
|
+
}
|
|
41
58
|
return;
|
|
42
59
|
}
|
|
43
60
|
if (hasOrgAccess(scope)) {
|
|
@@ -47,6 +64,7 @@ function createTenantFilter(specs) {
|
|
|
47
64
|
...request._policyFilters ?? {},
|
|
48
65
|
...resolved
|
|
49
66
|
};
|
|
67
|
+
stashTenantFields(request, resolved);
|
|
50
68
|
return;
|
|
51
69
|
}
|
|
52
70
|
reply.code(403).send({
|
|
@@ -81,10 +99,13 @@ function createFlexibleTenantFilter(specs) {
|
|
|
81
99
|
const scope = getRequestScope(request);
|
|
82
100
|
if (isElevated(scope)) {
|
|
83
101
|
const { resolved } = resolveAll(scope, specs);
|
|
84
|
-
if (Object.keys(resolved).length > 0)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
102
|
+
if (Object.keys(resolved).length > 0) {
|
|
103
|
+
request._policyFilters = {
|
|
104
|
+
...request._policyFilters ?? {},
|
|
105
|
+
...resolved
|
|
106
|
+
};
|
|
107
|
+
stashTenantFields(request, resolved);
|
|
108
|
+
}
|
|
88
109
|
return;
|
|
89
110
|
}
|
|
90
111
|
if (hasOrgAccess(scope)) {
|
|
@@ -94,6 +115,7 @@ function createFlexibleTenantFilter(specs) {
|
|
|
94
115
|
...request._policyFilters ?? {},
|
|
95
116
|
...resolved
|
|
96
117
|
};
|
|
118
|
+
stashTenantFields(request, resolved);
|
|
97
119
|
return;
|
|
98
120
|
}
|
|
99
121
|
reply.code(403).send({
|
|
@@ -109,6 +131,14 @@ function createFlexibleTenantFilter(specs) {
|
|
|
109
131
|
* Create tenant injection middleware.
|
|
110
132
|
* Walks the configured tenant fields and writes each into the request body.
|
|
111
133
|
* Fails closed if any required dimension is missing for non-elevated callers.
|
|
134
|
+
*
|
|
135
|
+
* Also stashes the resolved fields on `request._tenantFields` so
|
|
136
|
+
* `BaseController.tenantRepoOptions()` can forward them to the repo layer
|
|
137
|
+
* as top-level options — needed by plugin-scoped repos like mongokit's
|
|
138
|
+
* `multiTenantPlugin`, which reads tenant from `context.<field>` rather
|
|
139
|
+
* than from `data.<field>`. Without this forwarding, multi-field preset
|
|
140
|
+
* writes (update/delete) work only when the plugin's `allowDataInjection`
|
|
141
|
+
* fallback covers the operation's policy key, which is write-only.
|
|
112
142
|
*/
|
|
113
143
|
function createTenantInjection(specs) {
|
|
114
144
|
return async (request, reply) => {
|
|
@@ -124,6 +154,10 @@ function createTenantInjection(specs) {
|
|
|
124
154
|
return;
|
|
125
155
|
}
|
|
126
156
|
if (request.body) Object.assign(request.body, resolved);
|
|
157
|
+
request._tenantFields = {
|
|
158
|
+
...request._tenantFields ?? {},
|
|
159
|
+
...resolved
|
|
160
|
+
};
|
|
127
161
|
};
|
|
128
162
|
}
|
|
129
163
|
function multiTenantPreset(options = {}) {
|
|
@@ -138,8 +172,14 @@ function multiTenantPreset(options = {}) {
|
|
|
138
172
|
const flexibleTenantFilter = createFlexibleTenantFilter(specs);
|
|
139
173
|
const tenantInjection = createTenantInjection(specs);
|
|
140
174
|
const getFilter = (route) => allowPublic.includes(route) ? flexibleTenantFilter : strictTenantFilter;
|
|
175
|
+
const fieldRules = {};
|
|
176
|
+
for (const spec of specs) fieldRules[spec.field] = {
|
|
177
|
+
systemManaged: true,
|
|
178
|
+
preserveForElevated: true
|
|
179
|
+
};
|
|
141
180
|
return {
|
|
142
181
|
name: "multiTenant",
|
|
182
|
+
schemaOptions: { fieldRules },
|
|
143
183
|
middlewares: {
|
|
144
184
|
list: [getFilter("list")],
|
|
145
185
|
get: [getFilter("get")],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { lt as RouteDefinition, nt as PresetResult, pt as ControllerHandler, ut as RouteMcpConfig } from "../index-Cm0vUrr_.mjs";
|
|
2
|
+
import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/presets/search.d.ts
|
|
5
5
|
/**
|
package/dist/presets/search.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as isElevated, n as PUBLIC_SCOPE } from "./types-AOD8fxIw.mjs";
|
|
2
|
+
import { C as requireAuth, T as requireRoles, y as allowPublic } from "./permissions-B4vU9L0Q.mjs";
|
|
2
3
|
import { multiTenantPreset } from "./presets/multiTenant.mjs";
|
|
3
|
-
import { C as requireAuth, T as requireRoles, y as allowPublic } from "./permissions-Dk6mshja.mjs";
|
|
4
4
|
//#region src/presets/ownedByUser.ts
|
|
5
5
|
/**
|
|
6
6
|
* Create ownership check middleware.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { r as CacheStore } from "./interface-Da0r7Lna.mjs";
|
|
2
|
+
import { i as QueryCache } from "./QueryCache-DOBNHBE0.mjs";
|
|
3
|
+
import { FastifyPluginAsync } from "fastify";
|
|
4
|
+
|
|
5
|
+
//#region src/cache/queryCachePlugin.d.ts
|
|
6
|
+
interface QueryCachePluginOptions {
|
|
7
|
+
/** CacheStore instance. Default: MemoryCacheStore with default options. */
|
|
8
|
+
store?: CacheStore;
|
|
9
|
+
/** Global defaults for staleTime/gcTime (seconds) */
|
|
10
|
+
defaults?: {
|
|
11
|
+
staleTime?: number;
|
|
12
|
+
gcTime?: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
interface QueryCacheDefaults {
|
|
16
|
+
staleTime: number;
|
|
17
|
+
gcTime: number;
|
|
18
|
+
}
|
|
19
|
+
/** Cross-resource invalidation rules collected from resource configs */
|
|
20
|
+
interface CrossResourceRule {
|
|
21
|
+
pattern: string;
|
|
22
|
+
tags: string[];
|
|
23
|
+
}
|
|
24
|
+
declare module "fastify" {
|
|
25
|
+
interface FastifyInstance {
|
|
26
|
+
queryCache: QueryCache;
|
|
27
|
+
queryCacheConfig: QueryCacheDefaults;
|
|
28
|
+
/** Register cross-resource invalidation rules (called by defineResource) */
|
|
29
|
+
registerCacheInvalidationRule?(rule: CrossResourceRule): void;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
declare const queryCachePlugin: FastifyPluginAsync<QueryCachePluginOptions>;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { queryCachePlugin as i, QueryCacheDefaults as n, QueryCachePluginOptions as r, CrossResourceRule as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { i as versionKey, r as tagVersionKey } from "./keys-
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
2
|
+
import { i as versionKey, r as tagVersionKey } from "./keys-CARyUjiR.mjs";
|
|
3
|
+
import { t as MemoryCacheStore } from "./memory-DikHSvWa.mjs";
|
|
4
|
+
import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
|
|
5
5
|
import fp from "fastify-plugin";
|
|
6
6
|
//#region src/cache/QueryCache.ts
|
|
7
7
|
var QueryCache = class {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "./EventTransport-
|
|
1
|
+
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "./EventTransport-CfVEGaEl.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/events/transports/redis-stream.d.ts
|
|
4
4
|
interface RedisStreamLike {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-Cm0vUrr_.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/registry/introspectionPlugin.d.ts
|
package/dist/registry/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-
|
|
2
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
1
|
+
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-D63ee7fl.mjs";
|
|
2
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-DkAeAuTX.mjs";
|
|
3
3
|
export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
|
|
@@ -11,7 +11,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```typescript
|
|
14
|
-
* import { requestContext } from '@classytic/arc';
|
|
14
|
+
* import { requestContext } from '@classytic/arc/context';
|
|
15
15
|
*
|
|
16
16
|
* // Anywhere in the call stack — no parameter passing needed
|
|
17
17
|
* async function auditAction(action: string) {
|