@classytic/arc 2.9.1 → 2.10.3
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 +19 -90
- package/dist/{BaseController-Vu2yc56T.mjs → BaseController-CbKKIflT.mjs} +8 -44
- package/dist/{ResourceRegistry-Dq3_zBQP.mjs → ResourceRegistry-BPd6NQDm.mjs} +1 -1
- package/dist/adapters/index.d.mts +3 -3
- package/dist/adapters/index.mjs +2 -2
- package/dist/{adapters-BBqAVvPK.mjs → adapters-BXY4i-hw.mjs} +210 -41
- package/dist/audit/index.d.mts +38 -3
- package/dist/audit/index.mjs +41 -7
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +5 -5
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/cache/index.d.mts +17 -15
- package/dist/cache/index.mjs +15 -14
- package/dist/{caching-CjybdRwx.mjs → caching-CBpK_SCM.mjs} +8 -3
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -4
- package/dist/{defineResource-C__jkwvs.mjs → core-CcR01lup.mjs} +44 -12
- package/dist/{createActionRouter-DH1YFL9m.mjs → createActionRouter-Bp_5c_2b.mjs} +1 -1
- package/dist/{createApp-CBJUJKGP.mjs → createApp-BuvPma24.mjs} +14 -14
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-DxQ6ACbt.mjs → elevation-C7hgL_aI.mjs} +2 -2
- package/dist/{errorHandler-CZDW4EXS.mjs → errorHandler-Bb49BvPD.mjs} +1 -1
- package/dist/{errorHandler-DixGcttC.d.mts → errorHandler-DRQ3EqfL.d.mts} +1 -1
- package/dist/{eventPlugin-BxvaCIZF.d.mts → eventPlugin-CxWgpd6K.d.mts} +1 -1
- package/dist/{eventPlugin-Dl7MoVWH.mjs → eventPlugin-DCUjuiQT.mjs} +1 -1
- package/dist/events/index.d.mts +8 -5
- package/dist/events/index.mjs +34 -17
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -2
- package/dist/{types-DZi1aYhm.d.mts → fields-Lo1VUDpt.d.mts} +121 -1
- package/dist/{filesUpload-q8oHt--L.mjs → filesUpload-t21LS-py.mjs} +2 -2
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +7 -4
- package/dist/idempotency/index.mjs +9 -11
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-Cibkchnx.d.mts → index-8qw4y6ff.d.mts} +2 -2
- package/dist/{index-C-xjcA6F.d.mts → index-ChIw3776.d.mts} +283 -408
- package/dist/{interface-YrWsmKqE.d.mts → index-Cl0uoKd5.d.mts} +1885 -2741
- package/dist/{index-CtGKT0lf.d.mts → index-DStwgFUK.d.mts} +81 -7
- package/dist/index.d.mts +7 -8
- package/dist/index.mjs +11 -12
- 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-D218ikEo.d.mts +77 -0
- package/dist/{memory-BFAYkf8H.mjs → memory-B5Amv9A1.mjs} +23 -8
- package/dist/{openapi-CXuTG1M9.mjs → openapi-B5F8AddX.mjs} +2 -2
- package/dist/org/index.d.mts +2 -2
- package/dist/permissions/index.d.mts +3 -4
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-oNZawnkR.mjs → permissions-Dk6mshja.mjs} +315 -397
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +12 -14
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +91 -4
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-hM4WhNWY.mjs → presets-fLJVXdVn.mjs} +1 -1
- package/dist/{queryCachePlugin-CnTZZTC5.d.mts → queryCachePlugin-BKbWjgDG.d.mts} +1 -1
- package/dist/{queryCachePlugin-DbUVroUG.mjs → queryCachePlugin-DQCEfJis.mjs} +8 -8
- package/dist/{queryParser-Cs-6SHQK.mjs → queryParser-DBqBB6AC.mjs} +1 -1
- package/dist/{redis-MXLp1oOf.d.mts → redis-DqyeggCa.d.mts} +1 -1
- package/dist/{redis-stream-Bz-4q96t.d.mts → redis-stream-CakIQmwR.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-C3cWymnW.mjs → resourceToTools-BElv3xPT.mjs} +3 -3
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +2 -2
- package/dist/{sse-CJpt7LGI.mjs → sse-yBCgOLGu.mjs} +1 -1
- package/dist/testing/index.d.mts +6 -5
- package/dist/testing/index.mjs +8 -10
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -31
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-CoSzA-s-.d.mts → types-Btdda02s.d.mts} +1 -1
- package/dist/{types-CunEX4UX.d.mts → types-Co8k3NyS.d.mts} +9 -9
- package/dist/types-Csi3FLfq.mjs +27 -0
- package/dist/utils/index.d.mts +207 -3
- package/dist/utils/index.mjs +3 -4
- package/dist/{utils-B7FuRr9w.mjs → utils-B2fNOD_i.mjs} +285 -2
- package/dist/{versioning-Cm8qoFDg.mjs → versioning-C2U_bLY0.mjs} +3 -5
- package/package.json +15 -18
- package/skills/arc/SKILL.md +7 -11
- package/skills/arc/references/production.md +0 -41
- package/dist/circuitBreaker-CvXkjfrW.d.mts +0 -206
- package/dist/circuitBreaker-l18oRgL5.mjs +0 -284
- package/dist/core-DNncu0xF.mjs +0 -34
- package/dist/dynamic/index.d.mts +0 -93
- package/dist/dynamic/index.mjs +0 -122
- package/dist/fields-BC7zcmI9.d.mts +0 -121
- package/dist/interface-DplgQO2e.d.mts +0 -54
- package/dist/policies/index.d.mts +0 -425
- package/dist/policies/index.mjs +0 -318
- package/dist/rpc/index.d.mts +0 -90
- package/dist/rpc/index.mjs +0 -248
- /package/dist/{EventTransport-CqZ8FyM_.d.mts → EventTransport-CUw5NNWe.d.mts} +0 -0
- /package/dist/{HookSystem-BjFu7zf1.mjs → HookSystem-BNYKnrXF.mjs} +0 -0
- /package/dist/{applyPermissionResult-bqGpo9ML.mjs → applyPermissionResult-QhV1Pa-g.mjs} +0 -0
- /package/dist/{betterAuthOpenApi--rdY15Ld.mjs → betterAuthOpenApi-BBRVhjQN.mjs} +0 -0
- /package/dist/{constants-Cxde4rpC.mjs → constants-BhY1OHoH.mjs} +0 -0
- /package/dist/{elevation-B6S5csVA.d.mts → elevation-C5SwtkAn.d.mts} +0 -0
- /package/dist/{errors-BI8kEKsO.d.mts → errors-CCSsMpXE.d.mts} +0 -0
- /package/dist/{errors-CqWnSqM-.mjs → errors-D5c-5BJL.mjs} +0 -0
- /package/dist/{externalPaths-Bapitwvd.d.mts → externalPaths-BQ8QijNH.d.mts} +0 -0
- /package/dist/{fields-CU6FlaDV.mjs → fields-bxkeltzz.mjs} +0 -0
- /package/dist/{interface-B-pe8fhj.d.mts → interface-CSbZdv_3.d.mts} +0 -0
- /package/dist/{loadResources-Bksk8ydA.mjs → loadResources-BAzJItAJ.mjs} +0 -0
- /package/dist/{logger-CDjpjySd.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{metrics-TuOmguhi.mjs → metrics-DuhiSEZI.mjs} +0 -0
- /package/dist/{pluralize-CWP6MB39.mjs → pluralize-A0tWEl1K.mjs} +0 -0
- /package/dist/{registry-B0Wl7uVV.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{replyHelpers-BLojtuvR.mjs → replyHelpers-CXtJDAZ0.mjs} +0 -0
- /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{sessionManager-D-oNWHz3.d.mts → sessionManager-BkzVU8h2.d.mts} +0 -0
- /package/dist/{storage-BwGQXUpd.d.mts → storage-CVk_SEn2.d.mts} +0 -0
- /package/dist/{store-helpers-DFiZl5TL.mjs → store-helpers-ZCSMJJAX.mjs} +0 -0
- /package/dist/{tracing-xqXzWeaf.d.mts → tracing-65B51Dw3.d.mts} +0 -0
- /package/dist/{types-ZUu_h0jp.mjs → types-DV9WDfeg.mjs} +0 -0
package/dist/dynamic/index.mjs
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { t as ArcQueryParser } from "../queryParser-Cs-6SHQK.mjs";
|
|
2
|
-
import { n as defineResource } from "../defineResource-C__jkwvs.mjs";
|
|
3
|
-
import { C as publicRead, T as readOnly, b as fullPublic, v as adminOnly, w as publicReadAdminWrite, x as ownerWithAdminBypass, y as authenticated } from "../permissions-oNZawnkR.mjs";
|
|
4
|
-
//#region src/dynamic/ArcDynamicLoader.ts
|
|
5
|
-
const VALID_FIELD_TYPES = new Set([
|
|
6
|
-
"string",
|
|
7
|
-
"number",
|
|
8
|
-
"boolean",
|
|
9
|
-
"date",
|
|
10
|
-
"object",
|
|
11
|
-
"array"
|
|
12
|
-
]);
|
|
13
|
-
function validateSchema(schema) {
|
|
14
|
-
if (!schema.app || typeof schema.app !== "string") throw new Error("AAS: 'app' name is required");
|
|
15
|
-
if (!Array.isArray(schema.resources) || schema.resources.length === 0) throw new Error("AAS: 'resources' must be a non-empty array");
|
|
16
|
-
for (const r of schema.resources) {
|
|
17
|
-
if (!r.name || typeof r.name !== "string") throw new Error("AAS: each resource must have a 'name' string");
|
|
18
|
-
if (!r.permissions) throw new Error(`AAS: resource "${r.name}" must have 'permissions'`);
|
|
19
|
-
if (r.fields) for (const [fieldName, fieldDef] of Object.entries(r.fields)) {
|
|
20
|
-
const type = typeof fieldDef === "string" ? fieldDef : fieldDef.type;
|
|
21
|
-
if (!VALID_FIELD_TYPES.has(type)) throw new Error(`AAS: resource "${r.name}" field "${fieldName}" has invalid type "${type}". Valid types: ${[...VALID_FIELD_TYPES].join(", ")}`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Load an Arc Architecture Schema (JSON) and produce fully configured ResourceDefinitions.
|
|
27
|
-
*
|
|
28
|
-
* Each resource gets:
|
|
29
|
-
* - Adapter from the resolver
|
|
30
|
-
* - Permissions from presets or fine-grained map
|
|
31
|
-
* - schemaOptions.fieldRules for validation and MCP tool schemas
|
|
32
|
-
* - ArcQueryParser with allowedFilterFields/allowedSortFields for MCP auto-derive
|
|
33
|
-
* - Presets applied
|
|
34
|
-
*/
|
|
35
|
-
var ArcDynamicLoader = class {
|
|
36
|
-
context;
|
|
37
|
-
constructor(context) {
|
|
38
|
-
this.context = context;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Load an AAS definition and return fully constructed ResourceDefinitions.
|
|
42
|
-
* Validates the schema before processing — throws on malformed input.
|
|
43
|
-
*/
|
|
44
|
-
load(schema) {
|
|
45
|
-
validateSchema(schema);
|
|
46
|
-
return schema.resources.map((r) => {
|
|
47
|
-
const adapter = this.context.adapterResolver(r.name, r.adapterPattern);
|
|
48
|
-
const fieldRules = this.buildFieldRules(r.fields);
|
|
49
|
-
const queryParser = this.buildQueryParser(r);
|
|
50
|
-
return defineResource({
|
|
51
|
-
name: r.name,
|
|
52
|
-
displayName: r.displayName,
|
|
53
|
-
prefix: r.prefix,
|
|
54
|
-
adapter,
|
|
55
|
-
queryParser,
|
|
56
|
-
presets: r.presets,
|
|
57
|
-
permissions: this.resolvePermissions(r.permissions),
|
|
58
|
-
disabledRoutes: r.disabledRoutes,
|
|
59
|
-
tenantField: r.tenantField,
|
|
60
|
-
schemaOptions: fieldRules ? {
|
|
61
|
-
fieldRules,
|
|
62
|
-
filterableFields: r.filterable
|
|
63
|
-
} : void 0
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
buildFieldRules(fields) {
|
|
68
|
-
if (!fields) return void 0;
|
|
69
|
-
const rules = {};
|
|
70
|
-
for (const [name, def] of Object.entries(fields)) rules[name] = typeof def === "string" ? { type: def } : def;
|
|
71
|
-
return rules;
|
|
72
|
-
}
|
|
73
|
-
buildQueryParser(r) {
|
|
74
|
-
if (!r.filterable && !r.sortable) return void 0;
|
|
75
|
-
return new ArcQueryParser({
|
|
76
|
-
allowedFilterFields: r.filterable,
|
|
77
|
-
allowedSortFields: r.sortable
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
resolvePermissions(policy) {
|
|
81
|
-
if (typeof policy === "string") return this.resolvePreset(policy);
|
|
82
|
-
return this.resolveFinGrained(policy);
|
|
83
|
-
}
|
|
84
|
-
resolvePreset(preset) {
|
|
85
|
-
switch (preset) {
|
|
86
|
-
case "publicRead": return publicRead();
|
|
87
|
-
case "publicReadAdminWrite": return publicReadAdminWrite();
|
|
88
|
-
case "authenticated": return authenticated();
|
|
89
|
-
case "adminOnly": return adminOnly();
|
|
90
|
-
case "ownerWithAdminBypass": return ownerWithAdminBypass();
|
|
91
|
-
case "fullPublic": return fullPublic();
|
|
92
|
-
case "readOnly": return readOnly();
|
|
93
|
-
default:
|
|
94
|
-
if (this.context.permissionResolver) {
|
|
95
|
-
const resolved = this.context.permissionResolver(preset);
|
|
96
|
-
if (resolved) return resolved;
|
|
97
|
-
}
|
|
98
|
-
throw new Error(`Unknown permission preset: "${preset}"`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
resolveFinGrained(policy) {
|
|
102
|
-
const pick = (preset, op) => preset[op] ?? authenticated()[op];
|
|
103
|
-
const map = {
|
|
104
|
-
public: (op) => pick(publicRead(), op),
|
|
105
|
-
auth: (op) => pick(authenticated(), op),
|
|
106
|
-
admin: (op) => pick(adminOnly(), op),
|
|
107
|
-
owner: (op) => pick(ownerWithAdminBypass(), op)
|
|
108
|
-
};
|
|
109
|
-
const permissions = {};
|
|
110
|
-
const ops = {
|
|
111
|
-
list: policy.list,
|
|
112
|
-
get: policy.get,
|
|
113
|
-
create: policy.create,
|
|
114
|
-
update: policy.update,
|
|
115
|
-
delete: policy.delete
|
|
116
|
-
};
|
|
117
|
-
for (const [op, level] of Object.entries(ops)) if (level && map[level]) permissions[op] = map[level](op);
|
|
118
|
-
return permissions;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
//#endregion
|
|
122
|
-
export { ArcDynamicLoader };
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
//#region src/permissions/fields.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Field-Level Permissions
|
|
4
|
-
*
|
|
5
|
-
* Control field visibility and writability per role.
|
|
6
|
-
* Integrated into the response path (read) and sanitization path (write).
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* import { fields, defineResource } from '@classytic/arc';
|
|
11
|
-
*
|
|
12
|
-
* const userResource = defineResource({
|
|
13
|
-
* name: 'user',
|
|
14
|
-
* adapter: userAdapter,
|
|
15
|
-
* fields: {
|
|
16
|
-
* salary: fields.visibleTo(['admin', 'hr']),
|
|
17
|
-
* internalNotes: fields.writableBy(['admin']),
|
|
18
|
-
* email: fields.redactFor(['viewer']),
|
|
19
|
-
* password: fields.hidden(),
|
|
20
|
-
* },
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
type FieldPermissionType = "hidden" | "visibleTo" | "writableBy" | "redactFor";
|
|
25
|
-
interface FieldPermission {
|
|
26
|
-
readonly _type: FieldPermissionType;
|
|
27
|
-
readonly roles?: readonly string[];
|
|
28
|
-
readonly redactValue?: unknown;
|
|
29
|
-
}
|
|
30
|
-
type FieldPermissionMap = Record<string, FieldPermission>;
|
|
31
|
-
declare const fields: {
|
|
32
|
-
/**
|
|
33
|
-
* Field is never included in responses. Not writable via API.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* fields: { password: fields.hidden() }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
hidden(): FieldPermission;
|
|
41
|
-
/**
|
|
42
|
-
* Field is only visible to users with specified roles.
|
|
43
|
-
* Other users don't see the field at all.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```typescript
|
|
47
|
-
* fields: { salary: fields.visibleTo(['admin', 'hr']) }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
visibleTo(roles: readonly string[]): FieldPermission;
|
|
51
|
-
/**
|
|
52
|
-
* Field is only writable by users with specified roles.
|
|
53
|
-
* All users can still read the field. Users without the role
|
|
54
|
-
* have the field silently stripped from write operations.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```typescript
|
|
58
|
-
* fields: { role: fields.writableBy(['admin']) }
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
writableBy(roles: readonly string[]): FieldPermission;
|
|
62
|
-
/**
|
|
63
|
-
* Field is redacted (replaced with a placeholder) for specified roles.
|
|
64
|
-
* Other users see the real value.
|
|
65
|
-
*
|
|
66
|
-
* @param roles - Roles that see the redacted value
|
|
67
|
-
* @param redactValue - Replacement value (default: '***')
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```typescript
|
|
71
|
-
* fields: {
|
|
72
|
-
* email: fields.redactFor(['viewer']),
|
|
73
|
-
* ssn: fields.redactFor(['basic'], '***-**-****'),
|
|
74
|
-
* }
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
redactFor(roles: readonly string[], redactValue?: unknown): FieldPermission;
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Apply field-level READ permissions to a response object.
|
|
81
|
-
* Strips hidden fields, enforces visibility, and applies redaction.
|
|
82
|
-
*
|
|
83
|
-
* @param data - The response object (mutated in place for performance)
|
|
84
|
-
* @param fieldPermissions - Field permission map from resource config
|
|
85
|
-
* @param userRoles - Current user's roles (empty array for unauthenticated)
|
|
86
|
-
* @returns The filtered object
|
|
87
|
-
*/
|
|
88
|
-
declare function applyFieldReadPermissions<T extends Record<string, unknown>>(data: T, fieldPermissions: FieldPermissionMap, userRoles: readonly string[]): T;
|
|
89
|
-
/**
|
|
90
|
-
* Result of applying write permissions — includes both the filtered body
|
|
91
|
-
* and the list of fields that were stripped so callers can decide whether
|
|
92
|
-
* to reject the request (secure default) or silently strip (legacy).
|
|
93
|
-
*/
|
|
94
|
-
interface FieldWritePermissionResult<T extends Record<string, unknown>> {
|
|
95
|
-
readonly body: T;
|
|
96
|
-
readonly deniedFields: readonly string[];
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Apply field-level WRITE permissions to request body.
|
|
100
|
-
*
|
|
101
|
-
* Returns both the filtered body and the list of denied fields. Callers are
|
|
102
|
-
* expected to reject the request when `deniedFields.length > 0` — silently
|
|
103
|
-
* stripping fields hides misconfigurations and real attacks. See
|
|
104
|
-
* `BodySanitizer` for the default policy.
|
|
105
|
-
*
|
|
106
|
-
* @param body - The request body (returns a new filtered copy)
|
|
107
|
-
* @param fieldPermissions - Field permission map from resource config
|
|
108
|
-
* @param userRoles - Current user's roles
|
|
109
|
-
*/
|
|
110
|
-
declare function applyFieldWritePermissions<T extends Record<string, unknown>>(body: T, fieldPermissions: FieldPermissionMap, userRoles: readonly string[]): FieldWritePermissionResult<T>;
|
|
111
|
-
/**
|
|
112
|
-
* Resolve effective roles by merging global user roles with org-level roles.
|
|
113
|
-
*
|
|
114
|
-
* Global roles come from `req.user.role` (normalized via getUserRoles()).
|
|
115
|
-
* Org roles come from `req.context.orgRoles` (set by BA adapter's org bridge).
|
|
116
|
-
*
|
|
117
|
-
* When no org context exists, returns global roles only — backward compatible.
|
|
118
|
-
*/
|
|
119
|
-
declare function resolveEffectiveRoles(userRoles: readonly string[], orgRoles: readonly string[]): string[];
|
|
120
|
-
//#endregion
|
|
121
|
-
export { applyFieldWritePermissions as a, applyFieldReadPermissions as i, FieldPermissionMap as n, fields as o, FieldPermissionType as r, resolveEffectiveRoles as s, FieldPermission as t };
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
//#region src/cache/interface.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Generic Cache Store Interface
|
|
4
|
-
*
|
|
5
|
-
* Shared contract for reusable cache backends (memory, Redis, etc.).
|
|
6
|
-
* Used by runtime systems such as dynamic permission matrices and QueryCache.
|
|
7
|
-
*/
|
|
8
|
-
interface CacheLogger {
|
|
9
|
-
warn(message: string, ...args: unknown[]): void;
|
|
10
|
-
error(message: string, ...args: unknown[]): void;
|
|
11
|
-
}
|
|
12
|
-
interface CacheSetOptions {
|
|
13
|
-
/** Time-to-live in milliseconds */
|
|
14
|
-
ttlMs?: number;
|
|
15
|
-
}
|
|
16
|
-
interface CacheStats {
|
|
17
|
-
/** Number of entries currently stored */
|
|
18
|
-
entries: number;
|
|
19
|
-
/** Estimated memory usage in bytes (-1 if unavailable) */
|
|
20
|
-
memoryBytes: number;
|
|
21
|
-
/** Cache hit count since creation */
|
|
22
|
-
hits: number;
|
|
23
|
-
/** Cache miss count since creation */
|
|
24
|
-
misses: number;
|
|
25
|
-
/** Number of entries evicted since creation */
|
|
26
|
-
evictions: number;
|
|
27
|
-
}
|
|
28
|
-
interface CacheStore<TValue = unknown> {
|
|
29
|
-
/** Store name for logs/diagnostics */
|
|
30
|
-
readonly name: string;
|
|
31
|
-
/**
|
|
32
|
-
* Get cached value by key.
|
|
33
|
-
* Returns undefined when missing or expired.
|
|
34
|
-
*/
|
|
35
|
-
get(key: string): Promise<TValue | undefined>;
|
|
36
|
-
/**
|
|
37
|
-
* Set a cache value.
|
|
38
|
-
* Store implementation handles TTL and eviction policy.
|
|
39
|
-
*/
|
|
40
|
-
set(key: string, value: TValue, options?: CacheSetOptions): Promise<void>;
|
|
41
|
-
/**
|
|
42
|
-
* Delete a single cache key.
|
|
43
|
-
*/
|
|
44
|
-
delete(key: string): Promise<void>;
|
|
45
|
-
/**
|
|
46
|
-
* Clear all keys in this store namespace.
|
|
47
|
-
* Optional because distributed stores may not support cheap global clear.
|
|
48
|
-
*/
|
|
49
|
-
clear?(): Promise<void>;
|
|
50
|
-
/** Cache statistics for observability. */
|
|
51
|
-
stats?(): CacheStats;
|
|
52
|
-
}
|
|
53
|
-
//#endregion
|
|
54
|
-
export { CacheStore as i, CacheSetOptions as n, CacheStats as r, CacheLogger as t };
|