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/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
- if (name.startsWith("each") || /\s/.test(name)) {
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
- parent.children.push({
304503
- kind: "block",
304504
- conditional: frame.closer.conditional,
304505
- negated: frame.closer.negated,
304506
- children: frame.children
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 renderBlocks(tokens, conditionals, resolved) {
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
- const flag = conditionals[token.conditional] ?? false;
304540
- resolved[token.conditional] = flag;
304541
- const include = token.negated ? !flag : flag;
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, conditionals, resolved);
304620
+ out += renderBlocks(token.children, sink);
304544
304621
  } else {
304545
- renderBlocks(token.children, conditionals, resolved);
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 afterConditionals = renderBlocks(tree, conditionals, conditionalsResolved);
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).