@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
2
|
import { C as isService, S as isOrgInScope, a as getDPoPJkt, b as isElevated, d as getScopeContext, f as getScopeContextMap, g as getUserId, m as getTeamId, o as getMandate, p as getServiceScopes, u as getRequestScope, v as hasOrgAccess, x as isMember } from "./types-Bi0r0vjG.mjs";
|
|
3
|
-
import { t as getUserRoles } from "./types-
|
|
3
|
+
import { t as getUserRoles } from "./types-DV9WDfeg.mjs";
|
|
4
4
|
import { t as MemoryCacheStore } from "./memory-QOLe11D5.mjs";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
//#region src/permissions/applyPermissionResult.ts
|
|
@@ -99,6 +99,173 @@ async function evaluateAndApplyPermission(check, context, request, reply, opts)
|
|
|
99
99
|
return true;
|
|
100
100
|
}
|
|
101
101
|
//#endregion
|
|
102
|
+
//#region src/permissions/fields.ts
|
|
103
|
+
/**
|
|
104
|
+
* Field-Level Permissions
|
|
105
|
+
*
|
|
106
|
+
* Control field visibility and writability per role.
|
|
107
|
+
* Integrated into the response path (read) and sanitization path (write).
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* import { fields, defineResource } from '@classytic/arc';
|
|
112
|
+
*
|
|
113
|
+
* const userResource = defineResource({
|
|
114
|
+
* name: 'user',
|
|
115
|
+
* adapter: userAdapter,
|
|
116
|
+
* fields: {
|
|
117
|
+
* salary: fields.visibleTo(['admin', 'hr']),
|
|
118
|
+
* internalNotes: fields.writableBy(['admin']),
|
|
119
|
+
* email: fields.redactFor(['viewer']),
|
|
120
|
+
* password: fields.hidden(),
|
|
121
|
+
* },
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
/** Type guard for Mongoose-like documents with toObject() */
|
|
126
|
+
function isMongooseDoc(obj) {
|
|
127
|
+
return !!obj && typeof obj === "object" && "toObject" in obj && typeof obj.toObject === "function";
|
|
128
|
+
}
|
|
129
|
+
const fields = {
|
|
130
|
+
/**
|
|
131
|
+
* Field is never included in responses. Not writable via API.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* fields: { password: fields.hidden() }
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
hidden() {
|
|
139
|
+
return { _type: "hidden" };
|
|
140
|
+
},
|
|
141
|
+
/**
|
|
142
|
+
* Field is only visible to users with specified roles.
|
|
143
|
+
* Other users don't see the field at all.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* fields: { salary: fields.visibleTo(['admin', 'hr']) }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
visibleTo(roles) {
|
|
151
|
+
return {
|
|
152
|
+
_type: "visibleTo",
|
|
153
|
+
roles
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
/**
|
|
157
|
+
* Field is only writable by users with specified roles.
|
|
158
|
+
* All users can still read the field. Users without the role
|
|
159
|
+
* have the field silently stripped from write operations.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* fields: { role: fields.writableBy(['admin']) }
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
writableBy(roles) {
|
|
167
|
+
return {
|
|
168
|
+
_type: "writableBy",
|
|
169
|
+
roles
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
/**
|
|
173
|
+
* Field is redacted (replaced with a placeholder) for specified roles.
|
|
174
|
+
* Other users see the real value.
|
|
175
|
+
*
|
|
176
|
+
* @param roles - Roles that see the redacted value
|
|
177
|
+
* @param redactValue - Replacement value (default: '***')
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* fields: {
|
|
182
|
+
* email: fields.redactFor(['viewer']),
|
|
183
|
+
* ssn: fields.redactFor(['basic'], '***-**-****'),
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
redactFor(roles, redactValue = "***") {
|
|
188
|
+
return {
|
|
189
|
+
_type: "redactFor",
|
|
190
|
+
roles,
|
|
191
|
+
redactValue
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Apply field-level READ permissions to a response object.
|
|
197
|
+
* Strips hidden fields, enforces visibility, and applies redaction.
|
|
198
|
+
*
|
|
199
|
+
* @param data - The response object (mutated in place for performance)
|
|
200
|
+
* @param fieldPermissions - Field permission map from resource config
|
|
201
|
+
* @param userRoles - Current user's roles (empty array for unauthenticated)
|
|
202
|
+
* @returns The filtered object
|
|
203
|
+
*/
|
|
204
|
+
function applyFieldReadPermissions(data, fieldPermissions, userRoles) {
|
|
205
|
+
if (!data || typeof data !== "object") return data;
|
|
206
|
+
const result = { ...isMongooseDoc(data) ? data.toObject() : data };
|
|
207
|
+
for (const [field, perm] of Object.entries(fieldPermissions)) switch (perm._type) {
|
|
208
|
+
case "hidden":
|
|
209
|
+
delete result[field];
|
|
210
|
+
break;
|
|
211
|
+
case "visibleTo":
|
|
212
|
+
if (!perm.roles?.some((r) => userRoles.includes(r))) delete result[field];
|
|
213
|
+
break;
|
|
214
|
+
case "redactFor":
|
|
215
|
+
if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
|
|
216
|
+
break;
|
|
217
|
+
case "writableBy": break;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Apply field-level WRITE permissions to request body.
|
|
223
|
+
*
|
|
224
|
+
* Returns both the filtered body and the list of denied fields. Callers are
|
|
225
|
+
* expected to reject the request when `deniedFields.length > 0` — silently
|
|
226
|
+
* stripping fields hides misconfigurations and real attacks. See
|
|
227
|
+
* `BodySanitizer` for the default policy.
|
|
228
|
+
*
|
|
229
|
+
* @param body - The request body (returns a new filtered copy)
|
|
230
|
+
* @param fieldPermissions - Field permission map from resource config
|
|
231
|
+
* @param userRoles - Current user's roles
|
|
232
|
+
*/
|
|
233
|
+
function applyFieldWritePermissions(body, fieldPermissions, userRoles) {
|
|
234
|
+
const result = { ...body };
|
|
235
|
+
const deniedFields = [];
|
|
236
|
+
for (const [field, perm] of Object.entries(fieldPermissions)) switch (perm._type) {
|
|
237
|
+
case "hidden":
|
|
238
|
+
if (field in result) {
|
|
239
|
+
deniedFields.push(field);
|
|
240
|
+
delete result[field];
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
case "writableBy":
|
|
244
|
+
if (field in result && !perm.roles?.some((r) => userRoles.includes(r))) {
|
|
245
|
+
deniedFields.push(field);
|
|
246
|
+
delete result[field];
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
body: result,
|
|
252
|
+
deniedFields
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Resolve effective roles by merging global user roles with org-level roles.
|
|
257
|
+
*
|
|
258
|
+
* Global roles come from `req.user.role` (normalized via getUserRoles()).
|
|
259
|
+
* Org roles come from `req.context.orgRoles` (set by BA adapter's org bridge).
|
|
260
|
+
*
|
|
261
|
+
* When no org context exists, returns global roles only — backward compatible.
|
|
262
|
+
*/
|
|
263
|
+
function resolveEffectiveRoles(userRoles, orgRoles) {
|
|
264
|
+
if (orgRoles.length === 0) return [...userRoles];
|
|
265
|
+
if (userRoles.length === 0) return [...orgRoles];
|
|
266
|
+
return [...new Set([...userRoles, ...orgRoles])];
|
|
267
|
+
}
|
|
268
|
+
//#endregion
|
|
102
269
|
//#region src/permissions/agent.ts
|
|
103
270
|
/**
|
|
104
271
|
* Agent-Auth Permission Helpers — DPoP + capability mandates for AI-agent flows
|
|
@@ -1148,173 +1315,6 @@ function createDynamicPermissionMatrix(config) {
|
|
|
1148
1315
|
};
|
|
1149
1316
|
}
|
|
1150
1317
|
//#endregion
|
|
1151
|
-
//#region src/permissions/fields.ts
|
|
1152
|
-
/**
|
|
1153
|
-
* Field-Level Permissions
|
|
1154
|
-
*
|
|
1155
|
-
* Control field visibility and writability per role.
|
|
1156
|
-
* Integrated into the response path (read) and sanitization path (write).
|
|
1157
|
-
*
|
|
1158
|
-
* @example
|
|
1159
|
-
* ```typescript
|
|
1160
|
-
* import { fields, defineResource } from '@classytic/arc';
|
|
1161
|
-
*
|
|
1162
|
-
* const userResource = defineResource({
|
|
1163
|
-
* name: 'user',
|
|
1164
|
-
* adapter: userAdapter,
|
|
1165
|
-
* fields: {
|
|
1166
|
-
* salary: fields.visibleTo(['admin', 'hr']),
|
|
1167
|
-
* internalNotes: fields.writableBy(['admin']),
|
|
1168
|
-
* email: fields.redactFor(['viewer']),
|
|
1169
|
-
* password: fields.hidden(),
|
|
1170
|
-
* },
|
|
1171
|
-
* });
|
|
1172
|
-
* ```
|
|
1173
|
-
*/
|
|
1174
|
-
/** Type guard for Mongoose-like documents with toObject() */
|
|
1175
|
-
function isMongooseDoc(obj) {
|
|
1176
|
-
return !!obj && typeof obj === "object" && "toObject" in obj && typeof obj.toObject === "function";
|
|
1177
|
-
}
|
|
1178
|
-
const fields = {
|
|
1179
|
-
/**
|
|
1180
|
-
* Field is never included in responses. Not writable via API.
|
|
1181
|
-
*
|
|
1182
|
-
* @example
|
|
1183
|
-
* ```typescript
|
|
1184
|
-
* fields: { password: fields.hidden() }
|
|
1185
|
-
* ```
|
|
1186
|
-
*/
|
|
1187
|
-
hidden() {
|
|
1188
|
-
return { _type: "hidden" };
|
|
1189
|
-
},
|
|
1190
|
-
/**
|
|
1191
|
-
* Field is only visible to users with specified roles.
|
|
1192
|
-
* Other users don't see the field at all.
|
|
1193
|
-
*
|
|
1194
|
-
* @example
|
|
1195
|
-
* ```typescript
|
|
1196
|
-
* fields: { salary: fields.visibleTo(['admin', 'hr']) }
|
|
1197
|
-
* ```
|
|
1198
|
-
*/
|
|
1199
|
-
visibleTo(roles) {
|
|
1200
|
-
return {
|
|
1201
|
-
_type: "visibleTo",
|
|
1202
|
-
roles
|
|
1203
|
-
};
|
|
1204
|
-
},
|
|
1205
|
-
/**
|
|
1206
|
-
* Field is only writable by users with specified roles.
|
|
1207
|
-
* All users can still read the field. Users without the role
|
|
1208
|
-
* have the field silently stripped from write operations.
|
|
1209
|
-
*
|
|
1210
|
-
* @example
|
|
1211
|
-
* ```typescript
|
|
1212
|
-
* fields: { role: fields.writableBy(['admin']) }
|
|
1213
|
-
* ```
|
|
1214
|
-
*/
|
|
1215
|
-
writableBy(roles) {
|
|
1216
|
-
return {
|
|
1217
|
-
_type: "writableBy",
|
|
1218
|
-
roles
|
|
1219
|
-
};
|
|
1220
|
-
},
|
|
1221
|
-
/**
|
|
1222
|
-
* Field is redacted (replaced with a placeholder) for specified roles.
|
|
1223
|
-
* Other users see the real value.
|
|
1224
|
-
*
|
|
1225
|
-
* @param roles - Roles that see the redacted value
|
|
1226
|
-
* @param redactValue - Replacement value (default: '***')
|
|
1227
|
-
*
|
|
1228
|
-
* @example
|
|
1229
|
-
* ```typescript
|
|
1230
|
-
* fields: {
|
|
1231
|
-
* email: fields.redactFor(['viewer']),
|
|
1232
|
-
* ssn: fields.redactFor(['basic'], '***-**-****'),
|
|
1233
|
-
* }
|
|
1234
|
-
* ```
|
|
1235
|
-
*/
|
|
1236
|
-
redactFor(roles, redactValue = "***") {
|
|
1237
|
-
return {
|
|
1238
|
-
_type: "redactFor",
|
|
1239
|
-
roles,
|
|
1240
|
-
redactValue
|
|
1241
|
-
};
|
|
1242
|
-
}
|
|
1243
|
-
};
|
|
1244
|
-
/**
|
|
1245
|
-
* Apply field-level READ permissions to a response object.
|
|
1246
|
-
* Strips hidden fields, enforces visibility, and applies redaction.
|
|
1247
|
-
*
|
|
1248
|
-
* @param data - The response object (mutated in place for performance)
|
|
1249
|
-
* @param fieldPermissions - Field permission map from resource config
|
|
1250
|
-
* @param userRoles - Current user's roles (empty array for unauthenticated)
|
|
1251
|
-
* @returns The filtered object
|
|
1252
|
-
*/
|
|
1253
|
-
function applyFieldReadPermissions(data, fieldPermissions, userRoles) {
|
|
1254
|
-
if (!data || typeof data !== "object") return data;
|
|
1255
|
-
const result = { ...isMongooseDoc(data) ? data.toObject() : data };
|
|
1256
|
-
for (const [field, perm] of Object.entries(fieldPermissions)) switch (perm._type) {
|
|
1257
|
-
case "hidden":
|
|
1258
|
-
delete result[field];
|
|
1259
|
-
break;
|
|
1260
|
-
case "visibleTo":
|
|
1261
|
-
if (!perm.roles?.some((r) => userRoles.includes(r))) delete result[field];
|
|
1262
|
-
break;
|
|
1263
|
-
case "redactFor":
|
|
1264
|
-
if (perm.roles?.some((r) => userRoles.includes(r))) result[field] = perm.redactValue ?? "***";
|
|
1265
|
-
break;
|
|
1266
|
-
case "writableBy": break;
|
|
1267
|
-
}
|
|
1268
|
-
return result;
|
|
1269
|
-
}
|
|
1270
|
-
/**
|
|
1271
|
-
* Apply field-level WRITE permissions to request body.
|
|
1272
|
-
*
|
|
1273
|
-
* Returns both the filtered body and the list of denied fields. Callers are
|
|
1274
|
-
* expected to reject the request when `deniedFields.length > 0` — silently
|
|
1275
|
-
* stripping fields hides misconfigurations and real attacks. See
|
|
1276
|
-
* `BodySanitizer` for the default policy.
|
|
1277
|
-
*
|
|
1278
|
-
* @param body - The request body (returns a new filtered copy)
|
|
1279
|
-
* @param fieldPermissions - Field permission map from resource config
|
|
1280
|
-
* @param userRoles - Current user's roles
|
|
1281
|
-
*/
|
|
1282
|
-
function applyFieldWritePermissions(body, fieldPermissions, userRoles) {
|
|
1283
|
-
const result = { ...body };
|
|
1284
|
-
const deniedFields = [];
|
|
1285
|
-
for (const [field, perm] of Object.entries(fieldPermissions)) switch (perm._type) {
|
|
1286
|
-
case "hidden":
|
|
1287
|
-
if (field in result) {
|
|
1288
|
-
deniedFields.push(field);
|
|
1289
|
-
delete result[field];
|
|
1290
|
-
}
|
|
1291
|
-
break;
|
|
1292
|
-
case "writableBy":
|
|
1293
|
-
if (field in result && !perm.roles?.some((r) => userRoles.includes(r))) {
|
|
1294
|
-
deniedFields.push(field);
|
|
1295
|
-
delete result[field];
|
|
1296
|
-
}
|
|
1297
|
-
break;
|
|
1298
|
-
}
|
|
1299
|
-
return {
|
|
1300
|
-
body: result,
|
|
1301
|
-
deniedFields
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
/**
|
|
1305
|
-
* Resolve effective roles by merging global user roles with org-level roles.
|
|
1306
|
-
*
|
|
1307
|
-
* Global roles come from `req.user.role` (normalized via getUserRoles()).
|
|
1308
|
-
* Org roles come from `req.context.orgRoles` (set by BA adapter's org bridge).
|
|
1309
|
-
*
|
|
1310
|
-
* When no org context exists, returns global roles only — backward compatible.
|
|
1311
|
-
*/
|
|
1312
|
-
function resolveEffectiveRoles(userRoles, orgRoles) {
|
|
1313
|
-
if (orgRoles.length === 0) return [...userRoles];
|
|
1314
|
-
if (userRoles.length === 0) return [...orgRoles];
|
|
1315
|
-
return [...new Set([...userRoles, ...orgRoles])];
|
|
1316
|
-
}
|
|
1317
|
-
//#endregion
|
|
1318
1318
|
//#region src/permissions/roleHierarchy.ts
|
|
1319
1319
|
/**
|
|
1320
1320
|
* Create a role hierarchy from a parent → children map.
|
|
@@ -1490,4 +1490,4 @@ function readOnly(overrides) {
|
|
|
1490
1490
|
}, overrides);
|
|
1491
1491
|
}
|
|
1492
1492
|
//#endregion
|
|
1493
|
-
export {
|
|
1493
|
+
export { requireMandate as A, requireAuth as C, when as D, roles as E, applyPermissionResult as F, evaluateAndApplyPermission as I, normalizePermissionResult as L, applyFieldWritePermissions as M, fields as N, requireAgentScope as O, resolveEffectiveRoles as P, not as S, requireRoles as T, requireTeamMembership as _, presets_exports as a, anyOf as b, readOnly as c, createOrgPermissions as d, requireOrgInScope as f, requireServiceScope as g, requireScopeContext as h, ownerWithAdminBypass as i, applyFieldReadPermissions as j, requireDPoP as k, createRoleHierarchy as l, requireOrgRole as m, authenticated as n, publicRead as o, requireOrgMembership as p, fullPublic as r, publicReadAdminWrite as s, adminOnly as t, createDynamicPermissionMatrix as u, allOf as v, requireOwnership as w, denyAll as x, allowPublic as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ft as OperationFilter, It as PipelineConfig, Lt as PipelineContext, Mt as Guard, Nt as Interceptor, Pt as NextFunction, Rt as PipelineStep, yt as IControllerResponse, zt as Transform } from "../index-
|
|
1
|
+
import { Ft as OperationFilter, It as PipelineConfig, Lt as PipelineContext, Mt as Guard, Nt as Interceptor, Pt as NextFunction, Rt as PipelineStep, yt as IControllerResponse, zt as Transform } from "../index-C1JSBan-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/pipeline/guard.d.ts
|
|
4
4
|
interface GuardOptions {
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,66 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import { _ as HealthOptions, a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, g as HealthCheck, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6, v as _default$3, y as healthPlugin } from "../versioning-
|
|
4
|
-
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-
|
|
5
|
-
import { t as TracingOptions } from "../tracing-
|
|
1
|
+
import { Kt as AnyRecord, Q as MiddlewareConfig, dt as RouteDefinition, mt as RouteSchemaOptions, nt as PresetHook } from "../index-C1JSBan-.mjs";
|
|
2
|
+
import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-7LIR0nDv.mjs";
|
|
3
|
+
import { _ as HealthOptions, a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, g as HealthCheck, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6, v as _default$3, y as healthPlugin } from "../versioning-5H4930tj.mjs";
|
|
4
|
+
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-DuqTqeqn.mjs";
|
|
5
|
+
import { t as TracingOptions } from "../tracing-bRqqUxFO.mjs";
|
|
6
6
|
import { PaginatedResult } from "@classytic/repo-core/pagination";
|
|
7
7
|
import { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
8
8
|
import * as _$node_stream0 from "node:stream";
|
|
9
9
|
|
|
10
|
-
//#region src/core/arcCorePlugin.d.ts
|
|
11
|
-
interface ArcCorePluginOptions {
|
|
12
|
-
/** Enable event emission for CRUD operations (requires eventPlugin) */
|
|
13
|
-
emitEvents?: boolean;
|
|
14
|
-
/** Hook system instance (for testing/custom setup) */
|
|
15
|
-
hookSystem?: HookSystem;
|
|
16
|
-
/** Resource registry instance (for testing/custom setup) */
|
|
17
|
-
registry?: ResourceRegistry;
|
|
18
|
-
}
|
|
19
|
-
interface PluginMeta {
|
|
20
|
-
name: string;
|
|
21
|
-
version?: string;
|
|
22
|
-
options?: Record<string, unknown>;
|
|
23
|
-
registeredAt: string;
|
|
24
|
-
}
|
|
25
|
-
interface ArcCore {
|
|
26
|
-
/** Instance-scoped hook system */
|
|
27
|
-
hooks: HookSystem;
|
|
28
|
-
/** Instance-scoped resource registry */
|
|
29
|
-
registry: ResourceRegistry;
|
|
30
|
-
/** Whether event emission is enabled */
|
|
31
|
-
emitEvents: boolean;
|
|
32
|
-
/** External OpenAPI paths contributed by auth adapters or third-party integrations */
|
|
33
|
-
externalOpenApiPaths: ExternalOpenApiPaths[];
|
|
34
|
-
/** Registered plugins for introspection */
|
|
35
|
-
plugins: Map<string, PluginMeta>;
|
|
36
|
-
}
|
|
37
|
-
declare module "fastify" {
|
|
38
|
-
interface FastifyInstance {
|
|
39
|
-
/**
|
|
40
|
-
* Arc core decorator. Optional because:
|
|
41
|
-
*
|
|
42
|
-
* 1. Consumers who import any `@classytic/arc/*` subpath get this module
|
|
43
|
-
* augmentation merged into every `FastifyInstance` they see — even
|
|
44
|
-
* instances on apps that never register {@link arcCorePlugin}. Making
|
|
45
|
-
* it required would force those apps to assert or guard every
|
|
46
|
-
* property access.
|
|
47
|
-
* 2. Hosts that extend `FastifyInstance` to narrow `arc` to their own
|
|
48
|
-
* type (`interface X extends FastifyInstance { arc?: MyArc }`) were
|
|
49
|
-
* previously blocked because non-optional `arc: ArcCore` conflicts
|
|
50
|
-
* with the re-declaration. An optional field lets hosts re-declare
|
|
51
|
-
* with a compatible subtype without fighting TS.
|
|
52
|
-
*
|
|
53
|
-
* Inside Arc's own code, any call site that runs *after* `arcCorePlugin`
|
|
54
|
-
* has registered treats this as non-null — see the call sites in
|
|
55
|
-
* `factory/registerAuth.ts` and `factory/createApp.ts` which assert
|
|
56
|
-
* with `fastify.arc!` or narrow explicitly.
|
|
57
|
-
*/
|
|
58
|
-
arc?: ArcCore;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
62
|
-
declare const _default: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
63
|
-
//#endregion
|
|
64
10
|
//#region src/plugins/createPlugin.d.ts
|
|
65
11
|
interface PluginResourceResult {
|
|
66
12
|
/** Additional routes to add to the resource (v2.8 `RouteDefinition` shape) */
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -3,13 +3,13 @@ import { c as getOrgId } from "../types-Bi0r0vjG.mjs";
|
|
|
3
3
|
import { t as requestContext } from "../requestContext-SSaaTgW8.mjs";
|
|
4
4
|
import { t as hasEvents } from "../typeGuards-BzkXkvVv.mjs";
|
|
5
5
|
import { t as HookSystem } from "../HookSystem-Cmf7-Etp.mjs";
|
|
6
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
7
|
-
import { n as caching_default, t as cachingPlugin } from "../caching-
|
|
8
|
-
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-
|
|
9
|
-
import { n as metrics_default, t as metricsPlugin } from "../metrics-
|
|
10
|
-
import { t as replyHelpersPlugin } from "../replyHelpers-
|
|
11
|
-
import { n as sse_default, t as ssePlugin } from "../sse-
|
|
12
|
-
import { n as versioning_default, t as versioningPlugin } from "../versioning-
|
|
6
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-CzSzVK1m.mjs";
|
|
7
|
+
import { n as caching_default, t as cachingPlugin } from "../caching-8MfrrUYU.mjs";
|
|
8
|
+
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-wQejMBT3.mjs";
|
|
9
|
+
import { n as metrics_default, t as metricsPlugin } from "../metrics-B-PU4-Yu.mjs";
|
|
10
|
+
import { t as replyHelpersPlugin } from "../replyHelpers-boS5Rx26.mjs";
|
|
11
|
+
import { n as sse_default, t as ssePlugin } from "../sse-jh5OqFjR.mjs";
|
|
12
|
+
import { n as versioning_default, t as versioningPlugin } from "../versioning-CuIwUQZ2.mjs";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
14
14
|
import fp from "fastify-plugin";
|
|
15
15
|
//#region src/core/arcCorePlugin.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-
|
|
1
|
+
import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-bRqqUxFO.mjs";
|
|
2
2
|
export { type TracingOptions, createSpan, isTracingAvailable, traced, _default as tracingPlugin };
|
|
@@ -58,7 +58,7 @@ try {
|
|
|
58
58
|
function createTracerProvider(options) {
|
|
59
59
|
if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
|
|
60
60
|
const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
|
|
61
|
-
const resolvedVersion = serviceVersion ?? "2.
|
|
61
|
+
const resolvedVersion = serviceVersion ?? "2.17.0";
|
|
62
62
|
const exporter = new OTLPTraceExporter({ url: exporterUrl });
|
|
63
63
|
const provider = new NodeTracerProvider({ resource: { attributes: {
|
|
64
64
|
"service.name": serviceName,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/testing/preloadResources.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalize an eager `import.meta.glob` result into a `ResourceLike[]`.
|
|
4
|
+
*
|
|
5
|
+
* Accepts either:
|
|
6
|
+
* - `{ import: 'default' }` form: values are the resource directly
|
|
7
|
+
* - default form: values are the full module — picks first export with `toPlugin()`
|
|
8
|
+
*
|
|
9
|
+
* Throws if any module doesn't yield a valid `ResourceLike`.
|
|
10
|
+
*/
|
|
11
|
+
function preloadResources(globResult) {
|
|
12
|
+
const resources = [];
|
|
13
|
+
for (const [path, value] of Object.entries(globResult)) {
|
|
14
|
+
const resource = pickResource(value);
|
|
15
|
+
if (!resource) throw new Error(`preloadResources: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
|
|
16
|
+
resources.push(resource);
|
|
17
|
+
}
|
|
18
|
+
return resources.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Normalize a lazy `import.meta.glob` result into a `Promise<ResourceLike[]>`.
|
|
22
|
+
*
|
|
23
|
+
* Use this when resources depend on prior bootstrap (e.g., engine init) and
|
|
24
|
+
* cannot be evaluated at import time of the preload file.
|
|
25
|
+
*/
|
|
26
|
+
async function preloadResourcesAsync(globResult) {
|
|
27
|
+
return (await Promise.all(Object.entries(globResult).map(async ([path, loader]) => {
|
|
28
|
+
const resource = pickResource(await loader());
|
|
29
|
+
if (!resource) throw new Error(`preloadResourcesAsync: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
|
|
30
|
+
return resource;
|
|
31
|
+
}))).sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
32
|
+
}
|
|
33
|
+
function pickResource(value) {
|
|
34
|
+
if (!value || typeof value !== "object") return void 0;
|
|
35
|
+
if (typeof value.toPlugin === "function") return value;
|
|
36
|
+
const mod = value;
|
|
37
|
+
const candidates = [
|
|
38
|
+
mod.default,
|
|
39
|
+
mod.resource,
|
|
40
|
+
...Object.values(mod)
|
|
41
|
+
];
|
|
42
|
+
for (const c of candidates) if (c && typeof c === "object" && typeof c.toPlugin === "function") return c;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { preloadResourcesAsync as n, preloadResources as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { rt as PresetResult } from "../index-
|
|
2
|
-
import { i as RequestScope } from "../types-
|
|
3
|
-
import { c as PermissionCheck } from "../fields-
|
|
4
|
-
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-
|
|
1
|
+
import { rt as PresetResult } from "../index-C1JSBan-.mjs";
|
|
2
|
+
import { i as RequestScope } from "../types-CfapW2t8.mjs";
|
|
3
|
+
import { c as PermissionCheck } from "../fields-DqZLp5d6.mjs";
|
|
4
|
+
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-HcAgP5Ni.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/presets/filesUpload.d.ts
|
|
7
7
|
interface FilesUploadPresetRoutes {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as NotFoundError, u as ValidationError } from "../errors-j4aJm1Wg.mjs";
|
|
2
2
|
import { c as getOrgId, g as getUserId } from "../types-Bi0r0vjG.mjs";
|
|
3
|
-
import { C as
|
|
4
|
-
import { t as multipartBody } from "../multipartBody-
|
|
3
|
+
import { C as requireAuth, y as allowPublic } from "../permissions-B1Qy55fg.mjs";
|
|
4
|
+
import { t as multipartBody } from "../multipartBody-VjVWmZl8.mjs";
|
|
5
5
|
//#region src/presets/filesUpload.ts
|
|
6
6
|
const DEFAULT_FIELD_NAME = "file";
|
|
7
7
|
const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
|
package/dist/presets/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kt as AnyRecord, bt as IRequestContext, d as PaginationResult, rt as PresetResult, st as ResourceConfig, yt as IControllerResponse } from "../index-
|
|
1
|
+
import { Kt as AnyRecord, bt as IRequestContext, d as PaginationResult, rt as PresetResult, st as ResourceConfig, yt as IControllerResponse } from "../index-C1JSBan-.mjs";
|
|
2
2
|
import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
|
|
3
3
|
import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
|
|
4
4
|
import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
|
package/dist/presets/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { multiTenantPreset } from "./multiTenant.mjs";
|
|
2
|
-
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-
|
|
2
|
+
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-BYbPobbF.mjs";
|
|
3
3
|
import { filesUploadPreset } from "./filesUpload.mjs";
|
|
4
4
|
import { searchPreset } from "./search.mjs";
|
|
5
5
|
export { applyPresets, auditedPreset, bulkPreset, filesUploadPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, searchPreset, slugLookupPreset, softDeletePreset, treePreset };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { dt as RouteDefinition, ft as RouteMcpConfig, ht as ControllerHandler, rt as PresetResult } from "../index-
|
|
2
|
-
import { c as PermissionCheck } from "../fields-
|
|
1
|
+
import { dt as RouteDefinition, ft as RouteMcpConfig, ht as ControllerHandler, rt as PresetResult } from "../index-C1JSBan-.mjs";
|
|
2
|
+
import { c as PermissionCheck } from "../fields-DqZLp5d6.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/presets/search.d.ts
|
|
5
5
|
/**
|
package/dist/presets/search.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as isElevated, n as PUBLIC_SCOPE } from "./types-Bi0r0vjG.mjs";
|
|
2
|
-
import { C as
|
|
2
|
+
import { C as requireAuth, T as requireRoles, y as allowPublic } from "./permissions-B1Qy55fg.mjs";
|
|
3
3
|
import { multiTenantPreset } from "./presets/multiTenant.mjs";
|
|
4
4
|
//#region src/presets/ownedByUser.ts
|
|
5
5
|
/**
|
|
@@ -70,14 +70,16 @@ function softDeletePreset() {
|
|
|
70
70
|
handler: "getDeleted",
|
|
71
71
|
summary: "Get soft-deleted items",
|
|
72
72
|
permissions: permissions.list ?? requireRoles(["admin"]),
|
|
73
|
-
operation: "listDeleted"
|
|
73
|
+
operation: "listDeleted",
|
|
74
|
+
_presetSource: "softDelete"
|
|
74
75
|
}, {
|
|
75
76
|
method: "POST",
|
|
76
77
|
path: "/:id/restore",
|
|
77
78
|
handler: "restore",
|
|
78
79
|
summary: "Restore soft-deleted item",
|
|
79
80
|
permissions: permissions.update ?? requireRoles(["admin"]),
|
|
80
|
-
operation: "restore"
|
|
81
|
+
operation: "restore",
|
|
82
|
+
_presetSource: "softDelete"
|
|
81
83
|
}]
|
|
82
84
|
};
|
|
83
85
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as CacheStore } from "./interface-
|
|
2
|
-
import { i as QueryCache } from "./QueryCache-
|
|
1
|
+
import { r as CacheStore } from "./interface-BVkZsvEe.mjs";
|
|
2
|
+
import { i as QueryCache } from "./QueryCache-8YmAQ-zW.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/cache/queryCachePlugin.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-
|
|
1
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-B1GFiYUy.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/events/transports/redis-stream.d.ts
|
|
4
4
|
interface RedisStreamLike {
|