diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 843cdb8b2..2a7f6e9c4 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -40,13 +40,13 @@ export default function ParameterComponent({ info = "", }: ParameterComponentType): JSX.Element { const ref = useRef(null); - const refHtml = useRef(null); - const infoHtml = useRef(null); + const refHtml = useRef(null); + const infoHtml = useRef(null); const updateNodeInternals = useUpdateNodeInternals(); const [position, setPosition] = useState(0); const { setTabsState, tabId, save, flows } = useContext(TabsContext); - const flow = flows.find((f) => f.id === tabId).data?.nodes ?? null; + const flow = flows.find((f) => f.id === tabId)?.data?.nodes ?? null; // Update component position useEffect(() => { @@ -68,7 +68,7 @@ export default function ParameterComponent({ const handleOnNewValue = (newValue: string | string[] | boolean): void => { let newData = cloneDeep(data); - newData.node.template[name].value = newValue; + newData.node!.template[name].value = newValue; setData(newData); // Set state to pending setTabsState((prev) => { @@ -99,6 +99,7 @@ export default function ParameterComponent({ function renderTooltips() { let groupedObj = groupByFamily(myData, tooltipTitle, left, flow); + console.log(groupedObj) if (groupedObj && groupedObj.length > 0) { refHtml.current = groupedObj.map((item, i) => { @@ -207,7 +208,7 @@ export default function ParameterComponent({ position={left ? Position.Left : Position.Right} id={id} isValidConnection={(connection) => - isValidConnection(connection, reactFlowInstance) + isValidConnection(connection, reactFlowInstance!) } className={classNames( left ? "-ml-0.5 " : "-mr-0.5 ", @@ -255,7 +256,7 @@ export default function ParameterComponent({
{ handleOnNewValue(t); }} @@ -283,7 +284,7 @@ export default function ParameterComponent({ ) : left === true && type === "code" ? (
{ data.node = nodeClass; }} @@ -302,7 +303,7 @@ export default function ParameterComponent({ fileTypes={data.node?.template[name].fileTypes} suffixes={data.node?.template[name].suffixes} onFileChange={(t: string) => { - data.node.template[name].file_path = t; + data.node!.template[name].file_path = t; save(); }} > diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 69185b3a3..8f788cc02 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -13,6 +13,7 @@ import { cleanEdges } from "../../utils/reactflowUtils"; import { nodeColors, nodeIconsLucide } from "../../utils/styleUtils"; import { classNames, toTitleCase } from "../../utils/utils"; import ParameterComponent from "./components/parameterComponent"; +import { validationStatusType } from "../../types/components"; export default function GenericNode({ data: olddata, @@ -26,7 +27,7 @@ export default function GenericNode({ const updateNodeInternals = useUpdateNodeInternals(); const { types, deleteNode, reactFlowInstance } = useContext(typesContext); const name = nodeIconsLucide[data.type] ? data.type : types[data.type]; - const [validationStatus, setValidationStatus] = useState(null); + const [validationStatus, setValidationStatus] = useState(null); // State for outline color const { sseData, isBuilding } = useSSE(); useEffect(() => { @@ -77,7 +78,7 @@ export default function GenericNode({ "generic-node-div" )} > - {data.node.beta && ( + {data.node?.beta && (
BETA
@@ -114,6 +115,7 @@ export default function GenericNode({ ) : (
+ {typeof validationStatus.params === "string" ? validationStatus.params .split("\n") @@ -160,16 +162,16 @@ export default function GenericNode({
{data.node?.description}
<> - {Object.keys(data.node.template) + {Object.keys(data.node!.template) .filter((t) => t.charAt(0) !== "_") .map((t: string, idx) => (
- {data.node.template[t].show && - !data.node.template[t].advanced ? ( + {data.node!.template[t].show && + !data.node!.template[t].advanced ? ( {" "}
diff --git a/src/frontend/src/components/AccordionComponent/index.tsx b/src/frontend/src/components/AccordionComponent/index.tsx index e7cd92081..e00932c76 100644 --- a/src/frontend/src/components/AccordionComponent/index.tsx +++ b/src/frontend/src/components/AccordionComponent/index.tsx @@ -29,7 +29,7 @@ export default function AccordionComponent({ } function handleClick(): void { - value === "" ? setValue(keyValue) : setValue(""); + value === "" ? setValue(keyValue!) : setValue(""); } return ( @@ -40,7 +40,7 @@ export default function AccordionComponent({ value={value} onValueChange={setValue} > - + { handleClick(); diff --git a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx index bfafb5dd9..eedb36495 100644 --- a/src/frontend/src/components/EditFlowSettingsComponent/index.tsx +++ b/src/frontend/src/components/EditFlowSettingsComponent/index.tsx @@ -18,7 +18,7 @@ export const EditFlowSettings: React.FC = ({ updateFlow, }: InputProps): JSX.Element => { const [isMaxLength, setIsMaxLength] = useState(false); - const nameLists = useRef([]); + const nameLists = useRef([]); useEffect(() => { readFlowsFromDatabase().then((flows) => { flows.forEach((flow) => { @@ -47,7 +47,7 @@ export const EditFlowSettings: React.FC = ({ ); const handleDescriptionChange = (event: ChangeEvent) => { - flows.find((f) => f.id === tabId).description = event.target.value; + flows.find((f) => f.id === tabId)!.description = event.target.value; setDesc(flows.find((f) => f.id === tabId)?.description); setDescription(event.target.value); }; diff --git a/src/frontend/src/components/RadialProgress/index.tsx b/src/frontend/src/components/RadialProgress/index.tsx index f5160c40b..5c46fd6b8 100644 --- a/src/frontend/src/components/RadialProgress/index.tsx +++ b/src/frontend/src/components/RadialProgress/index.tsx @@ -5,14 +5,14 @@ export default function RadialProgressComponent({ color, }: RadialProgressType): JSX.Element { const style = { - "--value": value * 100, + "--value": value! * 100, "--size": "1.5rem", "--thickness": "2px", } as React.CSSProperties; return (
- {Math.trunc(value * 100)}% + {Math.trunc(value! * 100)}%
); } diff --git a/src/frontend/src/components/ReactTooltipComponent/index.tsx b/src/frontend/src/components/ReactTooltipComponent/index.tsx index 9103ae21c..18eb67b33 100644 --- a/src/frontend/src/components/ReactTooltipComponent/index.tsx +++ b/src/frontend/src/components/ReactTooltipComponent/index.tsx @@ -27,7 +27,7 @@ const TooltipReact: FC = ({ content={content} className={classNames( "z-[9999] !bg-white !text-xs !font-normal !text-foreground !opacity-100 !shadow-md", - className + className! )} place={position} clickable={clickable} diff --git a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx index b7ecda920..25053fbeb 100644 --- a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx +++ b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx @@ -36,7 +36,7 @@ export default function BuildTrigger({ if (isBuilding) { return; } - const errors = validateNodes(reactFlowInstance); + const errors = validateNodes(reactFlowInstance!); if (errors.length > 0) { setErrorData({ title: "Oops! Looks like you missed something", diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index e6bc3999d..043dd208f 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -48,7 +48,7 @@ export default function Chat({ flow }: ChatType): JSX.Element { useEffect(() => { const prevNodes = prevNodesRef.current; const currentNodes = nodes.map((node: NodeType) => - _.cloneDeep(node.data.node.template) + _.cloneDeep(node.data.node?.template) ); if ( tabsState && @@ -63,7 +63,7 @@ export default function Chat({ flow }: ChatType): JSX.Element { tabsState[flow.id] && tabsState[flow.id].formKeysData && tabsState[flow.id].formKeysData.input_keys && - Object.keys(tabsState[flow.id].formKeysData.input_keys).length > 0 + Object.keys(tabsState[flow.id].formKeysData.input_keys!).length > 0 ) { setCanOpen(true); } else { diff --git a/src/frontend/src/components/codeAreaComponent/index.tsx b/src/frontend/src/components/codeAreaComponent/index.tsx index 05e8127da..5a37dfc3c 100644 --- a/src/frontend/src/components/codeAreaComponent/index.tsx +++ b/src/frontend/src/components/codeAreaComponent/index.tsx @@ -33,7 +33,7 @@ export default function CodeAreaComponent({ dynamic={dynamic} value={myValue} nodeClass={nodeClass} - setNodeClass={setNodeClass} + setNodeClass={setNodeClass!} setValue={(t: string) => { setMyValue(t); onChange(t); diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index c6527caf0..97db8c4af 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -43,7 +43,7 @@ export default function CodeTabsComponent({ }: codeTabsPropsType) { const [isCopied, setIsCopied] = useState(false); const [data, setData] = useState(flow ? flow["data"]["nodes"] : null); - const [openAccordion, setOpenAccordion] = useState([]); + const [openAccordion, setOpenAccordion] = useState([]); const { dark } = useContext(darkContext); useEffect(() => { @@ -89,8 +89,8 @@ export default function CodeTabsComponent({ }; function openAccordions() { - let accordionsToOpen = []; - tweaks?.tweak.current.forEach((el) => { + let accordionsToOpen: string[] = []; + tweaks?.tweak!.current.forEach((el) => { Object.keys(el).forEach((key) => { if (Object.keys(el[key]).length > 0) { accordionsToOpen.push(key); @@ -190,7 +190,7 @@ export default function CodeTabsComponent({ > {data?.map((t: any, index) => (
- {tweaks?.tweaksList.current.includes(t["data"]["id"]) && ( + {tweaks?.tweaksList!.current.includes(t["data"]["id"]) && ( { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -278,7 +278,7 @@ export default function CodeTabsComponent({ ) : t.data.node.template[n] .multiline ? ( { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node @@ -342,14 +342,14 @@ export default function CodeTabsComponent({ setData((old) => { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -371,14 +371,14 @@ export default function CodeTabsComponent({ setData((old) => { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = e; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], e, t.data.node.template[n] @@ -391,7 +391,7 @@ export default function CodeTabsComponent({ ) : t.data.node.template[n].type === "file" ? ( { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -478,14 +478,14 @@ export default function CodeTabsComponent({ setData((old) => { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -521,14 +521,14 @@ export default function CodeTabsComponent({ setData((old) => { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -539,7 +539,7 @@ export default function CodeTabsComponent({ ) : t.data.node.template[n].type === "prompt" ? ( { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -586,8 +586,8 @@ export default function CodeTabsComponent({ ) : t.data.node.template[n].type === "code" ? ( { let newInputList = cloneDeep(old); - newInputList[ + newInputList![ index ].data.node.template[ n ].value = k; return newInputList; }); - tweaks.buildTweakObject( + tweaks.buildTweakObject!( t["data"]["id"], k, t.data.node.template[n] @@ -646,7 +646,7 @@ export default function CodeTabsComponent({ )} - {tweaks?.tweaksList.current.length === 0 && ( + {tweaks?.tweaksList!.current.length === 0 && ( <>
No tweaks are available for this flow. diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx index 22de840dd..335e3d43e 100644 --- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx +++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx @@ -26,7 +26,7 @@ export const MenuBar = ({ flows, tabId }: menuBarPropsType): JSX.Element => { function handleAddFlow() { try { - addFlow(null, true).then((id) => { + addFlow(null!, true).then((id) => { navigate("/flow/" + id); }); // saveFlowStyleInDataBase(); @@ -46,7 +46,7 @@ export const MenuBar = ({ flows, tabId }: menuBarPropsType): JSX.Element => { diff --git a/src/frontend/src/components/promptComponent/index.tsx b/src/frontend/src/components/promptComponent/index.tsx index cf05b34f9..1350f5733 100644 --- a/src/frontend/src/components/promptComponent/index.tsx +++ b/src/frontend/src/components/promptComponent/index.tsx @@ -23,9 +23,9 @@ export default function PromptAreaComponent({ useEffect(() => { if (value !== "" && !editNode) { - postValidatePrompt(field_name, value, nodeClass).then((apiReturn) => { + postValidatePrompt(field_name!, value, nodeClass!).then((apiReturn) => { if (apiReturn.data) { - setNodeClass(apiReturn.data.frontend_node); + setNodeClass!(apiReturn.data.frontend_node); // need to update reactFlowInstance to re-render the nodes. } }); diff --git a/src/frontend/src/contexts/darkContext.tsx b/src/frontend/src/contexts/darkContext.tsx index d152ced34..091b7577f 100644 --- a/src/frontend/src/contexts/darkContext.tsx +++ b/src/frontend/src/contexts/darkContext.tsx @@ -10,13 +10,13 @@ export const darkContext = createContext(initialValue); export function DarkProvider({ children }) { const [dark, setDark] = useState( - JSON.parse(window.localStorage.getItem("isDark")) ?? false + JSON.parse(window.localStorage.getItem("isDark")!) ?? false ); useEffect(() => { if (dark) { - document.getElementById("body").classList.add("dark"); + document.getElementById("body")!.classList.add("dark"); } else { - document.getElementById("body").classList.remove("dark"); + document.getElementById("body")!.classList.remove("dark"); } window.localStorage.setItem("isDark", dark.toString()); }, [dark]); diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index 5ea8c11c0..85e1346b9 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -153,11 +153,11 @@ export function TabsProvider({ children }: { children: ReactNode }) { } function updateDisplay_name(node: NodeType, template: APIClassType) { - node.data.node.display_name = template["display_name"] || node.data.type; + node.data.node!.display_name = template["display_name"] || node.data.type; } function updateNodeDocumentation(node: NodeType, template: APIClassType) { - node.data.node.documentation = template["documentation"]; + node.data.node!.documentation = template["documentation"]; } function processFlowNodes(flow) { @@ -180,7 +180,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { } function updateNodeBaseClasses(node: NodeType, template: APIClassType) { - node.data.node.base_classes = template["base_classes"]; + node.data.node!.base_classes = template["base_classes"]; } function updateNodeEdges( @@ -191,7 +191,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { flow.data.edges.forEach((edge) => { if (edge.source === node.id) { edge.sourceHandle = edge.sourceHandle - .split("|") + ?.split("|") .slice(0, 2) .concat(template["base_classes"]) .join("|"); @@ -200,13 +200,13 @@ export function TabsProvider({ children }: { children: ReactNode }) { } function updateNodeDescription(node: NodeType, template: APIClassType) { - node.data.node.description = template["description"]; + node.data.node!.description = template["description"]; } function updateNodeTemplate(node: NodeType, template: APIClassType) { - node.data.node.template = updateTemplate( + node.data.node!.template = updateTemplate( template["template"] as unknown as APITemplateType, - node.data.node.template as APITemplateType + node.data.node!.template as APITemplateType ); } @@ -241,7 +241,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { link.download = `${ flowName && flowName != "" ? flowName - : flows.find((f) => f.id === tabId).name + : flows.find((f) => f.id === tabId)!.name }.json`; // simulate a click on the link element to trigger the download @@ -293,10 +293,10 @@ export function TabsProvider({ children }: { children: ReactNode }) { input.onchange = (e: Event) => { // check if the file type is application/json if ( - (e.target as HTMLInputElement).files[0].type === "application/json" + (e.target as HTMLInputElement).files![0].type === "application/json" ) { // get the file from the file input - const currentfile = (e.target as HTMLInputElement).files[0]; + const currentfile = (e.target as HTMLInputElement).files![0]; // read the file as text currentfile.text().then((text) => { // parse the text into a JSON object @@ -318,9 +318,9 @@ export function TabsProvider({ children }: { children: ReactNode }) { // add a change event listener to the file input input.onchange = (e: Event) => { // check if the file type is application/json - if ((e.target as HTMLInputElement).files[0].type === "application/json") { + if ((e.target as HTMLInputElement).files![0].type === "application/json") { // get the file from the file input - const file = (e.target as HTMLInputElement).files[0]; + const file = (e.target as HTMLInputElement).files![0]; // read the file as text const formData = new FormData(); formData.append("file", file); @@ -357,8 +357,8 @@ export function TabsProvider({ children }: { children: ReactNode }) { let minimumX = Infinity; let minimumY = Infinity; let idsMap = {}; - let nodes = reactFlowInstance.getNodes(); - let edges = reactFlowInstance.getEdges(); + let nodes = reactFlowInstance!.getNodes(); + let edges = reactFlowInstance!.getEdges(); selectionInstance.nodes.forEach((n) => { if (n.position.y < minimumY) { minimumY = n.position.y; @@ -369,8 +369,8 @@ export function TabsProvider({ children }: { children: ReactNode }) { }); const insidePosition = position.paneX - ? { x: position.paneX + position.x, y: position.paneY + position.y } - : reactFlowInstance.project({ x: position.x, y: position.y }); + ? { x: position.paneX + position.x, y: position.paneY! + position.y } + : reactFlowInstance!.project({ x: position.x, y: position.y }); selectionInstance.nodes.forEach((n: NodeType) => { // Generate a unique node ID @@ -396,7 +396,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { .map((e) => ({ ...e, selected: false })) .concat({ ...newNode, selected: false }); }); - reactFlowInstance.setNodes(nodes); + reactFlowInstance!.setNodes(nodes); selectionInstance.edges.forEach((e) => { let source = idsMap[e.source]; @@ -436,13 +436,13 @@ export function TabsProvider({ children }: { children: ReactNode }) { edges.map((e) => ({ ...e, selected: false })) ); }); - reactFlowInstance.setEdges(edges); + reactFlowInstance!.setEdges(edges); } const addFlow = async ( flow?: FlowType, newProject?: Boolean - ): Promise => { + ): Promise => { if (newProject) { let flowData = extractDataFromFlow(flow); if (flowData.description == "") { @@ -475,7 +475,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { } } else { paste( - { nodes: flow.data.nodes, edges: flow.data.edges }, + { nodes: flow!.data.nodes, edges: flow!.data.edges }, { x: 10, y: 10 } ); } diff --git a/src/frontend/src/contexts/typesContext.tsx b/src/frontend/src/contexts/typesContext.tsx index d4523bf60..011ca0269 100644 --- a/src/frontend/src/contexts/typesContext.tsx +++ b/src/frontend/src/contexts/typesContext.tsx @@ -69,7 +69,7 @@ export function TypesProvider({ children }: { children: ReactNode }) { ); } // Clear the interval if successful. - clearInterval(intervalId); + clearInterval(intervalId!); } catch (error) { console.error("An error has occurred while fetching types."); } @@ -80,18 +80,18 @@ export function TypesProvider({ children }: { children: ReactNode }) { return () => { // This will clear the interval when the component unmounts, or when the dependencies of the useEffect hook change. - clearInterval(intervalId); + clearInterval(intervalId!); // Indicate that the component has been unmounted. isMounted = false; }; }, []); function deleteNode(idx: string) { - reactFlowInstance.setNodes( - reactFlowInstance.getNodes().filter((n: Node) => n.id !== idx) + reactFlowInstance!.setNodes( + reactFlowInstance!.getNodes().filter((n: Node) => n.id !== idx) ); - reactFlowInstance.setEdges( - reactFlowInstance + reactFlowInstance!.setEdges( + reactFlowInstance! .getEdges() .filter((ns) => ns.source !== idx && ns.target !== idx) ); diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index 9e716ebb7..9c785e843 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -16,7 +16,7 @@ function ApiInterceptor() { const interceptor = api.interceptors.response.use( (response) => response, async (error: AxiosError) => { - if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url)) { + if (URL_EXCLUDED_FROM_ERROR_RETRIES.includes(error.config?.url!)) { return Promise.reject(error); } let retryCount = 0; @@ -25,7 +25,7 @@ function ApiInterceptor() { await sleep(5000); // Sleep for 5 seconds retryCount++; try { - const response = await axios.request(error.config); + const response = await axios.request(error.config!); return response; } catch (error) { if (retryCount === 3) { diff --git a/src/frontend/src/icons/PowerPoint/index.tsx b/src/frontend/src/icons/PowerPoint/index.tsx index 89d6fb53b..19dae1e6e 100644 --- a/src/frontend/src/icons/PowerPoint/index.tsx +++ b/src/frontend/src/icons/PowerPoint/index.tsx @@ -1,9 +1,9 @@ import React, { forwardRef } from "react"; -import { ReactComponent as PowerPointSVG } from "./PowerPoint.svg"; +import SvgPowerPoint from "./PowerPoint"; export const PowerPointIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { - return ; + return ; }); diff --git a/src/frontend/src/modals/EditNodeModal/index.tsx b/src/frontend/src/modals/EditNodeModal/index.tsx index d5bc970c3..50f7c41c1 100644 --- a/src/frontend/src/modals/EditNodeModal/index.tsx +++ b/src/frontend/src/modals/EditNodeModal/index.tsx @@ -55,7 +55,7 @@ const EditNodeModal = forwardRef( function changeAdvanced(n: string): void { setMyData((old) => { let newData = cloneDeep(old); - newData.node.template[n].advanced = !newData.node.template[n].advanced; + newData.node!.template[n].advanced = !newData.node!.template[n].advanced; return newData; }); } @@ -66,7 +66,7 @@ const EditNodeModal = forwardRef( ) => { setMyData((old) => { let newData = cloneDeep(old); - newData.node.template[name].value = newValue; + newData.node!.template[name].value = newValue; return newData; }); }; @@ -78,7 +78,7 @@ const EditNodeModal = forwardRef( return ( {children} - + {myData.type} ID: {myData.id} @@ -113,7 +113,7 @@ const EditNodeModal = forwardRef( - {Object.keys(myData.node.template) + {Object.keys(myData.node!.template) .filter( (t) => t.charAt(0) !== "_" && @@ -158,7 +158,7 @@ const EditNodeModal = forwardRef( value={ myData.node.template[n].value ?? "" } - onChange={(t: string) => { + onChange={(t: string | string[]) => { handleOnNewValue(t, n); }} /> @@ -233,7 +233,7 @@ const EditNodeModal = forwardRef( editNode={true} disabled={disabled} value={myData.node.template[n].value ?? ""} - onChange={(t: string) => { + onChange={(t: string | string[]) => { handleOnNewValue(t, n); }} fileTypes={ @@ -241,7 +241,7 @@ const EditNodeModal = forwardRef( } suffixes={myData.node.template[n].suffixes} onFileChange={(t: string) => { - data.node.template[n].file_path = t; + data.node!.template[n].file_path = t; }} >
@@ -256,7 +256,7 @@ const EditNodeModal = forwardRef( myData.node = nodeClass; }} value={myData.node.template[n].value ?? ""} - onChange={(t: string) => { + onChange={(t: string | string[]) => { handleOnNewValue(t, n); }} /> @@ -265,7 +265,7 @@ const EditNodeModal = forwardRef(
{ data.node = nodeClass; @@ -274,7 +274,7 @@ const EditNodeModal = forwardRef( disabled={disabled} editNode={true} value={myData.node.template[n].value ?? ""} - onChange={(t: string) => { + onChange={(t: string | string[]) => { handleOnNewValue(t, n); }} /> diff --git a/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx b/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx index 4b80248db..c7eb0b1e0 100644 --- a/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx +++ b/src/frontend/src/modals/NodeModal/components/ModalField/index.tsx @@ -75,7 +75,7 @@ export default function ModalField({ { + onChange={(t: string | string[]) => { data.node.template[name].value = t; }} /> @@ -136,7 +136,7 @@ export default function ModalField({ { + onChange={(t: string | string[]) => { data.node.template[name].value = t; }} fileTypes={data.node.template[name].fileTypes} @@ -152,7 +152,7 @@ export default function ModalField({ field_name={name} disabled={false} value={data.node.template[name].value ?? ""} - onChange={(t: string) => { + onChange={(t: string | string[]) => { data.node.template[name].value = t; }} /> @@ -167,7 +167,7 @@ export default function ModalField({ nodeClass={data.node} disabled={false} value={data.node.template[name].value ?? ""} - onChange={(t: string) => { + onChange={(t: string | string[]) => { data.node.template[name].value = t; }} /> diff --git a/src/frontend/src/modals/codeAreaModal/index.tsx b/src/frontend/src/modals/codeAreaModal/index.tsx index 6e40de384..f80f12e25 100644 --- a/src/frontend/src/modals/codeAreaModal/index.tsx +++ b/src/frontend/src/modals/codeAreaModal/index.tsx @@ -28,16 +28,16 @@ export default function CodeAreaModal({ const [code, setCode] = useState(value); const { dark } = useContext(darkContext); const { reactFlowInstance } = useContext(typesContext); - const [height, setHeight] = useState(null); + const [height, setHeight] = useState(null); const { setErrorData, setSuccessData } = useContext(alertContext); const [error, setError] = useState<{ - detail: { error: string; traceback: string }; - }>(null); + detail: { error: string | undefined; traceback: string | undefined }; + } | null>(null); useEffect(() => { // if nodeClass.template has more fields other than code and dynamic is true // do not run handleClick - if (dynamic && Object.keys(nodeClass.template).length > 2) { + if (dynamic && Object.keys(nodeClass!.template).length > 2) { return; } processCode(); @@ -84,7 +84,7 @@ export default function CodeAreaModal({ } function processDynamicField() { - postCustomComponent(code, nodeClass) + postCustomComponent(code, nodeClass!) .then((apiReturn) => { const { data } = apiReturn; if (data) { diff --git a/src/frontend/src/modals/exportModal/index.tsx b/src/frontend/src/modals/exportModal/index.tsx index 55ac18c15..7d797ad66 100644 --- a/src/frontend/src/modals/exportModal/index.tsx +++ b/src/frontend/src/modals/exportModal/index.tsx @@ -31,8 +31,8 @@ const ExportModal = forwardRef( { if (checked) downloadFlow( - flows.find((f) => f.id === tabId), - name, + flows.find((f) => f.id === tabId)!, + name!, description ); else downloadFlow( - removeApiKeys(flows.find((f) => f.id === tabId)), - name, + removeApiKeys(flows.find((f) => f.id === tabId)!), + name!, description ); setOpen(false); diff --git a/src/frontend/src/modals/flowSettingsModal/index.tsx b/src/frontend/src/modals/flowSettingsModal/index.tsx index 00bf8517d..08079f79a 100644 --- a/src/frontend/src/modals/flowSettingsModal/index.tsx +++ b/src/frontend/src/modals/flowSettingsModal/index.tsx @@ -17,17 +17,17 @@ export default function FlowSettingsModal({ const { flows, tabId, updateFlow, setTabsState, saveFlow } = useContext(TabsContext); const maxLength = 50; - const [name, setName] = useState(flows.find((f) => f.id === tabId).name); + const [name, setName] = useState(flows.find((f) => f.id === tabId)!.name); const [description, setDescription] = useState( - flows.find((f) => f.id === tabId).description + flows.find((f) => f.id === tabId)!.description ); const [invalidName, setInvalidName] = useState(false); function handleClick(): void { let savedFlow = flows.find((f) => f.id === tabId); - savedFlow.name = name; - savedFlow.description = description; - saveFlow(savedFlow); + savedFlow!.name = name; + savedFlow!.description = description; + saveFlow(savedFlow!); setSuccessData({ title: "Changes saved successfully" }); setOpen(false); } diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index dfa16da1a..5d1bb5a3c 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -45,11 +45,11 @@ export default function FormModal({ const inputKeys = formKeysData.input_keys; const handleKeys = formKeysData.handle_keys; - const keyToUse = Object.keys(inputKeys).find( - (k) => !handleKeys?.some((j) => j === k) && inputKeys[k] === "" + const keyToUse = Object.keys(inputKeys!).find( + (k) => !handleKeys?.some((j) => j === k) && inputKeys![k] === "" ); - return inputKeys[keyToUse]; + return inputKeys![keyToUse!]; } catch (error) { console.error(error); // return a sensible default or `undefined` if no default is possible @@ -68,10 +68,10 @@ export default function FormModal({ const tabsStateFlowId = tabsState[flow.id]; const tabsStateFlowIdFormKeysData = tabsStateFlowId.formKeysData; const [chatKey, setChatKey] = useState( - Object.keys(tabsState[flow.id].formKeysData.input_keys).find( + Object.keys(tabsState[flow.id].formKeysData.input_keys!).find( (k) => - !tabsState[flow.id].formKeysData.handle_keys.some((j) => j === k) && - tabsState[flow.id].formKeysData.input_keys[k] === "" + !tabsState[flow.id].formKeysData.handle_keys!.some((j) => j === k) && + tabsState[flow.id].formKeysData.input_keys![k] === "" ) ); @@ -211,7 +211,7 @@ export default function FormModal({ }); } if (data.type === "start") { - addChatHistory("", false, chatKey); + addChatHistory("", false, chatKey!); isStream = true; } if (data.type === "end") { @@ -335,16 +335,16 @@ export default function FormModal({ }, [open]); function sendMessage(): void { - let nodeValidationErrors = validateNodes(reactFlowInstance); + let nodeValidationErrors = validateNodes(reactFlowInstance!); if (nodeValidationErrors.length === 0) { setLockChat(true); let inputs = tabsState[id.current].formKeysData.input_keys; setChatValue(""); const message = inputs; addChatHistory( - message, + message!, true, - chatKey, + chatKey!, tabsState[flow.id].formKeysData.template ); sendAll({ @@ -357,7 +357,7 @@ export default function FormModal({ setTabsState((old) => { if (!chatKey) return old; let newTabsState = _.cloneDeep(old); - newTabsState[id.current].formKeysData.input_keys[chatKey] = ""; + newTabsState[id.current].formKeysData.input_keys![chatKey] = ""; return newTabsState; }); } else { @@ -376,9 +376,9 @@ export default function FormModal({ function handleOnCheckedChange(checked: boolean, i: string) { if (checked === true) { setChatKey(i); - setChatValue(tabsState[flow.id].formKeysData.input_keys[i]); + setChatValue(tabsState[flow.id].formKeysData.input_keys![i]); } else { - setChatKey(null); + setChatKey(null!); setChatValue(""); } } @@ -422,7 +422,7 @@ export default function FormModal({
- {Object.keys(tabsState[id.current].formKeysData.input_keys).map( + {Object.keys(tabsState[id.current].formKeysData.input_keys!).map( (i, k) => (
{ setTabsState((old) => { let newTabsState = _.cloneDeep(old); - newTabsState[id.current].formKeysData.input_keys[ + newTabsState[id.current].formKeysData.input_keys![ i ] = e.target.value; return newTabsState; @@ -578,7 +578,7 @@ export default function FormModal({ setChatValue(value); setTabsState((old) => { let newTabsState = _.cloneDeep(old); - newTabsState[id.current].formKeysData.input_keys[ + newTabsState[id.current].formKeysData.input_keys![ chatKey ] = value; return newTabsState; diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index 4deac515f..824921a2f 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -39,7 +39,7 @@ export default function GenericModal({ const [myModalType] = useState(type); const [inputValue, setInputValue] = useState(value); const [isEdit, setIsEdit] = useState(true); - const [wordsHighlight, setWordsHighlight] = useState([]); + const [wordsHighlight, setWordsHighlight] = useState([]); const { setErrorData, setSuccessData, setNoticeData } = useContext(alertContext); const ref = useRef(); @@ -48,14 +48,14 @@ export default function GenericModal({ function checkVariables(valueToCheck: string): void { const regex = /\{([^{}]+)\}/g; - const matches = []; + const matches: string[] = []; let match; while ((match = regex.exec(valueToCheck))) { matches.push(`{${match[1]}}`); } - let invalid_chars = []; - let fixed_variables = []; + let invalid_chars: string[] = []; + let fixed_variables: string[] = []; let input_variables = matches; for (let variable of input_variables) { let new_var = variable; @@ -120,7 +120,7 @@ export default function GenericModal({ } function validatePrompt(closeModal: boolean): void { - postValidatePrompt(field_name, inputValue, nodeClass) + postValidatePrompt(field_name, inputValue, nodeClass!) .then((apiReturn) => { if (apiReturn.data) { let inputVariables = apiReturn.data.input_variables ?? []; @@ -134,7 +134,7 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); - setNodeClass(apiReturn.data?.frontend_node); + setNodeClass!(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); } diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 78eb32b67..13d0019dc 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -57,7 +57,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element { const [position, setPosition] = useState({ x: 0, y: 0 }); const [lastSelection, setLastSelection] = - useState(null); + useState(null); useEffect(() => { // this effect is used to attach the global event handlers @@ -281,7 +281,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element { setNodes((nds) => nds.concat(newNode)); } else if (event.dataTransfer.types.some((t) => t === "Files")) { takeSnapshot(); - uploadFlow(false, event.dataTransfer.files.item(0)); + uploadFlow(false, event.dataTransfer.files.item(0)!); } }, // Specify dependencies for useCallback @@ -314,7 +314,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element { const onEdgeUpdate = useCallback( (oldEdge: Edge, newConnection: Connection) => { - if (isValidConnection(newConnection, reactFlowInstance)) { + if (isValidConnection(newConnection, reactFlowInstance!)) { edgeUpdateSuccessful.current = true; setEdges((els) => updateEdge(oldEdge, newConnection, els)); } @@ -404,7 +404,7 @@ export default function Page({ flow }: { flow: FlowType }): JSX.Element { [&>button]:border-b-border hover:[&>button]:bg-border" > - +
) : ( <> diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index 09e5e3258..e6a317c7a 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -120,7 +120,7 @@ export default function ExtraSidebar(): JSX.Element { "extra-side-bar-buttons " + (isPending ? "" : "button-disable") } onClick={(event) => { - saveFlow(flow); + saveFlow(flow!); setSuccessData({ title: "Changes saved successfully" }); }} > diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index e5c4d85c7..699caae0b 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -13,7 +13,7 @@ export default function NodeToolbarComponent({ deleteNode, }: nodeToolbarPropsType): JSX.Element { const [nodeLength, setNodeLength] = useState( - Object.keys(data.node.template).filter( + Object.keys(data.node!.template).filter( (t) => t.charAt(0) !== "_" && data.node?.template[t].show && diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index e854e35d9..c8231cfd2 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -10,7 +10,7 @@ export default function FlowPage(): JSX.Element { // Set flow tab id useEffect(() => { - setTabId(id); + setTabId(id!); }, [id]); // Initialize state variable for the version @@ -26,7 +26,7 @@ export default function FlowPage(): JSX.Element { {flows.length > 0 && tabId !== "" && flows.findIndex((flow) => flow.id === tabId) !== -1 && ( - flow.id === tabId)} /> + flow.id === tabId)!} /> )} { - addFlow(null, true).then((id) => { + addFlow(null!, true).then((id) => { navigate("/flow/" + id); }); }} diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 5cde1fa8f..5cc6863fc 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -180,7 +180,7 @@ export type InputProps = { invalidName: boolean; setName: (name: string) => void; setDescription: (description: string) => void; - updateFlow: (flow: { id: string; name: string }) => void; + updateFlow: (flow: { id: string; name: string; }) => void; setInvalidName: (invalidName: boolean) => void; }; @@ -208,7 +208,6 @@ export interface languageMap { } export type groupedObjType = { - component: string; family: string; type: string; }; @@ -384,6 +383,7 @@ type tabsArrayType = { language: string; mode: string; name: string; + description: string; }; type getValueNodeType = { @@ -427,3 +427,10 @@ export type crashComponentPropsType = { }; resetErrorBoundary: (args) => void; }; + +export type validationStatusType = { + id: string; + params: string; + progress: number; + valid: boolean; +}; diff --git a/src/frontend/src/types/flow/index.ts b/src/frontend/src/types/flow/index.ts index e1a2fda2a..de6e6bc59 100644 --- a/src/frontend/src/types/flow/index.ts +++ b/src/frontend/src/types/flow/index.ts @@ -11,7 +11,7 @@ export type FlowType = { export type NodeType = { id: string; type?: string; - position: XYPosition; + position: XYPosition | undefined; data: NodeDataType; }; export type NodeDataType = { diff --git a/src/frontend/src/utils/reactflowUtils.ts b/src/frontend/src/utils/reactflowUtils.ts index 94a20d586..cbf37a741 100644 --- a/src/frontend/src/utils/reactflowUtils.ts +++ b/src/frontend/src/utils/reactflowUtils.ts @@ -38,7 +38,7 @@ export function cleanEdges({ const id = [ sourceNode.data.type, sourceNode.data.id, - ...sourceNode.data.node?.base_classes, + ...sourceNode.data.node?.base_classes!, ].join("|"); if (id !== sourceHandle) { newEdges = newEdges.filter((e) => e.id !== edge.id); @@ -69,7 +69,7 @@ export function isValidConnection( ) || targetHandle?.split("|")[0] === "str" ) { - let targetNode = reactFlowInstance?.getNode(target)?.data?.node; + let targetNode = reactFlowInstance?.getNode(target!)?.data?.node; if (!targetNode) { if ( !reactFlowInstance @@ -79,11 +79,11 @@ export function isValidConnection( return true; } } else if ( - (!targetNode.template[targetHandle?.split("|")[1]].list && + (!targetNode.template[targetHandle?.split("|")[1]!].list && !reactFlowInstance .getEdges() .find((e) => e.targetHandle === targetHandle)) || - targetNode.template[targetHandle?.split("|")[1]].list + targetNode.template[targetHandle?.split("|")[1]!].list ) { return true; } diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 4e871bceb..8a1f7fb7a 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -5,6 +5,7 @@ import { IVarHighlightType, groupDataType, groupedObjType, tweakType } from "../ import { FlowType, NodeType } from "../types/flow"; import { TabsState } from "../types/tabs"; import { buildTweaks } from "./reactflowUtils"; +import { APIClassType, APIObjectType } from "../types/api"; export function classNames(...classes: Array): string { return classes.filter(Boolean).join(" "); @@ -88,10 +89,10 @@ export function checkUpperWords(str: string): string { export const isWrappedWithClass = (event: any, className: string | undefined) => event.target.closest(`.${className}`); -export function groupByFamily(data: groupDataType, baseClasses: string, left: boolean, flow?: NodeType[]): groupedObjType[] { +export function groupByFamily(data, baseClasses: string, left: boolean, flow?: NodeType[]): groupedObjType[] { const baseClassesSet = new Set(baseClasses.split("\n")); - let arrOfPossibleInputs = []; - let arrOfPossibleOutputs = []; + let arrOfPossibleInputs: Array<{ category: string; nodes: string[]; full: boolean; }> = []; + let arrOfPossibleOutputs: Array<{ category: string; nodes: string[]; full: boolean; }> = []; let checkedNodes = new Map(); const excludeTypes = new Set([ "str", @@ -116,26 +117,26 @@ export function groupByFamily(data: groupDataType, baseClasses: string, left: bo checkedNodes.set(nodeData.type, { hasBaseClassInTemplate: foundNode?.hasBaseClassInTemplate || - Object.values(nodeData.node.template).some(checkBaseClass), + Object.values(nodeData.node!.template).some(checkBaseClass), hasBaseClassInBaseClasses: foundNode?.hasBaseClassInBaseClasses || - nodeData.node.base_classes.some((t) => baseClassesSet.has(t)), + nodeData.node!.base_classes.some((t) => baseClassesSet.has(t)), }); } } for (const [d, nodes] of Object.entries(data)) { - let tempInputs = [], - tempOutputs = []; + let tempInputs: string[] = [], + tempOutputs: string[] = []; for (const [n, node] of Object.entries(nodes)) { let foundNode = checkedNodes.get(n); if (!foundNode) { foundNode = { - hasBaseClassInTemplate: Object.values(node.template).some( + hasBaseClassInTemplate: Object.values(node!.template).some( checkBaseClass ), - hasBaseClassInBaseClasses: node.base_classes.some((t) => + hasBaseClassInBaseClasses: node!.base_classes.some((t) => baseClassesSet.has(t) ), }; @@ -177,7 +178,7 @@ export function buildInputs(tabsState: TabsState, id: string): string { tabsState[id] && tabsState[id].formKeysData && tabsState[id].formKeysData.input_keys && - Object.keys(tabsState[id].formKeysData.input_keys).length > 0 + Object.keys(tabsState[id].formKeysData.input_keys!).length > 0 ? JSON.stringify(tabsState[id].formKeysData.input_keys) : '{"input": "message"}'; } @@ -265,7 +266,7 @@ export function getPythonApiCode( // node.data.id // } const tweaks = buildTweaks(flow); - const inputs = buildInputs(tabsState, flow.id); + const inputs = buildInputs(tabsState!, flow.id); return `import requests from typing import Optional @@ -317,7 +318,7 @@ export function getCurlCode( ): string { const flowId = flow.id; const tweaks = buildTweaks(flow); - const inputs = buildInputs(tabsState, flow.id); + const inputs = buildInputs(tabsState!, flow.id); return `curl -X POST \\ ${window.location.protocol}//${ @@ -343,7 +344,7 @@ export function getPythonCode( ): string { const flowName = flow.name; const tweaks = buildTweaks(flow); - const inputs = buildInputs(tabsState, flow.id); + const inputs = buildInputs(tabsState!, flow.id); return `from langflow import load_flow_from_json TWEAKS = ${ tweak && tweak.length > 0 @@ -364,7 +365,7 @@ flow(inputs)`; export function getWidgetCode(flow: FlowType, tabsState?: TabsState): string { const flowId = flow.id; const flowName = flow.name; - const inputs = buildInputs(tabsState, flow.id); + const inputs = buildInputs(tabsState!, flow.id); return ` @@ -375,10 +376,10 @@ chat_input_field: Input key that you want the chat to send the user message with window_title="${flowName}" flow_id="${flowId}" ${ - tabsState[flow.id] && tabsState[flow.id].formKeysData + tabsState![flow.id] && tabsState![flow.id].formKeysData ? `chat_inputs='${inputs}' chat_input_field="${ - Object.keys(tabsState[flow.id].formKeysData.input_keys)[0] + Object.keys(tabsState![flow.id].formKeysData.input_keys!)[0] }" ` : "" diff --git a/src/frontend/tsconfig.json b/src/frontend/tsconfig.json index c411ff4e7..1879137c5 100644 --- a/src/frontend/tsconfig.json +++ b/src/frontend/tsconfig.json @@ -6,7 +6,7 @@ "skipLibCheck": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, - "strict": false, + "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "module": "esnext",