datadog-mcp 5.8.0 → 5.8.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 +90 -322
- package/dist/index.js +111 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -303622,7 +303622,8 @@ async function histogramEventsV2(api, params, limits, site) {
|
|
|
303622
303622
|
const fullQuery = buildEventQuery({
|
|
303623
303623
|
query: params.query,
|
|
303624
303624
|
sources: params.sources,
|
|
303625
|
-
tags: params.tags
|
|
303625
|
+
tags: params.tags,
|
|
303626
|
+
transitionType: params.transitionType
|
|
303626
303627
|
});
|
|
303627
303628
|
const cap = limits.maxEventsForHistogram;
|
|
303628
303629
|
const perPage = Math.max(1, Math.min(1e3, cap));
|
|
@@ -304394,7 +304395,8 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
|
|
|
304394
304395
|
tags,
|
|
304395
304396
|
bucket_by: histogramBucketBy,
|
|
304396
304397
|
timezone,
|
|
304397
|
-
cursor
|
|
304398
|
+
cursor,
|
|
304399
|
+
transitionType
|
|
304398
304400
|
},
|
|
304399
304401
|
limits,
|
|
304400
304402
|
site
|
|
@@ -304456,6 +304458,28 @@ function lookupVariable(path, variables) {
|
|
|
304456
304458
|
return String(cursor);
|
|
304457
304459
|
}
|
|
304458
304460
|
var TAG_REGEX = /\{\{\s*([#^/>])?\s*([^}]*?)\s*\}\}/g;
|
|
304461
|
+
var TAG_CONDITIONAL_HEAD = /^(is_match|is_exact_match)\b/;
|
|
304462
|
+
var QUOTED_ARG_REGEX = /"([^"]*)"/g;
|
|
304463
|
+
function parseTagConditionalHead(body, prefix) {
|
|
304464
|
+
const headMatch = TAG_CONDITIONAL_HEAD.exec(body);
|
|
304465
|
+
if (!headMatch?.[1]) {
|
|
304466
|
+
return null;
|
|
304467
|
+
}
|
|
304468
|
+
const conditional = headMatch[1];
|
|
304469
|
+
const args = [];
|
|
304470
|
+
QUOTED_ARG_REGEX.lastIndex = 0;
|
|
304471
|
+
let arg;
|
|
304472
|
+
while ((arg = QUOTED_ARG_REGEX.exec(body)) !== null) {
|
|
304473
|
+
args.push(arg[1] ?? "");
|
|
304474
|
+
}
|
|
304475
|
+
const [variable, ...comparisons] = args;
|
|
304476
|
+
if (variable === void 0 || variable === "" || comparisons.length === 0) {
|
|
304477
|
+
throw unsupportedSyntaxError(
|
|
304478
|
+
`${conditional} requires a quoted tag and at least one quoted comparison value (found {{${prefix}${body}}})`
|
|
304479
|
+
);
|
|
304480
|
+
}
|
|
304481
|
+
return { conditional, variable, comparisons };
|
|
304482
|
+
}
|
|
304459
304483
|
function parseBlocks(template) {
|
|
304460
304484
|
const stack = [{ children: [] }];
|
|
304461
304485
|
let cursor = 0;
|
|
@@ -304475,16 +304499,32 @@ function parseBlocks(template) {
|
|
|
304475
304499
|
throw unsupportedSyntaxError(`partials are not supported (found {{> ${name}}})`);
|
|
304476
304500
|
}
|
|
304477
304501
|
if (prefix === "#" || prefix === "^") {
|
|
304478
|
-
|
|
304502
|
+
const tagHead = parseTagConditionalHead(name, prefix);
|
|
304503
|
+
if (tagHead) {
|
|
304504
|
+
stack.push({
|
|
304505
|
+
children: [],
|
|
304506
|
+
closer: {
|
|
304507
|
+
kind: "tag",
|
|
304508
|
+
conditional: tagHead.conditional,
|
|
304509
|
+
negated: prefix === "^",
|
|
304510
|
+
variable: tagHead.variable,
|
|
304511
|
+
comparisons: tagHead.comparisons
|
|
304512
|
+
}
|
|
304513
|
+
});
|
|
304514
|
+
} else if (name.startsWith("each") || /\s/.test(name)) {
|
|
304479
304515
|
throw unsupportedSyntaxError(`loops are not supported (found {{${prefix}${name}}})`);
|
|
304480
|
-
}
|
|
304481
|
-
if (!SUPPORTED_SET.has(name)) {
|
|
304516
|
+
} else if (!SUPPORTED_SET.has(name)) {
|
|
304482
304517
|
throw unsupportedSyntaxError(`unknown conditional '${name}' in {{${prefix}${name}}}`);
|
|
304518
|
+
} else {
|
|
304519
|
+
stack.push({
|
|
304520
|
+
children: [],
|
|
304521
|
+
closer: {
|
|
304522
|
+
kind: "boolean",
|
|
304523
|
+
conditional: name,
|
|
304524
|
+
negated: prefix === "^"
|
|
304525
|
+
}
|
|
304526
|
+
});
|
|
304483
304527
|
}
|
|
304484
|
-
stack.push({
|
|
304485
|
-
children: [],
|
|
304486
|
-
closer: { conditional: name, negated: prefix === "^" }
|
|
304487
|
-
});
|
|
304488
304528
|
} else if (prefix === "/") {
|
|
304489
304529
|
const frame = stack.pop();
|
|
304490
304530
|
if (!frame || !frame.closer) {
|
|
@@ -304499,12 +304539,23 @@ function parseBlocks(template) {
|
|
|
304499
304539
|
if (!parent) {
|
|
304500
304540
|
throw unsupportedSyntaxError("block stack underflow while closing tag");
|
|
304501
304541
|
}
|
|
304502
|
-
|
|
304503
|
-
|
|
304504
|
-
|
|
304505
|
-
|
|
304506
|
-
|
|
304507
|
-
|
|
304542
|
+
if (frame.closer.kind === "tag") {
|
|
304543
|
+
parent.children.push({
|
|
304544
|
+
kind: "tagBlock",
|
|
304545
|
+
conditional: frame.closer.conditional,
|
|
304546
|
+
negated: frame.closer.negated,
|
|
304547
|
+
variable: frame.closer.variable,
|
|
304548
|
+
comparisons: frame.closer.comparisons,
|
|
304549
|
+
children: frame.children
|
|
304550
|
+
});
|
|
304551
|
+
} else {
|
|
304552
|
+
parent.children.push({
|
|
304553
|
+
kind: "block",
|
|
304554
|
+
conditional: frame.closer.conditional,
|
|
304555
|
+
negated: frame.closer.negated,
|
|
304556
|
+
children: frame.children
|
|
304557
|
+
});
|
|
304558
|
+
}
|
|
304508
304559
|
} else {
|
|
304509
304560
|
const top = stack[stack.length - 1];
|
|
304510
304561
|
if (top) {
|
|
@@ -304529,20 +304580,46 @@ function parseBlocks(template) {
|
|
|
304529
304580
|
}
|
|
304530
304581
|
return root.children;
|
|
304531
304582
|
}
|
|
304532
|
-
function
|
|
304583
|
+
function evaluateTagConditional(name, variable, comparisons, variables) {
|
|
304584
|
+
const resolvedValue = lookupVariable(variable, variables);
|
|
304585
|
+
const value = resolvedValue ?? "";
|
|
304586
|
+
if (name === "is_exact_match") {
|
|
304587
|
+
return comparisons.some((comparison) => value === comparison);
|
|
304588
|
+
}
|
|
304589
|
+
return comparisons.some((comparison) => value.includes(comparison));
|
|
304590
|
+
}
|
|
304591
|
+
function renderBlocks(tokens, sink) {
|
|
304533
304592
|
let out = "";
|
|
304534
304593
|
for (const token of tokens) {
|
|
304535
304594
|
if (token.kind === "literal") {
|
|
304536
304595
|
out += token.text;
|
|
304537
304596
|
continue;
|
|
304538
304597
|
}
|
|
304539
|
-
|
|
304540
|
-
|
|
304541
|
-
|
|
304598
|
+
let include;
|
|
304599
|
+
if (token.kind === "tagBlock") {
|
|
304600
|
+
const matched = evaluateTagConditional(
|
|
304601
|
+
token.conditional,
|
|
304602
|
+
token.variable,
|
|
304603
|
+
token.comparisons,
|
|
304604
|
+
sink.variables
|
|
304605
|
+
);
|
|
304606
|
+
sink.tagResolved.push({
|
|
304607
|
+
name: token.conditional,
|
|
304608
|
+
negated: token.negated,
|
|
304609
|
+
variable: token.variable,
|
|
304610
|
+
comparisons: token.comparisons,
|
|
304611
|
+
matched
|
|
304612
|
+
});
|
|
304613
|
+
include = token.negated ? !matched : matched;
|
|
304614
|
+
} else {
|
|
304615
|
+
const flag = sink.conditionals[token.conditional] ?? false;
|
|
304616
|
+
sink.resolved[token.conditional] = flag;
|
|
304617
|
+
include = token.negated ? !flag : flag;
|
|
304618
|
+
}
|
|
304542
304619
|
if (include) {
|
|
304543
|
-
out += renderBlocks(token.children,
|
|
304620
|
+
out += renderBlocks(token.children, sink);
|
|
304544
304621
|
} else {
|
|
304545
|
-
renderBlocks(token.children,
|
|
304622
|
+
renderBlocks(token.children, sink);
|
|
304546
304623
|
}
|
|
304547
304624
|
}
|
|
304548
304625
|
return out;
|
|
@@ -304572,13 +304649,20 @@ function renderMonitorTemplate(template, context) {
|
|
|
304572
304649
|
const conditionals = context.conditionals ?? {};
|
|
304573
304650
|
const tree = parseBlocks(template);
|
|
304574
304651
|
const conditionalsResolved = {};
|
|
304575
|
-
const
|
|
304652
|
+
const tagConditionalsResolved = [];
|
|
304653
|
+
const afterConditionals = renderBlocks(tree, {
|
|
304654
|
+
conditionals,
|
|
304655
|
+
variables,
|
|
304656
|
+
resolved: conditionalsResolved,
|
|
304657
|
+
tagResolved: tagConditionalsResolved
|
|
304658
|
+
});
|
|
304576
304659
|
const { rendered, used, missing } = substituteVariables(afterConditionals, variables);
|
|
304577
304660
|
return {
|
|
304578
304661
|
rendered,
|
|
304579
304662
|
variablesUsed: used,
|
|
304580
304663
|
variablesMissing: missing,
|
|
304581
|
-
conditionalsResolved
|
|
304664
|
+
conditionalsResolved,
|
|
304665
|
+
tagConditionalsResolved
|
|
304582
304666
|
};
|
|
304583
304667
|
}
|
|
304584
304668
|
|
|
@@ -305322,6 +305406,10 @@ preview: Render a Datadog monitor message template against a context (read-only
|
|
|
305322
305406
|
- Inputs: either inline 'message' OR 'monitor_id' (or existing 'id'); plus optional 'context' { variables, conditionals }.
|
|
305323
305407
|
- Supported syntax: {{variable.name}} substitution and conditional blocks {{#name}}...{{/name}} / {{^name}}...{{/name}}
|
|
305324
305408
|
where name is one of: ${SUPPORTED_CONDITIONALS.join(", ")}.
|
|
305409
|
+
- Also supports Datadog tag conditionals {{#is_match "tag" "val" ...}} (substring) and
|
|
305410
|
+
{{#is_exact_match "tag" "val" ...}} (exact), plus their {{^...}} negations. The tag is resolved
|
|
305411
|
+
against context.variables; multiple comparison values are OR'd; comparison is case-sensitive.
|
|
305412
|
+
Evaluated tag conditionals are reported in 'tagConditionalsResolved'.
|
|
305325
305413
|
- Missing variables render as {{undefined:name}} markers and are reported in 'variablesMissing'.
|
|
305326
305414
|
- Loops ({{#each ...}}) and partials ({{> ...}}) return EUNSUPPORTED_TEMPLATE_SYNTAX.
|
|
305327
305415
|
- Allowed under --read-only (no mutation; at most a getMonitor load).
|