@itm-platform/mcp-server 1.0.0 → 1.0.2
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 +173 -141
- package/package.json +2 -2
- package/dist/src/auth/api-key-auth.d.ts +0 -3
- package/dist/src/auth/api-key-auth.d.ts.map +0 -1
- package/dist/src/auth/api-key-auth.js +0 -53
- package/dist/src/auth/api-key-auth.js.map +0 -1
- package/dist/src/auth/effective-user-context.d.ts +0 -16
- package/dist/src/auth/effective-user-context.d.ts.map +0 -1
- package/dist/src/auth/effective-user-context.js +0 -9
- package/dist/src/auth/effective-user-context.js.map +0 -1
- package/dist/src/auth/license-resolver.d.ts +0 -6
- package/dist/src/auth/license-resolver.d.ts.map +0 -1
- package/dist/src/auth/license-resolver.js +0 -12
- package/dist/src/auth/license-resolver.js.map +0 -1
- package/dist/src/auth/oauth-auth.d.ts +0 -22
- package/dist/src/auth/oauth-auth.d.ts.map +0 -1
- package/dist/src/auth/oauth-auth.js +0 -34
- package/dist/src/auth/oauth-auth.js.map +0 -1
- package/dist/src/auth/oauth-metadata.d.ts +0 -10
- package/dist/src/auth/oauth-metadata.d.ts.map +0 -1
- package/dist/src/auth/oauth-metadata.js +0 -8
- package/dist/src/auth/oauth-metadata.js.map +0 -1
- package/dist/src/auth/token-extraction.d.ts +0 -2
- package/dist/src/auth/token-extraction.d.ts.map +0 -1
- package/dist/src/auth/token-extraction.js +0 -7
- package/dist/src/auth/token-extraction.js.map +0 -1
- package/dist/src/clients/audit-client.d.ts +0 -25
- package/dist/src/clients/audit-client.d.ts.map +0 -1
- package/dist/src/clients/audit-client.js +0 -37
- package/dist/src/clients/audit-client.js.map +0 -1
- package/dist/src/clients/datamart-client.d.ts +0 -16
- package/dist/src/clients/datamart-client.d.ts.map +0 -1
- package/dist/src/clients/datamart-client.js +0 -32
- package/dist/src/clients/datamart-client.js.map +0 -1
- package/dist/src/clients/index.d.ts +0 -18
- package/dist/src/clients/index.d.ts.map +0 -1
- package/dist/src/clients/index.js +0 -11
- package/dist/src/clients/index.js.map +0 -1
- package/dist/src/clients/rest-client.d.ts +0 -14
- package/dist/src/clients/rest-client.d.ts.map +0 -1
- package/dist/src/clients/rest-client.js +0 -29
- package/dist/src/clients/rest-client.js.map +0 -1
- package/dist/src/logger.d.ts +0 -3
- package/dist/src/logger.d.ts.map +0 -1
- package/dist/src/logger.js +0 -37
- package/dist/src/logger.js.map +0 -1
- package/dist/src/prompts/portfolio-overview.d.ts +0 -3
- package/dist/src/prompts/portfolio-overview.d.ts.map +0 -1
- package/dist/src/prompts/portfolio-overview.js +0 -21
- package/dist/src/prompts/portfolio-overview.js.map +0 -1
- package/dist/src/prompts/project-status.d.ts +0 -3
- package/dist/src/prompts/project-status.d.ts.map +0 -1
- package/dist/src/prompts/project-status.js +0 -24
- package/dist/src/prompts/project-status.js.map +0 -1
- package/dist/src/prompts/risk-analysis.d.ts +0 -3
- package/dist/src/prompts/risk-analysis.d.ts.map +0 -1
- package/dist/src/prompts/risk-analysis.js +0 -23
- package/dist/src/prompts/risk-analysis.js.map +0 -1
- package/dist/src/prompts/team-workload.d.ts +0 -3
- package/dist/src/prompts/team-workload.d.ts.map +0 -1
- package/dist/src/prompts/team-workload.js +0 -29
- package/dist/src/prompts/team-workload.js.map +0 -1
- package/dist/src/resources/calendars.d.ts +0 -4
- package/dist/src/resources/calendars.d.ts.map +0 -1
- package/dist/src/resources/calendars.js +0 -18
- package/dist/src/resources/calendars.js.map +0 -1
- package/dist/src/resources/schemas.d.ts +0 -4
- package/dist/src/resources/schemas.d.ts.map +0 -1
- package/dist/src/resources/schemas.js +0 -34
- package/dist/src/resources/schemas.js.map +0 -1
- package/dist/src/server.d.ts +0 -2
- package/dist/src/server.d.ts.map +0 -1
- package/dist/src/server.js +0 -213
- package/dist/src/server.js.map +0 -1
- package/dist/src/tools/datamart.d.ts +0 -17
- package/dist/src/tools/datamart.d.ts.map +0 -1
- package/dist/src/tools/datamart.js +0 -68
- package/dist/src/tools/datamart.js.map +0 -1
- package/dist/src/tools/financials.d.ts +0 -4
- package/dist/src/tools/financials.d.ts.map +0 -1
- package/dist/src/tools/financials.js +0 -50
- package/dist/src/tools/financials.js.map +0 -1
- package/dist/src/tools/graphql-queries.d.ts +0 -22
- package/dist/src/tools/graphql-queries.d.ts.map +0 -1
- package/dist/src/tools/graphql-queries.js +0 -26
- package/dist/src/tools/graphql-queries.js.map +0 -1
- package/dist/src/tools/portfolio.d.ts +0 -10
- package/dist/src/tools/portfolio.d.ts.map +0 -1
- package/dist/src/tools/portfolio.js +0 -54
- package/dist/src/tools/portfolio.js.map +0 -1
- package/dist/src/tools/projects.d.ts +0 -42
- package/dist/src/tools/projects.d.ts.map +0 -1
- package/dist/src/tools/projects.js +0 -73
- package/dist/src/tools/projects.js.map +0 -1
- package/dist/src/tools/reference-data.d.ts +0 -4
- package/dist/src/tools/reference-data.d.ts.map +0 -1
- package/dist/src/tools/reference-data.js +0 -19
- package/dist/src/tools/reference-data.js.map +0 -1
- package/dist/src/tools/risks-issues.d.ts +0 -4
- package/dist/src/tools/risks-issues.d.ts.map +0 -1
- package/dist/src/tools/risks-issues.js +0 -33
- package/dist/src/tools/risks-issues.js.map +0 -1
- package/dist/src/tools/services.d.ts +0 -41
- package/dist/src/tools/services.d.ts.map +0 -1
- package/dist/src/tools/services.js +0 -67
- package/dist/src/tools/services.js.map +0 -1
- package/dist/src/tools/tasks.d.ts +0 -4
- package/dist/src/tools/tasks.d.ts.map +0 -1
- package/dist/src/tools/tasks.js +0 -17
- package/dist/src/tools/tasks.js.map +0 -1
- package/dist/src/tools/users.d.ts +0 -4
- package/dist/src/tools/users.d.ts.map +0 -1
- package/dist/src/tools/users.js +0 -30
- package/dist/src/tools/users.js.map +0 -1
- package/dist/src/tools/write-tools.d.ts +0 -75
- package/dist/src/tools/write-tools.d.ts.map +0 -1
- package/dist/src/tools/write-tools.js +0 -193
- package/dist/src/tools/write-tools.js.map +0 -1
- package/dist/src/validation/query-validator.d.ts +0 -15
- package/dist/src/validation/query-validator.d.ts.map +0 -1
- package/dist/src/validation/query-validator.js +0 -141
- package/dist/src/validation/query-validator.js.map +0 -1
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { hashParameters } from '../clients/audit-client.js';
|
|
3
|
-
import { createLogger } from '../logger.js';
|
|
4
|
-
import { hasScope } from '../auth/effective-user-context.js';
|
|
5
|
-
export const STALE_AFTER_WRITE_NOTICE = 'Note: DataMart reads (search_projects, get_project, list_project_tasks, etc.) ' +
|
|
6
|
-
'may return stale data for 5-60 seconds after a write due to eventual consistency. ' +
|
|
7
|
-
'The confirmed state above is from the v2 REST API (source of truth).';
|
|
8
|
-
export function buildInsufficientScopeResponse() {
|
|
9
|
-
return {
|
|
10
|
-
content: [{ type: 'text', text: 'Error: insufficient_scope -- the mcp:write scope is required for write operations' }],
|
|
11
|
-
isError: true,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
export function buildWriteResponse(data) {
|
|
15
|
-
return {
|
|
16
|
-
content: [
|
|
17
|
-
{ type: 'text', text: JSON.stringify(data, null, 2) },
|
|
18
|
-
{ type: 'text', text: STALE_AFTER_WRITE_NOTICE },
|
|
19
|
-
],
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
export async function auditWrap(clients, toolName, args, userContext, operation) {
|
|
23
|
-
const start = Date.now();
|
|
24
|
-
try {
|
|
25
|
-
const result = await operation();
|
|
26
|
-
try {
|
|
27
|
-
await clients.audit.log({
|
|
28
|
-
timestamp: new Date().toISOString(),
|
|
29
|
-
userId: userContext.userId,
|
|
30
|
-
accountId: userContext.accountId,
|
|
31
|
-
toolName,
|
|
32
|
-
parametersHash: hashParameters(args),
|
|
33
|
-
success: true,
|
|
34
|
-
aiClientId: userContext.aiClientId,
|
|
35
|
-
durationMs: Date.now() - start,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// fire-and-forget: audit failure must not break writes
|
|
40
|
-
}
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
try {
|
|
45
|
-
await clients.audit.log({
|
|
46
|
-
timestamp: new Date().toISOString(),
|
|
47
|
-
userId: userContext.userId,
|
|
48
|
-
accountId: userContext.accountId,
|
|
49
|
-
toolName,
|
|
50
|
-
parametersHash: hashParameters(args),
|
|
51
|
-
success: false,
|
|
52
|
-
error: err instanceof Error ? err.message : String(err),
|
|
53
|
-
aiClientId: userContext.aiClientId,
|
|
54
|
-
durationMs: Date.now() - start,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// fire-and-forget
|
|
59
|
-
}
|
|
60
|
-
throw err;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
export function splitCreateTaskArgs(args) {
|
|
64
|
-
const { projectId, ...body } = args;
|
|
65
|
-
return { path: `projects/${projectId}/tasks`, body };
|
|
66
|
-
}
|
|
67
|
-
export function splitUpdateTaskArgs(args) {
|
|
68
|
-
const { projectId, taskId, ...body } = args;
|
|
69
|
-
return { path: `projects/${projectId}/tasks/${taskId}`, body };
|
|
70
|
-
}
|
|
71
|
-
export function splitCreateRiskArgs(args) {
|
|
72
|
-
const { projectId, ...body } = args;
|
|
73
|
-
return { path: `projects/${projectId}/risks`, body };
|
|
74
|
-
}
|
|
75
|
-
export function splitCreateIssueArgs(args) {
|
|
76
|
-
const { projectId, ...body } = args;
|
|
77
|
-
return { path: `projects/${projectId}/issues`, body };
|
|
78
|
-
}
|
|
79
|
-
export function splitUpdateProjectArgs(args) {
|
|
80
|
-
const { projectId, ...body } = args;
|
|
81
|
-
return { path: `projects/${projectId}`, body };
|
|
82
|
-
}
|
|
83
|
-
export function registerWriteTools(server, clients, userContext, log, effectiveUserContext) {
|
|
84
|
-
const l = log ?? createLogger('write-tools');
|
|
85
|
-
server.registerTool('create_task', {
|
|
86
|
-
description: 'Create a new task in a project. Returns the created task from v2 REST (source of truth). Use get_reference_data with entity "gettaskstatuses", "gettasktypes", or "gettaskpriorities" to discover valid IDs.',
|
|
87
|
-
inputSchema: {
|
|
88
|
-
projectId: z.number().describe('The project ID to create the task in'),
|
|
89
|
-
Name: z.string().describe('Task name (required)'),
|
|
90
|
-
Description: z.string().optional().describe('Task description'),
|
|
91
|
-
StatusId: z.number().optional().describe('Task status ID'),
|
|
92
|
-
TypeId: z.number().optional().describe('Task type ID'),
|
|
93
|
-
PriorityId: z.number().optional().describe('Task priority ID'),
|
|
94
|
-
StartDate: z.string().optional().describe('Start date (ISO 8601)'),
|
|
95
|
-
EndDate: z.string().optional().describe('End date (ISO 8601)'),
|
|
96
|
-
AssignedToUserId: z.number().optional().describe('User ID to assign the task to'),
|
|
97
|
-
},
|
|
98
|
-
}, async (args) => {
|
|
99
|
-
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
100
|
-
return buildInsufficientScopeResponse();
|
|
101
|
-
const { path, body } = splitCreateTaskArgs(args);
|
|
102
|
-
l.info({ tool: 'create_task', projectId: args.projectId }, 'Write tool invoked');
|
|
103
|
-
const data = await auditWrap(clients, 'create_task', args, userContext, () => clients.rest.post(path, body));
|
|
104
|
-
l.debug({ tool: 'create_task', projectId: args.projectId }, 'Write tool completed');
|
|
105
|
-
return buildWriteResponse(data);
|
|
106
|
-
});
|
|
107
|
-
server.registerTool('update_task', {
|
|
108
|
-
description: 'Update task fields (status, dates, assignee, progress, etc.) via PATCH. Only send the fields you want to change. Returns the updated task from v2 REST.',
|
|
109
|
-
inputSchema: {
|
|
110
|
-
projectId: z.number().describe('The project ID containing the task'),
|
|
111
|
-
taskId: z.number().describe('The task ID to update'),
|
|
112
|
-
Name: z.string().optional().describe('New task name'),
|
|
113
|
-
Description: z.string().optional().describe('New description'),
|
|
114
|
-
StatusId: z.number().optional().describe('New status ID'),
|
|
115
|
-
TypeId: z.number().optional().describe('New type ID'),
|
|
116
|
-
PriorityId: z.number().optional().describe('New priority ID'),
|
|
117
|
-
StartDate: z.string().optional().describe('New start date (ISO 8601)'),
|
|
118
|
-
EndDate: z.string().optional().describe('New end date (ISO 8601)'),
|
|
119
|
-
PercentComplete: z.number().min(0).max(100).optional().describe('Completion percentage (0-100)'),
|
|
120
|
-
AssignedToUserId: z.number().optional().describe('User ID to reassign to'),
|
|
121
|
-
},
|
|
122
|
-
}, async (args) => {
|
|
123
|
-
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
124
|
-
return buildInsufficientScopeResponse();
|
|
125
|
-
const { path, body } = splitUpdateTaskArgs(args);
|
|
126
|
-
l.info({ tool: 'update_task', projectId: args.projectId, taskId: args.taskId }, 'Write tool invoked');
|
|
127
|
-
const data = await auditWrap(clients, 'update_task', args, userContext, () => clients.rest.patch(path, body));
|
|
128
|
-
l.debug({ tool: 'update_task', projectId: args.projectId, taskId: args.taskId }, 'Write tool completed');
|
|
129
|
-
return buildWriteResponse(data);
|
|
130
|
-
});
|
|
131
|
-
server.registerTool('create_risk', {
|
|
132
|
-
description: 'Log a new risk in a project. Returns the created risk from v2 REST. Use get_reference_data with entity "riskstatuses" or "risktypes" to discover valid IDs.',
|
|
133
|
-
inputSchema: {
|
|
134
|
-
projectId: z.number().describe('The project ID to create the risk in'),
|
|
135
|
-
Name: z.string().describe('Risk name (required)'),
|
|
136
|
-
Description: z.string().optional().describe('Risk description'),
|
|
137
|
-
StatusId: z.number().optional().describe('Risk status ID'),
|
|
138
|
-
TypeId: z.number().optional().describe('Risk type ID'),
|
|
139
|
-
Probability: z.number().optional().describe('Probability level'),
|
|
140
|
-
Impact: z.number().optional().describe('Impact level'),
|
|
141
|
-
MitigationPlan: z.string().optional().describe('Mitigation plan description'),
|
|
142
|
-
},
|
|
143
|
-
}, async (args) => {
|
|
144
|
-
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
145
|
-
return buildInsufficientScopeResponse();
|
|
146
|
-
const { path, body } = splitCreateRiskArgs(args);
|
|
147
|
-
l.info({ tool: 'create_risk', projectId: args.projectId }, 'Write tool invoked');
|
|
148
|
-
const data = await auditWrap(clients, 'create_risk', args, userContext, () => clients.rest.post(path, body));
|
|
149
|
-
l.debug({ tool: 'create_risk', projectId: args.projectId }, 'Write tool completed');
|
|
150
|
-
return buildWriteResponse(data);
|
|
151
|
-
});
|
|
152
|
-
server.registerTool('create_issue', {
|
|
153
|
-
description: 'Log a new issue in a project. Returns the created issue from v2 REST. Use get_reference_data with entity "issuestatuses" or "issuetypes" to discover valid IDs.',
|
|
154
|
-
inputSchema: {
|
|
155
|
-
projectId: z.number().describe('The project ID to create the issue in'),
|
|
156
|
-
Name: z.string().describe('Issue name (required)'),
|
|
157
|
-
Description: z.string().optional().describe('Issue description'),
|
|
158
|
-
StatusId: z.number().optional().describe('Issue status ID'),
|
|
159
|
-
TypeId: z.number().optional().describe('Issue type ID'),
|
|
160
|
-
Severity: z.number().optional().describe('Severity level'),
|
|
161
|
-
Resolution: z.string().optional().describe('Resolution description'),
|
|
162
|
-
},
|
|
163
|
-
}, async (args) => {
|
|
164
|
-
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
165
|
-
return buildInsufficientScopeResponse();
|
|
166
|
-
const { path, body } = splitCreateIssueArgs(args);
|
|
167
|
-
l.info({ tool: 'create_issue', projectId: args.projectId }, 'Write tool invoked');
|
|
168
|
-
const data = await auditWrap(clients, 'create_issue', args, userContext, () => clients.rest.post(path, body));
|
|
169
|
-
l.debug({ tool: 'create_issue', projectId: args.projectId }, 'Write tool completed');
|
|
170
|
-
return buildWriteResponse(data);
|
|
171
|
-
});
|
|
172
|
-
server.registerTool('update_project', {
|
|
173
|
-
description: 'Update project fields (name, status, dates, priority, etc.) via PATCH. Only send the fields you want to change. Returns the updated project from v2 REST.',
|
|
174
|
-
inputSchema: {
|
|
175
|
-
projectId: z.number().describe('The project ID to update'),
|
|
176
|
-
Name: z.string().optional().describe('New project name'),
|
|
177
|
-
Description: z.string().optional().describe('New project description'),
|
|
178
|
-
StatusId: z.number().optional().describe('New project status ID'),
|
|
179
|
-
PriorityId: z.number().optional().describe('New priority ID'),
|
|
180
|
-
StartDate: z.string().optional().describe('New start date (ISO 8601)'),
|
|
181
|
-
EndDate: z.string().optional().describe('New end date (ISO 8601)'),
|
|
182
|
-
},
|
|
183
|
-
}, async (args) => {
|
|
184
|
-
if (effectiveUserContext && !hasScope(effectiveUserContext, 'mcp:write'))
|
|
185
|
-
return buildInsufficientScopeResponse();
|
|
186
|
-
const { path, body } = splitUpdateProjectArgs(args);
|
|
187
|
-
l.info({ tool: 'update_project', projectId: args.projectId }, 'Write tool invoked');
|
|
188
|
-
const data = await auditWrap(clients, 'update_project', args, userContext, () => clients.rest.patch(path, body));
|
|
189
|
-
l.debug({ tool: 'update_project', projectId: args.projectId }, 'Write tool completed');
|
|
190
|
-
return buildWriteResponse(data);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
//# sourceMappingURL=write-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"write-tools.js","sourceRoot":"","sources":["../../../src/tools/write-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface ValidationResult {
|
|
2
|
-
ok: boolean;
|
|
3
|
-
error?: {
|
|
4
|
-
code: string;
|
|
5
|
-
message: string;
|
|
6
|
-
};
|
|
7
|
-
warning?: string;
|
|
8
|
-
}
|
|
9
|
-
interface DataMartBody {
|
|
10
|
-
query?: string;
|
|
11
|
-
variables?: Record<string, unknown>;
|
|
12
|
-
}
|
|
13
|
-
export declare function validateDataMartQuery(body: DataMartBody | null | undefined): ValidationResult;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=query-validator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query-validator.d.ts","sourceRoot":"","sources":["../../../src/validation/query-validator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAiGD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAAG,gBAAgB,CA8C7F"}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
// SYNC: Ported from ITM.PMPilot (inference/datamart/validators.js).
|
|
2
|
-
// If you change the allowed operators or aggregation stages here, update the PMPilot copy too.
|
|
3
|
-
//
|
|
4
|
-
// Differences from PMPilot's copy:
|
|
5
|
-
// - TypeScript types
|
|
6
|
-
// - Adds $not to ALLOWED_WHERE_OPERATORS (allowed by DataMart's validate.ts)
|
|
7
|
-
const ALLOWED_WHERE_OPERATORS = new Set([
|
|
8
|
-
'$eq', '$ne', '$in', '$nin', '$gt', '$gte', '$lt', '$lte',
|
|
9
|
-
'$regex', '$options', '$exists', '$not', '$and', '$or', '$nor',
|
|
10
|
-
]);
|
|
11
|
-
const ALLOWED_AGG_STAGES = new Set([
|
|
12
|
-
'$match', '$project', '$group', '$sort', '$limit', '$skip',
|
|
13
|
-
'$unwind', '$addFields', '$set', '$unset',
|
|
14
|
-
]);
|
|
15
|
-
function isAggregateQuery(query) {
|
|
16
|
-
return /\baggregateComponents\s*\(/.test(query);
|
|
17
|
-
}
|
|
18
|
-
function isListQuery(query) {
|
|
19
|
-
return /\bcomponents\s*\(/.test(query) && !isAggregateQuery(query);
|
|
20
|
-
}
|
|
21
|
-
function selectsJsonSubfields(query) {
|
|
22
|
-
return /\bcomponent\s*\{/.test(query)
|
|
23
|
-
|| /\bcomponents\s*\{/.test(query)
|
|
24
|
-
|| /\baggregateComponents\s*\{/.test(query);
|
|
25
|
-
}
|
|
26
|
-
function pipelineHasFacet(p) {
|
|
27
|
-
return p.some(st => st && typeof st === 'object' && Object.prototype.hasOwnProperty.call(st, '$facet'));
|
|
28
|
-
}
|
|
29
|
-
function validateWhereObject(whereObj, path = '$') {
|
|
30
|
-
if (whereObj == null || typeof whereObj !== 'object')
|
|
31
|
-
return { ok: true };
|
|
32
|
-
for (const [key, value] of Object.entries(whereObj)) {
|
|
33
|
-
if (key.startsWith('$')) {
|
|
34
|
-
if (!ALLOWED_WHERE_OPERATORS.has(key)) {
|
|
35
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Disallowed operator ${key} at ${path}` } };
|
|
36
|
-
}
|
|
37
|
-
if (key === '$and' || key === '$or' || key === '$nor') {
|
|
38
|
-
if (Array.isArray(value)) {
|
|
39
|
-
for (let i = 0; i < value.length; i++) {
|
|
40
|
-
const res = validateWhereObject(value[i], `${path}.${key}[${i}]`);
|
|
41
|
-
if (!res.ok)
|
|
42
|
-
return res;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
// $not wraps a single condition object
|
|
48
|
-
if (key === '$not') {
|
|
49
|
-
if (value && typeof value === 'object') {
|
|
50
|
-
const res = validateWhereObject(value, `${path}.${key}`);
|
|
51
|
-
if (!res.ok)
|
|
52
|
-
return res;
|
|
53
|
-
}
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (value && typeof value === 'object') {
|
|
58
|
-
const res = validateWhereObject(value, `${path}.${key}`);
|
|
59
|
-
if (!res.ok)
|
|
60
|
-
return res;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return { ok: true };
|
|
64
|
-
}
|
|
65
|
-
function validatePipeline(pipeline) {
|
|
66
|
-
if (!Array.isArray(pipeline)) {
|
|
67
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation pipeline must be an array' } };
|
|
68
|
-
}
|
|
69
|
-
if (pipeline.length === 0) {
|
|
70
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation pipeline must include a final $limit stage' } };
|
|
71
|
-
}
|
|
72
|
-
for (let i = 0; i < pipeline.length; i++) {
|
|
73
|
-
const stage = pipeline[i];
|
|
74
|
-
const keys = stage && typeof stage === 'object' ? Object.keys(stage) : [];
|
|
75
|
-
if (keys.length !== 1) {
|
|
76
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Aggregation stage at index ${i} must have exactly one key` } };
|
|
77
|
-
}
|
|
78
|
-
if (!ALLOWED_AGG_STAGES.has(keys[0])) {
|
|
79
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: `Forbidden stage ${keys[0]} at index ${i}` } };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
const last = pipeline[pipeline.length - 1];
|
|
83
|
-
const lastKey = last && typeof last === 'object' ? Object.keys(last)[0] : null;
|
|
84
|
-
if (lastKey !== '$limit') {
|
|
85
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Aggregation must end with a final $limit stage' } };
|
|
86
|
-
}
|
|
87
|
-
const limitVal = last['$limit'];
|
|
88
|
-
if (typeof limitVal !== 'number' || !Number.isFinite(limitVal) || limitVal <= 0) {
|
|
89
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Final $limit must be a positive number' } };
|
|
90
|
-
}
|
|
91
|
-
if (limitVal > 1000) {
|
|
92
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Final $limit must be ≤ 1000' } };
|
|
93
|
-
}
|
|
94
|
-
return { ok: true };
|
|
95
|
-
}
|
|
96
|
-
export function validateDataMartQuery(body) {
|
|
97
|
-
if (!body || typeof body !== 'object')
|
|
98
|
-
return { ok: true };
|
|
99
|
-
const query = body.query ?? '';
|
|
100
|
-
const variables = (body.variables ?? {});
|
|
101
|
-
if (selectsJsonSubfields(query)) {
|
|
102
|
-
return { ok: false, error: { code: 'CLIENT_VALIDATION', message: 'Do not select subfields of JSON; project fields via variables (proj / w / p) instead.' } };
|
|
103
|
-
}
|
|
104
|
-
if (isAggregateQuery(query)) {
|
|
105
|
-
const pipeline = variables.p ?? variables.pipeline;
|
|
106
|
-
const res = validatePipeline(pipeline);
|
|
107
|
-
if (!res.ok)
|
|
108
|
-
return res;
|
|
109
|
-
if (pipelineHasFacet(pipeline)) {
|
|
110
|
-
return {
|
|
111
|
-
ok: false,
|
|
112
|
-
error: {
|
|
113
|
-
code: 'CLIENT_VALIDATION',
|
|
114
|
-
message: 'Forbidden stage $facet. For totals use components(where...).total with limit=1, or run separate $count pipelines.',
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return { ok: true };
|
|
119
|
-
}
|
|
120
|
-
if (isListQuery(query)) {
|
|
121
|
-
const limit = variables.limit;
|
|
122
|
-
if (typeof limit === 'number' && limit > 100) {
|
|
123
|
-
return { ok: true, warning: 'High limit requested (>100). Server may clamp to 200.' };
|
|
124
|
-
}
|
|
125
|
-
const whereObj = variables.w ?? variables.where;
|
|
126
|
-
if (whereObj) {
|
|
127
|
-
const res = validateWhereObject(whereObj, '$.w');
|
|
128
|
-
if (!res.ok)
|
|
129
|
-
return res;
|
|
130
|
-
}
|
|
131
|
-
return { ok: true };
|
|
132
|
-
}
|
|
133
|
-
const genericWhere = variables.w ?? variables.where;
|
|
134
|
-
if (genericWhere) {
|
|
135
|
-
const res = validateWhereObject(genericWhere, '$.w');
|
|
136
|
-
if (!res.ok)
|
|
137
|
-
return res;
|
|
138
|
-
}
|
|
139
|
-
return { ok: true };
|
|
140
|
-
}
|
|
141
|
-
//# sourceMappingURL=query-validator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query-validator.js","sourceRoot":"","sources":["../../../src/validation/query-validator.ts"],"names":[],"mappings":"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"}
|