mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-25 16:26:51 +08:00
Feat: HTTP componant supports variables (#10432)
### What problem does this PR solve? HTTP component supports variables. #10382   ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -26,6 +26,7 @@ import { INextOperatorForm } from '../../interface';
|
||||
import { buildOutputList } from '../../utils/build-output-list';
|
||||
import { FormWrapper } from '../components/form-wrapper';
|
||||
import { Output } from '../components/output';
|
||||
import { PromptEditor } from '../components/prompt-editor';
|
||||
import { FormSchema, FormSchemaType } from './schema';
|
||||
import { useEditVariableRecord } from './use-edit-variable';
|
||||
import { VariableDialog } from './variable-dialog';
|
||||
@ -98,7 +99,13 @@ function InvokeForm({ node }: INextOperatorForm) {
|
||||
<FormItem>
|
||||
<FormLabel>{t('flow.url')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder="http://" />
|
||||
<PromptEditor
|
||||
value={field.value}
|
||||
onChange={field.onChange}
|
||||
placeholder="http://"
|
||||
showToolbar={false}
|
||||
multiLine={false}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
|
||||
@ -6,8 +6,54 @@ export const VariableFormSchema = z.object({
|
||||
value: z.string(),
|
||||
});
|
||||
|
||||
// {user_id} or {component@variable}
|
||||
const placeholderRegex = /\{([a-zA-Z_][a-zA-Z0-9_.@-]*)\}/g;
|
||||
|
||||
// URL validation schema that accepts:
|
||||
// 1. Standard URLs (e.g. https://example.com/api)
|
||||
// 2. URLs with variable placeholders in curly braces (e.g. https://api/{user_id}/posts)
|
||||
const urlValidation = z.string().refine(
|
||||
(val) => {
|
||||
if (!val) return false;
|
||||
|
||||
const hasPlaceholders = val.includes('{') && val.includes('}');
|
||||
const matches = [...val.matchAll(placeholderRegex)];
|
||||
|
||||
if (hasPlaceholders) {
|
||||
if (
|
||||
!matches.length ||
|
||||
matches.some((m) => !/^[a-zA-Z_][a-zA-Z0-9_.@-]*$/.test(m[1]))
|
||||
)
|
||||
return false;
|
||||
|
||||
if ((val.match(/{/g) || []).length !== (val.match(/}/g) || []).length)
|
||||
return false;
|
||||
|
||||
const testURL = val.replace(placeholderRegex, 'placeholder');
|
||||
|
||||
return isValidURL(testURL);
|
||||
}
|
||||
|
||||
return isValidURL(val);
|
||||
},
|
||||
{
|
||||
message: 'Must be a valid URL or URL with variable placeholders',
|
||||
},
|
||||
);
|
||||
|
||||
function isValidURL(str: string): boolean {
|
||||
try {
|
||||
// Try to construct a full URL; prepend http:// if protocol is missing
|
||||
new URL(str.startsWith('http') ? str : `http://${str}`);
|
||||
return true;
|
||||
} catch {
|
||||
// Allow relative paths (e.g. /api/users) if needed
|
||||
return /^\/[a-zA-Z0-9]/.test(str);
|
||||
}
|
||||
}
|
||||
|
||||
export const FormSchema = z.object({
|
||||
url: z.string().url(),
|
||||
url: urlValidation,
|
||||
method: z.string(),
|
||||
timeout: z.number(),
|
||||
headers: z.string(),
|
||||
|
||||
Reference in New Issue
Block a user