@classytic/arc 2.6.3 → 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.
Files changed (135) hide show
  1. package/README.md +84 -1
  2. package/dist/{BaseController-DzRtluEF.mjs → BaseController-CpMfCXdn.mjs} +134 -16
  3. package/dist/adapters/index.d.mts +2 -2
  4. package/dist/adapters/index.mjs +1 -1
  5. package/dist/{adapters-gM-WYjNe.mjs → adapters-BxGgSHjj.mjs} +1 -9
  6. package/dist/applyPermissionResult-D6GPMsvh.mjs +37 -0
  7. package/dist/audit/index.d.mts +1 -1
  8. package/dist/audit/index.mjs +1 -1
  9. package/dist/audit/mongodb.d.mts +1 -1
  10. package/dist/audit/mongodb.mjs +1 -1
  11. package/dist/auth/index.d.mts +4 -4
  12. package/dist/auth/index.mjs +7 -6
  13. package/dist/auth/mongoose.d.mts +191 -0
  14. package/dist/auth/mongoose.mjs +73 -0
  15. package/dist/auth/redis-session.d.mts +1 -1
  16. package/dist/{betterAuthOpenApi-lz0IRbXJ.mjs → betterAuthOpenApi-CCw3YX0g.mjs} +1 -1
  17. package/dist/cache/index.d.mts +2 -2
  18. package/dist/cache/index.mjs +2 -2
  19. package/dist/cli/commands/docs.mjs +2 -2
  20. package/dist/cli/commands/generate.mjs +1 -1
  21. package/dist/cli/commands/init.mjs +7 -5
  22. package/dist/cli/commands/introspect.mjs +1 -1
  23. package/dist/core/index.d.mts +3 -3
  24. package/dist/core/index.mjs +4 -4
  25. package/dist/{core-C1XCMtqM.mjs → core-BWekSEju.mjs} +41 -13
  26. package/dist/{createApp-D2w0LdYJ.mjs → createApp-B_nvKNAQ.mjs} +11 -11
  27. package/dist/{defineResource-wWMBB4GP.mjs → defineResource-DZzyl4a4.mjs} +42 -37
  28. package/dist/docs/index.d.mts +2 -2
  29. package/dist/docs/index.mjs +1 -1
  30. package/dist/dynamic/index.d.mts +2 -2
  31. package/dist/dynamic/index.mjs +2 -2
  32. package/dist/{elevation-BEdACOLB.mjs → elevation-By_p2lnn.mjs} +1 -1
  33. package/dist/elevation-Dm-HTBCt.d.mts +23 -0
  34. package/dist/{errorHandler-Do4vVQ1f.d.mts → errorHandler-COa51ho_.d.mts} +1 -1
  35. package/dist/{errorHandler-r2595m8T.mjs → errorHandler-DXUttWEO.mjs} +1 -1
  36. package/dist/{eventPlugin-DW45v4V5.d.mts → eventPlugin-BgLxJkIB.d.mts} +1 -1
  37. package/dist/{eventPlugin-Ba00swHF.mjs → eventPlugin-DsaNNXzZ.mjs} +1 -1
  38. package/dist/events/index.d.mts +3 -3
  39. package/dist/events/index.mjs +1 -1
  40. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  41. package/dist/events/transports/redis.d.mts +1 -1
  42. package/dist/factory/index.d.mts +1 -1
  43. package/dist/factory/index.mjs +1 -1
  44. package/dist/hooks/index.d.mts +1 -1
  45. package/dist/hooks/index.mjs +1 -1
  46. package/dist/idempotency/index.d.mts +3 -3
  47. package/dist/idempotency/mongodb.d.mts +1 -1
  48. package/dist/idempotency/redis.d.mts +1 -1
  49. package/dist/index-BYpRGXif.d.mts +640 -0
  50. package/dist/{index-gz6iuzCp.d.mts → index-KXM8_JmQ.d.mts} +47 -4
  51. package/dist/{index-CHeJa4Zd.d.mts → index-StgFaQKD.d.mts} +1 -1
  52. package/dist/index.d.mts +8 -8
  53. package/dist/index.mjs +10 -9
  54. package/dist/integrations/event-gateway.d.mts +1 -1
  55. package/dist/integrations/event-gateway.mjs +1 -1
  56. package/dist/integrations/index.d.mts +1 -1
  57. package/dist/integrations/mcp/index.d.mts +2 -2
  58. package/dist/integrations/mcp/index.mjs +1 -1
  59. package/dist/integrations/mcp/testing.d.mts +1 -1
  60. package/dist/integrations/mcp/testing.mjs +1 -1
  61. package/dist/{interface-DYH8AXGe.d.mts → interface-Dwzqt4mn.d.mts} +150 -14
  62. package/dist/{mongodb-pMvOlR5_.d.mts → mongodb-Bq90j-Uj.d.mts} +1 -1
  63. package/dist/{mongodb-kltrBPa1.d.mts → mongodb-DdyYlIXg.d.mts} +1 -1
  64. package/dist/{openapi-CBmZ6EQN.mjs → openapi-C5UhIeWu.mjs} +1 -1
  65. package/dist/org/index.d.mts +2 -2
  66. package/dist/org/index.mjs +1 -1
  67. package/dist/permissions/index.d.mts +4 -4
  68. package/dist/permissions/index.mjs +3 -2
  69. package/dist/{permissions-C8ImI8gC.mjs → permissions-CH4cNwJi.mjs} +358 -64
  70. package/dist/plugins/index.d.mts +4 -4
  71. package/dist/plugins/index.mjs +10 -10
  72. package/dist/plugins/response-cache.mjs +1 -1
  73. package/dist/plugins/tracing-entry.d.mts +1 -1
  74. package/dist/plugins/tracing-entry.mjs +1 -1
  75. package/dist/policies/index.d.mts +1 -1
  76. package/dist/presets/index.d.mts +3 -3
  77. package/dist/presets/index.mjs +1 -1
  78. package/dist/presets/multiTenant.d.mts +53 -3
  79. package/dist/presets/multiTenant.mjs +89 -47
  80. package/dist/{presets-BMfdy34e.mjs → presets-BFrGvvjL.mjs} +2 -2
  81. package/dist/{queryCachePlugin-DcmETvcB.d.mts → queryCachePlugin-Bw8XyJpX.d.mts} +1 -1
  82. package/dist/{queryCachePlugin-XtFplYO9.mjs → queryCachePlugin-CwTpR04-.mjs} +2 -2
  83. package/dist/{redis-D0Qc-9EW.d.mts → redis-CyCntzTO.d.mts} +1 -1
  84. package/dist/{redis-stream-BW9UKLZM.d.mts → redis-stream-We_Ucl9-.d.mts} +1 -1
  85. package/dist/registry/index.d.mts +1 -1
  86. package/dist/registry/index.mjs +2 -2
  87. package/dist/{resourceToTools-nCJWnG1r.mjs → resourceToTools-CkVSSzKg.mjs} +64 -21
  88. package/dist/rpc/index.d.mts +1 -1
  89. package/dist/rpc/index.mjs +1 -1
  90. package/dist/scope/index.d.mts +3 -2
  91. package/dist/scope/index.mjs +4 -3
  92. package/dist/{sse-BF7GR7IB.mjs → sse-Bp3dabF1.mjs} +2 -2
  93. package/dist/testing/index.d.mts +2 -2
  94. package/dist/testing/index.mjs +1 -1
  95. package/dist/types/index.d.mts +4 -3
  96. package/dist/types/index.mjs +1 -1
  97. package/dist/types-AOD8fxIw.mjs +229 -0
  98. package/dist/types-CNEbix8T.d.mts +286 -0
  99. package/dist/{types-B4_TDdPe.d.mts → types-ClmkMDK1.d.mts} +1 -1
  100. package/dist/{types-By-5mIfn.d.mts → types-D0qf0Mf4.d.mts} +9 -9
  101. package/dist/types-DPsC0taJ.d.mts +178 -0
  102. package/dist/utils/index.d.mts +3 -3
  103. package/dist/utils/index.mjs +5 -5
  104. package/package.json +17 -5
  105. package/skills/arc/SKILL.md +253 -6
  106. package/skills/arc/references/multi-tenancy.md +208 -0
  107. package/dist/elevation-C_taLQrM.d.mts +0 -147
  108. package/dist/index-NGZksqM5.d.mts +0 -398
  109. package/dist/types-BNUccdcf.d.mts +0 -101
  110. package/dist/types-BhtYdxZU.mjs +0 -91
  111. /package/dist/{EventTransport-wc5hSLik.d.mts → EventTransport-CUpRK_Lg.d.mts} +0 -0
  112. /package/dist/{HookSystem-COkyWztM.mjs → HookSystem-D7lfx--K.mjs} +0 -0
  113. /package/dist/{ResourceRegistry-C6ngvOnn.mjs → ResourceRegistry-DsHiG9cL.mjs} +0 -0
  114. /package/dist/{caching-BSXB-Xr7.mjs → caching-5DtLwIqb.mjs} +0 -0
  115. /package/dist/{circuitBreaker-JP2GdJ4b.d.mts → circuitBreaker-DwxrljLB.d.mts} +0 -0
  116. /package/dist/{circuitBreaker-BOBOpN2w.mjs → circuitBreaker-l18oRgL5.mjs} +0 -0
  117. /package/dist/{errors-CcVbl1-T.d.mts → errors-CCSsMpXE.d.mts} +0 -0
  118. /package/dist/{errors-NoQKsbAT.mjs → errors-Cg58SLNi.mjs} +0 -0
  119. /package/dist/{externalPaths-DpO-s7r8.d.mts → externalPaths-Dg7OLsKo.d.mts} +0 -0
  120. /package/dist/{fields-DFwdaWCq.d.mts → fields-CYuLMJPD.d.mts} +0 -0
  121. /package/dist/{interface-gr-7qo9j.d.mts → interface-B9rHWPxD.d.mts} +0 -0
  122. /package/dist/{interface-D_BWALyZ.d.mts → interface-CnluRL4_.d.mts} +0 -0
  123. /package/dist/{logger-Dz3j1ItV.mjs → logger-DLg8-Ueg.mjs} +0 -0
  124. /package/dist/{memory-BFAYkf8H.mjs → memory-Cp7_cAko.mjs} +0 -0
  125. /package/dist/{metrics-Csh4nsvv.mjs → metrics-Qnvwc-LQ.mjs} +0 -0
  126. /package/dist/{mongodb-BuQ7fNTg.mjs → mongodb-mlgxkYI3.mjs} +0 -0
  127. /package/dist/{pluralize-CcT6qF0a.mjs → pluralize-COpOVar8.mjs} +0 -0
  128. /package/dist/{registry-I-ogLgL9.mjs → registry-B3lRFBWo.mjs} +0 -0
  129. /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
  130. /package/dist/{schemaConverter-DjzHpFam.mjs → schemaConverter-0TyONAwM.mjs} +0 -0
  131. /package/dist/{sessionManager-wbkYj2HL.d.mts → sessionManager-IW4sbIea.d.mts} +0 -0
  132. /package/dist/{tracing-bz_U4EM1.d.mts → tracing-65B51Dw3.d.mts} +0 -0
  133. /package/dist/{typeGuards-Cj5Rgvlg.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
  134. /package/dist/{utils-Dc0WhlIl.mjs → utils-B-l6410F.mjs} +0 -0
  135. /package/dist/{versioning-BzfeHmhj.mjs → versioning-aUUVziBY.mjs} +0 -0
@@ -1,9 +1,59 @@
1
- import { S as CrudRouteKey, Z as PresetResult } from "../interface-DYH8AXGe.mjs";
1
+ import { S as CrudRouteKey, Z as PresetResult } from "../interface-Dwzqt4mn.mjs";
2
2
 
3
3
  //#region src/presets/multiTenant.d.ts
4
+ /**
5
+ * One tenant dimension for multi-field filtering. Discriminated by source:
6
+ * - `type: 'org'` → reads `getOrgId(scope)`
7
+ * - `type: 'team'` → reads `getTeamId(scope)`
8
+ * - `contextKey` → reads `getScopeContext(scope, contextKey)` (any custom dimension)
9
+ */
10
+ type TenantFieldSpec = {
11
+ field: string;
12
+ type: "org";
13
+ } | {
14
+ field: string;
15
+ type: "team";
16
+ } | {
17
+ field: string;
18
+ contextKey: string;
19
+ };
4
20
  interface MultiTenantOptions {
5
- /** Field name in database (default: 'organizationId') */
21
+ /**
22
+ * Single-field form: name of the database field to filter by.
23
+ * Reads `getOrgId(scope)` as the value source.
24
+ *
25
+ * Mutually exclusive with `tenantFields` — pass one or the other, not both.
26
+ *
27
+ * @default 'organizationId'
28
+ */
6
29
  tenantField?: string;
30
+ /**
31
+ * Multi-field form (2.7.1+): list of tenant dimensions to filter by in
32
+ * lockstep. Use this when a resource is scoped by more than just
33
+ * organization — e.g. organization + branch, organization + project,
34
+ * or organization + team + workspace.
35
+ *
36
+ * Each entry is a discriminated `TenantFieldSpec` declaring where the
37
+ * value comes from. Use `type: 'org'` / `type: 'team'` for built-in scope
38
+ * fields, or `contextKey: '...'` to read from `scope.context` (set by
39
+ * your auth function).
40
+ *
41
+ * Fail-closed: if any required dimension is missing, the request is
42
+ * rejected. Elevated scopes apply whatever resolves and skip the rest.
43
+ *
44
+ * Mutually exclusive with `tenantField`.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * multiTenantPreset({
49
+ * tenantFields: [
50
+ * { field: 'organizationId', type: 'org' },
51
+ * { field: 'branchId', contextKey: 'branchId' },
52
+ * ],
53
+ * })
54
+ * ```
55
+ */
56
+ tenantFields?: readonly TenantFieldSpec[];
7
57
  /**
8
58
  * Routes that allow public access (no auth required)
9
59
  * When a route is in this array:
@@ -18,4 +68,4 @@ interface MultiTenantOptions {
18
68
  }
19
69
  declare function multiTenantPreset(options?: MultiTenantOptions): PresetResult;
20
70
  //#endregion
21
- export { MultiTenantOptions, multiTenantPreset };
71
+ export { MultiTenantOptions, TenantFieldSpec, multiTenantPreset };
@@ -1,31 +1,59 @@
1
- import { o as DEFAULT_TENANT_FIELD } from "../constants-Cxde4rpC.mjs";
2
- import { d as isElevated, f as isMember, i as getOrgId, n as PUBLIC_SCOPE } from "../types-BhtYdxZU.mjs";
1
+ import "../constants-Cxde4rpC.mjs";
2
+ import { _ as isElevated, c as getRequestScope, f as getTeamId, h as hasOrgAccess, l as getScopeContext, o as getOrgId } from "../types-AOD8fxIw.mjs";
3
3
  //#region src/presets/multiTenant.ts
4
- /** Read request.scope safely */
5
- function getScope(request) {
6
- return request.scope ?? PUBLIC_SCOPE;
4
+ /**
5
+ * Resolve a single TenantFieldSpec against the current scope.
6
+ * Returns `undefined` if the source value isn't present on the scope.
7
+ */
8
+ function resolveSpec(scope, spec) {
9
+ if ("contextKey" in spec) return getScopeContext(scope, spec.contextKey);
10
+ if (spec.type === "org") return getOrgId(scope);
11
+ if (spec.type === "team") return getTeamId(scope);
12
+ }
13
+ /** Resolve every spec — returns the partial map of fields that have a value. */
14
+ function resolveAll(scope, specs) {
15
+ const resolved = {};
16
+ const missing = [];
17
+ for (const spec of specs) {
18
+ const value = resolveSpec(scope, spec);
19
+ if (value !== void 0) resolved[spec.field] = value;
20
+ else missing.push(spec.field);
21
+ }
22
+ return {
23
+ resolved,
24
+ missing
25
+ };
7
26
  }
8
27
  /**
9
- * Create tenant filter middleware
10
- * Adds tenant filter to query for list/get operations.
11
- * Reads `request.scope` for org context and elevation bypass.
28
+ * Create tenant filter middleware (strict).
29
+ * Walks the configured tenant fields and applies all of them in lockstep.
30
+ * Fails closed if any non-elevated caller is missing a required dimension.
12
31
  */
13
- function createTenantFilter(tenantField) {
32
+ function createTenantFilter(specs) {
14
33
  return async (request, reply) => {
15
- const scope = getScope(request);
34
+ const scope = getRequestScope(request);
16
35
  if (isElevated(scope)) {
17
- const orgId = getOrgId(scope);
18
- if (orgId) request._policyFilters = {
36
+ const { resolved } = resolveAll(scope, specs);
37
+ if (Object.keys(resolved).length > 0) request._policyFilters = {
19
38
  ...request._policyFilters ?? {},
20
- [tenantField]: orgId
39
+ ...resolved
21
40
  };
22
41
  return;
23
42
  }
24
- if (isMember(scope)) {
25
- request._policyFilters = {
26
- ...request._policyFilters ?? {},
27
- [tenantField]: scope.organizationId
28
- };
43
+ if (hasOrgAccess(scope)) {
44
+ const { resolved, missing } = resolveAll(scope, specs);
45
+ if (missing.length === 0) {
46
+ request._policyFilters = {
47
+ ...request._policyFilters ?? {},
48
+ ...resolved
49
+ };
50
+ return;
51
+ }
52
+ reply.code(403).send({
53
+ success: false,
54
+ error: "Forbidden",
55
+ message: `Tenant context incomplete — missing: ${missing.join(", ")}`
56
+ });
29
57
  return;
30
58
  }
31
59
  if (scope.kind === "public") {
@@ -44,57 +72,71 @@ function createTenantFilter(tenantField) {
44
72
  };
45
73
  }
46
74
  /**
47
- * Create flexible tenant filter middleware
48
- * For routes in allowPublic: only filter when org context is present
49
- * No org context = allow through (public data)
50
- * Org context present = require auth and apply filter
75
+ * Create flexible tenant filter middleware (allowPublic).
76
+ * Same policy as the strict variant for authenticated callers, but
77
+ * allows public/unauthenticated requests through without filtering.
51
78
  */
52
- function createFlexibleTenantFilter(tenantField) {
53
- return async (request, _reply) => {
54
- const scope = getScope(request);
79
+ function createFlexibleTenantFilter(specs) {
80
+ return async (request, reply) => {
81
+ const scope = getRequestScope(request);
55
82
  if (isElevated(scope)) {
56
- const orgId = getOrgId(scope);
57
- if (orgId) request._policyFilters = {
83
+ const { resolved } = resolveAll(scope, specs);
84
+ if (Object.keys(resolved).length > 0) request._policyFilters = {
58
85
  ...request._policyFilters ?? {},
59
- [tenantField]: orgId
86
+ ...resolved
60
87
  };
61
88
  return;
62
89
  }
63
- if (isMember(scope)) {
64
- request._policyFilters = {
65
- ...request._policyFilters ?? {},
66
- [tenantField]: scope.organizationId
67
- };
90
+ if (hasOrgAccess(scope)) {
91
+ const { resolved, missing } = resolveAll(scope, specs);
92
+ if (missing.length === 0) {
93
+ request._policyFilters = {
94
+ ...request._policyFilters ?? {},
95
+ ...resolved
96
+ };
97
+ return;
98
+ }
99
+ reply.code(403).send({
100
+ success: false,
101
+ error: "Forbidden",
102
+ message: `Tenant context incomplete — missing: ${missing.join(", ")}`
103
+ });
68
104
  return;
69
105
  }
70
106
  };
71
107
  }
72
108
  /**
73
- * Create tenant injection middleware
74
- * Injects tenant ID into request body on create.
75
- * Reads `request.scope` for org context.
109
+ * Create tenant injection middleware.
110
+ * Walks the configured tenant fields and writes each into the request body.
111
+ * Fails closed if any required dimension is missing for non-elevated callers.
76
112
  */
77
- function createTenantInjection(tenantField) {
113
+ function createTenantInjection(specs) {
78
114
  return async (request, reply) => {
79
- const scope = getScope(request);
80
- const orgId = getOrgId(scope);
81
- if (isElevated(scope) && !orgId) return;
82
- if (!orgId) {
115
+ const scope = getRequestScope(request);
116
+ if (isElevated(scope) && !getOrgId(scope)) return;
117
+ const { resolved, missing } = resolveAll(scope, specs);
118
+ if (missing.length > 0) {
83
119
  reply.code(403).send({
84
120
  success: false,
85
121
  error: "Forbidden",
86
- message: "Organization context required to create resources"
122
+ message: `Tenant context incomplete missing: ${missing.join(", ")}`
87
123
  });
88
124
  return;
89
125
  }
90
- if (request.body) request.body[tenantField] = orgId;
126
+ if (request.body) Object.assign(request.body, resolved);
91
127
  };
92
128
  }
93
129
  function multiTenantPreset(options = {}) {
94
- const { tenantField = DEFAULT_TENANT_FIELD, allowPublic = [] } = options;
95
- const strictTenantFilter = createTenantFilter(tenantField);
96
- const flexibleTenantFilter = createFlexibleTenantFilter(tenantField);
97
- const tenantInjection = createTenantInjection(tenantField);
130
+ const { tenantField, tenantFields, allowPublic = [] } = options;
131
+ if (tenantField !== void 0 && tenantFields !== void 0) throw new Error("multiTenantPreset: pass either `tenantField` (single-field) or `tenantFields` (multi-field), not both");
132
+ const specs = tenantFields ?? [{
133
+ field: tenantField ?? "organizationId",
134
+ type: "org"
135
+ }];
136
+ if (specs.length === 0) throw new Error("multiTenantPreset: `tenantFields` must contain at least one entry");
137
+ const strictTenantFilter = createTenantFilter(specs);
138
+ const flexibleTenantFilter = createFlexibleTenantFilter(specs);
139
+ const tenantInjection = createTenantInjection(specs);
98
140
  const getFilter = (route) => allowPublic.includes(route) ? flexibleTenantFilter : strictTenantFilter;
99
141
  return {
100
142
  name: "multiTenant",
@@ -1,6 +1,6 @@
1
- import { d as isElevated, n as PUBLIC_SCOPE } from "./types-BhtYdxZU.mjs";
1
+ import { _ as isElevated, n as PUBLIC_SCOPE } from "./types-AOD8fxIw.mjs";
2
2
  import { multiTenantPreset } from "./presets/multiTenant.mjs";
3
- import { d as requireRoles, n as allowPublic, s as requireAuth } from "./permissions-C8ImI8gC.mjs";
3
+ import { f as requireRoles, n as allowPublic, s as requireAuth } from "./permissions-CH4cNwJi.mjs";
4
4
  //#region src/presets/ownedByUser.ts
5
5
  /**
6
6
  * Create ownership check middleware.
@@ -1,4 +1,4 @@
1
- import { i as CacheStore } from "./interface-D_BWALyZ.mjs";
1
+ import { i as CacheStore } from "./interface-CnluRL4_.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/cache/QueryCache.d.ts
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
2
  import { i as versionKey, r as tagVersionKey } from "./keys-qcD-TVJl.mjs";
3
- import { t as hasEvents } from "./typeGuards-Cj5Rgvlg.mjs";
4
- import { t as MemoryCacheStore } from "./memory-BFAYkf8H.mjs";
3
+ import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
4
+ import { t as MemoryCacheStore } from "./memory-Cp7_cAko.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 { n as IdempotencyResult, r as IdempotencyStore } from "./interface-gr-7qo9j.mjs";
1
+ import { n as IdempotencyResult, r as IdempotencyStore } from "./interface-B9rHWPxD.mjs";
2
2
 
3
3
  //#region src/idempotency/stores/redis.d.ts
4
4
  interface RedisClient {
@@ -1,4 +1,4 @@
1
- import { i as EventTransport, n as EventHandler, r as EventLogger, t as DomainEvent } from "./EventTransport-wc5hSLik.mjs";
1
+ import { i as EventTransport, n as EventHandler, r as EventLogger, t as DomainEvent } from "./EventTransport-CUpRK_Lg.mjs";
2
2
 
3
3
  //#region src/events/transports/redis-stream.d.ts
4
4
  interface RedisStreamLike {
@@ -1,4 +1,4 @@
1
- import { Bt as ResourceRegistry, R as IntrospectionPluginOptions, zt as RegisterOptions } from "../interface-DYH8AXGe.mjs";
1
+ import { Bt as ResourceRegistry, R as IntrospectionPluginOptions, zt as RegisterOptions } from "../interface-Dwzqt4mn.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/registry/introspectionPlugin.d.ts
@@ -1,3 +1,3 @@
1
- import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-I-ogLgL9.mjs";
2
- import { t as ResourceRegistry } from "../ResourceRegistry-C6ngvOnn.mjs";
1
+ import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-B3lRFBWo.mjs";
2
+ import { t as ResourceRegistry } from "../ResourceRegistry-DsHiG9cL.mjs";
3
3
  export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
@@ -1,5 +1,6 @@
1
- import { t as BaseController } from "./BaseController-DzRtluEF.mjs";
2
- import { t as pluralize } from "./pluralize-CcT6qF0a.mjs";
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 scope = buildScope(auth);
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
- /** Convert MCP operator keys (`price_gt`) to MongoKit bracket notation (`price[gt]`). */
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 = {};
@@ -648,15 +692,15 @@ function createHandler(op, controller, resourceName, permissions) {
648
692
  }],
649
693
  isError: true
650
694
  };
651
- const policyFilters = await evaluatePermission(permissions?.[op], ctx.session, resourceName, op, input);
652
- if (policyFilters === false) return {
695
+ const permResult = await evaluatePermission(permissions?.[op], ctx.session, resourceName, op, input);
696
+ if (permResult && !permResult.granted) return {
653
697
  content: [{
654
698
  type: "text",
655
- text: `Permission denied: ${op} on ${resourceName}`
699
+ text: `Permission denied: ${op} on ${resourceName}${permResult.reason ? ` — ${permResult.reason}` : ""}`
656
700
  }],
657
701
  isError: true
658
702
  };
659
- return toCallToolResult(await method(buildRequestContext(input, ctx.session, op, policyFilters || void 0)));
703
+ return toCallToolResult(await method(buildRequestContext(input, ctx.session, op, permResult?.filters, permResult?.scope)));
660
704
  } catch (err) {
661
705
  const msg = err instanceof Error ? err.message : String(err);
662
706
  ctx.log("error", `${resourceName}.${op}: ${msg}`).catch(() => {});
@@ -698,10 +742,13 @@ function createAdditionalRouteHandler(route, controller, hasId) {
698
742
  /**
699
743
  * Evaluate a resource's permission check in MCP context.
700
744
  *
701
- * Returns:
702
- * - `false` if permission denied
703
- * - `Record<string, unknown>` if granted with filters (ownership patterns)
704
- * - `null` if granted without filters (or no permission check defined)
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.
705
752
  */
706
753
  async function evaluatePermission(check, session, resource, action, input) {
707
754
  if (!check) return null;
@@ -710,7 +757,7 @@ async function evaluatePermission(check, session, resource, action, input) {
710
757
  _id: session.userId,
711
758
  ...session
712
759
  } : null;
713
- const result = await check({
760
+ return normalizePermissionResult(await check({
714
761
  user,
715
762
  request: {
716
763
  user,
@@ -724,11 +771,7 @@ async function evaluatePermission(check, session, resource, action, input) {
724
771
  resourceId: typeof input.id === "string" ? input.id : void 0,
725
772
  params: {},
726
773
  data: input
727
- });
728
- if (typeof result === "boolean") return result ? null : false;
729
- const permResult = result;
730
- if (!permResult.granted) return false;
731
- return permResult.filters ?? null;
774
+ }));
732
775
  }
733
776
  /**
734
777
  * Derive a fieldRules-shaped object from the adapter's auto-generated body
@@ -1,4 +1,4 @@
1
- import { r as CircuitBreakerOptions } from "../circuitBreaker-JP2GdJ4b.mjs";
1
+ import { r as CircuitBreakerOptions } from "../circuitBreaker-DwxrljLB.mjs";
2
2
 
3
3
  //#region src/rpc/serviceClient.d.ts
4
4
  interface RetryConfig {
@@ -1,4 +1,4 @@
1
- import { t as CircuitBreaker } from "../circuitBreaker-BOBOpN2w.mjs";
1
+ import { t as CircuitBreaker } from "../circuitBreaker-l18oRgL5.mjs";
2
2
  //#region src/rpc/serviceClient.ts
3
3
  /**
4
4
  * Service Client — Resource-Oriented RPC
@@ -1,4 +1,5 @@
1
- import { _ as isMember, a as AUTHENTICATED_SCOPE, c as getOrgContext, d as getTeamId, f as getUserId, g as isElevated, h as isAuthenticated, i as elevationPlugin, l as getOrgId, m as hasOrgAccess, n as ElevationOptions, o as PUBLIC_SCOPE, p as getUserRoles, r as _default, s as RequestScope, t as ElevationEvent, u as getOrgRoles } from "../elevation-C_taLQrM.mjs";
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 };
@@ -1,6 +1,6 @@
1
- import { a as getOrgRoles, c as getUserRoles, d as isElevated, f as isMember, i as getOrgId, l as hasOrgAccess, n as PUBLIC_SCOPE, o as getTeamId, r as getOrgContext, s as getUserId, t as AUTHENTICATED_SCOPE, u as isAuthenticated } from "../types-BhtYdxZU.mjs";
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-BEdACOLB.mjs";
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 { i as getOrgId, n as PUBLIC_SCOPE } from "./types-BhtYdxZU.mjs";
3
- import { t as arcLog } from "./logger-Dz3j1ItV.mjs";
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({
@@ -1,5 +1,5 @@
1
- import { Ut as CrudRepository, Vt as ResourceDefinition, u as AnyRecord } from "../interface-DYH8AXGe.mjs";
2
- import { d as ResourceLike, r as CreateAppOptions } from "../types-By-5mIfn.mjs";
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";
@@ -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-D2w0LdYJ.mjs").then((n) => n.r);
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",
@@ -1,4 +1,5 @@
1
- import { _ as isMember, a as AUTHENTICATED_SCOPE, d as getTeamId, g as isElevated, h as isAuthenticated, l as getOrgId, m as hasOrgAccess, n as ElevationOptions, o as PUBLIC_SCOPE, s as RequestScope, t as ElevationEvent, u as getOrgRoles } from "../elevation-C_taLQrM.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-DYH8AXGe.mjs";
3
- import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-BNUccdcf.mjs";
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 };
@@ -1,4 +1,4 @@
1
- import { a as getOrgRoles, d as isElevated, f as isMember, i as getOrgId, l as hasOrgAccess, n as PUBLIC_SCOPE, o as getTeamId, t as AUTHENTICATED_SCOPE, u as isAuthenticated } from "../types-BhtYdxZU.mjs";
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.