@classytic/arc 2.6.2 → 2.7.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 +95 -1
- package/dist/{BaseController-AbbRx3e0.mjs → BaseController-CpMfCXdn.mjs} +214 -16
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +1 -1
- package/dist/{adapters-CTn28N4y.mjs → adapters-BxGgSHjj.mjs} +7 -13
- package/dist/applyPermissionResult-D6GPMsvh.mjs +37 -0
- package/dist/audit/index.d.mts +1 -1
- package/dist/audit/index.mjs +1 -1
- package/dist/audit/mongodb.d.mts +1 -1
- package/dist/audit/mongodb.mjs +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +7 -6
- package/dist/auth/mongoose.d.mts +191 -0
- package/dist/auth/mongoose.mjs +73 -0
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-lz0IRbXJ.mjs → betterAuthOpenApi-CCw3YX0g.mjs} +1 -1
- package/dist/cache/index.d.mts +2 -2
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +7 -5
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -4
- package/dist/{core-C1XCMtqM.mjs → core-BWekSEju.mjs} +41 -13
- package/dist/{createApp-D2w0LdYJ.mjs → createApp-B_nvKNAQ.mjs} +11 -11
- package/dist/{defineResource-Ckxg6HrZ.mjs → defineResource-DZzyl4a4.mjs} +73 -56
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/dynamic/index.d.mts +2 -2
- package/dist/dynamic/index.mjs +2 -2
- package/dist/{elevation-BEdACOLB.mjs → elevation-By_p2lnn.mjs} +1 -1
- package/dist/elevation-Dm-HTBCt.d.mts +23 -0
- package/dist/{errorHandler-Do4vVQ1f.d.mts → errorHandler-COa51ho_.d.mts} +1 -1
- package/dist/{errorHandler-r2595m8T.mjs → errorHandler-DXUttWEO.mjs} +1 -1
- package/dist/{eventPlugin-DW45v4V5.d.mts → eventPlugin-BgLxJkIB.d.mts} +1 -1
- package/dist/{eventPlugin-Ba00swHF.mjs → eventPlugin-DsaNNXzZ.mjs} +1 -1
- package/dist/events/index.d.mts +3 -3
- package/dist/events/index.mjs +1 -1
- 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 +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/mongodb.d.mts +1 -1
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/index-BYpRGXif.d.mts +640 -0
- package/dist/{index-B4uZm82R.d.mts → index-KXM8_JmQ.d.mts} +47 -4
- package/dist/{index-DrCqa3Jq.d.mts → index-StgFaQKD.d.mts} +3 -3
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +10 -9
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- 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/{interface-CrN45qz1.d.mts → interface-Dwzqt4mn.d.mts} +204 -18
- package/dist/{mongodb-pMvOlR5_.d.mts → mongodb-Bq90j-Uj.d.mts} +1 -1
- package/dist/{mongodb-kltrBPa1.d.mts → mongodb-DdyYlIXg.d.mts} +1 -1
- package/dist/{openapi-CBmZ6EQN.mjs → openapi-C5UhIeWu.mjs} +1 -1
- package/dist/org/index.d.mts +2 -2
- package/dist/org/index.mjs +1 -1
- package/dist/permissions/index.d.mts +4 -4
- package/dist/permissions/index.mjs +3 -2
- package/dist/{permissions-C8ImI8gC.mjs → permissions-CH4cNwJi.mjs} +358 -64
- package/dist/plugins/index.d.mts +4 -4
- 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 +1 -1
- package/dist/policies/index.d.mts +1 -1
- package/dist/presets/index.d.mts +3 -3
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +53 -3
- package/dist/presets/multiTenant.mjs +89 -47
- package/dist/{presets-BMfdy34e.mjs → presets-BFrGvvjL.mjs} +2 -2
- package/dist/{queryCachePlugin-DcmETvcB.d.mts → queryCachePlugin-Bw8XyJpX.d.mts} +1 -1
- package/dist/{queryCachePlugin-XtFplYO9.mjs → queryCachePlugin-CwTpR04-.mjs} +2 -2
- package/dist/{redis-D0Qc-9EW.d.mts → redis-CyCntzTO.d.mts} +1 -1
- package/dist/{redis-stream-BW9UKLZM.d.mts → redis-stream-We_Ucl9-.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-DH3c3e-T.mjs → resourceToTools-CkVSSzKg.mjs} +313 -33
- package/dist/rpc/index.d.mts +1 -1
- package/dist/rpc/index.mjs +1 -1
- package/dist/scope/index.d.mts +3 -2
- package/dist/scope/index.mjs +4 -3
- package/dist/{sse-BF7GR7IB.mjs → sse-Bp3dabF1.mjs} +2 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +1 -1
- package/dist/types/index.d.mts +4 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types-AOD8fxIw.mjs +229 -0
- package/dist/types-CNEbix8T.d.mts +286 -0
- package/dist/{types-DurlBP2N.d.mts → types-ClmkMDK1.d.mts} +1 -1
- package/dist/{types-C1Z28coa.d.mts → types-D0qf0Mf4.d.mts} +9 -9
- package/dist/types-DPsC0taJ.d.mts +178 -0
- package/dist/utils/index.d.mts +3 -3
- package/dist/utils/index.mjs +5 -5
- package/package.json +34 -22
- package/skills/arc/SKILL.md +278 -6
- package/skills/arc/references/multi-tenancy.md +208 -0
- package/dist/elevation-C_taLQrM.d.mts +0 -147
- package/dist/index-NGZksqM5.d.mts +0 -398
- package/dist/types-BNUccdcf.d.mts +0 -101
- package/dist/types-BhtYdxZU.mjs +0 -91
- /package/dist/{EventTransport-wc5hSLik.d.mts → EventTransport-CUpRK_Lg.d.mts} +0 -0
- /package/dist/{HookSystem-COkyWztM.mjs → HookSystem-D7lfx--K.mjs} +0 -0
- /package/dist/{ResourceRegistry-C6ngvOnn.mjs → ResourceRegistry-DsHiG9cL.mjs} +0 -0
- /package/dist/{caching-BSXB-Xr7.mjs → caching-5DtLwIqb.mjs} +0 -0
- /package/dist/{circuitBreaker-JP2GdJ4b.d.mts → circuitBreaker-DwxrljLB.d.mts} +0 -0
- /package/dist/{circuitBreaker-BOBOpN2w.mjs → circuitBreaker-l18oRgL5.mjs} +0 -0
- /package/dist/{errors-CcVbl1-T.d.mts → errors-CCSsMpXE.d.mts} +0 -0
- /package/dist/{errors-NoQKsbAT.mjs → errors-Cg58SLNi.mjs} +0 -0
- /package/dist/{externalPaths-DpO-s7r8.d.mts → externalPaths-Dg7OLsKo.d.mts} +0 -0
- /package/dist/{fields-DFwdaWCq.d.mts → fields-CYuLMJPD.d.mts} +0 -0
- /package/dist/{interface-gr-7qo9j.d.mts → interface-B9rHWPxD.d.mts} +0 -0
- /package/dist/{interface-D_BWALyZ.d.mts → interface-CnluRL4_.d.mts} +0 -0
- /package/dist/{logger-Dz3j1ItV.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{memory-BFAYkf8H.mjs → memory-Cp7_cAko.mjs} +0 -0
- /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
- /package/dist/{mongodb-BuQ7fNTg.mjs → mongodb-mlgxkYI3.mjs} +0 -0
- /package/dist/{pluralize-CcT6qF0a.mjs → pluralize-COpOVar8.mjs} +0 -0
- /package/dist/{registry-I-ogLgL9.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{schemaConverter-DjzHpFam.mjs → schemaConverter-0TyONAwM.mjs} +0 -0
- /package/dist/{sessionManager-wbkYj2HL.d.mts → sessionManager-IW4sbIea.d.mts} +0 -0
- /package/dist/{tracing-bz_U4EM1.d.mts → tracing-65B51Dw3.d.mts} +0 -0
- /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
- /package/dist/{utils-Dc0WhlIl.mjs → utils-B-l6410F.mjs} +0 -0
- /package/dist/{versioning-BzfeHmhj.mjs → versioning-aUUVziBY.mjs} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { t as BaseController } from "./BaseController-
|
|
2
|
-
import {
|
|
1
|
+
import { t as BaseController } from "./BaseController-CpMfCXdn.mjs";
|
|
2
|
+
import { n as normalizePermissionResult } from "./applyPermissionResult-D6GPMsvh.mjs";
|
|
3
|
+
import { t as pluralize } from "./pluralize-COpOVar8.mjs";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
//#region src/integrations/mcp/createMcpServer.ts
|
|
5
6
|
/**
|
|
@@ -88,7 +89,9 @@ const PAGINATION_SHAPE = {
|
|
|
88
89
|
page: z.number().int().min(1).optional().describe("Page number (1-based)"),
|
|
89
90
|
limit: z.number().int().min(1).max(100).optional().describe("Items per page (max 100)"),
|
|
90
91
|
sort: z.string().optional().describe("Sort field, prefix with - for descending"),
|
|
91
|
-
search: z.string().optional().describe("Full-text search query")
|
|
92
|
+
search: z.string().optional().describe("Full-text search query"),
|
|
93
|
+
select: z.string().optional().describe("Comma-separated field list to project (e.g. 'name,price'). Prefix with '-' to exclude (e.g. '-description')."),
|
|
94
|
+
populate: z.string().optional().describe("Comma-separated relation paths to hydrate (e.g. 'supplier,category'). Follows Mongoose populate syntax when the adapter is MongoKit.")
|
|
92
95
|
};
|
|
93
96
|
/**
|
|
94
97
|
* Convert Arc fieldRules to a flat Zod shape.
|
|
@@ -179,6 +182,7 @@ function buildListShape(fieldRules, options) {
|
|
|
179
182
|
if (allHidden.has(name)) continue;
|
|
180
183
|
const rule = fieldRules[name];
|
|
181
184
|
if (!rule) continue;
|
|
185
|
+
if (rule.hidden || rule.systemManaged) continue;
|
|
182
186
|
const filterField = buildFieldSchema(rule);
|
|
183
187
|
shape[name] = filterField.optional();
|
|
184
188
|
if (allowedOperators?.length) {
|
|
@@ -212,9 +216,17 @@ function buildListShape(fieldRules, options) {
|
|
|
212
216
|
* | create | {} | {} | all input fields |
|
|
213
217
|
* | update | { id } | {} | input minus id |
|
|
214
218
|
* | delete | { id } | {} | undefined |
|
|
219
|
+
*
|
|
220
|
+
* **scopeOverride** — when a permission check (e.g. `requireApiKey()`) returns
|
|
221
|
+
* `PermissionResult.scope`, the MCP tool handler must install it on the request
|
|
222
|
+
* context the same way CRUD/action routes do. This parameter follows the exact
|
|
223
|
+
* same non-downgrade rule as `applyPermissionResult`: it overrides only when
|
|
224
|
+
* the session-derived scope is `public` (i.e. MCP called with `auth: false`).
|
|
225
|
+
* An authenticated session scope is never overwritten.
|
|
215
226
|
*/
|
|
216
|
-
function buildRequestContext(input, auth, operation, policyFilters) {
|
|
217
|
-
const
|
|
227
|
+
function buildRequestContext(input, auth, operation, policyFilters, scopeOverride) {
|
|
228
|
+
const sessionScope = buildScope(auth);
|
|
229
|
+
const scope = scopeOverride && sessionScope.kind === "public" ? scopeOverride : sessionScope;
|
|
218
230
|
const base = {
|
|
219
231
|
user: auth ? {
|
|
220
232
|
id: auth.userId,
|
|
@@ -264,7 +276,30 @@ function buildRequestContext(input, auth, operation, policyFilters) {
|
|
|
264
276
|
};
|
|
265
277
|
}
|
|
266
278
|
}
|
|
267
|
-
/**
|
|
279
|
+
/**
|
|
280
|
+
* Convert MCP operator keys (`price_gt`, `location_withinRadius`) to the
|
|
281
|
+
* nested object shape MongoKit's QueryParser expects (`{ price: { gt: ... } }`,
|
|
282
|
+
* `{ location: { withinRadius: ... } }`).
|
|
283
|
+
*
|
|
284
|
+
* **Comparison operators** (price_gt, age_lte, …): coerce filter values via
|
|
285
|
+
* the parser's coercion path.
|
|
286
|
+
*
|
|
287
|
+
* **Set operators** (status_in, role_nin, …): MongoKit accepts both
|
|
288
|
+
* comma-separated strings and arrays.
|
|
289
|
+
*
|
|
290
|
+
* **Existence** (deletedAt_exists): coerced to boolean by the parser.
|
|
291
|
+
*
|
|
292
|
+
* **Geo operators** (location_near, location_withinRadius, location_geoWithin,
|
|
293
|
+
* location_nearSphere): MongoKit 3.5.5+ — values are coordinate strings the
|
|
294
|
+
* parser's geo primitive handles. Without these in the allowlist, MCP agents
|
|
295
|
+
* couldn't pass geo filters at all and Arc would silently leak unfiltered docs.
|
|
296
|
+
*
|
|
297
|
+
* Keep this set in sync with MongoKit's QueryParser operators map (search for
|
|
298
|
+
* `private readonly operators` in QueryParser.ts) plus the geo operators
|
|
299
|
+
* recognized by `isGeoOperator` in primitives/geo.ts. We deliberately list
|
|
300
|
+
* them explicitly here rather than asking the parser at runtime — Arc must
|
|
301
|
+
* not import MongoKit internals just to know what an operator looks like.
|
|
302
|
+
*/
|
|
268
303
|
const OPERATOR_SUFFIXES = new Set([
|
|
269
304
|
"eq",
|
|
270
305
|
"ne",
|
|
@@ -274,7 +309,16 @@ const OPERATOR_SUFFIXES = new Set([
|
|
|
274
309
|
"lte",
|
|
275
310
|
"in",
|
|
276
311
|
"nin",
|
|
277
|
-
"exists"
|
|
312
|
+
"exists",
|
|
313
|
+
"size",
|
|
314
|
+
"type",
|
|
315
|
+
"like",
|
|
316
|
+
"contains",
|
|
317
|
+
"regex",
|
|
318
|
+
"near",
|
|
319
|
+
"nearSphere",
|
|
320
|
+
"withinRadius",
|
|
321
|
+
"geoWithin"
|
|
278
322
|
]);
|
|
279
323
|
function expandOperatorKeys(input) {
|
|
280
324
|
const out = {};
|
|
@@ -314,6 +358,146 @@ function buildScope(auth) {
|
|
|
314
358
|
};
|
|
315
359
|
}
|
|
316
360
|
//#endregion
|
|
361
|
+
//#region src/integrations/mcp/jsonSchemaToZod.ts
|
|
362
|
+
/**
|
|
363
|
+
* @classytic/arc — JSON Schema → Zod shape converter
|
|
364
|
+
*
|
|
365
|
+
* Converts an adapter-emitted JSON Schema body shape (`createBody` / `updateBody`)
|
|
366
|
+
* to a flat Zod shape compatible with the MCP SDK's `registerTool({ inputSchema })`
|
|
367
|
+
* contract.
|
|
368
|
+
*
|
|
369
|
+
* Why this exists:
|
|
370
|
+
* - The MCP SDK expects a flat `Record<string, ZodType>` shape (it wraps it in
|
|
371
|
+
* z.object() internally).
|
|
372
|
+
* - When users don't supply explicit `schemaOptions.fieldRules`, MCP would
|
|
373
|
+
* otherwise see an empty schema and silently strip every body field — that's
|
|
374
|
+
* a real DX footgun.
|
|
375
|
+
* - Adapters (Mongoose, MongoKit's buildCrudSchemasFromModel, custom) already
|
|
376
|
+
* emit JSON Schema describing the body. We translate it to Zod so MCP tools
|
|
377
|
+
* can validate input the same way REST routes do.
|
|
378
|
+
*
|
|
379
|
+
* Supported JSON Schema features:
|
|
380
|
+
* - Primitives: string, number, integer, boolean, null (skipped)
|
|
381
|
+
* - Constraints: minLength, maxLength, minimum, maximum, pattern, enum, format
|
|
382
|
+
* - Arrays: typed items + nested object items
|
|
383
|
+
* - Nested objects with `properties` (recursive)
|
|
384
|
+
* - Type unions: ["string", "null"] → string (null skipped)
|
|
385
|
+
* - Composition: oneOf / anyOf / allOf → first viable branch
|
|
386
|
+
* - $ref → permissive (z.unknown()) — refs are not resolved
|
|
387
|
+
* - Unknown types → z.unknown() (lenient — let the controller validate)
|
|
388
|
+
*
|
|
389
|
+
* NOT supported (intentionally — keeps the surface small + deterministic):
|
|
390
|
+
* - Conditional schemas (if/then/else)
|
|
391
|
+
* - dependencies / dependentRequired
|
|
392
|
+
* - Custom keywords beyond standard JSON Schema
|
|
393
|
+
*/
|
|
394
|
+
/**
|
|
395
|
+
* Convert a JSON Schema **object** body to a flat Zod shape.
|
|
396
|
+
* Returns `undefined` if the input has no usable properties.
|
|
397
|
+
*
|
|
398
|
+
* @param schema Top-level JSON Schema (must be `type: 'object'` with `properties`)
|
|
399
|
+
* @param mode 'create' enforces required fields, 'update' makes everything optional
|
|
400
|
+
*/
|
|
401
|
+
function jsonSchemaToZodShape(schema, mode = "create") {
|
|
402
|
+
if (!schema || typeof schema !== "object") return void 0;
|
|
403
|
+
if (!schema.properties || typeof schema.properties !== "object") return void 0;
|
|
404
|
+
const requiredSet = new Set(schema.required ?? []);
|
|
405
|
+
const shape = {};
|
|
406
|
+
for (const [name, propSchema] of Object.entries(schema.properties)) {
|
|
407
|
+
if (!propSchema || typeof propSchema !== "object") continue;
|
|
408
|
+
const fieldZod = jsonSchemaPropertyToZod(propSchema);
|
|
409
|
+
if (!fieldZod) continue;
|
|
410
|
+
shape[name] = mode === "create" && requiredSet.has(name) ? fieldZod : fieldZod.optional();
|
|
411
|
+
}
|
|
412
|
+
return Object.keys(shape).length > 0 ? shape : void 0;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Convert one JSON Schema node to a Zod type.
|
|
416
|
+
* Handles primitives, arrays, nested objects, type unions, and composition.
|
|
417
|
+
*/
|
|
418
|
+
function jsonSchemaPropertyToZod(prop) {
|
|
419
|
+
if (prop.$ref) return applyDescription(z.unknown(), prop);
|
|
420
|
+
if (Array.isArray(prop.oneOf) && prop.oneOf.length > 0) for (const branch of prop.oneOf) {
|
|
421
|
+
const z1 = jsonSchemaPropertyToZod(branch);
|
|
422
|
+
if (z1) return applyDescription(z1, prop);
|
|
423
|
+
}
|
|
424
|
+
if (Array.isArray(prop.anyOf) && prop.anyOf.length > 0) for (const branch of prop.anyOf) {
|
|
425
|
+
const z1 = jsonSchemaPropertyToZod(branch);
|
|
426
|
+
if (z1) return applyDescription(z1, prop);
|
|
427
|
+
}
|
|
428
|
+
if (Array.isArray(prop.allOf) && prop.allOf.length > 0) for (let i = prop.allOf.length - 1; i >= 0; i--) {
|
|
429
|
+
const branch = prop.allOf[i];
|
|
430
|
+
const z1 = jsonSchemaPropertyToZod(branch);
|
|
431
|
+
if (z1) return applyDescription(z1, prop);
|
|
432
|
+
}
|
|
433
|
+
if (Array.isArray(prop.enum) && prop.enum.length > 0) {
|
|
434
|
+
const stringValues = prop.enum.filter((v) => typeof v === "string");
|
|
435
|
+
if (stringValues.length > 0) return applyDescription(z.enum(stringValues), prop);
|
|
436
|
+
return applyDescription(z.number(), prop);
|
|
437
|
+
}
|
|
438
|
+
const typeCandidates = pickEffectiveType(prop.type);
|
|
439
|
+
for (const t of typeCandidates) switch (t) {
|
|
440
|
+
case "string": return applyStringConstraints(z.string(), prop);
|
|
441
|
+
case "number":
|
|
442
|
+
case "integer": return applyNumberConstraints(z.number(), prop);
|
|
443
|
+
case "boolean": return applyDescription(z.boolean(), prop);
|
|
444
|
+
case "array": return applyDescription(arrayToZod(prop), prop);
|
|
445
|
+
case "object": return applyDescription(objectToZod(prop), prop);
|
|
446
|
+
case "null": continue;
|
|
447
|
+
default: break;
|
|
448
|
+
}
|
|
449
|
+
return applyDescription(z.unknown(), prop);
|
|
450
|
+
}
|
|
451
|
+
function pickEffectiveType(rawType) {
|
|
452
|
+
if (!rawType) return [];
|
|
453
|
+
if (Array.isArray(rawType)) return rawType.filter((t) => t !== "null");
|
|
454
|
+
return rawType === "null" ? [] : [rawType];
|
|
455
|
+
}
|
|
456
|
+
function arrayToZod(prop) {
|
|
457
|
+
const items = prop.items;
|
|
458
|
+
if (items && typeof items === "object") {
|
|
459
|
+
const itemZod = jsonSchemaPropertyToZod(items);
|
|
460
|
+
if (itemZod) return z.array(itemZod);
|
|
461
|
+
}
|
|
462
|
+
return z.array(z.unknown());
|
|
463
|
+
}
|
|
464
|
+
function objectToZod(prop) {
|
|
465
|
+
if (prop.properties && typeof prop.properties === "object") {
|
|
466
|
+
const requiredSet = new Set(prop.required ?? []);
|
|
467
|
+
const innerShape = {};
|
|
468
|
+
for (const [k, v] of Object.entries(prop.properties)) {
|
|
469
|
+
if (!v || typeof v !== "object") continue;
|
|
470
|
+
const inner = jsonSchemaPropertyToZod(v);
|
|
471
|
+
if (!inner) continue;
|
|
472
|
+
innerShape[k] = requiredSet.has(k) ? inner : inner.optional();
|
|
473
|
+
}
|
|
474
|
+
if (Object.keys(innerShape).length > 0) return z.object(innerShape);
|
|
475
|
+
}
|
|
476
|
+
return z.record(z.string(), z.unknown());
|
|
477
|
+
}
|
|
478
|
+
function applyStringConstraints(base, prop) {
|
|
479
|
+
let s = base;
|
|
480
|
+
if (typeof prop.minLength === "number") s = s.min(prop.minLength);
|
|
481
|
+
if (typeof prop.maxLength === "number") s = s.max(prop.maxLength);
|
|
482
|
+
if (typeof prop.pattern === "string") try {
|
|
483
|
+
s = s.regex(new RegExp(prop.pattern));
|
|
484
|
+
} catch {}
|
|
485
|
+
if (prop.format === "email") s = s.email();
|
|
486
|
+
if (prop.format === "uuid") s = s.uuid();
|
|
487
|
+
if (prop.format === "uri" || prop.format === "url") s = s.url();
|
|
488
|
+
return applyDescription(s, prop);
|
|
489
|
+
}
|
|
490
|
+
function applyNumberConstraints(base, prop) {
|
|
491
|
+
let n = base;
|
|
492
|
+
if (typeof prop.minimum === "number") n = n.min(prop.minimum);
|
|
493
|
+
if (typeof prop.maximum === "number") n = n.max(prop.maximum);
|
|
494
|
+
return applyDescription(n, prop);
|
|
495
|
+
}
|
|
496
|
+
function applyDescription(zodType, prop) {
|
|
497
|
+
if (typeof prop.description === "string" && prop.description.length > 0) return zodType.describe(prop.description);
|
|
498
|
+
return zodType;
|
|
499
|
+
}
|
|
500
|
+
//#endregion
|
|
317
501
|
//#region src/integrations/mcp/resourceToTools.ts
|
|
318
502
|
/**
|
|
319
503
|
* @classytic/arc — Resource → MCP Tools Generator
|
|
@@ -359,9 +543,11 @@ const ANNOTATIONS = {
|
|
|
359
543
|
function resourceToTools(resource, config = {}) {
|
|
360
544
|
const controller = resource.controller ?? (resource.adapter ? createMcpController(resource) : void 0);
|
|
361
545
|
if (!controller) return [];
|
|
362
|
-
const
|
|
546
|
+
const explicitFieldRules = resource.schemaOptions?.fieldRules;
|
|
363
547
|
const hiddenFields = resource.schemaOptions?.hiddenFields;
|
|
364
548
|
const readonlyFields = resource.schemaOptions?.readonlyFields;
|
|
549
|
+
const adapterBodies = explicitFieldRules ? void 0 : getAdapterBodies(resource);
|
|
550
|
+
const fieldRules = explicitFieldRules ?? deriveFieldRulesFromAdapter(resource);
|
|
365
551
|
const filterableFields = resource.schemaOptions?.filterableFields ?? resource.queryParser?.allowedFilterFields;
|
|
366
552
|
const sortableFields = resource.queryParser?.allowedSortFields;
|
|
367
553
|
const allowedOperators = resource.queryParser?.allowedOperators;
|
|
@@ -388,7 +574,8 @@ function resourceToTools(resource, config = {}) {
|
|
|
388
574
|
readonlyFields,
|
|
389
575
|
extraHideFields: config.hideFields,
|
|
390
576
|
filterableFields,
|
|
391
|
-
allowedOperators
|
|
577
|
+
allowedOperators,
|
|
578
|
+
adapterBodies
|
|
392
579
|
}),
|
|
393
580
|
handler: createHandler(op, controller, resource.name, resource.permissions)
|
|
394
581
|
});
|
|
@@ -442,20 +629,57 @@ function buildInputSchema(op, fieldRules, opts) {
|
|
|
442
629
|
...opts
|
|
443
630
|
});
|
|
444
631
|
case "get": return { id: z.string().describe("Resource ID") };
|
|
445
|
-
case "create":
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
mode: "update",
|
|
632
|
+
case "create":
|
|
633
|
+
if (!fieldRules && opts.adapterBodies?.createBody) {
|
|
634
|
+
const shape = jsonSchemaToZodShape(opts.adapterBodies.createBody, "create");
|
|
635
|
+
if (shape) return shape;
|
|
636
|
+
}
|
|
637
|
+
return fieldRulesToZod(fieldRules, {
|
|
638
|
+
mode: "create",
|
|
453
639
|
...opts
|
|
454
|
-
})
|
|
455
|
-
|
|
640
|
+
});
|
|
641
|
+
case "update": {
|
|
642
|
+
const idShape = { id: z.string().describe("Resource ID") };
|
|
643
|
+
if (!fieldRules && opts.adapterBodies?.updateBody) {
|
|
644
|
+
const shape = jsonSchemaToZodShape(opts.adapterBodies.updateBody, "update");
|
|
645
|
+
if (shape) return {
|
|
646
|
+
...idShape,
|
|
647
|
+
...shape
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
return {
|
|
651
|
+
...idShape,
|
|
652
|
+
...fieldRulesToZod(fieldRules, {
|
|
653
|
+
mode: "update",
|
|
654
|
+
...opts
|
|
655
|
+
})
|
|
656
|
+
};
|
|
657
|
+
}
|
|
456
658
|
case "delete": return { id: z.string().describe("Resource ID") };
|
|
457
659
|
}
|
|
458
660
|
}
|
|
661
|
+
/**
|
|
662
|
+
* Pull the adapter's `createBody` / `updateBody` schemas, if any.
|
|
663
|
+
* Returns `undefined` when the adapter doesn't generate schemas or throws.
|
|
664
|
+
*/
|
|
665
|
+
function getAdapterBodies(resource) {
|
|
666
|
+
const adapter = resource.adapter;
|
|
667
|
+
if (!adapter || typeof adapter.generateSchemas !== "function") return void 0;
|
|
668
|
+
try {
|
|
669
|
+
const generated = adapter.generateSchemas(resource.schemaOptions, {
|
|
670
|
+
idField: resource.idField,
|
|
671
|
+
resourceName: resource.name
|
|
672
|
+
});
|
|
673
|
+
if (!generated || typeof generated !== "object") return void 0;
|
|
674
|
+
const schemas = generated;
|
|
675
|
+
return {
|
|
676
|
+
createBody: schemas.createBody,
|
|
677
|
+
updateBody: schemas.updateBody
|
|
678
|
+
};
|
|
679
|
+
} catch {
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
459
683
|
function createHandler(op, controller, resourceName, permissions) {
|
|
460
684
|
const ctrl = controller;
|
|
461
685
|
return async (input, ctx) => {
|
|
@@ -468,15 +692,15 @@ function createHandler(op, controller, resourceName, permissions) {
|
|
|
468
692
|
}],
|
|
469
693
|
isError: true
|
|
470
694
|
};
|
|
471
|
-
const
|
|
472
|
-
if (
|
|
695
|
+
const permResult = await evaluatePermission(permissions?.[op], ctx.session, resourceName, op, input);
|
|
696
|
+
if (permResult && !permResult.granted) return {
|
|
473
697
|
content: [{
|
|
474
698
|
type: "text",
|
|
475
|
-
text: `Permission denied: ${op} on ${resourceName}`
|
|
699
|
+
text: `Permission denied: ${op} on ${resourceName}${permResult.reason ? ` — ${permResult.reason}` : ""}`
|
|
476
700
|
}],
|
|
477
701
|
isError: true
|
|
478
702
|
};
|
|
479
|
-
return toCallToolResult(await method(buildRequestContext(input, ctx.session, op,
|
|
703
|
+
return toCallToolResult(await method(buildRequestContext(input, ctx.session, op, permResult?.filters, permResult?.scope)));
|
|
480
704
|
} catch (err) {
|
|
481
705
|
const msg = err instanceof Error ? err.message : String(err);
|
|
482
706
|
ctx.log("error", `${resourceName}.${op}: ${msg}`).catch(() => {});
|
|
@@ -518,10 +742,13 @@ function createAdditionalRouteHandler(route, controller, hasId) {
|
|
|
518
742
|
/**
|
|
519
743
|
* Evaluate a resource's permission check in MCP context.
|
|
520
744
|
*
|
|
521
|
-
* Returns
|
|
522
|
-
* -
|
|
523
|
-
*
|
|
524
|
-
*
|
|
745
|
+
* Returns the full normalized `PermissionResult` so the caller can honor
|
|
746
|
+
* ALL side-effects (filters + scope) consistently with CRUD/action routes.
|
|
747
|
+
* Returns `null` when no permission is defined (= allow, no side effects).
|
|
748
|
+
*
|
|
749
|
+
* Promoting booleans to `PermissionResult` via the shared `normalizePermissionResult`
|
|
750
|
+
* helper keeps the contract aligned with the rest of Arc — there is a single
|
|
751
|
+
* normalization path for every call site.
|
|
525
752
|
*/
|
|
526
753
|
async function evaluatePermission(check, session, resource, action, input) {
|
|
527
754
|
if (!check) return null;
|
|
@@ -530,7 +757,7 @@ async function evaluatePermission(check, session, resource, action, input) {
|
|
|
530
757
|
_id: session.userId,
|
|
531
758
|
...session
|
|
532
759
|
} : null;
|
|
533
|
-
|
|
760
|
+
return normalizePermissionResult(await check({
|
|
534
761
|
user,
|
|
535
762
|
request: {
|
|
536
763
|
user,
|
|
@@ -544,11 +771,64 @@ async function evaluatePermission(check, session, resource, action, input) {
|
|
|
544
771
|
resourceId: typeof input.id === "string" ? input.id : void 0,
|
|
545
772
|
params: {},
|
|
546
773
|
data: input
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
774
|
+
}));
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Derive a fieldRules-shaped object from the adapter's auto-generated body
|
|
778
|
+
* schemas. Used as a fallback when the resource doesn't supply explicit
|
|
779
|
+
* fieldRules — this lets MCP create/update tools accept the same body fields
|
|
780
|
+
* that the REST routes already accept.
|
|
781
|
+
*
|
|
782
|
+
* Returns `undefined` if no usable schema can be extracted, in which case
|
|
783
|
+
* `fieldRulesToZod` falls back to its own behavior (empty shape).
|
|
784
|
+
*/
|
|
785
|
+
function deriveFieldRulesFromAdapter(resource) {
|
|
786
|
+
const adapter = resource.adapter;
|
|
787
|
+
if (!adapter || typeof adapter.generateSchemas !== "function") return void 0;
|
|
788
|
+
let generated;
|
|
789
|
+
try {
|
|
790
|
+
generated = adapter.generateSchemas(resource.schemaOptions, {
|
|
791
|
+
idField: resource.idField,
|
|
792
|
+
resourceName: resource.name
|
|
793
|
+
});
|
|
794
|
+
} catch {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
if (!generated || typeof generated !== "object") return void 0;
|
|
798
|
+
const schemas = generated;
|
|
799
|
+
const createBody = schemas.createBody;
|
|
800
|
+
const updateBody = schemas.updateBody;
|
|
801
|
+
const properties = createBody?.properties ?? updateBody?.properties;
|
|
802
|
+
if (!properties || typeof properties !== "object") return void 0;
|
|
803
|
+
const requiredSet = new Set(createBody?.required ?? []);
|
|
804
|
+
const rules = {};
|
|
805
|
+
for (const [name, propSchema] of Object.entries(properties)) {
|
|
806
|
+
if (!propSchema || typeof propSchema !== "object") continue;
|
|
807
|
+
const prop = propSchema;
|
|
808
|
+
const rawType = prop.type;
|
|
809
|
+
const rule = { type: mapJsonSchemaTypeToArcType((Array.isArray(rawType) ? rawType.filter((t) => typeof t === "string") : typeof rawType === "string" ? [rawType] : [])[0]) };
|
|
810
|
+
if (requiredSet.has(name)) rule.required = true;
|
|
811
|
+
if (typeof prop.description === "string") rule.description = prop.description;
|
|
812
|
+
if (Array.isArray(prop.enum)) rule.enum = prop.enum.filter((v) => typeof v === "string");
|
|
813
|
+
if (typeof prop.minLength === "number") rule.minLength = prop.minLength;
|
|
814
|
+
if (typeof prop.maxLength === "number") rule.maxLength = prop.maxLength;
|
|
815
|
+
if (typeof prop.minimum === "number") rule.min = prop.minimum;
|
|
816
|
+
if (typeof prop.maximum === "number") rule.max = prop.maximum;
|
|
817
|
+
if (typeof prop.pattern === "string") rule.pattern = prop.pattern;
|
|
818
|
+
rules[name] = rule;
|
|
819
|
+
}
|
|
820
|
+
return Object.keys(rules).length > 0 ? rules : void 0;
|
|
821
|
+
}
|
|
822
|
+
function mapJsonSchemaTypeToArcType(jsonType) {
|
|
823
|
+
switch (jsonType) {
|
|
824
|
+
case "string": return "string";
|
|
825
|
+
case "number":
|
|
826
|
+
case "integer": return "number";
|
|
827
|
+
case "boolean": return "boolean";
|
|
828
|
+
case "array": return "array";
|
|
829
|
+
case "object": return "object";
|
|
830
|
+
default: return "string";
|
|
831
|
+
}
|
|
552
832
|
}
|
|
553
833
|
function toCallToolResult(result) {
|
|
554
834
|
if (!result.success) return {
|
package/dist/rpc/index.d.mts
CHANGED
package/dist/rpc/index.mjs
CHANGED
package/dist/scope/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as isAuthenticated, a as getClientId, b as isOrgInScope, c as getOrgRoles, d as getScopeContextMap, f as getServiceScopes, g as hasOrgAccess, h as getUserRoles, i as getAncestorOrgIds, l as getRequestScope, m as getUserId, n as PUBLIC_SCOPE, o as getOrgContext, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, u as getScopeContext, v as isElevated, x as isService, y as isMember } from "../types-CNEbix8T.mjs";
|
|
2
|
+
import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-Dm-HTBCt.mjs";
|
|
2
3
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
3
4
|
|
|
4
5
|
//#region src/scope/rateLimitKey.d.ts
|
|
@@ -29,4 +30,4 @@ interface ResolveOrgFromHeaderOptions {
|
|
|
29
30
|
*/
|
|
30
31
|
declare function resolveOrgFromHeader(options: ResolveOrgFromHeaderOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
31
32
|
//#endregion
|
|
32
|
-
export { AUTHENTICATED_SCOPE, type ElevationEvent, type ElevationOptions, PUBLIC_SCOPE, type RateLimitKeyContext, type RequestScope, type ResolveOrgFromHeaderOptions, type TenantKeyGeneratorOptions, createTenantKeyGenerator, _default as elevationPlugin, elevationPlugin as elevationPluginFn, getOrgContext, getOrgId, getOrgRoles, getTeamId, getUserId, getUserRoles, hasOrgAccess, isAuthenticated, isElevated, isMember, resolveOrgFromHeader };
|
|
33
|
+
export { AUTHENTICATED_SCOPE, type ElevationEvent, type ElevationOptions, PUBLIC_SCOPE, type RateLimitKeyContext, type RequestScope, type ResolveOrgFromHeaderOptions, type TenantKeyGeneratorOptions, createTenantKeyGenerator, _default as elevationPlugin, elevationPlugin as elevationPluginFn, getAncestorOrgIds, getClientId, getOrgContext, getOrgId, getOrgRoles, getRequestScope, getScopeContext, getScopeContextMap, getServiceScopes, getTeamId, getUserId, getUserRoles, hasOrgAccess, isAuthenticated, isElevated, isMember, isOrgInScope, isService, resolveOrgFromHeader };
|
package/dist/scope/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { _ as isElevated, a as getOrgContext, b as isService, c as getRequestScope, d as getServiceScopes, f as getTeamId, g as isAuthenticated, h as hasOrgAccess, i as getClientId, l as getScopeContext, m as getUserRoles, n as PUBLIC_SCOPE, o as getOrgId, p as getUserId, r as getAncestorOrgIds, s as getOrgRoles, t as AUTHENTICATED_SCOPE, u as getScopeContextMap, v as isMember, y as isOrgInScope } from "../types-AOD8fxIw.mjs";
|
|
2
2
|
import { n as normalizeRoles } from "../types-ZUu_h0jp.mjs";
|
|
3
|
-
import { n as elevation_default, t as elevationPlugin } from "../elevation-
|
|
3
|
+
import { n as elevation_default, t as elevationPlugin } from "../elevation-By_p2lnn.mjs";
|
|
4
4
|
//#region src/scope/rateLimitKey.ts
|
|
5
5
|
function createTenantKeyGenerator(opts) {
|
|
6
6
|
if (opts?.strategy) return opts.strategy;
|
|
@@ -8,6 +8,7 @@ function createTenantKeyGenerator(opts) {
|
|
|
8
8
|
const scope = ctx.scope;
|
|
9
9
|
if (!scope || scope.kind === "public") return ctx.ip;
|
|
10
10
|
if (scope.kind === "member") return scope.organizationId;
|
|
11
|
+
if (scope.kind === "service") return scope.organizationId;
|
|
11
12
|
if (scope.kind === "elevated") return scope.organizationId ?? scope.userId ?? ctx.ip;
|
|
12
13
|
return scope.userId ?? ctx.ip;
|
|
13
14
|
};
|
|
@@ -75,4 +76,4 @@ function resolveOrgFromHeader(options) {
|
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
//#endregion
|
|
78
|
-
export { AUTHENTICATED_SCOPE, PUBLIC_SCOPE, createTenantKeyGenerator, elevation_default as elevationPlugin, elevationPlugin as elevationPluginFn, getOrgContext, getOrgId, getOrgRoles, getTeamId, getUserId, getUserRoles, hasOrgAccess, isAuthenticated, isElevated, isMember, resolveOrgFromHeader };
|
|
79
|
+
export { AUTHENTICATED_SCOPE, PUBLIC_SCOPE, createTenantKeyGenerator, elevation_default as elevationPlugin, elevationPlugin as elevationPluginFn, getAncestorOrgIds, getClientId, getOrgContext, getOrgId, getOrgRoles, getRequestScope, getScopeContext, getScopeContextMap, getServiceScopes, getTeamId, getUserId, getUserRoles, hasOrgAccess, isAuthenticated, isElevated, isMember, isOrgInScope, isService, resolveOrgFromHeader };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { t as arcLog } from "./logger-
|
|
2
|
+
import { n as PUBLIC_SCOPE, o as getOrgId } from "./types-AOD8fxIw.mjs";
|
|
3
|
+
import { t as arcLog } from "./logger-DLg8-Ueg.mjs";
|
|
4
4
|
import fp from "fastify-plugin";
|
|
5
5
|
//#region src/plugins/sse.ts
|
|
6
6
|
var sse_exports = /* @__PURE__ */ __exportAll({
|
package/dist/testing/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as ResourceLike, r as CreateAppOptions } from "../types-
|
|
1
|
+
import { Ut as CrudRepository, Vt as ResourceDefinition, u as AnyRecord } from "../interface-Dwzqt4mn.mjs";
|
|
2
|
+
import { d as ResourceLike, r as CreateAppOptions } from "../types-D0qf0Mf4.mjs";
|
|
3
3
|
import Fastify, { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
4
4
|
import { Connection } from "mongoose";
|
|
5
5
|
import { Mock } from "vitest";
|
package/dist/testing/index.mjs
CHANGED
|
@@ -1796,7 +1796,7 @@ function runEventTests(resourceName, displayName, events) {
|
|
|
1796
1796
|
* ```
|
|
1797
1797
|
*/
|
|
1798
1798
|
async function createTestApp(options = {}) {
|
|
1799
|
-
const { createApp } = await import("../createApp-
|
|
1799
|
+
const { createApp } = await import("../createApp-B_nvKNAQ.mjs").then((n) => n.r);
|
|
1800
1800
|
const { useInMemoryDb = true, mongoUri: providedMongoUri, ...appOptions } = options;
|
|
1801
1801
|
const defaultAuth = {
|
|
1802
1802
|
type: "jwt",
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import { $ as
|
|
3
|
-
import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-
|
|
1
|
+
import { _ as isAuthenticated, c as getOrgRoles, g as hasOrgAccess, n as PUBLIC_SCOPE, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, v as isElevated, y as isMember } from "../types-CNEbix8T.mjs";
|
|
2
|
+
import { $ as RateLimitConfig, A as FieldRule, B as JwtContext, C as CrudRouterOptions, Ct as getUserId, D as FastifyRequestExtras, E as EventsDecorator, F as InferDocType, Ft as IController, G as OpenApiSchemas, Gt as PaginatedResult, H as MiddlewareConfig, I as InferResourceDoc, It as IControllerResponse, J as PopulateOption, K as OwnershipCheck, Kt as PaginationParams, L as IntrospectionData, Lt as IRequestContext, M as HealthCheck, Mt as ControllerHandler, N as HealthOptions, Nt as ControllerLike, O as FastifyWithAuth, P as InferAdapterDoc, Pt as FastifyHandler, Q as QueryParserInterface, R as IntrospectionPluginOptions, Rt as RouteHandler, S as CrudRouteKey, St as envelope, T as EventDefinition, Tt as BaseControllerOptions, U as MiddlewareHandler, Ut as CrudRepository, V as LookupOption, W as ObjectId, Wt as InferDoc, X as PresetHook, Y as PresetFunction, Z as PresetResult, _ as Authenticator, _t as TypedResourceConfig, at as ResourceCacheConfig, b as ControllerQueryOptions, bt as ValidateOptions, ct as ResourceHooks, d as ApiResponse, dt as RouteHandlerMethod, et as RegistryEntry, f as ArcDecorator, ft as RouteSchemaOptions, g as AuthPluginOptions, gt as TypedRepository, h as AuthHelpers, ht as TypedController, it as RequestWithExtras, j as GracefulShutdownOptions, k as FastifyWithDecorators, l as AdditionalRoute, lt as ResourceMetadata, m as ArcRequest, mt as TokenPair, nt as RequestContext, ot as ResourceConfig, p as ArcInternalMetadata, pt as ServiceContext, q as ParsedQuery, qt as QueryOptions, rt as RequestIdOptions, st as ResourceHookContext, tt as RegistryStats, u as AnyRecord, ut as ResourcePermissions, v as AuthenticatorContext, vt as UserLike, w as CrudSchemas, x as CrudController, xt as ValidationResult, y as ConfigError, yt as UserOrganization, z as JWTPayload } from "../interface-Dwzqt4mn.mjs";
|
|
3
|
+
import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-DPsC0taJ.mjs";
|
|
4
|
+
import { n as ElevationOptions, t as ElevationEvent } from "../elevation-Dm-HTBCt.mjs";
|
|
4
5
|
export { AUTHENTICATED_SCOPE, AdditionalRoute, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, ArcRequest, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRepository, CrudRouteKey, CrudRouterOptions, CrudSchemas, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, PaginatedResult, PaginationParams, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryOptions, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteHandler, RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, envelope, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
|
package/dist/types/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as isElevated, f as getTeamId, g as isAuthenticated, h as hasOrgAccess, n as PUBLIC_SCOPE, o as getOrgId, s as getOrgRoles, t as AUTHENTICATED_SCOPE, v as isMember } from "../types-AOD8fxIw.mjs";
|
|
2
2
|
//#region src/types/index.ts
|
|
3
3
|
/**
|
|
4
4
|
* Response envelope helper — wraps data in Arc's standard `{ success, data }` format.
|