Getting error as `schema with key or id "https://json-schema.org/draft/2020-12/schema" already exists when performing schema Validation using ajv?

77 views Asked by At

I am working on a project using Nextjs, Reactjs and TypeScript. I have integrated Monaco editor in the website and want to validate the user provided JSON code against the draft 2020-12. I am using ajv for validation.
But it is not working as excepted.
Here is the React code I am using:
This is the Output component:

  import React, { useState } from "react";
  import * as schema from "~/_includes/draft/2020-12/schema.json";
  import Ajv from "ajv/dist/2020";
  const ajv = new Ajv({strict: false, allErrors: true });
  interface OutputProps {
    editorRef: React.RefObject<any>; // Adjust type as per your editorRef
    language: string; // Adjust type as per your language
  }
  const Output: React.FC<OutputProps> = ({ editorRef, language }) => {
  const [output, setOutput] = useState<string[] | null>(null);
  const sourceCode = editorRef.current?.getValue();
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [isError, setIsError] = useState<boolean>(false);
 const runCode = async () => {
    const sourceCode = editorRef.current.getValue();
    setIsLoading(true);
    if (!sourceCode) return; 
    
    try {
      const validate = ajv.compile(schema);
const userSchema = JSON.parse(sourceCode);
      const valid = validate(userSchema); 
 if (!valid) {
        console.log("wrong");
        // throw new Error("Invalid JSON code: " + validate.errors);
        throw new Error("Invalid JSON code: ");
      }
      else{
        setOutput(["Valid JSON"]);
        console.log("correct");
      }
 } catch (error: any) {
      console.error("Validation error:", error);
      setOutput([error.message]); // Display the validation error
      setIsError(true);
    } 
    finally {
      setIsLoading(false);
}
};

  return (
    <div style={{ width: "50%" }}>
      <h2 style={{ fontSize: "1.5rem", marginBottom: "0.5rem" }}>Output</h2>
      <button
        style={{
          padding: "0.5rem 1rem",
          fontSize: "1rem",
          marginBottom: "1rem",
          backgroundColor: isLoading ? "#ccc" : "#4caf50",
          color: "#fff",
          border: "none",
          borderRadius: "4px",
          cursor: "pointer",
        }}
        disabled={isLoading}
        onClick={runCode}
      >
        {isLoading ? "Running..." : "Run Code"}
      </button>
      <div
        style={{
          height: "75vh",
          padding: "0.5rem",
          border: `1px solid ${isError ? "red" : "#333"}`,
          borderRadius: "9px",
          overflowY: "auto",
          backgroundColor: isError ? "#ffcdd2" : "#f5f5f5",
        }}
      >
        {output
          ? output.map((line, i) => <p key={i}>{line}</p>)
          : 'Click "Run Code" to see the output here'}
      </div>
    </div>
  );
};

export default Output;

This is the Code editor component:

import React, { useRef, useState } from "react";
// import { Box, HStack } from "@chakra-ui/react";
import { Editor } from "@monaco-editor/react";
import LanguageSelector from "./LanguageSelector";
import Output from "./Output";
import Ajv from "ajv";
import { LANGUAGE_VERSIONS, CODE_SNIPPETS } from "~/constants/languages";

const ajv = new Ajv();

const CodeEditor: React.FC = () => {
  const editorRef = useRef<any>(null);
  const [value, setValue] = useState<string>("");
  const [language, setLanguage] = useState<string>("json");

  const onMount = (editor: any) => {
    editorRef.current = editor;
    editor.focus();
  };
  // type Language = keyof typeof CODE_SNIPPETS;
  const onSelect = (language: string) => {
    setLanguage(language);
    setValue(CODE_SNIPPETS[language]);
  };
  return (
    <div className="flex w-full">
    <div className="w-1/2">
     {/* <LanguageSelector language={language} onSelect={onSelect}/> */}
        <Editor
        options={{
          minimap: {
            enabled: false,
          },
        }}
        height="75vh"
        width="80%"
        theme="vs-dark"
        language={language}
        defaultValue={CODE_SNIPPETS[language]}
        onMount={onMount}
        value={value}
        onChange={(value) => setValue(value || '')}
      />
      </div>
  <Output editorRef={editorRef} language={language} />
        <div><LanguageSelector language={language} onSelect={onSelect}/></div>
        </div>
  );
};
export default CodeEditor;

I have tried using the URI for importing the JSON schema file as well as added the draft 2020-12 file in my project. Both of them are giving the same error as

schema with key or id "https://json-schema.org/draft/2020-12/schema" already exists

If anyone has any suggestion please help.

0

There are 0 answers