drupal-mcp-connector 2.24.0 → 2.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/package.json +1 -1
- package/src/lib/validate.js +0 -44
- package/src/lib/workflow-prompts.js +1 -25
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.24.1] - 2026-09-29
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
13
|
+
- **Unused validate helpers and stale workflow-prompt exports.** `clampLimit` /
|
|
14
|
+
`MAX_PAGE_LIMIT` and `validateFieldName` / `FIELD_NAME_RE` had no callers.
|
|
15
|
+
`workflowIndex`, `WORKFLOW_LIMITS`, and the unused `toolNameToPromptName`
|
|
16
|
+
re-export are gone. Filter/sort field names stay unvalidated so JSON:API
|
|
17
|
+
relationship paths keep working; `URLSearchParams` remains the T3 control.
|
|
18
|
+
|
|
10
19
|
## [2.24.0] - 2026-09-29
|
|
11
20
|
|
|
12
21
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drupal-mcp-connector",
|
|
3
|
-
"version": "2.24.
|
|
3
|
+
"version": "2.24.1",
|
|
4
4
|
"description": "Drupal MCP Connector — multi-site MCP server for Drupal with JSON:API and GraphQL, governed writes, draft translations, content tools, audit reports, and an SSH Drush bridge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/lib/validate.js
CHANGED
|
@@ -196,26 +196,6 @@ export function validateBaseUrl(url, siteName = "site") {
|
|
|
196
196
|
return url.replace(/\/$/, "");
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
// ---------------------------------------------------------------------------
|
|
200
|
-
// Pagination limit guard
|
|
201
|
-
// Prevents accidentally requesting thousands of records in a single call.
|
|
202
|
-
// ---------------------------------------------------------------------------
|
|
203
|
-
|
|
204
|
-
const MAX_PAGE_LIMIT = 200;
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Clamp a page limit to a safe maximum, falling back to a default for
|
|
208
|
-
* non-numeric or out-of-range input.
|
|
209
|
-
* @param {*} value Requested limit (any type; coerced to Number).
|
|
210
|
-
* @param {number} [defaultVal] Value returned for invalid/<1 input.
|
|
211
|
-
* @returns {number} A limit in the range [1, MAX_PAGE_LIMIT].
|
|
212
|
-
*/
|
|
213
|
-
export function clampLimit(value, defaultVal = 20) {
|
|
214
|
-
const n = Number(value);
|
|
215
|
-
if (!Number.isFinite(n) || n < 1) return defaultVal;
|
|
216
|
-
return Math.min(n, MAX_PAGE_LIMIT);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
199
|
// ---------------------------------------------------------------------------
|
|
220
200
|
// Local file upload path allowlist (#137 / audit C1)
|
|
221
201
|
// ---------------------------------------------------------------------------
|
|
@@ -329,27 +309,3 @@ export function assertUploadPathAllowed(filePath) {
|
|
|
329
309
|
}
|
|
330
310
|
return real;
|
|
331
311
|
}
|
|
332
|
-
|
|
333
|
-
// ---------------------------------------------------------------------------
|
|
334
|
-
// Field name sanitization (prevent crafted field names in JSON:API filters)
|
|
335
|
-
// ---------------------------------------------------------------------------
|
|
336
|
-
|
|
337
|
-
const FIELD_NAME_RE = /^[a-zA-Z_][a-zA-Z0-9_.]*$/;
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Validate a Drupal field machine name used in JSON:API filter parameters.
|
|
341
|
-
* Allows dotted paths (e.g. "field.subfield") for nested references.
|
|
342
|
-
* @param {string} value The field name to validate.
|
|
343
|
-
* @param {string} [fieldName] Human-readable name for error messages.
|
|
344
|
-
* @returns {string} The validated value.
|
|
345
|
-
* @throws {Error} if the value is not a valid field name.
|
|
346
|
-
*/
|
|
347
|
-
export function validateFieldName(value, fieldName = "field") {
|
|
348
|
-
if (typeof value !== "string" || !FIELD_NAME_RE.test(value)) {
|
|
349
|
-
throw new Error(
|
|
350
|
-
`${fieldName} "${value}" is not a valid field name. ` +
|
|
351
|
-
"Expected format: field_example or field.subfield"
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
return value;
|
|
355
|
-
}
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
* docs/module-workflows.md.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { sourceText
|
|
9
|
+
import { sourceText } from "./tool-prompts.js";
|
|
10
10
|
|
|
11
11
|
const ID_RE = /^[a-z][a-z0-9_]{0,47}$/;
|
|
12
12
|
const ARG_RE = /^[a-z][a-z0-9_]{0,47}$/;
|
|
13
|
-
const MAX_DESCRIPTION = 1024;
|
|
14
13
|
const MAX_INSTRUCTIONS = 8192;
|
|
15
14
|
const MAX_ARG_VALUE = 200;
|
|
16
15
|
const MAX_WORKFLOWS = 64;
|
|
@@ -465,26 +464,3 @@ export function replaceModuleWorkflows(workflows) {
|
|
|
465
464
|
export function lookupWorkflow(name) {
|
|
466
465
|
return INDEX.get(name);
|
|
467
466
|
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Index used by tests.
|
|
471
|
-
*
|
|
472
|
-
* @param {object[]} workflows
|
|
473
|
-
* @returns {Map<string, {readOnly: boolean, builtin: boolean, publicTools: string[]}>}
|
|
474
|
-
*/
|
|
475
|
-
export function workflowIndex(workflows) {
|
|
476
|
-
return new Map((workflows ?? []).map((wf) => [wf.name, {
|
|
477
|
-
readOnly: wf.readOnly,
|
|
478
|
-
builtin: wf.builtin,
|
|
479
|
-
publicTools: wf.publicTools,
|
|
480
|
-
}]));
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
export const WORKFLOW_LIMITS = {
|
|
484
|
-
MAX_DESCRIPTION,
|
|
485
|
-
MAX_INSTRUCTIONS,
|
|
486
|
-
MAX_WORKFLOWS,
|
|
487
|
-
};
|
|
488
|
-
|
|
489
|
-
// Re-export for callers that already import tool prompt hyphenation.
|
|
490
|
-
export { toolNameToPromptName };
|