feat: use RegExp.escape polyfill for robust PromQL duration regex; add compound duration test cases

Signed-off-by: ADITYA TIWARI <adityatiwari342005@gmail.com>
pull/17605/head
ADITYA TIWARI 5 months ago
parent 3b098799d4
commit 4fa435fad2
  1. 15
      web/ui/module/codemirror-promql/src/complete/hybrid.test.ts
  2. 20
      web/ui/module/codemirror-promql/src/complete/hybrid.ts

@ -652,11 +652,22 @@ describe('durationWithUnitRegexp test', () => {
{ input: '2d', expected: true },
{ input: '1w', expected: true },
{ input: '1y', expected: true },
{ input: '1d2h', expected: true },
{ input: '2h30m', expected: true },
{ input: '1h2m3s', expected: true },
{ input: '250ms2s', expected: true },
{ input: '2h3m4s5ms', expected: true },
{ input: '5', expected: false },
{ input: '5m5', expected: false },
{ input: 'm', expected: false },
{ input: 'd', expected: false },
{ input: '', expected: false },
{ input: '1hms', expected: false },
{ input: '2x', expected: false },
];
testCases.forEach(({ input, expected }) => {
expect(durationWithUnitRegexp.test(input)).toBe(expected);
});
});
});
it('should not match durations without units or partial units', () => {

@ -166,13 +166,25 @@ function arrayToCompletionResult(data: Completion[], from: number, to: number, i
} as CompletionResult;
}
// Matches complete duration with units (e.g., 5m, 30s, 1h, 500ms)
export const durationWithUnitRegexp = new RegExp(`^\\d+(?:${durationTerms.map((term) => escapeRegExp(term.label)).join('|')})$`);
// Polyfill RegExp.escape for compatibility with ES2024 and TypeScript.
// Ensures safe, standards-based regex escaping in all environments.
declare global {
interface RegExpConstructor {
escape?: (s: string) => string;
}
}
function escapeRegExp(value: string): string {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
if (!RegExp.escape) {
RegExp.escape = function(s: string): string {
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
};
}
// Matches complete PromQL durations, including compound units (e.g., 5m, 1d2h, 1h30m, etc.)
export const durationWithUnitRegexp = new RegExp(
`^(\\d+(${durationTerms.map(term => RegExp.escape!(term.label)).join('|')}))+$`
);
// Determines if a duration already has a complete time unit to prevent autocomplete insertion (issue #15452)
function hasCompleteDurationUnit(state: EditorState, node: SyntaxNode): boolean {
if (node.from >= node.to) {

Loading…
Cancel
Save