mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-25 13:45:52 +00:00
fix: disallow prompts with leading or trailing spaces (#6201)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import get from 'lodash/get';
|
||||
import { mockDataFunctions } from '@usebruno/common';
|
||||
import { PROMPT_VARIABLE_TEXT_PATTERN } from '@usebruno/common/utils';
|
||||
|
||||
const CodeMirror = require('codemirror');
|
||||
|
||||
@@ -31,8 +32,8 @@ export const defineCodeMirrorBrunoVariablesMode = (_variables, mode, highlightPa
|
||||
if (ch === '}' && stream.peek() === '}') {
|
||||
stream.eat('}');
|
||||
|
||||
// Prompt variable: starts with '?'
|
||||
if (word.startsWith('?')) {
|
||||
// Prompt variable: starts with '?', no leading/trailing spaces, no braces
|
||||
if (PROMPT_VARIABLE_TEXT_PATTERN.test(word)) {
|
||||
return `variable-prompt`;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ export {
|
||||
} from './template-hasher';
|
||||
|
||||
export {
|
||||
PROMPT_VARIABLE_TEXT_PATTERN,
|
||||
PROMPT_VARIABLE_TEMPLATE_PATTERN,
|
||||
extractPromptVariables,
|
||||
extractPromptVariablesFromString
|
||||
} from './prompt-variables';
|
||||
|
||||
@@ -45,10 +45,13 @@ describe('prompt variable utils', () => {
|
||||
expect(extractPromptVariables([{ text: 'Multiple {{?prompts}} in {{?one}} string', noPrompt: 'No prompt here' }, ['Another {{?test}} string', { prompt: '{{?nested}}', no: 'prompt' }]])).toEqual(['prompts', 'one', 'test', 'nested']);
|
||||
});
|
||||
|
||||
it('should deduplicate prompt variables', () => {
|
||||
// Strings
|
||||
expect(extractPromptVariables(['{{?world}} prompt here', 'Hello {{?world}}'])).toEqual(['world']);
|
||||
expect(extractPromptVariables(['Multiple {{?prompts}} in {{?one}} string', 'Another {{?one}} string'])).toEqual(['prompts', 'one']);
|
||||
it('should not extract prompt variables from invalid template patterns', () => {
|
||||
expect(extractPromptVariables('Prompt with valid {{?inner space}}')).toEqual(['inner space']);
|
||||
expect(extractPromptVariables('Prompt with invalid {{? leading space}}')).toEqual([]);
|
||||
expect(extractPromptVariables('Prompt with invalid {{?trailing space }}')).toEqual([]);
|
||||
expect(extractPromptVariables('Prompt with invalid {{?{curly brace}}')).toEqual([]);
|
||||
expect(extractPromptVariables('Prompt with invalid {{?}curly brace}}')).toEqual([]);
|
||||
expect(extractPromptVariables('Prompt with invalid {{?{curly brace}}}')).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,47 @@
|
||||
/**
|
||||
* Inner regex pattern for prompt variable names (without braces or `?` prefix)
|
||||
*
|
||||
* Pattern: /[^{}\s](?:[^{}]*[^{}\s])?/
|
||||
*
|
||||
* Breakdown:
|
||||
* | Part | Meaning |
|
||||
* | -------------- | ---------------------------------------------------------- |
|
||||
* | `[^\s{}]` | First character: not whitespace, `{`, or `}` |
|
||||
* | `(?:...)?` | Optional non-capturing group (allows single-char names) |
|
||||
* | `[^{}]*` | Middle characters: any except `{` or `}` (spaces allowed) |
|
||||
* | `[^\s{}]` | Last character: not whitespace, `{`, or `}` |
|
||||
*
|
||||
* This inner pattern is reused in:
|
||||
* - PROMPT_VARIABLE_TEXT_PATTERN: Matches "?Name" format (with anchors)
|
||||
* - PROMPT_VARIABLE_PATTERN: Matches "{{?Name}}" format (in templates)
|
||||
*
|
||||
* Valid examples: "Name", "Prompt Var", "x"
|
||||
* Invalid examples: " Name", "Name ", "{Name}", "Na{me}"
|
||||
*/
|
||||
const PROMPT_VARIABLE_PATTERN = /[^{}\s](?:[^{}]*[^{}\s])?/;
|
||||
|
||||
/**
|
||||
* Valid examples: "?Name", "?Prompt Var", "?x"
|
||||
* Invalid examples: "? Name", "?Name ", "?{{Name}}", "?{Name}"
|
||||
*/
|
||||
export const PROMPT_VARIABLE_TEXT_PATTERN = new RegExp(`^\\?(${PROMPT_VARIABLE_PATTERN.source})$`);
|
||||
|
||||
/**
|
||||
* Valid matches: "{{?Name}}", "{{?Prompt Var}}", "{{?x}}"
|
||||
* Invalid: "{{? Name}}", "{{?Name }}", "{{?{Name}}}"
|
||||
*/
|
||||
export const PROMPT_VARIABLE_TEMPLATE_PATTERN = new RegExp(`{{\\?(${PROMPT_VARIABLE_PATTERN.source})}}`, 'g');
|
||||
|
||||
/**
|
||||
* Extract prompt variables matching {{?<Prompt Text>}} from a string.
|
||||
* @param {string} str - The input string.
|
||||
* @returns {string[]} - An array of extracted prompt variables.
|
||||
*/
|
||||
export const extractPromptVariablesFromString = (str: string): string[] => {
|
||||
const regex = /{{\?([^}]+)}}/g;
|
||||
const prompts = new Set<string>();
|
||||
let match;
|
||||
while ((match = regex.exec(str)) !== null) {
|
||||
prompts.add(match[1].trim());
|
||||
while ((match = PROMPT_VARIABLE_TEMPLATE_PATTERN.exec(str)) !== null) {
|
||||
prompts.add(match[1]);
|
||||
}
|
||||
return Array.from(prompts);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user