From 6a0362e18f8ac8bf6ff772d9e49c7493bde55dae Mon Sep 17 00:00:00 2001 From: Eleanor Mao Date: Thu, 11 Apr 2024 17:17:37 +0800 Subject: [PATCH] feat: s --- package.json | 6 ++- src/ChatItem.tsx | 10 ++-- src/Create.tsx | 138 +++++++++++++++++++++++++++++++++++++++++------ src/Home.tsx | 6 ++- src/List.tsx | 112 +++++++++++++++++++++++++++++--------- src/RCIcon.tsx | 16 ++++++ src/ajax.ts | 127 +++++++++++++++++++++++++++++++++++++++++++ src/index.tsx | 39 +++++++------- src/loadYml.ts | 59 ++++++++++++++++++-- src/transform.ts | 53 +++++++++--------- yarn.lock | 34 +++++++++++- 11 files changed, 502 insertions(+), 98 deletions(-) create mode 100644 src/RCIcon.tsx create mode 100644 src/ajax.ts diff --git a/package.json b/package.json index cac3fab..2ad30a8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@types/node": "^16.18.95", "@types/react": "^18.2.74", "@types/react-dom": "^18.2.24", + "axios": "^1.6.8", "babel-jest": "^27.4.2", "babel-loader": "^8.2.3", "babel-plugin-named-asset-import": "^0.3.8", @@ -52,6 +53,7 @@ "postcss-normalize": "^10.0.1", "postcss-preset-env": "^7.0.1", "prompts": "^2.4.2", + "qs": "^6.12.0", "react": "^18.2.0", "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.1", @@ -102,6 +104,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@types/js-yaml": "^4.0.9", "@types/lodash": "^4.17.0", + "@types/qs": "^6.9.14", "monaco-editor-webpack-plugin": "^7.1.0" }, "jest": { @@ -159,5 +162,6 @@ "presets": [ "react-app" ] - } + }, + "proxy": "http://rcw-mock-lab02.lab.nordigy.ru:8080" } diff --git a/src/ChatItem.tsx b/src/ChatItem.tsx index 33cf7a2..7117386 100644 --- a/src/ChatItem.tsx +++ b/src/ChatItem.tsx @@ -3,7 +3,7 @@ * @Date : 2024-04-09 14:46:24 * @LastEditTime : 2024-04-09 14:46:24 * - * + * */ import React, { FC } from "react"; import { styled } from '@mui/material/styles'; @@ -11,10 +11,12 @@ import ListItem from '@mui/material/ListItem'; import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined'; import Box from '@mui/material/Box'; import FaceIcon from '@mui/icons-material/Face'; +import CircularProgress from '@mui/material/CircularProgress'; interface Props { isMe: boolean; message: string; + loading?: boolean; } @@ -43,8 +45,9 @@ const ChatMessageWrap = styled(Box)<{ isMe: boolean }>(({ isMe }) => ({ const ChatMessage = styled(Box)(() => ({ maxWidth: '80%', + whiteSpace: 'pre-line' })); -export const ChatItem: FC = ({ isMe, message }) => { +export const ChatItem: FC = ({ isMe, message, loading }) => { return ( @@ -53,7 +56,8 @@ export const ChatItem: FC = ({ isMe, message }) => { - {message} + {loading && } + {!loading && message} diff --git a/src/Create.tsx b/src/Create.tsx index f388b02..acf29d7 100644 --- a/src/Create.tsx +++ b/src/Create.tsx @@ -3,9 +3,9 @@ * @Date : 2024-04-09 10:36:44 * @LastEditTime : 2024-04-09 10:36:44 * - * + * */ -import React, { ChangeEvent, KeyboardEvent, useEffect, useRef, useState } from "react"; +import React, { ChangeEvent, KeyboardEvent, useEffect, useMemo, useRef, useState } from "react"; import Grid from '@mui/material/Grid'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -19,21 +19,72 @@ import { ChatItem } from "./ChatItem"; import Stack from '@mui/material/Stack'; import { uniqueId } from 'lodash'; import Typography from "@mui/material/Typography"; -import { Editor } from "./Editor"; +import { useLocation } from "react-router-dom"; +import axios from 'axios'; +import { Definition, DSL2Json, Json2Preview } from "./loadYml"; +import RefreshIcon from '@mui/icons-material/Refresh'; +import IconButton from '@mui/material/IconButton'; +import Tooltip from '@mui/material/Tooltip'; interface Message { id: string; message: string; isMe: boolean; + loading?: boolean; } -const SupportedBlock = ['BotMessage', 'Chat', 'EmailSender', 'Script']; +const SupportedBlock = ['BotMessage', 'Chat', 'GlipSender', 'Script']; export const Create = () => { - const [chatList, setChatList] = useState([]); - const [workflowName, setWorkFlowName] = useState('My workflow'); + const location = useLocation(); + const id = useMemo(() => new URLSearchParams(location.search).get('id'), [location]); + const [formJson, setFormJson] = useState(() => { + let value = { + id: 'abc', + description: '', + name: 'My workflow', + versionId: '', + }; + try { + value = JSON.parse(`create-${id}`); + } catch (e) { + } + return value; + }); + const [chatList, setChatList] = useState([{ + id: uniqueId('r'), + message: [ + 'Hello! Please tell me what kind of workflow you want to generate!\n', + 'Currently the node types I support are: Chat, BotMessage, GlipSender, Script'].join('\n'), + isMe: false + }]); const [chatInput, setChatInput] = useState(''); + const [workflowContent, setWorkflowContent] = useState(''); + // eslint-disable-next-line no-template-curly-in-string + const flowDefinition = useMemo(() => DSL2Json(workflowContent), [workflowContent]); + const previewImg = useMemo(() => Json2Preview(flowDefinition), [flowDefinition]); const chatContentRef = useRef(null); + const hasEmailSender = useMemo(() => workflowContent.includes('"EmailSender"'), [workflowContent]); + const hasBotAddin = useMemo(() => workflowContent.includes('"Chat"'), [workflowContent]); + const hasScript = useMemo(() => workflowContent.includes('"Script"'), [workflowContent]); + + const [emailData, setEmailData] = useState({ + to: '', + subject: '', + content: `${content}` + }); + useEffect(() => { + console.log(workflowContent); + console.log(flowDefinition); + }, [flowDefinition]); + // useEffect(() => { + // axios.post('/chat/start', { + // accountId: 10086, + // channelId: "10000", + // dialogId: "1", + // segmentId: "1" + // }); + // }, []); const handleChange = (e: ChangeEvent) => { setChatInput(e.target.value); }; @@ -41,13 +92,35 @@ export const Create = () => { const handleClickChip = (text: string) => () => { setChatInput(s => s + text); }; - const handleSend = () => { + const handleSend = async () => { + const rId = uniqueId('r'); + setChatList([...chatList, { - id: uniqueId(), + id: uniqueId('m'), message: chatInput, isMe: true + }, { + id: rId, + message: '', + isMe: false, + loading: true }]); setChatInput(''); + try { + const { data } = await axios.post<{ answer: string; workflowContent: string }>(`/bot/workflow/${id}/messages`, { + "question": chatInput + }); + setWorkflowContent(data.workflowContent); + setChatList(list => list.map(l => { + if (l.id === rId) { + l.loading = false; + l.message = data.answer; + } + return l; + })); + } catch (e) { + setChatList(list => list.filter(l => l.id !== rId)); + } }; useEffect(() => { @@ -56,25 +129,54 @@ export const Create = () => { } }, [chatList]); + const handleRefresh = async () => { + await axios.delete(`/bot/workflow/${id}/messages`); + setChatList([{ + id: uniqueId('r'), + message: [ + 'Hello! Please tell me what kind of workflow you want to generate!\n', + 'Currently the node types I support are: Chat, BotMessage, GlipSender, Script'].join('\n'), + isMe: false + }]); + setChatInput(''); + setWorkflowContent(''); + }; + return ( <> - { - setWorkFlowName(e.target.value); + setFormJson(json => ({ + ...json, + name: e.target.value + })); }}/> - + + + + + +
- {chatList.map(chat => )} + {chatList.map(chat => )} @@ -84,7 +186,7 @@ export const Create = () => { Supported Action Types: {SupportedBlock.map(label => ( - ))} @@ -96,6 +198,7 @@ export const Create = () => { handleSend(); } }} + autoFocus multiline maxRows={3} value={chatInput}/> @@ -110,14 +213,14 @@ export const Create = () => { - - Preview + + {!previewImg ? 'Workflow Preview...' : + preview} - - + { p: 2, boxShadow: 2, borderTop: 1, + bgcolor: 'background.default', borderColor: 'divider', display: { xs: 'flex' }, justifyContent: "flex-end" }}> diff --git a/src/Home.tsx b/src/Home.tsx index e8631f1..3dd853d 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -3,7 +3,7 @@ * @Date : 2024-04-09 09:27:12 * @LastEditTime : 2024-04-09 09:27:12 * - * + * */ import React from "react"; import { Outlet } from "react-router-dom"; @@ -15,6 +15,7 @@ import Paper from '@mui/material/Paper'; import IconButton from '@mui/material/IconButton'; import AccountCircle from '@mui/icons-material/AccountCircle'; import { styled } from '@mui/material/styles'; +import { RCIcon } from './RCIcon'; const Layout = styled(Box)(({ theme }) => ( { @@ -36,7 +37,7 @@ const Content = styled(Box)(({ theme }) => ({ export const Home = () => { return ( - + { component="div" sx={{ flexGrow: 1, display: { xs: 'block' } }} > + RingCentral AI Workflow Hub diff --git a/src/List.tsx b/src/List.tsx index a09eb4c..6766c96 100644 --- a/src/List.tsx +++ b/src/List.tsx @@ -3,68 +3,132 @@ * @Date : 2024-04-09 09:38:20 * @LastEditTime : 2024-04-09 09:38:20 * - * + * */ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import CardActionArea from '@mui/material/CardActionArea'; import Switch from '@mui/material/Switch'; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import AddIcon from '@mui/icons-material/Add'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; +import { RCIcon } from './RCIcon'; +import axios from "axios"; +import Container from '@mui/material/Container'; - -interface ListItem { - id: string; - active: boolean; - title: string; -} +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import TextField from '@mui/material/TextField'; const Flex = styled(Box)(() => ({ display: 'flex', + flexWrap: 'wrap' })); +interface Workflow { + description: string; + id: string; + name: string; +} + export const List = () => { - const [list] = useState([{ - id: 'a', - title: 'Workflow 1', - active: true - }]); + const [list, setList] = useState([]); + const [showModal, setShowModal] = useState(false); + + const navigate = useNavigate(); + useEffect(() => { + axios.get<{ + total: number + workflows: Workflow[] + }>('/api/public/wf/config/v1/account/10086/workflows').then(({ data }) => { + setList(data.workflows); + }); + }, []); + const handleOpen = () => { + setShowModal(true); + }; + const handleClose = () => { + setShowModal(false); + }; + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const formJson = Object.fromEntries((formData as any).entries()); + axios.post('/bot/workflow', { name: formJson.name }).then(({ data }) => { + sessionStorage.setItem(`create-${data.visibleId}`, JSON.stringify({ ...data, name: formJson.name })); + handleClose(); + navigate(`/create?id=${data.visibleId}`); + }); + }; return ( - <> + - + - + {list.map(item => ( - + - {item.title} + {item.name || 'My Workflow'} - rc + - + ))} - + + Create Workflow + + + To create a workflow, please name your workflow first. + + + + + + + + + ); }; diff --git a/src/RCIcon.tsx b/src/RCIcon.tsx new file mode 100644 index 0000000..11e18ac --- /dev/null +++ b/src/RCIcon.tsx @@ -0,0 +1,16 @@ +/* + * @Author : Eleanor Mao + * @Date : 2024-04-11 10:41:51 + * @LastEditTime : 2024-04-11 10:41:51 + * + * Copyright © RingCentral. All rights reserved. + */ +import React, { CSSProperties, FC } from "react"; + +export const RCIcon: FC<{ size?: number; style?: CSSProperties }> = ({ size = 20, style }) => { + return ( + rc + ); +}; diff --git a/src/ajax.ts b/src/ajax.ts new file mode 100644 index 0000000..9558dec --- /dev/null +++ b/src/ajax.ts @@ -0,0 +1,127 @@ +/* + * @Author : Eleanor Mao + * @Date : 2024-04-11 10:14:35 + * @LastEditTime : 2024-04-11 10:14:35 + * + * Copyright © RingCentral. All rights reserved. + */ +import axios from 'axios'; +import type { AxiosHeaders, AxiosError } from 'axios'; +import qs from 'qs'; +import { isFunction } from 'lodash'; + +type Params = { + [key: string]: string +} + +interface Props { + urlParams?: { + [key: string]: string + }; + paramsSerializer?: (params: Params) => string; + timeoutCallback?: (error: any) => void; + cancelCallback?: (error: any) => void; + arrayFormat?: 'repeat' | 'brackets' | 'comma' | 'indices'; + allowDots?: boolean; + headers?: AxiosHeaders; +} + +type IFunc = (url: string, data?: any, options?: Props) => Promise + +export interface Ajax { + post?: IFunc; + get?: IFunc; + put?: IFunc; + delete?: IFunc; + patch?: IFunc; +} + +type METHODS = ['post', 'get', 'put', 'delete', 'patch'] + +const methods: METHODS = ['post', 'get', 'put', 'delete', 'patch']; +const ins: Ajax = {}; + + +axios.defaults.headers.post['Content-Type'] = 'application/json'; +axios.defaults.headers.get.Accept = 'application/json'; +axios.defaults.timeout = 9500; + +const format = function ( + url: string, + obj: { + [key: string]: string + } +) { + let ret = url; + for (const key of Object.keys(obj)) { + ret = ret.replace('{' + key + '}', obj[key]); + } + return ret; +}; + + +methods.forEach(method => { + ins[method] = (url, data, options = {}) => { + data = data || {}; + + + if (options.urlParams) { + url = format(url, options.urlParams); + } + + if (method === 'get') { + data = { params: data }; + } else { + if ( + !(data instanceof FormData) && + options.headers && + options.headers['Content-Type'] === 'application/x-www-form-urlencoded' + ) { + data = qs.stringify(data, { + arrayFormat: options.arrayFormat ? options.arrayFormat : 'repeat', + allowDots: options.allowDots + }); + } + data = { data }; + } + + const promise = new Promise((resolve, reject) => { + return axios({ + url, + method, + ...data, + withCredentials: true, + timeout: 9500, + ...options + }) + .then(response => { + return response.data; + }) + .then(response => { + if (response instanceof Blob) { + resolve(response); + } + if (response.code === 0 || response.code === 200) { + resolve(response.data); + } else { + reject(response); + } + }) + .catch((error: AxiosError) => { + if (axios.isCancel(error)) { + return isFunction(options.cancelCallback) ? options.cancelCallback(error) : undefined; + } + + // https://github.com/axios/axios/issues/660 + // @ts-ignore + if (error.code === 'ECONNABORTED' && isFunction(options.timeoutCallback)) { + return options.timeoutCallback(error); + } + reject(error); + }); + }); + + return promise; + }; +}); + diff --git a/src/index.tsx b/src/index.tsx index bac1d68..e22181c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,30 +7,33 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { ThemeProvider, createTheme } from '@mui/material/styles'; -import {} from '@mui/material/colors'; - import CssBaseline from '@mui/material/CssBaseline'; + const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement + document.getElementById('root') as HTMLElement ); const theme = createTheme({ - palette: { - mode: 'light', - primary: { - main: '#3f51b5', + palette: { + mode: 'dark', + primary: { + main: '#3f51b5', + }, + tonalOffset: 0.6, + secondary: { + main: '#f50057', + }, + background: { + paper: '#404041', + default: '#242425', + }, }, - tonalOffset: 0.6, - secondary: { - main: '#f50057', - }, - }, }); root.render( - - - - - - + + + + + + ); diff --git a/src/loadYml.ts b/src/loadYml.ts index 6542cfa..f434192 100644 --- a/src/loadYml.ts +++ b/src/loadYml.ts @@ -23,8 +23,59 @@ function compress(s: string, pre: string): string { return "http://www.plantuml.com/plantuml" + pre + encode64_(compressed); } -export function loadYml(input: string): string { - const definition = jsYaml.load(input); - let outputValue = transformDSL(definition); - return compress(outputValue, '/svg/'); +export interface EventHandlerAction { + actionType: string; + targetState?: string; + scriptSource?: string; + transitionName?:string } + +export interface Action { + actionType: string; + scriptSource?: string; + id?: string; + question?: string; + score?: null; + token?: string; + type?: string; + content?:string; + subject?:string; + to?:string +} + +export interface EventHandler { + eventType: string; + condition?: any; + actions: EventHandlerAction[]; +} + +export interface State { + name: string; + actions: Action[]; + eventHandlers: EventHandler[]; +} + +export interface Definition { + states: State[]; + workflowName: string; +} + +export function Json2Preview(definition?: Definition): string { + if (!definition) return ''; + try { + console.log(transformDSL(definition)) + return compress(transformDSL(definition), '/svg/'); + } catch (e) { + console.error(e); + return ''; + } +} + +export function DSL2Json(input: string): Definition { + return jsYaml.load(input) as Definition; +} + +// @ts-ignore +window.ToJson = DSL2Json +// @ts-ignore +window.transform = transformDSL diff --git a/src/transform.ts b/src/transform.ts index 1266e28..943394b 100644 --- a/src/transform.ts +++ b/src/transform.ts @@ -1,24 +1,18 @@ +import { Action, Definition, State } from "./loadYml"; + const EVENT_COLOR = "#LightYellow"; const HTTP_COLOR = "#Peru"; const SCRIPT_COLOR = "#Olive;text:white"; const BOT_COLOR = "#Blue;text:white"; const EMAIL_SENDER_COLOR = "#Red;text:white"; +const DEFAULT_COLOR = '#Grey;text;white'; const EVENT_NAME = ": Event"; const HTTP_NAME = ": Http"; const SCRIPT_NAME = ": Script"; const BOT_NAME = ": Chat"; const EMAIL_SENDER_NAME = ": EmailSender"; - -interface Action { - actionType: string; -} - -interface State { - name: string; - actions: Action[]; - eventHandlers: any; -} +const EXIT_NAME = ": Exit"; function isHttp(actions: Action[]): boolean { return actions @@ -35,6 +29,10 @@ function isChat(actions: Action[]): boolean { .some((action) => action.actionType === 'Chat'); } +function isExit(actions: Action[]): boolean { + return actions.some((action) => action.actionType === 'Exit'); +} + function isEmailSender(actions: Action[]): boolean { return actions .some((action) => action.actionType === "EmailSender"); @@ -48,7 +46,7 @@ function isNotBlank(str: string): boolean { return str !== undefined && str !== null && str.trim() !== ""; } -function drawState(eventState: Map, state: State): string { +function drawState(eventState: Map>, state: State): string { let sb = ""; const name = state.name; const actions = state.actions; @@ -57,7 +55,7 @@ function drawState(eventState: Map, state: State): string { if (isEmpty(handlers)) { throw Error(`state ${name} handlers must not empty`); } - let events = new Set(); + let events = new Set(); for (const handle of handlers) { const stateName = handle.eventType; events.add(stateName); @@ -74,20 +72,21 @@ function drawState(eventState: Map, state: State): string { } else if (isEmailSender(actions)) { sb += `state ${name} ${EMAIL_SENDER_COLOR} ${EMAIL_SENDER_NAME}\n`; } else { - throw Error(`state ${name} actions is incorrect`); + console.log('====', name, actions); + // throw Error(`state ${name} actions is incorrect`); } } return sb; } -function append(from:any, to:any, description:any) { +function append(from: any, to: any, description: any) { if (isNotBlank(description)) { description = ": " + description; } - return `${from} ---> ${to}${description}\n`; + return `${from} ---> ${to || ''}${description}\n`; } -function wrapCond(cond:any) { +function wrapCond(cond: any) { if (isNotBlank(cond)) { return "(" + cond + ")"; } else { @@ -95,7 +94,7 @@ function wrapCond(cond:any) { } } -function drawTransitionCondition(eventCondition:any, transition:any) { +function drawTransitionCondition(eventCondition: any, transition: any) { const list = []; if (eventCondition !== undefined && eventCondition !== null) { list.push(eventCondition); @@ -111,7 +110,7 @@ function drawTransitionCondition(eventCondition:any, transition:any) { return list.join(" && "); } -function drawExitCondition(eventCondition:any, exit:any) { +function drawExitCondition(eventCondition: any, exit: any) { const list = []; if (eventCondition !== undefined && eventCondition !== null) { list.push(eventCondition); @@ -122,7 +121,7 @@ function drawExitCondition(eventCondition:any, exit:any) { return list.join(" && "); } -function drawStateLine(eventState:any, state:any) { +function drawStateLine(eventState: Map>, state: State) { const handlers = state.eventHandlers; if (isEmpty(handlers)) { return; @@ -141,13 +140,13 @@ function drawStateLine(eventState:any, state:any) { const actions = handler.actions; for (const action of actions) { const actionType = action.actionType; - let targetState = action.targetState; + let targetState = action.targetState || ''; if (actionType === "Transition") { if (eventState.has(targetState)) { let events = eventState.get(targetState); - if (events.size > 1) { + if (events && events.size > 1) { continue; - } else { + } else if (events) { targetState = events.values().next().value; } } @@ -162,15 +161,15 @@ function drawStateLine(eventState:any, state:any) { return sb; } -export function transformDSL(definition: any): string { +export function transformDSL(definition: Definition): string { let sb = ""; - const eventState = new Map(); - const states = definition["states"]; + const eventState = new Map>(); + const states = definition["states"] || []; for (const state of states) { - sb += drawState(eventState, state); + sb += drawState(eventState, state) || ''; } for (const state of states) { - sb += drawStateLine(eventState, state); + sb += drawStateLine(eventState, state) || ''; } return `@startuml diff --git a/yarn.lock b/yarn.lock index 8a5087c..9ec15d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2407,7 +2407,7 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.8.tgz#95f6c6a08f2ad868ba230ead1d2d7f7be3db3837" integrity sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw== -"@types/qs@*": +"@types/qs@*", "@types/qs@^6.9.14": version "6.9.14" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.14.tgz#169e142bfe493895287bee382af6039795e9b75b" integrity sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA== @@ -3123,6 +3123,15 @@ axe-core@=4.7.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== +axios@^1.6.8: + version "1.6.8" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" + integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" @@ -5062,7 +5071,7 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -follow-redirects@^1.0.0: +follow-redirects@^1.0.0, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -5110,6 +5119,15 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -8161,6 +8179,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -8183,6 +8206,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@^6.12.0: + version "6.12.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.0.tgz#edd40c3b823995946a8a0b1f208669c7a200db77" + integrity sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg== + dependencies: + side-channel "^1.0.6" + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"