funifier-mcp 0.3.17 → 0.3.19
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/.cursor/rules/funifier.mdc +3 -1
- package/.github/copilot-instructions.md +3 -1
- package/AGENTS.md +3 -1
- package/CHANGELOG.md +59 -0
- package/README.md +1 -1
- package/datasource-funifier-docs/.coverage.json +15 -5
- package/datasource-funifier-docs/.validation.json +77 -36
- package/datasource-funifier-docs/knowledge/guides/aggregates.md +13 -6
- package/datasource-funifier-docs/knowledge/guides/permission-audit.md +229 -0
- package/datasource-funifier-docs/knowledge/index.md +3 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +3 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/core/api-client.d.ts +2 -0
- package/dist/core/api-client.d.ts.map +1 -1
- package/dist/core/api-client.js +98 -47
- package/dist/core/api-client.js.map +1 -1
- package/dist/core/api-client.test.js +27 -0
- package/dist/core/api-client.test.js.map +1 -1
- package/dist/core/constants.d.ts +4 -0
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.js +8 -0
- package/dist/core/constants.js.map +1 -1
- package/dist/core/logger.d.ts +9 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +50 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/mcp/api-holder.test.d.ts +2 -0
- package/dist/mcp/api-holder.test.d.ts.map +1 -0
- package/dist/mcp/api-holder.test.js +45 -0
- package/dist/mcp/api-holder.test.js.map +1 -0
- package/dist/mcp/bundle.js +108 -105
- package/dist/mcp/check-update.d.ts +9 -0
- package/dist/mcp/check-update.d.ts.map +1 -1
- package/dist/mcp/check-update.js +35 -9
- package/dist/mcp/check-update.js.map +1 -1
- package/dist/mcp/check-update.test.js +36 -6
- package/dist/mcp/check-update.test.js.map +1 -1
- package/dist/mcp/doc-path.d.ts +11 -0
- package/dist/mcp/doc-path.d.ts.map +1 -0
- package/dist/mcp/doc-path.js +66 -0
- package/dist/mcp/doc-path.js.map +1 -0
- package/dist/mcp/doc-path.test.d.ts +2 -0
- package/dist/mcp/doc-path.test.d.ts.map +1 -0
- package/dist/mcp/doc-path.test.js +77 -0
- package/dist/mcp/doc-path.test.js.map +1 -0
- package/dist/mcp/index.js +19 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/resources/documentation.d.ts.map +1 -1
- package/dist/mcp/resources/documentation.js +7 -3
- package/dist/mcp/resources/documentation.js.map +1 -1
- package/dist/mcp/tools/_audit.d.ts +103 -0
- package/dist/mcp/tools/_audit.d.ts.map +1 -0
- package/dist/mcp/tools/_audit.js +241 -0
- package/dist/mcp/tools/_audit.js.map +1 -0
- package/dist/mcp/tools/_audit.test.d.ts +2 -0
- package/dist/mcp/tools/_audit.test.d.ts.map +1 -0
- package/dist/mcp/tools/_audit.test.js +412 -0
- package/dist/mcp/tools/_audit.test.js.map +1 -0
- package/dist/mcp/tools/_backup.d.ts +37 -3
- package/dist/mcp/tools/_backup.d.ts.map +1 -1
- package/dist/mcp/tools/_backup.js +142 -11
- package/dist/mcp/tools/_backup.js.map +1 -1
- package/dist/mcp/tools/_backup.test.js +195 -0
- package/dist/mcp/tools/_backup.test.js.map +1 -1
- package/dist/mcp/tools/_char-guard.d.ts +2 -1
- package/dist/mcp/tools/_char-guard.d.ts.map +1 -1
- package/dist/mcp/tools/_char-guard.js +10 -3
- package/dist/mcp/tools/_char-guard.js.map +1 -1
- package/dist/mcp/tools/_fetch-current.d.ts +2 -1
- package/dist/mcp/tools/_fetch-current.d.ts.map +1 -1
- package/dist/mcp/tools/_fetch-current.js +2 -74
- package/dist/mcp/tools/_fetch-current.js.map +1 -1
- package/dist/mcp/tools/_registry.d.ts +183 -0
- package/dist/mcp/tools/_registry.d.ts.map +1 -0
- package/dist/mcp/tools/_registry.js +88 -0
- package/dist/mcp/tools/_registry.js.map +1 -0
- package/dist/mcp/tools/_registry.test.d.ts +2 -0
- package/dist/mcp/tools/_registry.test.d.ts.map +1 -0
- package/dist/mcp/tools/_registry.test.js +103 -0
- package/dist/mcp/tools/_registry.test.js.map +1 -0
- package/dist/mcp/tools/_scope-engine.d.ts +40 -0
- package/dist/mcp/tools/_scope-engine.d.ts.map +1 -0
- package/dist/mcp/tools/_scope-engine.js +197 -0
- package/dist/mcp/tools/_scope-engine.js.map +1 -0
- package/dist/mcp/tools/_scope-engine.test.d.ts +2 -0
- package/dist/mcp/tools/_scope-engine.test.d.ts.map +1 -0
- package/dist/mcp/tools/_scope-engine.test.js +241 -0
- package/dist/mcp/tools/_scope-engine.test.js.map +1 -0
- package/dist/mcp/tools/database.d.ts +4 -0
- package/dist/mcp/tools/database.d.ts.map +1 -1
- package/dist/mcp/tools/database.js +23 -4
- package/dist/mcp/tools/database.js.map +1 -1
- package/dist/mcp/tools/database.test.js +19 -0
- package/dist/mcp/tools/database.test.js.map +1 -1
- package/dist/mcp/tools/delete.d.ts.map +1 -1
- package/dist/mcp/tools/delete.js +3 -98
- package/dist/mcp/tools/delete.js.map +1 -1
- package/dist/mcp/tools/execute.d.ts.map +1 -1
- package/dist/mcp/tools/execute.js +36 -4
- package/dist/mcp/tools/execute.js.map +1 -1
- package/dist/mcp/tools/execute.test.d.ts +2 -0
- package/dist/mcp/tools/execute.test.d.ts.map +1 -0
- package/dist/mcp/tools/execute.test.js +87 -0
- package/dist/mcp/tools/execute.test.js.map +1 -0
- package/dist/mcp/tools/get.d.ts.map +1 -1
- package/dist/mcp/tools/get.js +4 -93
- package/dist/mcp/tools/get.js.map +1 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +42 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/list.d.ts.map +1 -1
- package/dist/mcp/tools/list.js +3 -91
- package/dist/mcp/tools/list.js.map +1 -1
- package/dist/mcp/tools/logs.d.ts.map +1 -1
- package/dist/mcp/tools/logs.js +5 -3
- package/dist/mcp/tools/logs.js.map +1 -1
- package/dist/mcp/tools/permissions.d.ts.map +1 -1
- package/dist/mcp/tools/permissions.js +68 -11
- package/dist/mcp/tools/permissions.js.map +1 -1
- package/dist/mcp/tools/permissions.test.js +268 -4
- package/dist/mcp/tools/permissions.test.js.map +1 -1
- package/dist/mcp/tools/read-doc.d.ts.map +1 -1
- package/dist/mcp/tools/read-doc.js +10 -28
- package/dist/mcp/tools/read-doc.js.map +1 -1
- package/dist/mcp/tools/save.d.ts.map +1 -1
- package/dist/mcp/tools/save.js +4 -81
- package/dist/mcp/tools/save.js.map +1 -1
- package/package.json +3 -2
- package/skills/funifier/SKILL.md +3 -1
- package/skills/funifier/references/audit-permissions.md +97 -0
- package/skills/funifier/references/configure-security.md +6 -0
- package/skills/funifier/references/create-action.md +7 -0
- package/skills/funifier/references/create-aggregate.md +99 -79
- package/skills/funifier/references/create-audit.md +8 -0
- package/skills/funifier/references/create-challenge.md +7 -0
- package/skills/funifier/references/create-competition.md +7 -0
- package/skills/funifier/references/create-crossword.md +6 -0
- package/skills/funifier/references/create-custom-object.md +6 -0
- package/skills/funifier/references/create-custom-page.md +6 -0
- package/skills/funifier/references/create-folder.md +7 -0
- package/skills/funifier/references/create-lastmile.md +6 -0
- package/skills/funifier/references/create-leaderboard.md +6 -0
- package/skills/funifier/references/create-level.md +7 -0
- package/skills/funifier/references/create-lottery.md +7 -0
- package/skills/funifier/references/create-mystery.md +6 -0
- package/skills/funifier/references/create-notification.md +6 -0
- package/skills/funifier/references/create-point.md +7 -0
- package/skills/funifier/references/create-quiz.md +7 -0
- package/skills/funifier/references/create-scheduler.md +6 -0
- package/skills/funifier/references/create-story.md +6 -0
- package/skills/funifier/references/create-swap.md +6 -0
- package/skills/funifier/references/create-trigger.md +8 -0
- package/skills/funifier/references/create-virtual-good.md +6 -0
- package/skills/funifier/references/create-webhook.md +6 -0
- package/skills/funifier/references/create-websocket.md +6 -0
- package/skills/funifier/references/create-widget.md +6 -0
- package/skills/funifier/references/date-handling.md +6 -0
- package/skills/funifier/references/debug.md +6 -0
- package/skills/funifier/references/help.md +6 -0
- package/skills/funifier/references/implement-frontend.md +7 -0
- package/skills/funifier/references/import-csv.md +6 -0
- package/skills/funifier/references/manage-indexes.md +6 -0
- package/skills/funifier/references/manage-player.md +7 -0
- package/skills/funifier/references/manage-team.md +6 -0
- package/skills/funifier/references/query-aggregate.md +111 -0
- package/skills/funifier/references/upload-file.md +6 -0
- package/datasource-funifier-docs/.search-index.json +0 -58758
- package/datasource-funifier-docs/.skills-map.json +0 -141
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { ResourceType } from "./_registry";
|
|
2
|
+
export type { ResourceType };
|
|
2
3
|
export declare function fetchCurrentById(api: any, type: ResourceType, id: string): Promise<any | null>;
|
|
3
4
|
//# sourceMappingURL=_fetch-current.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_fetch-current.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_fetch-current.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"_fetch-current.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_fetch-current.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,YAAY,EAAE,MAAM,aAAa,CAAC;AAEzD,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAIrB"}
|
|
@@ -1,81 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.fetchCurrentById = fetchCurrentById;
|
|
4
|
+
const _registry_1 = require("./_registry");
|
|
4
5
|
async function fetchCurrentById(api, type, id) {
|
|
5
|
-
|
|
6
|
-
switch (type) {
|
|
7
|
-
case "trigger":
|
|
8
|
-
items = await api.listTriggers();
|
|
9
|
-
break;
|
|
10
|
-
case "scheduler":
|
|
11
|
-
items = await api.listSchedulers();
|
|
12
|
-
break;
|
|
13
|
-
case "aggregate":
|
|
14
|
-
items = await api.listAggregates();
|
|
15
|
-
break;
|
|
16
|
-
case "websocket":
|
|
17
|
-
items = await api.listWebsockets();
|
|
18
|
-
break;
|
|
19
|
-
case "widget":
|
|
20
|
-
items = await api.listWidgets();
|
|
21
|
-
break;
|
|
22
|
-
case "custom-page":
|
|
23
|
-
items = await api.listCustomPages();
|
|
24
|
-
break;
|
|
25
|
-
case "public-endpoint":
|
|
26
|
-
items = await api.listPublicEndpoints();
|
|
27
|
-
break;
|
|
28
|
-
case "challenge-aggregate":
|
|
29
|
-
items = await api.listChallengeAggregates();
|
|
30
|
-
break;
|
|
31
|
-
case "auth-module":
|
|
32
|
-
items = await api.listAuthModules();
|
|
33
|
-
break;
|
|
34
|
-
case "ai-knowledge":
|
|
35
|
-
items = await api.listAiKnowledge();
|
|
36
|
-
break;
|
|
37
|
-
case "audit":
|
|
38
|
-
items = await api.listAudits();
|
|
39
|
-
break;
|
|
40
|
-
case "action":
|
|
41
|
-
items = await api.listActions();
|
|
42
|
-
break;
|
|
43
|
-
case "challenge":
|
|
44
|
-
items = await api.listChallenges();
|
|
45
|
-
break;
|
|
46
|
-
case "point":
|
|
47
|
-
items = await api.listPoints();
|
|
48
|
-
break;
|
|
49
|
-
case "level":
|
|
50
|
-
items = await api.listLevels();
|
|
51
|
-
break;
|
|
52
|
-
case "leaderboard":
|
|
53
|
-
items = await api.listLeaderboards();
|
|
54
|
-
break;
|
|
55
|
-
case "quiz":
|
|
56
|
-
items = await api.listQuizzes();
|
|
57
|
-
break;
|
|
58
|
-
case "virtual-good-catalog":
|
|
59
|
-
items = await api.listVirtualGoodCatalogs();
|
|
60
|
-
break;
|
|
61
|
-
case "virtual-good-item":
|
|
62
|
-
items = await api.listVirtualGoodItems();
|
|
63
|
-
break;
|
|
64
|
-
case "folder":
|
|
65
|
-
items = await api.listFolders();
|
|
66
|
-
break;
|
|
67
|
-
case "folder-content":
|
|
68
|
-
items = await api.listFolderContents();
|
|
69
|
-
break;
|
|
70
|
-
case "folder-content-type":
|
|
71
|
-
items = await api.listFolderContentTypes();
|
|
72
|
-
break;
|
|
73
|
-
case "folder-log":
|
|
74
|
-
items = await api.listFolderLogs();
|
|
75
|
-
break;
|
|
76
|
-
default:
|
|
77
|
-
throw new Error(`Unknown resource type: ${type}`);
|
|
78
|
-
}
|
|
6
|
+
const items = await (0, _registry_1.listResource)(api, type);
|
|
79
7
|
const found = items.find((i) => i._id === id);
|
|
80
8
|
return found ?? null;
|
|
81
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_fetch-current.js","sourceRoot":"","sources":["../../../src/mcp/tools/_fetch-current.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"_fetch-current.js","sourceRoot":"","sources":["../../../src/mcp/tools/_fetch-current.ts"],"names":[],"mappings":";;AAIA,4CAQC;AAZD,2CAAyD;AAIlD,KAAK,UAAU,gBAAgB,CACpC,GAAQ,EACR,IAAkB,EAClB,EAAU;IAEV,MAAM,KAAK,GAAG,MAAM,IAAA,wBAAY,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IACnD,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
export interface ResourceDef {
|
|
2
|
+
/** api-client method that lists all items of this type (always present). */
|
|
3
|
+
list: string;
|
|
4
|
+
/** Exposed in the funifier_list and funifier_get type enums. */
|
|
5
|
+
publicList: boolean;
|
|
6
|
+
/** api-client save method — present ⇒ exposed in funifier_save and merge-on-update. */
|
|
7
|
+
save?: string;
|
|
8
|
+
/** Save methods that take a second `isNew` boolean argument. */
|
|
9
|
+
saveIsNewArg?: boolean;
|
|
10
|
+
/** api-client delete method — present ⇒ exposed in funifier_delete. */
|
|
11
|
+
delete?: string;
|
|
12
|
+
/** Server-side script is Groovy (vs JS) — drives the get/save companion file extension. */
|
|
13
|
+
groovy?: boolean;
|
|
14
|
+
}
|
|
15
|
+
declare const RAW_REGISTRY: {
|
|
16
|
+
trigger: {
|
|
17
|
+
list: string;
|
|
18
|
+
publicList: true;
|
|
19
|
+
save: string;
|
|
20
|
+
delete: string;
|
|
21
|
+
groovy: true;
|
|
22
|
+
};
|
|
23
|
+
scheduler: {
|
|
24
|
+
list: string;
|
|
25
|
+
publicList: true;
|
|
26
|
+
save: string;
|
|
27
|
+
delete: string;
|
|
28
|
+
groovy: true;
|
|
29
|
+
};
|
|
30
|
+
aggregate: {
|
|
31
|
+
list: string;
|
|
32
|
+
publicList: true;
|
|
33
|
+
save: string;
|
|
34
|
+
delete: string;
|
|
35
|
+
groovy: true;
|
|
36
|
+
};
|
|
37
|
+
websocket: {
|
|
38
|
+
list: string;
|
|
39
|
+
publicList: true;
|
|
40
|
+
save: string;
|
|
41
|
+
saveIsNewArg: true;
|
|
42
|
+
delete: string;
|
|
43
|
+
groovy: true;
|
|
44
|
+
};
|
|
45
|
+
widget: {
|
|
46
|
+
list: string;
|
|
47
|
+
publicList: true;
|
|
48
|
+
save: string;
|
|
49
|
+
delete: string;
|
|
50
|
+
};
|
|
51
|
+
"custom-page": {
|
|
52
|
+
list: string;
|
|
53
|
+
publicList: true;
|
|
54
|
+
save: string;
|
|
55
|
+
delete: string;
|
|
56
|
+
};
|
|
57
|
+
"public-endpoint": {
|
|
58
|
+
list: string;
|
|
59
|
+
publicList: true;
|
|
60
|
+
save: string;
|
|
61
|
+
delete: string;
|
|
62
|
+
groovy: true;
|
|
63
|
+
};
|
|
64
|
+
"challenge-aggregate": {
|
|
65
|
+
list: string;
|
|
66
|
+
publicList: true;
|
|
67
|
+
save: string;
|
|
68
|
+
delete: string;
|
|
69
|
+
};
|
|
70
|
+
"auth-module": {
|
|
71
|
+
list: string;
|
|
72
|
+
publicList: true;
|
|
73
|
+
save: string;
|
|
74
|
+
saveIsNewArg: true;
|
|
75
|
+
delete: string;
|
|
76
|
+
groovy: true;
|
|
77
|
+
};
|
|
78
|
+
"ai-knowledge": {
|
|
79
|
+
list: string;
|
|
80
|
+
publicList: true;
|
|
81
|
+
save: string;
|
|
82
|
+
delete: string;
|
|
83
|
+
};
|
|
84
|
+
audit: {
|
|
85
|
+
list: string;
|
|
86
|
+
publicList: true;
|
|
87
|
+
save: string;
|
|
88
|
+
delete: string;
|
|
89
|
+
};
|
|
90
|
+
action: {
|
|
91
|
+
list: string;
|
|
92
|
+
publicList: true;
|
|
93
|
+
save: string;
|
|
94
|
+
delete: string;
|
|
95
|
+
};
|
|
96
|
+
challenge: {
|
|
97
|
+
list: string;
|
|
98
|
+
publicList: true;
|
|
99
|
+
save: string;
|
|
100
|
+
delete: string;
|
|
101
|
+
};
|
|
102
|
+
point: {
|
|
103
|
+
list: string;
|
|
104
|
+
publicList: true;
|
|
105
|
+
save: string;
|
|
106
|
+
delete: string;
|
|
107
|
+
};
|
|
108
|
+
level: {
|
|
109
|
+
list: string;
|
|
110
|
+
publicList: true;
|
|
111
|
+
save: string;
|
|
112
|
+
delete: string;
|
|
113
|
+
};
|
|
114
|
+
leaderboard: {
|
|
115
|
+
list: string;
|
|
116
|
+
publicList: true;
|
|
117
|
+
save: string;
|
|
118
|
+
delete: string;
|
|
119
|
+
};
|
|
120
|
+
quiz: {
|
|
121
|
+
list: string;
|
|
122
|
+
publicList: true;
|
|
123
|
+
save: string;
|
|
124
|
+
delete: string;
|
|
125
|
+
};
|
|
126
|
+
"virtual-good-catalog": {
|
|
127
|
+
list: string;
|
|
128
|
+
publicList: true;
|
|
129
|
+
save: string;
|
|
130
|
+
delete: string;
|
|
131
|
+
};
|
|
132
|
+
"virtual-good-item": {
|
|
133
|
+
list: string;
|
|
134
|
+
publicList: true;
|
|
135
|
+
save: string;
|
|
136
|
+
delete: string;
|
|
137
|
+
};
|
|
138
|
+
folder: {
|
|
139
|
+
list: string;
|
|
140
|
+
publicList: false;
|
|
141
|
+
save: string;
|
|
142
|
+
delete: string;
|
|
143
|
+
};
|
|
144
|
+
"folder-content": {
|
|
145
|
+
list: string;
|
|
146
|
+
publicList: false;
|
|
147
|
+
save: string;
|
|
148
|
+
delete: string;
|
|
149
|
+
};
|
|
150
|
+
"folder-content-type": {
|
|
151
|
+
list: string;
|
|
152
|
+
publicList: false;
|
|
153
|
+
save: string;
|
|
154
|
+
};
|
|
155
|
+
"folder-log": {
|
|
156
|
+
list: string;
|
|
157
|
+
publicList: false;
|
|
158
|
+
save: string;
|
|
159
|
+
delete: string;
|
|
160
|
+
};
|
|
161
|
+
role: {
|
|
162
|
+
list: string;
|
|
163
|
+
publicList: true;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
export type ResourceType = keyof typeof RAW_REGISTRY;
|
|
167
|
+
export declare const RESOURCE_REGISTRY: Record<ResourceType, ResourceDef>;
|
|
168
|
+
/** Types exposed in funifier_list and funifier_get (insertion order preserved). */
|
|
169
|
+
export declare const PUBLIC_LIST_TYPES: ["folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role", ...("folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role")[]];
|
|
170
|
+
/** Types exposed in funifier_save. */
|
|
171
|
+
export declare const SAVE_TYPES: ["folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role", ...("folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role")[]];
|
|
172
|
+
/** Types exposed in funifier_delete. */
|
|
173
|
+
export declare const DELETE_TYPES: ["folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role", ...("folder" | "trigger" | "scheduler" | "aggregate" | "websocket" | "widget" | "custom-page" | "public-endpoint" | "challenge-aggregate" | "auth-module" | "ai-knowledge" | "audit" | "action" | "challenge" | "point" | "level" | "leaderboard" | "quiz" | "virtual-good-catalog" | "virtual-good-item" | "folder-content" | "folder-content-type" | "folder-log" | "role")[]];
|
|
174
|
+
/** Server-side script for this type is Groovy (vs plain JS). */
|
|
175
|
+
export declare function isGroovyType(type: string): boolean;
|
|
176
|
+
/** List every item of a resource type via its registered api-client method. */
|
|
177
|
+
export declare function listResource(api: any, type: ResourceType): Promise<any[]>;
|
|
178
|
+
/** Save a resource via its registered method, threading the `isNew` arg when required. */
|
|
179
|
+
export declare function saveResource(api: any, type: ResourceType, data: any): Promise<any>;
|
|
180
|
+
/** Delete a resource by id via its registered method. */
|
|
181
|
+
export declare function deleteResource(api: any, type: ResourceType, id: string): Promise<any>;
|
|
182
|
+
export {};
|
|
183
|
+
//# sourceMappingURL=_registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_registry.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_registry.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyBqB,CAAC;AAExC,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,YAAY,CAAC;AAIrD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,YAAY,EAAE,WAAW,CAAgB,CAAC;AASjF,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,6tBAAkC,CAAC;AACjE,sCAAsC;AACtC,eAAO,MAAM,UAAU,6tBAA8B,CAAC;AACtD,wCAAwC;AACxC,eAAO,MAAM,YAAY,6tBAAgC,CAAC;AAE1D,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAQD,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAEzE;AAED,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAIlF;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAIrF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Single source of truth mapping each Funifier resource type to its api-client
|
|
3
|
+
// methods and which tools expose it. Replaces the parallel switch/dispatch blocks
|
|
4
|
+
// that previously lived (and silently diverged) in save/delete/get/list and
|
|
5
|
+
// _fetch-current. Adding a resource type is now one entry here + (when needed) a
|
|
6
|
+
// summarize case in list.ts — see the consistency test in _registry.test.ts.
|
|
7
|
+
//
|
|
8
|
+
// Capability presence is EXPLICIT, not inferred from method existence, because the
|
|
9
|
+
// public tools intentionally diverge from internal use:
|
|
10
|
+
// - folders have list methods (used by save's merge-on-update) but are NOT
|
|
11
|
+
// exposed in the funifier_list / funifier_get enums (publicList: false);
|
|
12
|
+
// - role is read-only here (no save/delete) — mutations go through funifier_permissions;
|
|
13
|
+
// - folder-content-type is creatable but not deletable via funifier_delete.
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.DELETE_TYPES = exports.SAVE_TYPES = exports.PUBLIC_LIST_TYPES = exports.RESOURCE_REGISTRY = void 0;
|
|
16
|
+
exports.isGroovyType = isGroovyType;
|
|
17
|
+
exports.listResource = listResource;
|
|
18
|
+
exports.saveResource = saveResource;
|
|
19
|
+
exports.deleteResource = deleteResource;
|
|
20
|
+
const RAW_REGISTRY = {
|
|
21
|
+
trigger: { list: "listTriggers", publicList: true, save: "saveTrigger", delete: "deleteTrigger", groovy: true },
|
|
22
|
+
scheduler: { list: "listSchedulers", publicList: true, save: "saveScheduler", delete: "deleteScheduler", groovy: true },
|
|
23
|
+
aggregate: { list: "listAggregates", publicList: true, save: "saveAggregate", delete: "deleteAggregate", groovy: true },
|
|
24
|
+
websocket: { list: "listWebsockets", publicList: true, save: "saveWebsocket", saveIsNewArg: true, delete: "deleteWebsocket", groovy: true },
|
|
25
|
+
widget: { list: "listWidgets", publicList: true, save: "saveWidget", delete: "deleteWidget" },
|
|
26
|
+
"custom-page": { list: "listCustomPages", publicList: true, save: "saveCustomPage", delete: "deleteCustomPage" },
|
|
27
|
+
"public-endpoint": { list: "listPublicEndpoints", publicList: true, save: "savePublicEndpoint", delete: "deletePublicEndpoint", groovy: true },
|
|
28
|
+
"challenge-aggregate": { list: "listChallengeAggregates", publicList: true, save: "saveChallengeAggregate", delete: "deleteChallengeAggregate" },
|
|
29
|
+
"auth-module": { list: "listAuthModules", publicList: true, save: "saveAuthModule", saveIsNewArg: true, delete: "deleteAuthModule", groovy: true },
|
|
30
|
+
"ai-knowledge": { list: "listAiKnowledge", publicList: true, save: "saveAiKnowledge", delete: "deleteAiKnowledge" },
|
|
31
|
+
audit: { list: "listAudits", publicList: true, save: "saveAudit", delete: "deleteAudit" },
|
|
32
|
+
action: { list: "listActions", publicList: true, save: "saveAction", delete: "deleteAction" },
|
|
33
|
+
challenge: { list: "listChallenges", publicList: true, save: "saveChallenge", delete: "deleteChallenge" },
|
|
34
|
+
point: { list: "listPoints", publicList: true, save: "savePoint", delete: "deletePoint" },
|
|
35
|
+
level: { list: "listLevels", publicList: true, save: "saveLevel", delete: "deleteLevel" },
|
|
36
|
+
leaderboard: { list: "listLeaderboards", publicList: true, save: "saveLeaderboard", delete: "deleteLeaderboard" },
|
|
37
|
+
quiz: { list: "listQuizzes", publicList: true, save: "saveQuiz", delete: "deleteQuiz" },
|
|
38
|
+
"virtual-good-catalog": { list: "listVirtualGoodCatalogs", publicList: true, save: "saveVirtualGoodCatalog", delete: "deleteVirtualGoodCatalog" },
|
|
39
|
+
"virtual-good-item": { list: "listVirtualGoodItems", publicList: true, save: "saveVirtualGoodItem", delete: "deleteVirtualGoodItem" },
|
|
40
|
+
folder: { list: "listFolders", publicList: false, save: "saveFolder", delete: "deleteFolder" },
|
|
41
|
+
"folder-content": { list: "listFolderContents", publicList: false, save: "saveFolderContent", delete: "deleteFolderContent" },
|
|
42
|
+
"folder-content-type": { list: "listFolderContentTypes", publicList: false, save: "saveFolderContentType" },
|
|
43
|
+
"folder-log": { list: "listFolderLogs", publicList: false, save: "saveFolderLog", delete: "deleteFolderLog" },
|
|
44
|
+
role: { list: "listRoles", publicList: true },
|
|
45
|
+
};
|
|
46
|
+
// Re-typed as a uniform record so optional capabilities (save/delete/...) are
|
|
47
|
+
// accessible on every entry, while ResourceType still carries the literal keys.
|
|
48
|
+
exports.RESOURCE_REGISTRY = RAW_REGISTRY;
|
|
49
|
+
const ALL_TYPES = Object.keys(exports.RESOURCE_REGISTRY);
|
|
50
|
+
function typesWhere(pred) {
|
|
51
|
+
const arr = ALL_TYPES.filter((t) => pred(exports.RESOURCE_REGISTRY[t]));
|
|
52
|
+
return arr;
|
|
53
|
+
}
|
|
54
|
+
/** Types exposed in funifier_list and funifier_get (insertion order preserved). */
|
|
55
|
+
exports.PUBLIC_LIST_TYPES = typesWhere((d) => d.publicList);
|
|
56
|
+
/** Types exposed in funifier_save. */
|
|
57
|
+
exports.SAVE_TYPES = typesWhere((d) => !!d.save);
|
|
58
|
+
/** Types exposed in funifier_delete. */
|
|
59
|
+
exports.DELETE_TYPES = typesWhere((d) => !!d.delete);
|
|
60
|
+
/** Server-side script for this type is Groovy (vs plain JS). */
|
|
61
|
+
function isGroovyType(type) {
|
|
62
|
+
return !!exports.RESOURCE_REGISTRY[type]?.groovy;
|
|
63
|
+
}
|
|
64
|
+
function requireDef(type) {
|
|
65
|
+
const def = exports.RESOURCE_REGISTRY[type];
|
|
66
|
+
if (!def)
|
|
67
|
+
throw new Error(`Unknown resource type: ${type}`);
|
|
68
|
+
return def;
|
|
69
|
+
}
|
|
70
|
+
/** List every item of a resource type via its registered api-client method. */
|
|
71
|
+
function listResource(api, type) {
|
|
72
|
+
return api[requireDef(type).list]();
|
|
73
|
+
}
|
|
74
|
+
/** Save a resource via its registered method, threading the `isNew` arg when required. */
|
|
75
|
+
function saveResource(api, type, data) {
|
|
76
|
+
const def = requireDef(type);
|
|
77
|
+
if (!def.save)
|
|
78
|
+
throw new Error(`Resource type does not support save: ${type}`);
|
|
79
|
+
return def.saveIsNewArg ? api[def.save](data, !data._id) : api[def.save](data);
|
|
80
|
+
}
|
|
81
|
+
/** Delete a resource by id via its registered method. */
|
|
82
|
+
function deleteResource(api, type, id) {
|
|
83
|
+
const def = requireDef(type);
|
|
84
|
+
if (!def.delete)
|
|
85
|
+
throw new Error(`Resource type does not support delete: ${type}`);
|
|
86
|
+
return api[def.delete](id);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=_registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_registry.js","sourceRoot":"","sources":["../../../src/mcp/tools/_registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_registry.test.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_registry.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const api_client_1 = require("../../core/api-client");
|
|
5
|
+
const _registry_1 = require("./_registry");
|
|
6
|
+
// A dummy client exposes the real method surface without any network calls.
|
|
7
|
+
const api = (0, api_client_1.createAPIClient)({ apiKey: "k", secretKey: "s", serverUrl: "https://x.example" });
|
|
8
|
+
// Frozen snapshots of the per-tool type sets BEFORE the registry refactor. These
|
|
9
|
+
// guard against accidental drift: a registry edit that changes which types a tool
|
|
10
|
+
// exposes must update these lists deliberately.
|
|
11
|
+
const EXPECTED_PUBLIC_LIST = [
|
|
12
|
+
"trigger", "scheduler", "aggregate", "websocket", "widget", "custom-page",
|
|
13
|
+
"public-endpoint", "challenge-aggregate", "auth-module", "ai-knowledge", "audit",
|
|
14
|
+
"action", "challenge", "point", "level", "leaderboard", "quiz",
|
|
15
|
+
"virtual-good-catalog", "virtual-good-item", "role",
|
|
16
|
+
];
|
|
17
|
+
const EXPECTED_SAVE = [
|
|
18
|
+
"trigger", "scheduler", "aggregate", "websocket", "widget", "custom-page",
|
|
19
|
+
"public-endpoint", "challenge-aggregate", "auth-module", "ai-knowledge", "audit",
|
|
20
|
+
"action", "challenge", "point", "level", "leaderboard", "quiz",
|
|
21
|
+
"virtual-good-catalog", "virtual-good-item",
|
|
22
|
+
"folder", "folder-content", "folder-content-type", "folder-log",
|
|
23
|
+
];
|
|
24
|
+
const EXPECTED_DELETE = [
|
|
25
|
+
"trigger", "scheduler", "aggregate", "websocket", "widget", "custom-page",
|
|
26
|
+
"public-endpoint", "challenge-aggregate", "auth-module", "ai-knowledge", "audit",
|
|
27
|
+
"action", "challenge", "point", "level", "leaderboard", "quiz",
|
|
28
|
+
"virtual-good-catalog", "virtual-good-item",
|
|
29
|
+
"folder", "folder-content", "folder-log",
|
|
30
|
+
];
|
|
31
|
+
const EXPECTED_GROOVY = ["trigger", "scheduler", "aggregate", "websocket", "public-endpoint", "auth-module"];
|
|
32
|
+
(0, vitest_1.describe)("resource registry — frozen membership (guards against drift)", () => {
|
|
33
|
+
(0, vitest_1.it)("funifier_list / funifier_get expose exactly the public-list types", () => {
|
|
34
|
+
(0, vitest_1.expect)([..._registry_1.PUBLIC_LIST_TYPES]).toEqual(EXPECTED_PUBLIC_LIST);
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.it)("funifier_save exposes exactly the save types", () => {
|
|
37
|
+
(0, vitest_1.expect)([..._registry_1.SAVE_TYPES]).toEqual(EXPECTED_SAVE);
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.it)("funifier_delete exposes exactly the delete types", () => {
|
|
40
|
+
(0, vitest_1.expect)([..._registry_1.DELETE_TYPES]).toEqual(EXPECTED_DELETE);
|
|
41
|
+
});
|
|
42
|
+
(0, vitest_1.it)("folder-content-type is creatable but not deletable", () => {
|
|
43
|
+
(0, vitest_1.expect)(_registry_1.SAVE_TYPES).toContain("folder-content-type");
|
|
44
|
+
(0, vitest_1.expect)(_registry_1.DELETE_TYPES).not.toContain("folder-content-type");
|
|
45
|
+
});
|
|
46
|
+
(0, vitest_1.it)("role is read-only (list/get only, no save/delete)", () => {
|
|
47
|
+
(0, vitest_1.expect)(_registry_1.PUBLIC_LIST_TYPES).toContain("role");
|
|
48
|
+
(0, vitest_1.expect)(_registry_1.SAVE_TYPES).not.toContain("role");
|
|
49
|
+
(0, vitest_1.expect)(_registry_1.DELETE_TYPES).not.toContain("role");
|
|
50
|
+
});
|
|
51
|
+
(0, vitest_1.it)("Groovy types match the previous GROOVY_TYPES set", () => {
|
|
52
|
+
const groovy = Object.keys(_registry_1.RESOURCE_REGISTRY).filter(_registry_1.isGroovyType);
|
|
53
|
+
(0, vitest_1.expect)(groovy.sort()).toEqual([...EXPECTED_GROOVY].sort());
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
(0, vitest_1.describe)("resource registry — every method name resolves on the api client", () => {
|
|
57
|
+
const allTypes = Object.keys(_registry_1.RESOURCE_REGISTRY);
|
|
58
|
+
(0, vitest_1.it)("every list method exists", () => {
|
|
59
|
+
for (const type of allTypes) {
|
|
60
|
+
const m = _registry_1.RESOURCE_REGISTRY[type].list;
|
|
61
|
+
(0, vitest_1.expect)(typeof api[m], `${type}.list → ${m}`).toBe("function");
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
(0, vitest_1.it)("every save method exists", () => {
|
|
65
|
+
for (const type of allTypes) {
|
|
66
|
+
const m = _registry_1.RESOURCE_REGISTRY[type].save;
|
|
67
|
+
if (m)
|
|
68
|
+
(0, vitest_1.expect)(typeof api[m], `${type}.save → ${m}`).toBe("function");
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)("every delete method exists", () => {
|
|
72
|
+
for (const type of allTypes) {
|
|
73
|
+
const m = _registry_1.RESOURCE_REGISTRY[type].delete;
|
|
74
|
+
if (m)
|
|
75
|
+
(0, vitest_1.expect)(typeof api[m], `${type}.delete → ${m}`).toBe("function");
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.describe)("resource registry — dispatch", () => {
|
|
80
|
+
(0, vitest_1.it)("listResource calls the registered list method", async () => {
|
|
81
|
+
const calls = [];
|
|
82
|
+
const fake = { listTriggers: async () => { calls.push("listTriggers"); return [{ _id: "1" }]; } };
|
|
83
|
+
const result = await (0, _registry_1.listResource)(fake, "trigger");
|
|
84
|
+
(0, vitest_1.expect)(calls).toEqual(["listTriggers"]);
|
|
85
|
+
(0, vitest_1.expect)(result).toEqual([{ _id: "1" }]);
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.it)("saveResource threads the isNew arg for websocket/auth-module", async () => {
|
|
88
|
+
const seen = [];
|
|
89
|
+
const fake = { saveWebsocket: async (...args) => { seen.push(args); return {}; } };
|
|
90
|
+
await (0, _registry_1.saveResource)(fake, "websocket", { name: "n" }); // no _id ⇒ isNew true
|
|
91
|
+
(0, vitest_1.expect)(seen[0]).toEqual([{ name: "n" }, true]);
|
|
92
|
+
});
|
|
93
|
+
(0, vitest_1.it)("saveResource passes a single arg for plain types", async () => {
|
|
94
|
+
const seen = [];
|
|
95
|
+
const fake = { saveTrigger: async (...args) => { seen.push(args); return {}; } };
|
|
96
|
+
await (0, _registry_1.saveResource)(fake, "trigger", { _id: "x" });
|
|
97
|
+
(0, vitest_1.expect)(seen[0]).toEqual([{ _id: "x" }]);
|
|
98
|
+
});
|
|
99
|
+
(0, vitest_1.it)("deleteResource throws for a type that does not support delete", () => {
|
|
100
|
+
(0, vitest_1.expect)(() => (0, _registry_1.deleteResource)({}, "folder-content-type", "id")).toThrow("does not support delete");
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=_registry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_registry.test.js","sourceRoot":"","sources":["../../../src/mcp/tools/_registry.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure authorization engine mirroring SecurityFilter.doFilter from funifier-service.
|
|
3
|
+
* No I/O, no imports beyond types — fully unit-testable against a transcribed table.
|
|
4
|
+
*
|
|
5
|
+
* Source: SecurityFilter.java (funifier-service)
|
|
6
|
+
* Each rule carries a line reference so source drift can be detected via validate:skills claims.
|
|
7
|
+
*/
|
|
8
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | string;
|
|
9
|
+
export interface ScopeDecision {
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
rule: "public-path" | "all" | "exact" | "fallback-m1" | "fallback-m2" | "special-actionlog" | "special-mobile-device" | "database-keyword-missing" | "denied";
|
|
12
|
+
matchedToken?: string;
|
|
13
|
+
/** Minimal tokens that WOULD authorize this call — used to populate missing-findings. */
|
|
14
|
+
requiredTokens: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Non-path-auditable tokens: their usage cannot be proven or disproven from a path manifest.
|
|
18
|
+
* These are always classified `manual-review`, never `excess`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const MANUAL_REVIEW_TOKENS: ReadonlySet<string>;
|
|
21
|
+
/** SecurityFilter.java:85-86: strip "/v3/", replace "/" → "_". */
|
|
22
|
+
export declare function entityFull(path: string): string;
|
|
23
|
+
/** SecurityFilter.java:226-227: GET→read, POST/PUT→write, else lowercase. */
|
|
24
|
+
export declare function verbFor(method: HttpMethod): string;
|
|
25
|
+
/** SecurityFilter.java:108-151: true when the path requires no scope. */
|
|
26
|
+
export declare function isPublicPath(method: HttpMethod, path: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Evaluate whether `scope` authorizes `method` on `path`, reproducing the exact decision
|
|
29
|
+
* tree of SecurityFilter.doFilter.
|
|
30
|
+
*/
|
|
31
|
+
export declare function evaluateScope(scope: string, method: HttpMethod, path: string): ScopeDecision;
|
|
32
|
+
/**
|
|
33
|
+
* Returns the subset of tokens in `scope` that actually authorized at least one entry
|
|
34
|
+
* in `entries`. Used for excess-token calculation in the audit diff.
|
|
35
|
+
*/
|
|
36
|
+
export declare function usedTokens(scope: string, entries: ReadonlyArray<{
|
|
37
|
+
method: HttpMethod;
|
|
38
|
+
path: string;
|
|
39
|
+
}>): Set<string>;
|
|
40
|
+
//# sourceMappingURL=_scope-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_scope-engine.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/_scope-engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EACA,aAAa,GACb,KAAK,GACL,OAAO,GACP,aAAa,GACb,aAAa,GACb,mBAAmB,GACnB,uBAAuB,GACvB,0BAA0B,GAC1B,QAAQ,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAKnD,CAAC;AAOH,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,6EAA6E;AAC7E,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAIlD;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQtE;AAOD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CA0H5F;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC3D,GAAG,CAAC,MAAM,CAAC,CAoBb"}
|