PropertyTable 수정
This commit is contained in:
@@ -6,6 +6,7 @@ import AddCollectionDialog from '@/components/api-tester/AddCollectionDialog.jsx
|
|||||||
import AddAPIDialog from '@/components/api-tester/AddAPIDialog.jsx';
|
import AddAPIDialog from '@/components/api-tester/AddAPIDialog.jsx';
|
||||||
import AddScenarioDialog from '@/components/api-tester/AddScenarioDialog.jsx';
|
import AddScenarioDialog from '@/components/api-tester/AddScenarioDialog.jsx';
|
||||||
import {useLoadTest} from '@/providers/LoadTestProvider.jsx';
|
import {useLoadTest} from '@/providers/LoadTestProvider.jsx';
|
||||||
|
import VariableModal from '@/components/api-tester/VariableModal.jsx';
|
||||||
|
|
||||||
const menuConfig = [
|
const menuConfig = [
|
||||||
{
|
{
|
||||||
@@ -22,7 +23,8 @@ const menuConfig = [
|
|||||||
items: [
|
items: [
|
||||||
{id: 'collection-add', label: '컬렉션 추가', action: 'collection-add'},
|
{id: 'collection-add', label: '컬렉션 추가', action: 'collection-add'},
|
||||||
{id: 'request-add', label: '요청 추가', action: 'request-add'},
|
{id: 'request-add', label: '요청 추가', action: 'request-add'},
|
||||||
{id: 'scenario-add', label: '시나리오 추가', action: 'scenario-add'}
|
{id: 'scenario-add', label: '시나리오 추가', action: 'scenario-add'},
|
||||||
|
{id: 'variables-show', label: '변수 보기', action: 'variables-show'},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -81,6 +83,7 @@ const APITester = () => {
|
|||||||
const [showAddCollection, setShowAddCollection] = useState(false);
|
const [showAddCollection, setShowAddCollection] = useState(false);
|
||||||
const [showAddApi, setShowAddApi] = useState(false);
|
const [showAddApi, setShowAddApi] = useState(false);
|
||||||
const [showAddScenario, setShowAddScenario] = useState(false);
|
const [showAddScenario, setShowAddScenario] = useState(false);
|
||||||
|
const [showVariableModal, setShowVariableModal] = useState(false);
|
||||||
const { handleLogout, createCollection, createAPIRequest } = useAPI();
|
const { handleLogout, createCollection, createAPIRequest } = useAPI();
|
||||||
const {createScenario} = useLoadTest();
|
const {createScenario} = useLoadTest();
|
||||||
|
|
||||||
@@ -131,6 +134,9 @@ const APITester = () => {
|
|||||||
case 'scenario-add':
|
case 'scenario-add':
|
||||||
setShowAddScenario(true);
|
setShowAddScenario(true);
|
||||||
break;
|
break;
|
||||||
|
case 'variables-show':
|
||||||
|
setShowVariableModal(true);
|
||||||
|
break;
|
||||||
case 'logout':
|
case 'logout':
|
||||||
const success = await handleLogout();
|
const success = await handleLogout();
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -197,6 +203,10 @@ const APITester = () => {
|
|||||||
onOpenChange={setShowAddScenario}
|
onOpenChange={setShowAddScenario}
|
||||||
onSubmit={handleAddScenario}
|
onSubmit={handleAddScenario}
|
||||||
/>
|
/>
|
||||||
|
<VariableModal
|
||||||
|
open={showVariableModal}
|
||||||
|
onOpenChange={setShowVariableModal}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const DraggableApiItem = ({api, collectionId, onApiAction}) => {
|
|||||||
<FileText className="h-4 w-4 flex-shrink-0"/>
|
<FileText className="h-4 w-4 flex-shrink-0"/>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild className="block max-w-[150px]">
|
<TooltipTrigger asChild className="block max-w-[150px]">
|
||||||
<span className="block truncate">s
|
<span className="block truncate">
|
||||||
{api.name}
|
{api.name}
|
||||||
</span>
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||||
|
import { Trash } from 'lucide-react';
|
||||||
|
|
||||||
|
const VariableModal = ({ open, onOpenChange }) => {
|
||||||
|
const [variables, setVariables] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
const globals = window.globals || {};
|
||||||
|
setVariables(Object.entries(globals).map(([key, value]) => ({ key, value })));
|
||||||
|
}
|
||||||
|
}, [open]);
|
||||||
|
|
||||||
|
const handleKeyChange = (index, newKey) => {
|
||||||
|
const newVariables = [...variables];
|
||||||
|
const oldKey = newVariables[index].key;
|
||||||
|
newVariables[index].key = newKey;
|
||||||
|
setVariables(newVariables);
|
||||||
|
|
||||||
|
const globals = window.globals || {};
|
||||||
|
const value = globals[oldKey];
|
||||||
|
delete globals[oldKey];
|
||||||
|
globals[newKey] = value;
|
||||||
|
window.globals = globals;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleValueChange = (index, newValue) => {
|
||||||
|
const newVariables = [...variables];
|
||||||
|
newVariables[index].value = newValue;
|
||||||
|
setVariables(newVariables);
|
||||||
|
|
||||||
|
const globals = window.globals || {};
|
||||||
|
globals[newVariables[index].key] = newValue;
|
||||||
|
window.globals = globals;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDelete = (index) => {
|
||||||
|
const key = variables[index].key;
|
||||||
|
const newVariables = variables.filter((_, i) => i !== index);
|
||||||
|
setVariables(newVariables);
|
||||||
|
|
||||||
|
const globals = window.globals || {};
|
||||||
|
delete globals[key];
|
||||||
|
window.globals = globals;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
setVariables([...variables, { key: '', value: '' }]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent className="max-w-3xl">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>환경 변수</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
<div>
|
||||||
|
<div className="font-medium mb-2">Globals</div>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>키</TableHead>
|
||||||
|
<TableHead>값</TableHead>
|
||||||
|
<TableHead>
|
||||||
|
<Button variant="secondary" size="sm" onClick={handleAdd}>
|
||||||
|
추가
|
||||||
|
</Button>
|
||||||
|
</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{variables.map((variable, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell>
|
||||||
|
<Input
|
||||||
|
value={variable.key}
|
||||||
|
onChange={(e) => handleKeyChange(index, e.target.value)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Input
|
||||||
|
value={variable.value}
|
||||||
|
onChange={(e) => handleValueChange(index, e.target.value)}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => handleDelete(index)}
|
||||||
|
>
|
||||||
|
<Trash className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button variant="secondary" onClick={() => onOpenChange(false)}>
|
||||||
|
닫기
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VariableModal;
|
||||||
@@ -3,7 +3,6 @@ import {Button} from '@/components/ui/button';
|
|||||||
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select';
|
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from '@/components/ui/select';
|
||||||
import {Input} from '@/components/ui/input';
|
import {Input} from '@/components/ui/input';
|
||||||
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs';
|
import {Tabs, TabsContent, TabsList, TabsTrigger} from '@/components/ui/tabs';
|
||||||
import {Label} from '@/components/ui/label';
|
|
||||||
import EditableInput from '../shared/EditableInput';
|
import EditableInput from '../shared/EditableInput';
|
||||||
import PropertyTable from '../shared/PropertyTable';
|
import PropertyTable from '../shared/PropertyTable';
|
||||||
import ServerManager from '@/components/ServerManager.jsx';
|
import ServerManager from '@/components/ServerManager.jsx';
|
||||||
@@ -27,6 +26,19 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
const [basePath, setBasePath] = useState('');
|
const [basePath, setBasePath] = useState('');
|
||||||
const [currentTab, setCurrentTab] = useState('body');
|
const [currentTab, setCurrentTab] = useState('body');
|
||||||
const [currentResponseTab, setCurrentResponseTab] = useState('response-body');
|
const [currentResponseTab, setCurrentResponseTab] = useState('response-body');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentModel(prev => ({
|
||||||
|
...prev,
|
||||||
|
queryParams: model.queryParams || [],
|
||||||
|
headers: model.headers || [],
|
||||||
|
path: model.path || '',
|
||||||
|
requestBody: model.requestBody || '',
|
||||||
|
method: model.method || 'GET',
|
||||||
|
contentType: model.contentType || 'json'
|
||||||
|
}));
|
||||||
|
}, [model]);
|
||||||
|
|
||||||
const [responseData, setResponseData] = useState({
|
const [responseData, setResponseData] = useState({
|
||||||
headers: [],
|
headers: [],
|
||||||
status: '',
|
status: '',
|
||||||
@@ -52,16 +64,10 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
}, [currentModel.server]);
|
}, [currentModel.server]);
|
||||||
|
|
||||||
const handleServerChange = (serverId) => {
|
const handleServerChange = (serverId) => {
|
||||||
// const selectedServer = getServer(serverId);
|
|
||||||
|
|
||||||
setCurrentModel(prev => ({
|
setCurrentModel(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
server: serverId
|
server: serverId
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// if (selectedServer) {
|
|
||||||
// setBasePath(selectedServer.basePath || '');
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHeadersChange = (headers) => {
|
const handleHeadersChange = (headers) => {
|
||||||
@@ -71,7 +77,16 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePathChange = (path) => {
|
const handlePathChange = (e) => {
|
||||||
|
const path = e.target.value;
|
||||||
|
if (!path) {
|
||||||
|
setCurrentModel(prev => ({
|
||||||
|
...prev,
|
||||||
|
path: '',
|
||||||
|
queryParams: []
|
||||||
|
}));
|
||||||
|
return;
|
||||||
|
}
|
||||||
const queryParams = parseQueryParams(path);
|
const queryParams = parseQueryParams(path);
|
||||||
setCurrentModel(prev => ({
|
setCurrentModel(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
@@ -80,40 +95,50 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const buildUrlFromPathAndParams = (path, queryParams) => {
|
||||||
|
const baseUrl = path.split('?')[0];
|
||||||
|
const enabledParams = queryParams.filter(p => p.enabled && p.key);
|
||||||
|
|
||||||
|
if (!enabledParams.length) return baseUrl;
|
||||||
|
|
||||||
|
const queryString = enabledParams
|
||||||
|
.map(p => `${p.key}=${p.value || ''}`)
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
return `${baseUrl}?${queryString}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleQueryParamsChange = (newParams) => {
|
||||||
|
const newPath = buildUrlFromPathAndParams(currentModel.path.split('?')[0], newParams);
|
||||||
|
setCurrentModel(prev => ({
|
||||||
|
...prev,
|
||||||
|
path: newPath,
|
||||||
|
queryParams: newParams
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const parseQueryParams = (path) => {
|
const parseQueryParams = (path) => {
|
||||||
const queryParams = [];
|
const queryParams = [];
|
||||||
const queryString = path.split('?')[1];
|
const [, queryString] = path.split('?');
|
||||||
|
|
||||||
if (queryString) {
|
if (queryString) {
|
||||||
queryString.split('&').forEach(param => {
|
queryString.split('&').forEach(param => {
|
||||||
const [key, value] = param.split('=');
|
const [key, value] = param.split('=').map(decodeURIComponent);
|
||||||
queryParams.push({
|
if (key) {
|
||||||
enabled: true,
|
queryParams.push({
|
||||||
key,
|
enabled: true,
|
||||||
value: value || ''
|
key,
|
||||||
});
|
value: value || ''
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return queryParams;
|
return queryParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderRequestVariables = () => (
|
|
||||||
<div className="p-4">
|
|
||||||
<h3 className="text-sm font-medium mb-2">Available Variables</h3>
|
|
||||||
<div className="space-y-2">
|
|
||||||
<div>
|
|
||||||
<Label>request</Label>
|
|
||||||
<div className="text-sm text-gray-500">Request object containing headers, body, etc.</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>environment</Label>
|
|
||||||
<div className="text-sm text-gray-500">Current environment variables</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleSendRequest = async () => {
|
const handleSendRequest = async () => {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return;
|
return;
|
||||||
@@ -237,6 +262,7 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
value={currentModel.path}
|
value={currentModel.path}
|
||||||
onChange={handlePathChange}
|
onChange={handlePathChange}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
inputMode="text"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-2 shrink-0">
|
<div className="flex gap-2 shrink-0">
|
||||||
@@ -298,15 +324,15 @@ export const HTTPClientView = ({model, index}) => {
|
|||||||
|
|
||||||
<TabsContent value="params" className="h-full m-0">
|
<TabsContent value="params" className="h-full m-0">
|
||||||
<PropertyTable
|
<PropertyTable
|
||||||
properties={currentModel.queryParams}
|
properties={currentModel.queryParams || []}
|
||||||
onChange={handlePathChange}
|
onChange={handleQueryParamsChange}
|
||||||
/>
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
{/* Headers Tab Content */}
|
{/* Headers Tab Content */}
|
||||||
<TabsContent value="headers" className="h-full m-0">
|
<TabsContent value="headers" className="h-full m-0">
|
||||||
<PropertyTable
|
<PropertyTable
|
||||||
properties={currentModel.headers}
|
properties={currentModel.headers || []}
|
||||||
onChange={handleHeadersChange}
|
onChange={handleHeadersChange}
|
||||||
/>
|
/>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|||||||
@@ -106,10 +106,18 @@ const EditableInput = ({
|
|||||||
return parts;
|
return parts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (value !== internalValue) {
|
||||||
|
// setInternalValue(value);
|
||||||
|
// }
|
||||||
|
// }, [value]);
|
||||||
|
|
||||||
const handleInput = (e) => {
|
const handleInput = (e) => {
|
||||||
|
console.log('handleInput', e);
|
||||||
const newValue = e.target.textContent;
|
const newValue = e.target.textContent;
|
||||||
const newSelection = saveSelection();
|
const newSelection = saveSelection();
|
||||||
|
|
||||||
|
console.log(newValue);
|
||||||
setInternalValue(newValue);
|
setInternalValue(newValue);
|
||||||
setSelection(newSelection);
|
setSelection(newSelection);
|
||||||
onChange(newValue);
|
onChange(newValue);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
@@ -20,6 +20,10 @@ const PropertyTable = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [localProperties, setLocalProperties] = useState(properties);
|
const [localProperties, setLocalProperties] = useState(properties);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalProperties(properties);
|
||||||
|
}, [properties]);
|
||||||
|
|
||||||
// Handle property changes without causing infinite loops
|
// Handle property changes without causing infinite loops
|
||||||
const handlePropertyChange = (index, field, value) => {
|
const handlePropertyChange = (index, field, value) => {
|
||||||
const updatedProperties = localProperties.map((prop, i) => {
|
const updatedProperties = localProperties.map((prop, i) => {
|
||||||
@@ -29,7 +33,9 @@ const PropertyTable = ({
|
|||||||
return prop;
|
return prop;
|
||||||
});
|
});
|
||||||
setLocalProperties(updatedProperties);
|
setLocalProperties(updatedProperties);
|
||||||
onChange?.(updatedProperties);
|
requestAnimationFrame(() => {
|
||||||
|
onChange?.(updatedProperties);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add new property
|
// Add new property
|
||||||
@@ -62,8 +68,8 @@ const PropertyTable = ({
|
|||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead className="w-14">Enable</TableHead>
|
<TableHead className="w-14">Enable</TableHead>
|
||||||
<TableHead>Key</TableHead>
|
<TableHead className="w-[40%]">Key</TableHead>
|
||||||
<TableHead>Value</TableHead>
|
<TableHead className="w-[40%]">Value</TableHead>
|
||||||
<TableHead className="w-14">
|
<TableHead className="w-14">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleAdd}
|
onClick={handleAdd}
|
||||||
@@ -90,8 +96,8 @@ const PropertyTable = ({
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<EditableInput
|
<EditableInput
|
||||||
value={property.key}
|
value={property.key}
|
||||||
onChange={(e) =>
|
onChange={(value) =>
|
||||||
handlePropertyChange(index, 'key', e.target.value)
|
handlePropertyChange(index, 'key', value)
|
||||||
}
|
}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
@@ -99,8 +105,8 @@ const PropertyTable = ({
|
|||||||
<TableCell>
|
<TableCell>
|
||||||
<EditableInput
|
<EditableInput
|
||||||
value={property.value}
|
value={property.value}
|
||||||
onChange={(e) =>
|
onChange={(value) =>
|
||||||
handlePropertyChange(index, 'value', e.target.value)
|
handlePropertyChange(index, 'value',value)
|
||||||
}
|
}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -52,11 +52,9 @@ export const APIProvider = ({
|
|||||||
try {
|
try {
|
||||||
const validatedServers = await servers$.loadServers();
|
const validatedServers = await servers$.loadServers();
|
||||||
setServers(validatedServers);
|
setServers(validatedServers);
|
||||||
console.log({validatedServers});
|
|
||||||
return validatedServers;
|
return validatedServers;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
console.log({err});
|
|
||||||
return [];
|
return [];
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
@@ -65,7 +63,6 @@ export const APIProvider = ({
|
|||||||
|
|
||||||
const getServer = useCallback((serverId) => {
|
const getServer = useCallback((serverId) => {
|
||||||
const server = servers.find(server => server.id === serverId);
|
const server = servers.find(server => server.id === serverId);
|
||||||
console.log(server);
|
|
||||||
return server;
|
return server;
|
||||||
}, [servers]);
|
}, [servers]);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { getCSRFToken } from '@/services/token.js';
|
|||||||
|
|
||||||
class APIClient {
|
class APIClient {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.globals = {};
|
|
||||||
this.abortController = null;
|
this.abortController = null;
|
||||||
this.contextPath = document.querySelector('meta[name="context-path"]')?.getAttribute('content') || '/';
|
this.contextPath = document.querySelector('meta[name="context-path"]')?.getAttribute('content') || '/';
|
||||||
this.contextPath = this.contextPath.endsWith('/') ? this.contextPath : this.contextPath + '/';
|
this.contextPath = this.contextPath.endsWith('/') ? this.contextPath : this.contextPath + '/';
|
||||||
@@ -24,8 +23,7 @@ class APIClient {
|
|||||||
|
|
||||||
onLog(`Request: ${processedRequest.method} ${processedRequest.path}`);
|
onLog(`Request: ${processedRequest.method} ${processedRequest.path}`);
|
||||||
|
|
||||||
|
const response = await this.makeRequest(processedRequest);
|
||||||
const response = await this.makeRequest(model);
|
|
||||||
const formattedResponse = this.formatResponse(response);
|
const formattedResponse = this.formatResponse(response);
|
||||||
const finalResponse = await this.executePostRequestScript(
|
const finalResponse = await this.executePostRequestScript(
|
||||||
model.postRequestScript,
|
model.postRequestScript,
|
||||||
@@ -86,14 +84,18 @@ class APIClient {
|
|||||||
|
|
||||||
replacePlaceholdersWithVariables(original, variables) {
|
replacePlaceholdersWithVariables(original, variables) {
|
||||||
const request = JSON.parse(JSON.stringify(original));
|
const request = JSON.parse(JSON.stringify(original));
|
||||||
const mergedVariables = { ...this.globals, ...variables };
|
const mergedVariables = { ...window.globals, ...variables };
|
||||||
|
console.log(mergedVariables);
|
||||||
|
|
||||||
Object.entries(mergedVariables).forEach(([key, value]) => {
|
Object.entries(mergedVariables).forEach(([key, value]) => {
|
||||||
const placeholder = new RegExp(`{{${key}}}`, 'g');
|
const placeholder = new RegExp(`{{${key}}}`, 'g');
|
||||||
|
console.log(placeholder);
|
||||||
|
|
||||||
request.path = request.path?.replace(placeholder, value);
|
request.path = request.path?.replace(placeholder, value);
|
||||||
request.requestBody = request.requestBody?.replace(placeholder, value);
|
request.requestBody = request.requestBody?.replace(placeholder, value);
|
||||||
|
|
||||||
|
console.log("REQUEST BODY:",request.requestBody);
|
||||||
|
|
||||||
if (request.headers) {
|
if (request.headers) {
|
||||||
const headersStr = JSON.stringify(request.headers).replace(placeholder, value);
|
const headersStr = JSON.stringify(request.headers).replace(placeholder, value);
|
||||||
request.headers = JSON.parse(headersStr);
|
request.headers = JSON.parse(headersStr);
|
||||||
|
|||||||
Reference in New Issue
Block a user