From 6611a94652aec8278022d9e0be47b775d6aefc86 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Thu, 11 Aug 2022 15:12:31 +0530 Subject: [PATCH 01/15] Add markdown preview and toggle to md files. --- components/HooksEditor.tsx | 233 +++++++++------- components/Markdown.tsx | 14 + package.json | 1 + yarn.lock | 534 ++++++++++++++++++++++++++++++++++++- 4 files changed, 679 insertions(+), 103 deletions(-) create mode 100644 components/Markdown.tsx diff --git a/components/HooksEditor.tsx b/components/HooksEditor.tsx index 7b99b33..8dc8729 100644 --- a/components/HooksEditor.tsx +++ b/components/HooksEditor.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useSnapshot, ref } from "valtio"; import type monaco from "monaco-editor"; import { ArrowBendLeftUp } from "phosphor-react"; @@ -23,6 +23,8 @@ import Monaco from "./Monaco"; import { saveAllFiles } from "../state/actions/saveFile"; import { Tab, Tabs } from "./Tabs"; import { renameFile } from "../state/actions/createNewFile"; +import { Link } from "."; +import Markdown from './Markdown'; const checkWritable = (filename?: string): boolean => { if (apiHeaderFiles.find(file => file === filename)) { @@ -31,9 +33,7 @@ const checkWritable = (filename?: string): boolean => { return true; }; -const validateWritability = ( - editor: monaco.editor.IStandaloneCodeEditor -) => { +const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => { const filename = editor.getModel()?.uri.path.split("/").pop(); const isWritable = checkWritable(filename); editor.updateOptions({ readOnly: !isWritable }); @@ -105,6 +105,7 @@ const HooksEditor = () => { const snap = useSnapshot(state); const router = useRouter(); const { theme } = useTheme(); + const [isMdPreview, setIsMdPreview] = useState(true); useEffect(() => { if (editorRef.current) validateWritability(editorRef.current); @@ -144,10 +145,31 @@ const HooksEditor = () => { }} > {snap.files.map((file, index) => { - return ; + return ( + + ); })} ); + const previewToggle = ( + setIsMdPreview(!isMdPreview)} + css={{ + position: "absolute", + right: 0, + bottom: 0, + zIndex: 10, + m: "$1", + fontSize: "$sm", + }} + > + {isMdPreview ? "Exit Preview" : "View Preview"} + + ); return ( { }} > + {file?.language === "markdown" && previewToggle} {snap.files.length > 0 && router.isReady ? ( - (state.files[snap.active].content = val)} // Auto save? - beforeMount={monaco => { - if (!snap.editorCtx) { - snap.files.forEach(file => - monaco.editor.createModel( - file.content, - file.language, - monaco.Uri.parse(`file:///work/c/${file.name}`) - ) - ); - } + isMdPreview && file?.language === "markdown" ? ( + {file.content} + ) : ( + (state.files[snap.active].content = val)} // Auto save? + beforeMount={monaco => { + if (!snap.editorCtx) { + snap.files.forEach(file => + monaco.editor.createModel( + file.content, + file.language, + monaco.Uri.parse(`file:///work/c/${file.name}`) + ) + ); + } - // create the web socket - if (!subscriptionRef.current) { - monaco.languages.register({ - id: "c", - extensions: [".c", ".h"], - aliases: ["C", "c", "H", "h"], - mimetypes: ["text/plain"], - }); - MonacoServices.install(monaco); - const webSocket = createWebSocket( - process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || "" - ); - subscriptionRef.current = webSocket; - // listen when the web socket is opened - listen({ - webSocket: webSocket as WebSocket, - onConnection: connection => { - // create and start the language client - const languageClient = createLanguageClient(connection); - const disposable = languageClient.start(); + // create the web socket + if (!subscriptionRef.current) { + monaco.languages.register({ + id: "c", + extensions: [".c", ".h"], + aliases: ["C", "c", "H", "h"], + mimetypes: ["text/plain"], + }); + MonacoServices.install(monaco); + const webSocket = createWebSocket( + process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || "" + ); + subscriptionRef.current = webSocket; + // listen when the web socket is opened + listen({ + webSocket: webSocket as WebSocket, + onConnection: connection => { + // create and start the language client + const languageClient = createLanguageClient(connection); + const disposable = languageClient.start(); - connection.onClose(() => { - try { - disposable.dispose(); - } catch (err) { - console.log("err", err); - } - }); + connection.onClose(() => { + try { + disposable.dispose(); + } catch (err) { + console.log("err", err); + } + }); + }, + }); + } + + // editor.updateOptions({ + // minimap: { + // enabled: false, + // }, + // ...snap.editorSettings, + // }); + if (!state.editorCtx) { + state.editorCtx = ref(monaco.editor); + } + }} + onMount={(editor, monaco) => { + editorRef.current = editor; + monacoRef.current = monaco; + editor.updateOptions({ + glyphMargin: true, + lightbulb: { + enabled: true, }, }); - } - - // editor.updateOptions({ - // minimap: { - // enabled: false, - // }, - // ...snap.editorSettings, - // }); - if (!state.editorCtx) { - state.editorCtx = ref(monaco.editor); - } - }} - onMount={(editor, monaco) => { - editorRef.current = editor; - monacoRef.current = monaco; - editor.updateOptions({ - glyphMargin: true, - lightbulb: { - enabled: true, - }, - }); - editor.addCommand( - monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, - () => { - saveFile(); - } - ); - // When the markers (errors/warnings from clangd language server) change - // Lets improve the markers by adding extra content to them from related - // md files - monaco.editor.onDidChangeMarkers(() => { - if (monacoRef.current) { - setMarkers(monacoRef.current); - } - }); - - // Hacky way to hide Peek menu - editor.onContextMenu(e => { - const host = - document.querySelector(".shadow-root-host"); - - const contextMenuItems = - host?.shadowRoot?.querySelectorAll("li.action-item"); - contextMenuItems?.forEach(k => { - // If menu item contains "Peek" lets hide it - if (k.querySelector(".action-label")?.textContent === "Peek") { - // @ts-expect-error - k["style"].display = "none"; + editor.addCommand( + monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, + () => { + saveFile(); + } + ); + // When the markers (errors/warnings from clangd language server) change + // Lets improve the markers by adding extra content to them from related + // md files + monaco.editor.onDidChangeMarkers(() => { + if (monacoRef.current) { + setMarkers(monacoRef.current); } }); - }); - validateWritability(editor); - }} - theme={theme === "dark" ? "dark" : "light"} - /> + // Hacky way to hide Peek menu + editor.onContextMenu(e => { + const host = + document.querySelector(".shadow-root-host"); + + const contextMenuItems = + host?.shadowRoot?.querySelectorAll("li.action-item"); + contextMenuItems?.forEach(k => { + // If menu item contains "Peek" lets hide it + if ( + k.querySelector(".action-label")?.textContent === "Peek" + ) { + // @ts-expect-error + k["style"].display = "none"; + } + }); + }); + + validateWritability(editor); + }} + theme={theme === "dark" ? "dark" : "light"} + /> + ) ) : ( {!snap.loading && router.isReady && ( diff --git a/components/Markdown.tsx b/components/Markdown.tsx new file mode 100644 index 0000000..aa3f24d --- /dev/null +++ b/components/Markdown.tsx @@ -0,0 +1,14 @@ +import ReactMarkdown from 'react-markdown'; +import { styled } from '../stitches.config'; + +const Markdown = styled(ReactMarkdown, { + px: "$8", + "@md": { + px: "$20", + }, + pb: "$5", + height: "100%", + overflowY: "auto" +}); + +export default Markdown; \ No newline at end of file diff --git a/package.json b/package.json index a119d10..b84ee5a 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "react-hook-form": "^7.28.0", "react-hot-keys": "^2.7.1", "react-hot-toast": "^2.1.1", + "react-markdown": "^8.0.3", "react-new-window": "^0.2.1", "react-select": "^5.2.1", "react-split": "^2.0.14", diff --git a/yarn.lock b/yarn.lock index 0ad9ded..b64f19d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -951,6 +951,13 @@ resolved "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz" integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg== +"@types/debug@^4.0.0": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" + "@types/dinero.js@^1.9.0": version "1.9.0" resolved "https://registry.npmjs.org/@types/dinero.js/-/dinero.js-1.9.0.tgz" @@ -961,6 +968,13 @@ resolved "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz" integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ== +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + dependencies: + "@types/unist" "*" + "@types/json-schema@^7.0.8": version "7.0.9" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz" @@ -1002,6 +1016,23 @@ resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== +"@types/mdast@^3.0.0": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" + integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== + dependencies: + "@types/unist" "*" + +"@types/mdurl@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" + integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== + +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node@*": version "17.0.21" resolved "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz" @@ -1032,6 +1063,11 @@ resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== +"@types/prop-types@^15.0.0": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + "@types/react-transition-group@^4.4.0": version "4.4.4" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz" @@ -1062,6 +1098,11 @@ resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/unist@*", "@types/unist@^2.0.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" + integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== + "@types/ws@^7.2.0": version "7.4.7" resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz" @@ -1292,6 +1333,11 @@ babel-plugin-macros@^2.6.1: cosmiconfig "^6.0.0" resolve "^1.12.0" +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -1487,6 +1533,11 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" @@ -1529,6 +1580,11 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +comma-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98" + integrity sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg== + comment-parser@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" @@ -1654,11 +1710,25 @@ debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.0.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + decimal.js@^10.2.0: version "10.3.1" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" @@ -1676,11 +1746,21 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + detect-node-es@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + dinero.js@^1.9.1: version "1.9.1" resolved "https://registry.npmjs.org/dinero.js/-/dinero.js-1.9.1.tgz" @@ -2065,6 +2145,11 @@ ext@^1.1.2: dependencies: type "^2.5.0" +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -2336,6 +2421,11 @@ hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hast-util-whitespace@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz#4fc1086467cc1ef5ba20673cb6b03cec3a970f1c" + integrity sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz" @@ -2416,6 +2506,11 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" @@ -2460,6 +2555,11 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz" @@ -2540,6 +2640,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz" @@ -2741,6 +2846,11 @@ klaw-sync@^6.0.0: dependencies: graceful-fs "^4.1.11" +kleur@^4.0.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + language-subtag-registry@~0.3.2: version "0.3.21" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz" @@ -2873,6 +2983,60 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdast-util-definitions@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz#2c1d684b28e53f84938bb06317944bee8efa79db" + integrity sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + +mdast-util-from-markdown@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz#84df2924ccc6c995dec1e2368b2b208ad0a76268" + integrity sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + decode-named-character-reference "^1.0.0" + mdast-util-to-string "^3.1.0" + micromark "^3.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-decode-string "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-stringify-position "^3.0.0" + uvu "^0.5.0" + +mdast-util-to-hast@^12.1.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.2.0.tgz#4dbff7ab2b20b8d12fc8fe98bf804d97e7358cbf" + integrity sha512-YDwT5KhGzLgPpSnQhAlK1+WpCW4gsPmNNAxUNMkMTDhxQyPp2eX86WOelnKnLKEvSpfxqJbPbInHFkefXZBhEA== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + "@types/mdurl" "^1.0.0" + mdast-util-definitions "^5.0.0" + mdurl "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + trim-lines "^3.0.0" + unist-builder "^3.0.0" + unist-util-generated "^2.0.0" + unist-util-position "^4.0.0" + unist-util-visit "^4.0.0" + +mdast-util-to-string@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9" + integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA== + +mdurl@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + memoize-one@^5.0.0: version "5.2.1" resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" @@ -2888,6 +3052,201 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +micromark-core-commonmark@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" + integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-factory-destination "^1.0.0" + micromark-factory-label "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-factory-title "^1.0.0" + micromark-factory-whitespace "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-classify-character "^1.0.0" + micromark-util-html-tag-name "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + +micromark-factory-destination@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e" + integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-label@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137" + integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-factory-space@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633" + integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-title@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f" + integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-factory-whitespace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c" + integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86" + integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-chunked@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06" + integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-classify-character@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20" + integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-combine-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5" + integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-decode-numeric-character-reference@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946" + integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-decode-string@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02" + integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-encode@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383" + integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA== + +micromark-util-html-tag-name@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497" + integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA== + +micromark-util-normalize-identifier@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828" + integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-resolve-all@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88" + integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw== + dependencies: + micromark-util-types "^1.0.0" + +micromark-util-sanitize-uri@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz#27dc875397cd15102274c6c6da5585d34d4f12b2" + integrity sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-subtokenize@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105" + integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-util-symbol@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e" + integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ== + +micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20" + integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w== + +micromark@^3.0.0: + version "3.0.10" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.0.10.tgz#1eac156f0399d42736458a14b0ca2d86190b457c" + integrity sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + micromark-core-commonmark "^1.0.1" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz" @@ -2923,6 +3282,11 @@ monaco-editor@^0.33.0: resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.33.0.tgz#842e244f3750a2482f8a29c676b5684e75ff34af" integrity sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw== +mri@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -3339,7 +3703,7 @@ progress@^2.0.0: resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -3348,6 +3712,11 @@ prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, object-assign "^4.1.1" react-is "^16.13.1" +property-information@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22" + integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w== + proxy-compare@2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.0.3.tgz" @@ -3426,6 +3795,32 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-markdown@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.3.tgz#e8aba0d2f5a1b2124d476ee1fff9448a2f57e4b3" + integrity sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A== + dependencies: + "@types/hast" "^2.0.0" + "@types/prop-types" "^15.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^2.0.0" + prop-types "^15.0.0" + property-information "^6.0.0" + react-is "^18.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.3.0" + unified "^10.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + react-new-window@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/react-new-window/-/react-new-window-0.2.1.tgz" @@ -3572,6 +3967,25 @@ relative-time-format@^1.0.7: resolved "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.0.7.tgz" integrity sha512-BoLPaoL5y94ngPI4iJ9mNHqRS8NA+Hjs6oYHL5UYkbnA7/iTlvJiMoQQt8txhHhc+Y3e6yXWhwTAKvsQhnx2yg== +remark-parse@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775" + integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + unified "^10.0.0" + +remark-rehype@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279" + integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-to-hast "^12.1.0" + unified "^10.0.0" + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" @@ -3738,6 +4152,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +sade@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" + integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== + dependencies: + mri "^1.1.0" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -3857,6 +4278,11 @@ source-map@^0.5.7: resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +space-separated-tokens@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b" + integrity sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw== + split.js@^1.6.0: version "1.6.5" resolved "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz" @@ -3942,6 +4368,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-to-object@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== + dependencies: + inline-style-parser "0.1.1" + styled-jsx@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz" @@ -4027,6 +4460,16 @@ tr46@~0.0.3: resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +trough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" + integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== + tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0: version "3.13.0" resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz" @@ -4098,6 +4541,67 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +unified@^10.0.0: + version "10.1.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" + integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== + dependencies: + "@types/unist" "^2.0.0" + bail "^2.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^5.0.0" + +unist-builder@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-3.0.0.tgz#728baca4767c0e784e1e64bb44b5a5a753021a04" + integrity sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-generated@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113" + integrity sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw== + +unist-util-is@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236" + integrity sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ== + +unist-util-position@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.3.tgz#5290547b014f6222dff95c48d5c3c13a88fadd07" + integrity sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-stringify-position@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz#5c6aa07c90b1deffd9153be170dce628a869a447" + integrity sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-visit-parents@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521" + integrity sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + +unist-util-visit@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5" + integrity sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.0.0" + universal-github-app-jwt@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.0.tgz" @@ -4172,6 +4676,16 @@ uuid@^8.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uvu@^0.5.0: + version "0.5.6" + resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" + integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== + dependencies: + dequal "^2.0.0" + diff "^5.0.0" + kleur "^4.0.3" + sade "^1.7.3" + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" @@ -4184,6 +4698,24 @@ valtio@^1.2.5: dependencies: proxy-compare "2.0.3" +vfile-message@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.2.tgz#a2908f64d9e557315ec9d7ea3a910f658ac05f7d" + integrity sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + +vfile@^5.0.0: + version "5.3.4" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.4.tgz#bbb8c96b956693bbf70b2c67fdb5781dff769b93" + integrity sha512-KI+7cnst03KbEyN1+JE504zF5bJBZa+J+CrevLeyIMq0aPU681I2rQ5p4PlnQ6exFtWiUrg26QUdFMnAKR6PIw== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + vscode-jsonrpc@6.0.0, vscode-jsonrpc@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz" From 6dd571257307e3cd1b065f5c3938da431a78e9ba Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:21:59 +0530 Subject: [PATCH 02/15] Refactor fetchFiles.ts --- state/actions/fetchFiles.ts | 177 +++++++++++++++--------------------- 1 file changed, 75 insertions(+), 102 deletions(-) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index 10971e4..bf0ef6f 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -1,117 +1,90 @@ import { Octokit } from "@octokit/core"; -import Router from "next/router"; -import state from '../index'; +import state, { IFile } from '../index'; import { templateFileIds } from '../constants'; const octokit = new Octokit(); -/* Fetches Gist files from Githug Gists based on - * gistId and stores the content in global state +/** + * Fetches files from Github Gists based on gistId and stores them in global state */ -export const fetchFiles = (gistId: string) => { +export const fetchFiles = async (gistId: string) => { + if (!gistId || state.files.length) return + state.loading = true; - if (gistId && !state.files.length) { - state.logs.push({ - type: "log", - message: `Fetching Gist with id: ${gistId}`, - }); - - octokit + state.logs.push({ + type: "log", + message: `Fetching Gist with id: ${gistId}`, + }); + try { + const res = await octokit .request("GET /gists/{gist_id}", { gist_id: gistId }) - .then(async res => { - if (!Object.values(templateFileIds).map(v => v.id).includes(gistId)) { - return res - } - // in case of templates, fetch header file(s) and append to res - try { - const resHeader = await fetch(`${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`); - if (resHeader.ok) { - const resHeaderJson = await resHeader.json() - const headerFiles: Record = {}; - Object.entries(resHeaderJson).forEach(([key, value]) => { - const fname = `${key}.h`; - headerFiles[fname] = { filename: fname, content: value as string, language: 'C' } - }) - const files = { - ...res.data.files, - ...headerFiles - }; - res.data.files = files; - } - } catch (err) { - console.log(err) - } + const isTemplate = (id: string) => Object.values(templateFileIds).map(v => v.id).includes(id) + if (isTemplate(gistId)) { + // fetch headers + const headerRes = await fetch(`${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`); + if (!headerRes.ok) throw Error("Failed to fetch headers");; - return res; - // If you want to load templates from GIST instad, uncomment the code below and comment the code above. - // return octokit.request("GET /gists/{gist_id}", { gist_id: templateFileIds.headers }).then(({ data: { files: headerFiles } }) => { - // const files = { ...res.data.files, ...headerFiles } - // console.log(headerFiles) - // res.data.files = files - // return res - // }) + const headerJson = await headerRes.json() + const headerFiles: Record = {}; + Object.entries(headerJson).forEach(([key, value]) => { + const fname = `${key}.h`; + headerFiles[fname] = { filename: fname, content: value as string, language: 'C' } }) - .then((res) => { - if (res.data.files && Object.keys(res.data.files).length > 0) { - const files = Object.keys(res.data.files).map((filename) => ({ - name: res.data.files?.[filename]?.filename || "untitled.c", - language: res.data.files?.[filename]?.language?.toLowerCase() || "", - content: res.data.files?.[filename]?.content || "", - })); - // Sort files so that the source files are first - // In case of other files leave the order as it its - files.sort((a, b) => { - const aBasename = a.name.split('.')?.[0]; - const aCext = a.name?.toLowerCase().endsWith('.c'); - const bBasename = b.name.split('.')?.[0]; - const bCext = b.name?.toLowerCase().endsWith('.c'); - // If a has c extension and b doesn't move a up - if (aCext && !bCext) { - return -1; - } - if (!aCext && bCext) { - return 1 - } - // Otherwise fallback to default sorting based on basename - if (aBasename > bBasename) { - return 1; - } - if (bBasename > aBasename) { - return -1; - } - return 0; - }) - state.loading = false; - if (files.length > 0) { - state.logs.push({ - type: "success", - message: "Fetched successfully ✅", - }); - state.files = files; - state.gistId = gistId; - state.gistName = Object.keys(res.data.files)?.[0] || "untitled"; - state.gistOwner = res.data.owner?.login; - return; - } else { - // Open main modal if now files - state.mainModalOpen = true; - } - return Router.push({ pathname: "/develop" }); - } - state.loading = false; - }) - .catch((err) => { - // console.error(err) - state.loading = false; - state.logs.push({ - type: "error", - message: `Couldn't find Gist with id: ${gistId}`, - }); - return; - }); - return; + const files = { + ...res.data.files, + ...headerFiles + }; + res.data.files = files; + } + + if (!res.data.files) throw Error("No files could be fetched from given gist id!") + + const files: IFile[] = Object.keys(res.data.files).map((filename) => ({ + name: res.data.files?.[filename]?.filename || "untitled.c", + language: res.data.files?.[filename]?.language?.toLowerCase() || "", + content: res.data.files?.[filename]?.content || "", + })); + + // Sort files so that the source files are first + // In case of other files leave the order as it its + files.sort((a, b) => { + const aBasename = a.name.split('.')?.[0]; + const aExt = a.name.split('.').pop() || ''; + const bBasename = b.name.split('.')?.[0]; + const bExt = b.name.split('.').pop() || ''; + + // default priority is undefined == 0 + const extPriority: Record = { + c: 2, + md: 1, + h: -1 + } + + if (extPriority[aExt] || extPriority[bExt]) + return (extPriority[bExt] || 0) - (extPriority[aExt] || 0) + // Otherwise fallback to alphabetical sorting + return aBasename.localeCompare(bBasename) + }) + + state.logs.push({ + type: "success", + message: "Fetched successfully ✅", + }); + state.files = files; + state.gistId = gistId; + state.gistName = Object.keys(res.data.files)?.[0] || "untitled"; + state.gistOwner = res.data.owner?.login; + + } catch (err) { + let message: string + if (err instanceof Error) message = err.message + else message = `Something went wrong, try again later!` + state.logs.push({ + type: "error", + message: `Error: ${message}`, + }); } state.loading = false; }; From 4b2b4b25c03512d1d44429164da71c00b77874f6 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:22:57 +0530 Subject: [PATCH 03/15] Give md extension higher priority for sorting! --- state/actions/fetchFiles.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index bf0ef6f..e32e33e 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -57,8 +57,8 @@ export const fetchFiles = async (gistId: string) => { // default priority is undefined == 0 const extPriority: Record = { - c: 2, - md: 1, + c: 1, + md: 2, h: -1 } From aa6225178031a6f6b856c7e89fd20819ec5be4ff Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:32:53 +0530 Subject: [PATCH 04/15] Fix gist name. --- components/Navigation.tsx | 2 +- state/actions/fetchFiles.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/Navigation.tsx b/components/Navigation.tsx index dfa24f1..972bfb2 100644 --- a/components/Navigation.tsx +++ b/components/Navigation.tsx @@ -102,7 +102,7 @@ const Navigation = () => { ) : ( <> - {snap.files?.[0]?.name || "XRPL Hooks"} + {snap.gistName || "XRPL Hooks"} { }); state.files = files; state.gistId = gistId; - state.gistName = Object.keys(res.data.files)?.[0] || "untitled"; state.gistOwner = res.data.owner?.login; - + + const gistName = files.find(file => file.language === 'c' || file.language === 'javascript')?.name || "untitled"; + state.gistName = gistName } catch (err) { let message: string if (err instanceof Error) message = err.message From c7d77b26b5932e5c627a815e3f3ba9397699020b Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:36:46 +0530 Subject: [PATCH 05/15] Save markdown before previewing. --- components/HooksEditor.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/HooksEditor.tsx b/components/HooksEditor.tsx index 8dc8729..3cc730e 100644 --- a/components/HooksEditor.tsx +++ b/components/HooksEditor.tsx @@ -24,7 +24,7 @@ import { saveAllFiles } from "../state/actions/saveFile"; import { Tab, Tabs } from "./Tabs"; import { renameFile } from "../state/actions/createNewFile"; import { Link } from "."; -import Markdown from './Markdown'; +import Markdown from "./Markdown"; const checkWritable = (filename?: string): boolean => { if (apiHeaderFiles.find(file => file === filename)) { @@ -157,7 +157,12 @@ const HooksEditor = () => { ); const previewToggle = ( setIsMdPreview(!isMdPreview)} + onClick={() => { + if (!isMdPreview) { + saveFile(false); + } + setIsMdPreview(!isMdPreview); + }} css={{ position: "absolute", right: 0, From 380b6b1afd40e71f47674e79e0291cc2b5c9fbeb Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:40:15 +0530 Subject: [PATCH 06/15] Fix linting error --- state/actions/fetchFiles.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index a4c8ccc..01f0e40 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -1,7 +1,6 @@ import { Octokit } from "@octokit/core"; import state, { IFile } from '../index'; import { templateFileIds } from '../constants'; -import { file } from 'jszip'; const octokit = new Octokit(); @@ -76,7 +75,7 @@ export const fetchFiles = async (gistId: string) => { state.files = files; state.gistId = gistId; state.gistOwner = res.data.owner?.login; - + const gistName = files.find(file => file.language === 'c' || file.language === 'javascript')?.name || "untitled"; state.gistName = gistName } catch (err) { From b23b0066bb1af14e0795dd0f87ac6c6ec356e739 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:43:00 +0530 Subject: [PATCH 07/15] Change carbon and starter templates to forked. --- state/constants/templates.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/state/constants/templates.ts b/state/constants/templates.ts index d41e27a..2043809 100644 --- a/state/constants/templates.ts +++ b/state/constants/templates.ts @@ -6,7 +6,7 @@ import Starter from "../../components/icons/Starter"; export const templateFileIds = { 'starter': { - id: '9106f1fe60482d90475bfe8f1315affe', + id: '1f8109c80f504e6326db2735df2f0ad6', // Forked name: 'Starter', description: 'Just a basic starter with essential imports, just accepts any transaction coming through', icon: Starter @@ -25,7 +25,7 @@ export const templateFileIds = { icon: Notary }, 'carbon': { - id: '5941c19dce3e147948f564e224553c02', + id: '953662b22d065449f8ab6f69bc2afe41', // Forked name: 'Carbon', description: 'Send a percentage of sum to an address', icon: Carbon From 034fc3423b1fa42fb19f14df228c2607592f7714 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 15:54:34 +0530 Subject: [PATCH 08/15] Link comp in markdown. --- components/HooksEditor.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/components/HooksEditor.tsx b/components/HooksEditor.tsx index 3cc730e..2c3fd3f 100644 --- a/components/HooksEditor.tsx +++ b/components/HooksEditor.tsx @@ -191,7 +191,17 @@ const HooksEditor = () => { {file?.language === "markdown" && previewToggle} {snap.files.length > 0 && router.isReady ? ( isMdPreview && file?.language === "markdown" ? ( - {file.content} + ( + + {children} + + ), + }} + > + {file.content} + ) : ( Date: Fri, 12 Aug 2022 16:31:25 +0530 Subject: [PATCH 09/15] Log full error on console in fetchFiles. --- state/actions/fetchFiles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index 01f0e40..f4f63cb 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -79,6 +79,7 @@ export const fetchFiles = async (gistId: string) => { const gistName = files.find(file => file.language === 'c' || file.language === 'javascript')?.name || "untitled"; state.gistName = gistName } catch (err) { + console.error(err) let message: string if (err instanceof Error) message = err.message else message = `Something went wrong, try again later!` From 052be354d1bba2d882710da8bb0c6a7e27923d2c Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 23:06:58 +0530 Subject: [PATCH 10/15] Fix sorting logic --- state/actions/fetchFiles.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index f4f63cb..6dcd1b5 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -62,8 +62,10 @@ export const fetchFiles = async (gistId: string) => { h: -1 } - if (extPriority[aExt] || extPriority[bExt]) - return (extPriority[bExt] || 0) - (extPriority[aExt] || 0) + if (extPriority[aExt] || extPriority[bExt]) { + const comp = (extPriority[bExt] || 0) - (extPriority[aExt] || 0) + if (comp !== 0) return comp + } // Otherwise fallback to alphabetical sorting return aBasename.localeCompare(bBasename) }) From 9923dd9390898901267e31ce9607a231f93a515a Mon Sep 17 00:00:00 2001 From: muzam1l Date: Fri, 12 Aug 2022 23:15:05 +0530 Subject: [PATCH 11/15] Add prettier config. --- .prettierignore | 36 ++++++++++++++++++++++++++++++++++++ .prettierrc.json | 8 ++++++++ 2 files changed, 44 insertions(+) create mode 100644 .prettierrc.json diff --git a/.prettierignore b/.prettierignore index 2e1fa2d..4991f94 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,37 @@ +See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel +.vscode + *.md \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..3369b6f --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "tabWidth": 2, + "arrowParens": "avoid", + "semi": false, + "printWidth": 100, + "singleQuote": true, + "trailingComma": "none" +} \ No newline at end of file From dbbbfdb2f0d27fc5a5c271eb0a282d2a02fea3b0 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Tue, 16 Aug 2022 13:42:38 +0530 Subject: [PATCH 12/15] Increase C files priority in sorting. --- state/actions/fetchFiles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/actions/fetchFiles.ts b/state/actions/fetchFiles.ts index 6dcd1b5..2ae15cf 100644 --- a/state/actions/fetchFiles.ts +++ b/state/actions/fetchFiles.ts @@ -57,7 +57,7 @@ export const fetchFiles = async (gistId: string) => { // default priority is undefined == 0 const extPriority: Record = { - c: 1, + c: 3, md: 2, h: -1 } From 6418094b0f168c0028a01d5a226e2efa76c2ead1 Mon Sep 17 00:00:00 2001 From: muzam1l Date: Wed, 17 Aug 2022 11:50:49 +0530 Subject: [PATCH 13/15] Run prettier through everything. --- .prettierignore | 3 +- .prettierrc.json | 2 +- components/Accounts.tsx | 466 ++++----- components/AlertDialog/index.tsx | 63 +- components/AlertDialog/primitive.tsx | 109 +- components/Box.tsx | 10 +- components/Button.tsx | 382 ++++--- components/ButtonGroup.tsx | 34 +- components/Container.tsx | 18 +- components/ContextMenu/index.tsx | 106 +- components/ContextMenu/primitive.tsx | 128 +-- components/DebugStream.tsx | 219 ++-- components/DeployEditor.tsx | 169 ++- components/Dialog.tsx | 110 +- components/DropdownMenu.tsx | 149 +-- components/EditorNavigation.tsx | 323 +++--- components/Flex.tsx | 50 +- components/Heading.tsx | 22 +- components/HooksEditor.tsx | 246 ++--- components/Input.tsx | 224 ++-- components/Link.tsx | 12 +- components/LogBox.tsx | 173 ++- components/LogText.tsx | 34 +- components/Logo.tsx | 28 +- components/Monaco.tsx | 68 +- components/Navigation.tsx | 394 ++++--- components/PanelBox.tsx | 48 +- components/Popover.tsx | 123 +-- components/Pre.tsx | 16 +- components/RunScript/index.tsx | 259 +++-- components/Select.tsx | 117 +-- components/SetHookDialog.tsx | 323 +++--- components/Spinner.tsx | 16 +- components/Stack.tsx | 16 +- components/Switch.tsx | 40 +- components/Tabs.tsx | 337 +++--- components/Text.tsx | 42 +- components/Textarea.tsx | 158 ++- components/ThemeChanger.tsx | 38 +- components/Tooltip.tsx | 93 +- components/Transaction/index.tsx | 218 ++-- components/Transaction/json.tsx | 231 ++-- components/Transaction/ui.tsx | 275 +++-- components/icons/Carbon.tsx | 12 +- components/icons/Firewall.tsx | 12 +- components/icons/Notary.tsx | 12 +- components/icons/Peggy.tsx | 12 +- components/icons/Starter.tsx | 12 +- components/index.tsx | 32 +- content/amount-schema.json | 12 +- content/transactions.json | 4 +- hooks/useWindowSize.tsx | 26 +- next.config.js | 20 +- package.json | 2 + pages/_app.tsx | 137 +-- pages/_document.tsx | 31 +- pages/_middleware.ts | 16 +- pages/api/auth/[...nextauth].ts | 31 +- pages/api/faucet.ts | 38 +- pages/api/hello.ts | 5 +- pages/api/proxy.ts | 25 +- pages/deploy/[[...slug]].tsx | 66 +- pages/develop/[[...slug]].tsx | 234 ++--- pages/index.tsx | 6 +- pages/sign-in.tsx | 37 +- pages/test/[[...slug]].tsx | 128 ++- public/site.webmanifest | 34 +- raw-loader.d.ts | 8 +- state/actions/addFaucetAccount.ts | 88 +- state/actions/compileCode.ts | 112 +- state/actions/createNewFile.ts | 32 +- state/actions/deleteAccount.ts | 42 +- state/actions/deployHook.tsx | 274 +++-- state/actions/downloadAsZip.ts | 36 +- state/actions/fetchFiles.ts | 117 ++- state/actions/importAccount.ts | 34 +- state/actions/index.ts | 24 +- state/actions/persistSplits.ts | 5 +- state/actions/saveFile.ts | 24 +- state/actions/sendTransaction.ts | 103 +- state/actions/showAlert.ts | 46 +- state/actions/syncToGist.ts | 127 ++- state/actions/updateEditorSettings.ts | 18 +- state/constants/index.ts | 2 +- state/constants/templates.ts | 74 +- state/index.ts | 179 ++-- state/transactions.ts | 388 ++++--- stitches.config.ts | 628 +++++------ styles/keyframes.ts | 26 +- theme/editor/sunburst.json | 2 +- theme/editor/vibrant_ink.json | 2 +- tsconfig.json | 17 +- types/next-auth.d.ts | 10 +- utils/comment-parser.ts | 34 +- utils/decodeBinary.ts | 16 +- utils/decodeRestrictedBase64ToBytes.ts | 139 ++- utils/estimateFee.ts | 27 +- utils/helpers.ts | 14 +- utils/hookOnCalculator.ts | 35 +- utils/json.ts | 53 +- utils/languageClient.ts | 30 +- utils/object.ts | 35 +- utils/schema.ts | 65 +- utils/setHook.ts | 124 ++- utils/truncate.ts | 10 +- utils/wat-highlight.ts | 1336 ++++++++++++------------ utils/zip.ts | 32 +- utils/zlib.ts | 8 +- xrpl-hooks-docs/docs.ts | 192 ++-- yarn.lock | 5 + 110 files changed, 5458 insertions(+), 5951 deletions(-) diff --git a/.prettierignore b/.prettierignore index 4991f94..a877e3a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -34,4 +34,5 @@ yarn-error.log* .vercel .vscode -*.md \ No newline at end of file +*.md +utils/libwabt.js \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 3369b6f..0a3835d 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,4 +5,4 @@ "printWidth": 100, "singleQuote": true, "trailingComma": "none" -} \ No newline at end of file +} diff --git a/components/Accounts.tsx b/components/Accounts.tsx index 105c1a7..001284f 100644 --- a/components/Accounts.tsx +++ b/components/Accounts.tsx @@ -1,95 +1,93 @@ -import toast from "react-hot-toast"; -import { useSnapshot } from "valtio"; -import { ArrowSquareOut, Copy, Trash, Wallet, X } from "phosphor-react"; -import React, { useEffect, useState, FC } from "react"; -import Dinero from "dinero.js"; +import toast from 'react-hot-toast' +import { useSnapshot } from 'valtio' +import { ArrowSquareOut, Copy, Trash, Wallet, X } from 'phosphor-react' +import React, { useEffect, useState, FC } from 'react' +import Dinero from 'dinero.js' -import Button from "./Button"; -import { addFaucetAccount, importAccount } from "../state/actions"; -import state from "../state"; -import Box from "./Box"; -import { Container, Heading, Stack, Text, Flex } from "."; +import Button from './Button' +import { addFaucetAccount, importAccount } from '../state/actions' +import state from '../state' +import Box from './Box' +import { Container, Heading, Stack, Text, Flex } from '.' import { Dialog, DialogContent, DialogTitle, DialogDescription, DialogClose, - DialogTrigger, -} from "./Dialog"; -import { css } from "../stitches.config"; -import { Input, Label } from "./Input"; -import truncate from "../utils/truncate"; + DialogTrigger +} from './Dialog' +import { css } from '../stitches.config' +import { Input, Label } from './Input' +import truncate from '../utils/truncate' const labelStyle = css({ - color: "$mauve10", - textTransform: "uppercase", - fontSize: "10px", - mb: "$0.5", -}); -import transactionsData from "../content/transactions.json"; -import { SetHookDialog } from "./SetHookDialog"; -import { addFunds } from "../state/actions/addFaucetAccount"; -import { deleteHook } from "../state/actions/deployHook"; -import { capitalize } from "../utils/helpers"; -import { deleteAccount } from '../state/actions/deleteAccount'; + color: '$mauve10', + textTransform: 'uppercase', + fontSize: '10px', + mb: '$0.5' +}) +import transactionsData from '../content/transactions.json' +import { SetHookDialog } from './SetHookDialog' +import { addFunds } from '../state/actions/addFaucetAccount' +import { deleteHook } from '../state/actions/deployHook' +import { capitalize } from '../utils/helpers' +import { deleteAccount } from '../state/actions/deleteAccount' export const AccountDialog = ({ activeAccountAddress, - setActiveAccountAddress, + setActiveAccountAddress }: { - activeAccountAddress: string | null; - setActiveAccountAddress: React.Dispatch>; + activeAccountAddress: string | null + setActiveAccountAddress: React.Dispatch> }) => { - const snap = useSnapshot(state); - const [showSecret, setShowSecret] = useState(false); - const activeAccount = snap.accounts.find( - account => account.address === activeAccountAddress - ); + const snap = useSnapshot(state) + const [showSecret, setShowSecret] = useState(false) + const activeAccount = snap.accounts.find(account => account.address === activeAccountAddress) return ( { - setShowSecret(false); - !open && setActiveAccountAddress(null); + setShowSecret(false) + !open && setActiveAccountAddress(null) }} > {activeAccount?.name} @@ -97,25 +95,25 @@ export const AccountDialog = ({ - - - - + + + + Account Address - + - - + + Secret {showSecret ? activeAccount?.secret - : "•".repeat(activeAccount?.secret.length || 16)}{" "} + : '•'.repeat(activeAccount?.secret.length || 16)}{' '} - + - - + + Balances & Objects {Dinero({ - amount: Number(activeAccount?.xrp || "0"), - precision: 6, + amount: Number(activeAccount?.xrp || '0'), + precision: 6 }) .toUnit() .toLocaleString(undefined, { - style: "currency", - currency: "XRP", - currencyDisplay: "name", + style: 'currency', + currency: 'XRP', + currencyDisplay: 'name' })} - - + + Installed Hooks {activeAccount && activeAccount.hooks.length > 0 @@ -261,20 +255,20 @@ export const AccountDialog = ({ > {truncate(i, 12)} - ); + ) }) - : "–"} + : '–'} {activeAccount && activeAccount?.hooks?.length > 0 && ( - + - ); -}; + ) +} interface AccountProps { - card?: boolean; - hideDeployBtn?: boolean; - showHookStats?: boolean; + card?: boolean + hideDeployBtn?: boolean + showHookStats?: boolean } const Accounts: FC = props => { - const snap = useSnapshot(state); - const [activeAccountAddress, setActiveAccountAddress] = useState< - string | null - >(null); + const snap = useSnapshot(state) + const [activeAccountAddress, setActiveAccountAddress] = useState(null) useEffect(() => { const fetchAccInfo = async () => { - if (snap.clientStatus === "online") { + if (snap.clientStatus === 'online') { const requests = snap.accounts.map(acc => snap.client?.send({ id: `hooks-builder-req-info-${acc.address}`, - command: "account_info", - account: acc.address, + command: 'account_info', + account: acc.address }) - ); - const responses = await Promise.all(requests); + ) + const responses = await Promise.all(requests) responses.forEach((res: any) => { - const address = res?.account_data?.Account as string; - const balance = res?.account_data?.Balance as string; - const sequence = res?.account_data?.Sequence as number; - const accountToUpdate = state.accounts.find( - acc => acc.address === address - ); + const address = res?.account_data?.Account as string + const balance = res?.account_data?.Balance as string + const sequence = res?.account_data?.Sequence as number + const accountToUpdate = state.accounts.find(acc => acc.address === address) if (accountToUpdate) { - accountToUpdate.xrp = balance; - accountToUpdate.sequence = sequence; - accountToUpdate.error = null; + accountToUpdate.xrp = balance + accountToUpdate.sequence = sequence + accountToUpdate.error = null } else { - const oldAccount = state.accounts.find( - acc => acc.address === res?.account - ); + const oldAccount = state.accounts.find(acc => acc.address === res?.account) if (oldAccount) { - oldAccount.xrp = "0"; + oldAccount.xrp = '0' oldAccount.error = { code: res?.error, - message: res?.error_message, - }; + message: res?.error_message + } } } - }); + }) const objectRequests = snap.accounts.map(acc => { return snap.client?.send({ id: `hooks-builder-req-objects-${acc.address}`, - command: "account_objects", - account: acc.address, - }); - }); - const objectResponses = await Promise.all(objectRequests); + command: 'account_objects', + account: acc.address + }) + }) + const objectResponses = await Promise.all(objectRequests) objectResponses.forEach((res: any) => { - const address = res?.account as string; - const accountToUpdate = state.accounts.find( - acc => acc.address === address - ); + const address = res?.account as string + const accountToUpdate = state.accounts.find(acc => acc.address === address) if (accountToUpdate) { accountToUpdate.hooks = res.account_objects - .find((ac: any) => ac?.LedgerEntryType === "Hook") - ?.Hooks?.map((oo: any) => oo.Hook.HookHash) || []; + .find((ac: any) => ac?.LedgerEntryType === 'Hook') + ?.Hooks?.map((oo: any) => oo.Hook.HookHash) || [] } - }); + }) } - }; + } - let fetchAccountInfoInterval: NodeJS.Timer; - if (snap.clientStatus === "online") { - fetchAccInfo(); - fetchAccountInfoInterval = setInterval(() => fetchAccInfo(), 10000); + let fetchAccountInfoInterval: NodeJS.Timer + if (snap.clientStatus === 'online') { + fetchAccInfo() + fetchAccountInfoInterval = setInterval(() => fetchAccInfo(), 10000) } return () => { if (snap.accounts.length > 0) { if (fetchAccountInfoInterval) { - clearInterval(fetchAccountInfoInterval); + clearInterval(fetchAccountInfoInterval) } } - }; + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [snap.accounts.length, snap.clientStatus]); + }, [snap.accounts.length, snap.clientStatus]) return ( - + = props => { css={{ fontWeight: 300, m: 0, - fontSize: "11px", - color: "$mauve12", - px: "$3", - textTransform: "uppercase", - alignItems: "center", - display: "inline-flex", - gap: "$3", + fontSize: '11px', + color: '$mauve12', + px: '$3', + textTransform: 'uppercase', + alignItems: 'center', + display: 'inline-flex', + gap: '$3' }} > Accounts - + {snap.accounts.map(account => ( @@ -438,45 +424,45 @@ const Accounts: FC = props => { key={account.address + account.name} onClick={() => setActiveAccountAddress(account.address)} css={{ - px: "$3", - py: props.card ? "$3" : "$2", - cursor: "pointer", - borderBottom: props.card ? "1px solid $mauve6" : undefined, - "@hover": { - "&:hover": { - background: "$backgroundAlt", - }, - }, + px: '$3', + py: props.card ? '$3' : '$2', + cursor: 'pointer', + borderBottom: props.card ? '1px solid $mauve6' : undefined, + '@hover': { + '&:hover': { + background: '$backgroundAlt' + } + } }} > {account.name} - {account.address}{" "} + {account.address}{' '} {!account?.error ? ( `(${Dinero({ - amount: Number(account?.xrp || "0"), - precision: 6, + amount: Number(account?.xrp || '0'), + precision: 6 }) .toUnit() .toLocaleString(undefined, { - style: "currency", - currency: "XRP", - currencyDisplay: "name", + style: 'currency', + currency: 'XRP', + currencyDisplay: 'name' })})` ) : ( - + (Account not found, request funds to activate account) )} @@ -486,7 +472,7 @@ const Accounts: FC = props => {
{ - e.stopPropagation(); + e.stopPropagation() }} > @@ -494,9 +480,9 @@ const Accounts: FC = props => { )} {props.showHookStats && ( - + {account.hooks.length} hook - {account.hooks.length === 1 ? "" : "s"} installed + {account.hooks.length === 1 ? '' : 's'} installed )} @@ -508,37 +494,33 @@ const Accounts: FC = props => { setActiveAccountAddress={setActiveAccountAddress} /> - ); -}; + ) +} export const transactionsOptions = transactionsData.map(tx => ({ value: tx.TransactionType, - label: tx.TransactionType, -})); + label: tx.TransactionType +})) -const ImportAccountDialog = ({ - type = "import", -}: { - type?: "import" | "create"; -}) => { - const [secret, setSecret] = useState(""); - const [name, setName] = useState(""); +const ImportAccountDialog = ({ type = 'import' }: { type?: 'import' | 'create' }) => { + const [secret, setSecret] = useState('') + const [name, setName] = useState('') - const btnText = type === "import" ? "Import" : "Create"; - const title = type === "import" ? "Import Account" : "Create Account"; + const btnText = type === 'import' ? 'Import' : 'Create' + const title = type === 'import' ? 'Import Account' : 'Create Account' const handleSubmit = async () => { - if (type === "create") { - const value = capitalize(name); - await addFaucetAccount(value, true); - setName(""); - setSecret(""); - return; + if (type === 'create') { + const value = capitalize(name) + await addFaucetAccount(value, true) + setName('') + setSecret('') + return } - importAccount(secret, name); - setName(""); - setSecret(""); - }; + importAccount(secret, name) + setName('') + setSecret('') + } return ( @@ -547,9 +529,9 @@ const ImportAccountDialog = ({ - {title} + {title} - + @@ -562,7 +544,7 @@ const ImportAccountDialog = ({ onChange={e => setName(e.target.value)} /> - {type === "import" && ( + {type === 'import' && ( @@ -594,13 +576,13 @@ const ImportAccountDialog = ({ - + - ); -}; + ) +} -export default Accounts; +export default Accounts diff --git a/components/AlertDialog/index.tsx b/components/AlertDialog/index.tsx index eecfacb..36d4fb0 100644 --- a/components/AlertDialog/index.tsx +++ b/components/AlertDialog/index.tsx @@ -1,65 +1,62 @@ -import { FC, ReactNode } from "react"; -import { proxy, useSnapshot } from "valtio"; -import Button from "../Button"; -import Flex from "../Flex"; +import { FC, ReactNode } from 'react' +import { proxy, useSnapshot } from 'valtio' +import Button from '../Button' +import Flex from '../Flex' import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, - AlertDialogTitle, -} from "./primitive"; + AlertDialogTitle +} from './primitive' export interface AlertState { - isOpen: boolean; - title?: string; - body?: ReactNode; - cancelText?: string; - confirmText?: string; - confirmPrefix?: ReactNode; - onConfirm?: () => any; - onCancel?: () => any; + isOpen: boolean + title?: string + body?: ReactNode + cancelText?: string + confirmText?: string + confirmPrefix?: ReactNode + onConfirm?: () => any + onCancel?: () => any } export const alertState = proxy({ - isOpen: false, -}); + isOpen: false +}) const Alert: FC = () => { const { - title = "Are you sure?", + title = 'Are you sure?', isOpen, body, cancelText, - confirmText = "Ok", + confirmText = 'Ok', confirmPrefix, onCancel, - onConfirm, - } = useSnapshot(alertState); + onConfirm + } = useSnapshot(alertState) return ( - (alertState.isOpen = value)} - > + (alertState.isOpen = value)}> {title} {body} - + {(cancelText || onCancel) && ( - )} {isContentChanged && ( - File contents were changed after last compile, compile again to - incorporate your latest changes in the build. + File contents were changed after last compile, compile again to incorporate your latest + changes in the build. )} - ); + ) const NoContentView = !snap.loading && router.isReady && ( {`You haven't compiled any files yet, compile files on `} @@ -109,29 +98,27 @@ const DeployEditor = () => { develop view - ); + ) - const isContent = - snap.files?.filter(file => file.compiledWatContent).length > 0 && - router.isReady; + const isContent = snap.files?.filter(file => file.compiledWatContent).length > 0 && router.isReady return ( {!isContent ? ( @@ -141,41 +128,39 @@ const DeployEditor = () => { ) : ( { - monaco.languages.register({ id: "wat" }); - monaco.languages.setLanguageConfiguration("wat", wat.config); - monaco.languages.setMonarchTokensProvider("wat", wat.tokens); + monaco.languages.register({ id: 'wat' }) + monaco.languages.setLanguageConfiguration('wat', wat.config) + monaco.languages.setMonarchTokensProvider('wat', wat.tokens) }} onMount={editor => { editor.updateOptions({ glyphMargin: true, - readOnly: true, - }); + readOnly: true + }) }} - theme={theme === "dark" ? "dark" : "light"} + theme={theme === 'dark' ? 'dark' : 'light'} overlay={ - setShowContent(false)}> - Exit editor mode - + setShowContent(false)}>Exit editor mode } /> )} - ); -}; + ) +} -export default DeployEditor; +export default DeployEditor diff --git a/components/Dialog.tsx b/components/Dialog.tsx index 7fffd24..86d03d8 100644 --- a/components/Dialog.tsx +++ b/components/Dialog.tsx @@ -1,90 +1,88 @@ -import React from "react"; -import * as Stiches from "@stitches/react"; -import { keyframes } from "@stitches/react"; -import { blackA } from "@radix-ui/colors"; -import * as DialogPrimitive from "@radix-ui/react-dialog"; -import { styled } from "../stitches.config"; +import React from 'react' +import * as Stiches from '@stitches/react' +import { keyframes } from '@stitches/react' +import { blackA } from '@radix-ui/colors' +import * as DialogPrimitive from '@radix-ui/react-dialog' +import { styled } from '../stitches.config' const overlayShow = keyframes({ - "0%": { opacity: 0.01 }, - "100%": { opacity: 1 }, -}); + '0%': { opacity: 0.01 }, + '100%': { opacity: 1 } +}) const contentShow = keyframes({ - "0%": { opacity: 0.01 }, - "100%": { opacity: 1 }, -}); + '0%': { opacity: 0.01 }, + '100%': { opacity: 1 } +}) const StyledOverlay = styled(DialogPrimitive.Overlay, { zIndex: 10000, backgroundColor: blackA.blackA9, - position: "fixed", + position: 'fixed', inset: 0, top: 0, left: 0, right: 0, bottom: 0, - display: "grid", - placeItems: "center", - overflowY: "auto", - "@media (prefers-reduced-motion: no-preference)": { - animation: `${overlayShow} 250ms cubic-bezier(0.16, 1, 0.3, 1)`, + display: 'grid', + placeItems: 'center', + overflowY: 'auto', + '@media (prefers-reduced-motion: no-preference)': { + animation: `${overlayShow} 250ms cubic-bezier(0.16, 1, 0.3, 1)` }, - ".dark &": { - backgroundColor: blackA.blackA11, - }, -}); + '.dark &': { + backgroundColor: blackA.blackA11 + } +}) const StyledContent = styled(DialogPrimitive.Content, { zIndex: 1000, - backgroundColor: "$mauve2", - color: "$mauve12", - borderRadius: "$md", - position: "relative", - mb: "15%", - boxShadow: - "0px 10px 38px -5px rgba(22, 23, 24, 0.25), 0px 10px 20px -5px rgba(22, 23, 24, 0.2)", - width: "90vw", - maxWidth: "450px", + backgroundColor: '$mauve2', + color: '$mauve12', + borderRadius: '$md', + position: 'relative', + mb: '15%', + boxShadow: '0px 10px 38px -5px rgba(22, 23, 24, 0.25), 0px 10px 20px -5px rgba(22, 23, 24, 0.2)', + width: '90vw', + maxWidth: '450px', // maxHeight: "85vh", padding: 25, - "@media (prefers-reduced-motion: no-preference)": { - animation: `${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1)`, + '@media (prefers-reduced-motion: no-preference)': { + animation: `${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1)` }, - "&:focus": { outline: "none" }, - ".dark &": { - backgroundColor: "$mauve5", - boxShadow: - "0px 10px 38px 0px rgba(0, 0, 0, 0.85), 0px 10px 20px 0px rgba(0, 0, 0, 0.6)", - }, -}); + '&:focus': { outline: 'none' }, + '.dark &': { + backgroundColor: '$mauve5', + boxShadow: '0px 10px 38px 0px rgba(0, 0, 0, 0.85), 0px 10px 20px 0px rgba(0, 0, 0, 0.6)' + } +}) const Content: React.FC<{ css?: Stiches.CSS }> = ({ css, children }) => { return ( {children} - ); -}; + ) +} const StyledTitle = styled(DialogPrimitive.Title, { margin: 0, fontWeight: 500, - color: "$mauve12", - fontSize: 17, -}); + color: '$mauve12', + fontSize: 17 +}) const StyledDescription = styled(DialogPrimitive.Description, { - margin: "10px 0 10px", - color: "$mauve11", + margin: '10px 0 10px', + color: '$mauve11', fontSize: 15, - lineHeight: 1.5, -}); + lineHeight: 1.5 +}) // Exports -export const Dialog = styled(DialogPrimitive.Root); -export const DialogTrigger = DialogPrimitive.Trigger; -export const DialogContent = Content; -export const DialogTitle = StyledTitle; -export const DialogDescription = StyledDescription; -export const DialogClose = DialogPrimitive.Close; -export const DialogPortal = DialogPrimitive.Portal; +export const Dialog = styled(DialogPrimitive.Root) +export const DialogTrigger = DialogPrimitive.Trigger +export const DialogContent = Content +export const DialogTitle = StyledTitle +export const DialogDescription = StyledDescription +export const DialogClose = DialogPrimitive.Close +export const DialogPortal = DialogPrimitive.Portal diff --git a/components/DropdownMenu.tsx b/components/DropdownMenu.tsx index 9b7f871..c79259b 100644 --- a/components/DropdownMenu.tsx +++ b/components/DropdownMenu.tsx @@ -1,115 +1,120 @@ -import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; +import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' -import { styled } from "../stitches.config"; -import { slideDownAndFade, slideLeftAndFade, slideRightAndFade, slideUpAndFade } from '../styles/keyframes'; +import { styled } from '../stitches.config' +import { + slideDownAndFade, + slideLeftAndFade, + slideRightAndFade, + slideUpAndFade +} from '../styles/keyframes' const StyledContent = styled(DropdownMenuPrimitive.Content, { minWidth: 220, - backgroundColor: "$mauve2", + backgroundColor: '$mauve2', borderRadius: 6, padding: 5, boxShadow: - "0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)", - "@media (prefers-reduced-motion: no-preference)": { - animationDuration: "400ms", - animationTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)", - willChange: "transform, opacity", + '0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)', + '@media (prefers-reduced-motion: no-preference)': { + animationDuration: '400ms', + animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)', + willChange: 'transform, opacity', '&[data-state="open"]': { '&[data-side="top"]': { animationName: slideDownAndFade }, '&[data-side="right"]': { animationName: slideLeftAndFade }, '&[data-side="bottom"]': { animationName: slideUpAndFade }, - '&[data-side="left"]': { animationName: slideRightAndFade }, - }, + '&[data-side="left"]': { animationName: slideRightAndFade } + } }, - ".dark &": { - backgroundColor: "$mauve5", + '.dark &': { + backgroundColor: '$mauve5', boxShadow: - "0px 10px 38px -10px rgba(22, 23, 24, 0.85), 0px 10px 20px -15px rgba(22, 23, 24, 0.6)", - }, -}); + '0px 10px 38px -10px rgba(22, 23, 24, 0.85), 0px 10px 20px -15px rgba(22, 23, 24, 0.6)' + } +}) const itemStyles = { - all: "unset", + all: 'unset', fontSize: 13, lineHeight: 1, - color: "$mauve12", + color: '$mauve12', borderRadius: 3, - display: "flex", - alignItems: "center", + display: 'flex', + alignItems: 'center', height: 32, - padding: "0 5px", - position: "relative", - paddingLeft: "5px", - userSelect: "none", - py: "$0.5", - pr: "$2", - gap: "$2", + padding: '0 5px', + position: 'relative', + paddingLeft: '5px', + userSelect: 'none', + py: '$0.5', + pr: '$2', + gap: '$2', - "&[data-disabled]": { - color: "$mauve9", - pointerEvents: "none", + '&[data-disabled]': { + color: '$mauve9', + pointerEvents: 'none' }, - "&:focus": { - backgroundColor: "$purple9", - color: "$white", - }, -}; + '&:focus': { + backgroundColor: '$purple9', + color: '$white' + } +} -const StyledItem = styled(DropdownMenuPrimitive.Item, { ...itemStyles }); +const StyledItem = styled(DropdownMenuPrimitive.Item, { ...itemStyles }) const StyledCheckboxItem = styled(DropdownMenuPrimitive.CheckboxItem, { - ...itemStyles, -}); + ...itemStyles +}) const StyledRadioItem = styled(DropdownMenuPrimitive.RadioItem, { - ...itemStyles, -}); + ...itemStyles +}) const StyledTriggerItem = styled(DropdownMenuPrimitive.TriggerItem, { '&[data-state="open"]': { - backgroundColor: "$purple9", - color: "$purple9", + backgroundColor: '$purple9', + color: '$purple9' }, - ...itemStyles, -}); + ...itemStyles +}) const StyledLabel = styled(DropdownMenuPrimitive.Label, { paddingLeft: 25, fontSize: 12, - lineHeight: "25px", - color: "$mauve11", -}); + lineHeight: '25px', + color: '$mauve11' +}) const StyledSeparator = styled(DropdownMenuPrimitive.Separator, { height: 1, - backgroundColor: "$mauve7", - margin: 5, -}); + backgroundColor: '$mauve7', + margin: 5 +}) const StyledItemIndicator = styled(DropdownMenuPrimitive.ItemIndicator, { - position: "absolute", + position: 'absolute', left: 0, width: 25, - display: "inline-flex", - alignItems: "center", - justifyContent: "center", -}); + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center' +}) const StyledArrow = styled(DropdownMenuPrimitive.Arrow, { - fill: "$mauve2", - ".dark &": { - fill: "$mauve5", - }, -}); + fill: '$mauve2', + '.dark &': { + fill: '$mauve5' + } +}) // Exports -export const DropdownMenu = DropdownMenuPrimitive.Root; -export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; -export const DropdownMenuContent = StyledContent; -export const DropdownMenuItem = StyledItem; -export const DropdownMenuCheckboxItem = StyledCheckboxItem; -export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; -export const DropdownMenuRadioItem = StyledRadioItem; -export const DropdownMenuItemIndicator = StyledItemIndicator; -export const DropdownMenuTriggerItem = StyledTriggerItem; -export const DropdownMenuLabel = StyledLabel; -export const DropdownMenuSeparator = StyledSeparator; -export const DropdownMenuArrow = StyledArrow; +export const DropdownMenu = DropdownMenuPrimitive.Root +export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger +export const DropdownMenuContent = StyledContent +export const DropdownMenuItem = StyledItem +export const DropdownMenuCheckboxItem = StyledCheckboxItem +export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup +export const DropdownMenuRadioItem = StyledRadioItem +export const DropdownMenuItemIndicator = StyledItemIndicator +export const DropdownMenuTriggerItem = StyledTriggerItem +export const DropdownMenuLabel = StyledLabel +export const DropdownMenuSeparator = StyledSeparator +export const DropdownMenuArrow = StyledArrow diff --git a/components/EditorNavigation.tsx b/components/EditorNavigation.tsx index 9c47c1a..74b4595 100644 --- a/components/EditorNavigation.tsx +++ b/components/EditorNavigation.tsx @@ -1,9 +1,4 @@ -import React, { - useState, - useEffect, - useRef, - ReactNode, -} from "react"; +import React, { useState, useEffect, useRef, ReactNode } from 'react' import { Share, DownloadSimple, @@ -15,120 +10,113 @@ import { CloudArrowUp, CaretDown, User, - FilePlus, -} from "phosphor-react"; -import Image from "next/image"; + FilePlus +} from 'phosphor-react' +import Image from 'next/image' import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuArrow, - DropdownMenuSeparator, -} from "./DropdownMenu"; -import NewWindow from "react-new-window"; -import { signOut, useSession } from "next-auth/react"; -import { useSnapshot } from "valtio"; -import toast from "react-hot-toast"; + DropdownMenuSeparator +} from './DropdownMenu' +import NewWindow from 'react-new-window' +import { signOut, useSession } from 'next-auth/react' +import { useSnapshot } from 'valtio' +import toast from 'react-hot-toast' -import { - syncToGist, - updateEditorSettings, - downloadAsZip, -} from "../state/actions"; -import state from "../state"; -import Box from "./Box"; -import Button from "./Button"; -import Container from "./Container"; +import { syncToGist, updateEditorSettings, downloadAsZip } from '../state/actions' +import state from '../state' +import Box from './Box' +import Button from './Button' +import Container from './Container' import { Dialog, DialogTrigger, DialogContent, DialogTitle, DialogDescription, - DialogClose, -} from "./Dialog"; -import Flex from "./Flex"; -import Stack from "./Stack"; -import { Input, Label } from "./Input"; -import Tooltip from "./Tooltip"; -import { showAlert } from "../state/actions/showAlert"; - + DialogClose +} from './Dialog' +import Flex from './Flex' +import Stack from './Stack' +import { Input, Label } from './Input' +import Tooltip from './Tooltip' +import { showAlert } from '../state/actions/showAlert' const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { - const snap = useSnapshot(state); - const [editorSettingsOpen, setEditorSettingsOpen] = useState(false); - const { data: session, status } = useSession(); - const [popup, setPopUp] = useState(false); - const [editorSettings, setEditorSettings] = useState(snap.editorSettings); - + const snap = useSnapshot(state) + const [editorSettingsOpen, setEditorSettingsOpen] = useState(false) + const { data: session, status } = useSession() + const [popup, setPopUp] = useState(false) + const [editorSettings, setEditorSettings] = useState(snap.editorSettings) + useEffect(() => { if (session && session.user && popup) { - setPopUp(false); + setPopUp(false) } - }, [session, popup]); - + }, [session, popup]) const showNewGistAlert = () => { - showAlert("Are you sure?", { + showAlert('Are you sure?', { body: ( <> - This action will create new public Github Gist from - your current saved files. You can delete gist anytime from your GitHub - Gists page. + This action will create new public Github Gist from your current saved + files. You can delete gist anytime from your GitHub Gists page. ), - cancelText: "Cancel", - confirmText: "Create new Gist", + cancelText: 'Cancel', + confirmText: 'Create new Gist', confirmPrefix: , - onConfirm: () => syncToGist(session, true), - }); - }; + onConfirm: () => syncToGist(session, true) + }) + } - const scrollRef = useRef(null); - const containerRef = useRef(null); + const scrollRef = useRef(null) + const containerRef = useRef(null) return ( - + { if (scrollRef.current) { - scrollRef.current.scrollLeft += e.deltaY; + scrollRef.current.scrollLeft += e.deltaY } }} > @@ -138,37 +126,35 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { - - {status === "authenticated" ? ( + + {status === 'authenticated' ? ( ReactNode }) => { signOut()}> - {session?.user?.username} ( - {session?.user.name}) + {session?.user?.username} ({session?.user.name}) - window.open( - `http://gist.github.com/${session?.user.username}` - ) - } + onClick={() => window.open(`http://gist.github.com/${session?.user.username}`)} > Go to your Gist - signOut({ callbackUrl: "/" })}> + signOut({ callbackUrl: '/' })}> Log out @@ -200,48 +181,43 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { ) : ( - )} @@ -250,7 +226,7 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { onClick={downloadAsZip} outline size="sm" - css={{ alignItems: "center" }} + css={{ alignItems: 'center' }} > @@ -259,12 +235,10 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { - + Download as ZIP { navigator.clipboard.writeText( `${window.location.origin}/develop/${snap.gistId}` - ); - toast.success("Copied share link to clipboard!"); + ) + toast.success('Copied share link to clipboard!') }} > Copy share link to clipboard { - syncToGist(session); + syncToGist(session) }} > Push to Gist { - showNewGistAlert(); + showNewGistAlert() }} > Create as a new Gist @@ -357,9 +326,7 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { - {popup && !session ? ( - - ) : null} + {popup && !session ? : null} @@ -380,39 +347,33 @@ const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => { onChange={e => setEditorSettings(curr => ({ ...curr, - tabSize: Number(e.target.value), + tabSize: Number(e.target.value) })) } /> - + - - - + - ); -}; + ) +} -export default EditorNavigation; +export default EditorNavigation diff --git a/components/Flex.tsx b/components/Flex.tsx index c4cd396..eff9bf4 100644 --- a/components/Flex.tsx +++ b/components/Flex.tsx @@ -1,53 +1,53 @@ -import { styled } from "../stitches.config"; -import Box from "./Box"; +import { styled } from '../stitches.config' +import Box from './Box' const Flex = styled(Box, { - display: "flex", + display: 'flex', variants: { row: { true: { - flexDirection: "row", - }, + flexDirection: 'row' + } }, column: { true: { - flexDirection: "column", - }, + flexDirection: 'column' + } }, fluid: { true: { - width: "100%", - }, + width: '100%' + } }, align: { start: { - alignItems: "start", + alignItems: 'start' }, center: { - alignItems: "center", + alignItems: 'center' }, end: { - alignItems: "end", - }, + alignItems: 'end' + } }, justify: { start: { - justifyContent: "start", + justifyContent: 'start' }, center: { - justifyContent: "center", + justifyContent: 'center' }, end: { - justifyContent: "end", + justifyContent: 'end' }, - "space-between": { - justifyContent: "space-between", + 'space-between': { + justifyContent: 'space-between' }, - "space-around": { - justifyContent: "space-around", - }, - }, - }, -}); + 'space-around': { + justifyContent: 'space-around' + } + } + } +}) -export default Flex; +export default Flex diff --git a/components/Heading.tsx b/components/Heading.tsx index cb57fcd..5205368 100644 --- a/components/Heading.tsx +++ b/components/Heading.tsx @@ -1,16 +1,16 @@ -import { styled } from "../stitches.config"; +import { styled } from '../stitches.config' -const Heading = styled("span", { - fontFamily: "$heading", - lineHeight: "$heading", - fontWeight: "$heading", +const Heading = styled('span', { + fontFamily: '$heading', + lineHeight: '$heading', + fontWeight: '$heading', variants: { uppercase: { true: { - textTransform: "uppercase", - }, - }, - }, -}); + textTransform: 'uppercase' + } + } + } +}) -export default Heading; +export default Heading diff --git a/components/HooksEditor.tsx b/components/HooksEditor.tsx index 7b99b33..464221d 100644 --- a/components/HooksEditor.tsx +++ b/components/HooksEditor.tsx @@ -1,45 +1,43 @@ -import React, { useEffect, useRef } from "react"; -import { useSnapshot, ref } from "valtio"; -import type monaco from "monaco-editor"; -import { ArrowBendLeftUp } from "phosphor-react"; -import { useTheme } from "next-themes"; -import { useRouter } from "next/router"; +import React, { useEffect, useRef } from 'react' +import { useSnapshot, ref } from 'valtio' +import type monaco from 'monaco-editor' +import { ArrowBendLeftUp } from 'phosphor-react' +import { useTheme } from 'next-themes' +import { useRouter } from 'next/router' -import Box from "./Box"; -import Container from "./Container"; -import { createNewFile, saveFile } from "../state/actions"; -import { apiHeaderFiles } from "../state/constants"; -import state from "../state"; +import Box from './Box' +import Container from './Container' +import { createNewFile, saveFile } from '../state/actions' +import { apiHeaderFiles } from '../state/constants' +import state from '../state' -import EditorNavigation from "./EditorNavigation"; -import Text from "./Text"; -import { MonacoServices } from "@codingame/monaco-languageclient"; -import { createLanguageClient, createWebSocket } from "../utils/languageClient"; -import { listen } from "@codingame/monaco-jsonrpc"; -import ReconnectingWebSocket from "reconnecting-websocket"; +import EditorNavigation from './EditorNavigation' +import Text from './Text' +import { MonacoServices } from '@codingame/monaco-languageclient' +import { createLanguageClient, createWebSocket } from '../utils/languageClient' +import { listen } from '@codingame/monaco-jsonrpc' +import ReconnectingWebSocket from 'reconnecting-websocket' -import docs from "../xrpl-hooks-docs/docs"; -import Monaco from "./Monaco"; -import { saveAllFiles } from "../state/actions/saveFile"; -import { Tab, Tabs } from "./Tabs"; -import { renameFile } from "../state/actions/createNewFile"; +import docs from '../xrpl-hooks-docs/docs' +import Monaco from './Monaco' +import { saveAllFiles } from '../state/actions/saveFile' +import { Tab, Tabs } from './Tabs' +import { renameFile } from '../state/actions/createNewFile' const checkWritable = (filename?: string): boolean => { if (apiHeaderFiles.find(file => file === filename)) { - return false; + return false } - return true; -}; + return true +} -const validateWritability = ( - editor: monaco.editor.IStandaloneCodeEditor -) => { - const filename = editor.getModel()?.uri.path.split("/").pop(); - const isWritable = checkWritable(filename); - editor.updateOptions({ readOnly: !isWritable }); -}; +const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => { + const filename = editor.getModel()?.uri.path.split('/').pop() + const isWritable = checkWritable(filename) + editor.updateOptions({ readOnly: !isWritable }) +} -let decorations: { [key: string]: string[] } = {}; +let decorations: { [key: string]: string[] } = {} const setMarkers = (monacoE: typeof monaco) => { // Get all the markers that are active at the moment, @@ -50,10 +48,10 @@ const setMarkers = (monacoE: typeof monaco) => { // Filter out the markers that are hooks specific .filter( marker => - typeof marker?.code === "string" && + typeof marker?.code === 'string' && // Take only markers that starts with "hooks-" - marker?.code?.includes("hooks-") - ); + marker?.code?.includes('hooks-') + ) // Get the active model (aka active file you're editing) // const model = monacoE.editor?.getModel( @@ -62,15 +60,13 @@ const setMarkers = (monacoE: typeof monaco) => { // console.log(state.active); // Add decoration (aka extra hoverMessages) to markers in the // exact same range (location) where the markers are - const models = monacoE.editor.getModels(); + const models = monacoE.editor.getModels() models.forEach(model => { decorations[model.id] = model?.deltaDecorations( decorations?.[model.id] || [], markers .filter(marker => - marker?.resource.path - .split("/") - .includes(`${state.files?.[state.active]?.name}`) + marker?.resource.path.split('/').includes(`${state.files?.[state.active]?.name}`) ) .map(marker => ({ range: new monacoE.Range( @@ -86,47 +82,45 @@ const setMarkers = (monacoE: typeof monaco) => { // /xrpl-hooks-docs/xrpl-hooks-docs-files.json file // which was generated from rst files - (typeof marker.code === "string" && - docs[marker?.code]?.toString()) || - "", + (typeof marker.code === 'string' && docs[marker?.code]?.toString()) || '', supportHtml: true, - isTrusted: true, - }, - }, + isTrusted: true + } + } })) - ); - }); -}; + ) + }) +} const HooksEditor = () => { - const editorRef = useRef(); - const monacoRef = useRef(); - const subscriptionRef = useRef(null); - const snap = useSnapshot(state); - const router = useRouter(); - const { theme } = useTheme(); + const editorRef = useRef() + const monacoRef = useRef() + const subscriptionRef = useRef(null) + const snap = useSnapshot(state) + const router = useRouter() + const { theme } = useTheme() useEffect(() => { - if (editorRef.current) validateWritability(editorRef.current); - }, [snap.active]); + if (editorRef.current) validateWritability(editorRef.current) + }, [snap.active]) useEffect(() => { return () => { - subscriptionRef?.current?.close(); - }; - }, []); + subscriptionRef?.current?.close() + } + }, []) useEffect(() => { if (monacoRef.current) { - setMarkers(monacoRef.current); + setMarkers(monacoRef.current) } - }, [snap.active]); + }, [snap.active]) useEffect(() => { return () => { - saveAllFiles(); - }; - }, []); + saveAllFiles() + } + }, []) - const file = snap.files[snap.active]; + const file = snap.files[snap.active] const renderNav = () => ( { extensionRequired onCreateNewTab={createNewFile} onCloseTab={idx => state.files.splice(idx, 1)} - onRenameTab={(idx, nwName, oldName = "") => renameFile(oldName, nwName)} + onRenameTab={(idx, nwName, oldName = '') => renameFile(oldName, nwName)} headerExtraValidation={{ regex: /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g, - error: - 'Filename can contain only characters from a-z, A-Z, 0-9, "_" and "-"', + error: 'Filename can contain only characters from a-z, A-Z, 0-9, "_" and "-"' }} > {snap.files.map((file, index) => { - return ; + return })} - ); + ) return ( @@ -177,39 +170,39 @@ const HooksEditor = () => { file.language, monaco.Uri.parse(`file:///work/c/${file.name}`) ) - ); + ) } // create the web socket if (!subscriptionRef.current) { monaco.languages.register({ - id: "c", - extensions: [".c", ".h"], - aliases: ["C", "c", "H", "h"], - mimetypes: ["text/plain"], - }); - MonacoServices.install(monaco); + id: 'c', + extensions: ['.c', '.h'], + aliases: ['C', 'c', 'H', 'h'], + mimetypes: ['text/plain'] + }) + MonacoServices.install(monaco) const webSocket = createWebSocket( - process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || "" - ); - subscriptionRef.current = webSocket; + process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || '' + ) + subscriptionRef.current = webSocket // listen when the web socket is opened listen({ webSocket: webSocket as WebSocket, onConnection: connection => { // create and start the language client - const languageClient = createLanguageClient(connection); - const disposable = languageClient.start(); + const languageClient = createLanguageClient(connection) + const disposable = languageClient.start() connection.onClose(() => { try { - disposable.dispose(); + disposable.dispose() } catch (err) { - console.log("err", err); + console.log('err', err) } - }); - }, - }); + }) + } + }) } // editor.updateOptions({ @@ -219,75 +212,68 @@ const HooksEditor = () => { // ...snap.editorSettings, // }); if (!state.editorCtx) { - state.editorCtx = ref(monaco.editor); + state.editorCtx = ref(monaco.editor) } }} onMount={(editor, monaco) => { - editorRef.current = editor; - monacoRef.current = monaco; + editorRef.current = editor + monacoRef.current = monaco editor.updateOptions({ glyphMargin: true, lightbulb: { - enabled: true, - }, - }); - editor.addCommand( - monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, - () => { - saveFile(); + enabled: true } - ); + }) + editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => { + saveFile() + }) // When the markers (errors/warnings from clangd language server) change // Lets improve the markers by adding extra content to them from related // md files monaco.editor.onDidChangeMarkers(() => { if (monacoRef.current) { - setMarkers(monacoRef.current); + setMarkers(monacoRef.current) } - }); + }) // Hacky way to hide Peek menu editor.onContextMenu(e => { - const host = - document.querySelector(".shadow-root-host"); + const host = document.querySelector('.shadow-root-host') - const contextMenuItems = - host?.shadowRoot?.querySelectorAll("li.action-item"); + const contextMenuItems = host?.shadowRoot?.querySelectorAll('li.action-item') contextMenuItems?.forEach(k => { // If menu item contains "Peek" lets hide it - if (k.querySelector(".action-label")?.textContent === "Peek") { + if (k.querySelector('.action-label')?.textContent === 'Peek') { // @ts-expect-error - k["style"].display = "none"; + k['style'].display = 'none' } - }); - }); + }) + }) - validateWritability(editor); + validateWritability(editor) }} - theme={theme === "dark" ? "dark" : "light"} + theme={theme === 'dark' ? 'dark' : 'light'} /> ) : ( {!snap.loading && router.isReady && ( - + - + Click the link above to create your file @@ -298,7 +284,7 @@ const HooksEditor = () => { )} - ); -}; + ) +} -export default HooksEditor; +export default HooksEditor diff --git a/components/Input.tsx b/components/Input.tsx index 47dbda3..3470d12 100644 --- a/components/Input.tsx +++ b/components/Input.tsx @@ -1,169 +1,165 @@ -import React from "react"; -import { styled } from "../stitches.config"; -import * as LabelPrim from '@radix-ui/react-label'; +import React from 'react' +import { styled } from '../stitches.config' +import * as LabelPrim from '@radix-ui/react-label' -export const Input = styled("input", { +export const Input = styled('input', { // Reset - appearance: "none", - borderWidth: "0", - boxSizing: "border-box", - fontFamily: "inherit", - outline: "none", - width: "100%", - flex: "1", - backgroundColor: "$mauve4", - display: "inline-flex", - alignItems: "center", - justifyContent: "center", - borderRadius: "$sm", - px: "$2", - fontSize: "$md", + appearance: 'none', + borderWidth: '0', + boxSizing: 'border-box', + fontFamily: 'inherit', + outline: 'none', + width: '100%', + flex: '1', + backgroundColor: '$mauve4', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + borderRadius: '$sm', + px: '$2', + fontSize: '$md', lineHeight: 1, - color: "$mauve12", + color: '$mauve12', boxShadow: `0 0 0 1px $colors$mauve8`, height: 35, - WebkitTapHighlightColor: "rgba(0,0,0,0)", - "&::before": { - boxSizing: "border-box", + WebkitTapHighlightColor: 'rgba(0,0,0,0)', + '&::before': { + boxSizing: 'border-box' }, - "&::after": { - boxSizing: "border-box", + '&::after': { + boxSizing: 'border-box' }, - fontVariantNumeric: "tabular-nums", + fontVariantNumeric: 'tabular-nums', - "&:-webkit-autofill": { - boxShadow: "inset 0 0 0 1px $colors$blue6, inset 0 0 0 100px $colors$blue3", + '&:-webkit-autofill': { + boxShadow: 'inset 0 0 0 1px $colors$blue6, inset 0 0 0 100px $colors$blue3' }, - "&:-webkit-autofill::first-line": { - fontFamily: "$untitled", - color: "$mauve12", + '&:-webkit-autofill::first-line': { + fontFamily: '$untitled', + color: '$mauve12' }, - "&:focus": { + '&:focus': { boxShadow: `0 0 0 1px $colors$mauve10`, - "&:-webkit-autofill": { - boxShadow: `0 0 0 1px $colors$mauve10`, - }, + '&:-webkit-autofill': { + boxShadow: `0 0 0 1px $colors$mauve10` + } }, - "&::placeholder": { - color: "$mauve9", + '&::placeholder': { + color: '$mauve9' }, - "&:disabled": { - pointerEvents: "none", - backgroundColor: "$mauve2", - color: "$mauve8", - cursor: "not-allowed", - "&::placeholder": { - color: "$mauve7", - }, + '&:disabled': { + pointerEvents: 'none', + backgroundColor: '$mauve2', + color: '$mauve8', + cursor: 'not-allowed', + '&::placeholder': { + color: '$mauve7' + } }, - "&:read-only": { - backgroundColor: "$mauve2", - color: "$text", + '&:read-only': { + backgroundColor: '$mauve2', + color: '$text', opacity: 0.8, - "&:focus": { - boxShadow: "inset 0px 0px 0px 1px $colors$mauve7", - }, + '&:focus': { + boxShadow: 'inset 0px 0px 0px 1px $colors$mauve7' + } }, variants: { size: { sm: { - height: "$5", - fontSize: "$1", - lineHeight: "$sizes$4", - "&:-webkit-autofill::first-line": { - fontSize: "$1", - }, + height: '$5', + fontSize: '$1', + lineHeight: '$sizes$4', + '&:-webkit-autofill::first-line': { + fontSize: '$1' + } }, md: { - height: "$8", - fontSize: "$1", - lineHeight: "$sizes$5", - "&:-webkit-autofill::first-line": { - fontSize: "$1", - }, + height: '$8', + fontSize: '$1', + lineHeight: '$sizes$5', + '&:-webkit-autofill::first-line': { + fontSize: '$1' + } }, lg: { - height: "$12", - fontSize: "$2", - lineHeight: "$sizes$6", - "&:-webkit-autofill::first-line": { - fontSize: "$3", - }, - }, + height: '$12', + fontSize: '$2', + lineHeight: '$sizes$6', + '&:-webkit-autofill::first-line': { + fontSize: '$3' + } + } }, variant: { ghost: { - boxShadow: "none", - backgroundColor: "transparent", - "@hover": { - "&:hover": { - boxShadow: "inset 0 0 0 1px $colors$mauve7", - }, + boxShadow: 'none', + backgroundColor: 'transparent', + '@hover': { + '&:hover': { + boxShadow: 'inset 0 0 0 1px $colors$mauve7' + } }, - "&:focus": { - backgroundColor: "$loContrast", - boxShadow: `0 0 0 1px $colors$mauve10`, + '&:focus': { + backgroundColor: '$loContrast', + boxShadow: `0 0 0 1px $colors$mauve10` }, - "&:disabled": { - backgroundColor: "transparent", - }, - "&:read-only": { - backgroundColor: "transparent", + '&:disabled': { + backgroundColor: 'transparent' }, + '&:read-only': { + backgroundColor: 'transparent' + } }, deep: { - backgroundColor: "$deep", - boxShadow: "none", - }, + backgroundColor: '$deep', + boxShadow: 'none' + } }, state: { invalid: { - boxShadow: "inset 0 0 0 1px $colors$crimson7", - "&:focus": { - boxShadow: - "inset 0px 0px 0px 1px $colors$crimson8, 0px 0px 0px 1px $colors$crimson8", - }, + boxShadow: 'inset 0 0 0 1px $colors$crimson7', + '&:focus': { + boxShadow: 'inset 0px 0px 0px 1px $colors$crimson8, 0px 0px 0px 1px $colors$crimson8' + } }, valid: { - boxShadow: "inset 0 0 0 1px $colors$grass7", - "&:focus": { - boxShadow: - "inset 0px 0px 0px 1px $colors$grass8, 0px 0px 0px 1px $colors$grass8", - }, - }, + boxShadow: 'inset 0 0 0 1px $colors$grass7', + '&:focus': { + boxShadow: 'inset 0px 0px 0px 1px $colors$grass8, 0px 0px 0px 1px $colors$grass8' + } + } }, cursor: { default: { - cursor: "default", - "&:focus": { - cursor: "text", - }, + cursor: 'default', + '&:focus': { + cursor: 'text' + } }, text: { - cursor: "text", - }, - }, + cursor: 'text' + } + } }, defaultVariants: { - size: "md", - }, -}); + size: 'md' + } +}) // eslint-disable-next-line react/display-name -const ReffedInput = React.forwardRef< - HTMLInputElement, - React.ComponentProps ->((props, ref) => ); - -export default ReffedInput; +const ReffedInput = React.forwardRef>( + (props, ref) => +) +export default ReffedInput const LabelRoot = (props: LabelPrim.LabelProps) => export const Label = styled(LabelRoot, { display: 'inline-block', mb: '$1' -}) \ No newline at end of file +}) diff --git a/components/Link.tsx b/components/Link.tsx index fbd9e0b..86c5e1e 100644 --- a/components/Link.tsx +++ b/components/Link.tsx @@ -1,8 +1,8 @@ -import { styled } from "../stitches.config"; +import { styled } from '../stitches.config' -const StyledLink = styled("a", { - color: "CurrentColor", - textDecoration: "underline", +const StyledLink = styled('a', { + color: 'CurrentColor', + textDecoration: 'underline', cursor: 'pointer', variants: { highlighted: { @@ -11,6 +11,6 @@ const StyledLink = styled("a", { } } } -}); +}) -export default StyledLink; +export default StyledLink diff --git a/components/LogBox.tsx b/components/LogBox.tsx index 1411cb4..cc20cd7 100644 --- a/components/LogBox.tsx +++ b/components/LogBox.tsx @@ -1,30 +1,23 @@ -import { - useRef, - useLayoutEffect, - ReactNode, - FC, - useState, - useCallback, -} from "react"; -import { IconProps, Notepad, Prohibit } from "phosphor-react"; -import useStayScrolled from "react-stay-scrolled"; -import NextLink from "next/link"; +import { useRef, useLayoutEffect, ReactNode, FC, useState, useCallback } from 'react' +import { IconProps, Notepad, Prohibit } from 'phosphor-react' +import useStayScrolled from 'react-stay-scrolled' +import NextLink from 'next/link' -import Container from "./Container"; -import LogText from "./LogText"; -import state, { ILog } from "../state"; -import { Pre, Link, Heading, Button, Text, Flex, Box } from "."; -import regexifyString from "regexify-string"; -import { useSnapshot } from "valtio"; -import { AccountDialog } from "./Accounts"; +import Container from './Container' +import LogText from './LogText' +import state, { ILog } from '../state' +import { Pre, Link, Heading, Button, Text, Flex, Box } from '.' +import regexifyString from 'regexify-string' +import { useSnapshot } from 'valtio' +import { AccountDialog } from './Accounts' interface ILogBox { - title: string; - clearLog?: () => void; - logs: ILog[]; - renderNav?: () => ReactNode; - enhanced?: boolean; - Icon?: FC; + title: string + clearLog?: () => void + logs: ILog[] + renderNav?: () => ReactNode + enhanced?: boolean + Icon?: FC } const LogBox: FC = ({ @@ -34,40 +27,40 @@ const LogBox: FC = ({ children, renderNav, enhanced, - Icon = Notepad, + Icon = Notepad }) => { - const logRef = useRef(null); - const { stayScrolled /*, scrollBottom*/ } = useStayScrolled(logRef); + const logRef = useRef(null) + const { stayScrolled /*, scrollBottom*/ } = useStayScrolled(logRef) useLayoutEffect(() => { - stayScrolled(); - }, [stayScrolled, logs]); + stayScrolled() + }, [stayScrolled, logs]) return ( = ({ css={{ fontWeight: 300, m: 0, - fontSize: "11px", - color: "$mauve12", - px: "$3", - textTransform: "uppercase", - alignItems: "center", - display: "inline-flex", - gap: "$3", + fontSize: '11px', + color: '$mauve12', + px: '$3', + textTransform: 'uppercase', + alignItems: 'center', + display: 'inline-flex', + gap: '$3' }} > {title} @@ -95,7 +88,7 @@ const LogBox: FC = ({ > {renderNav?.()} - + {clearLog && ( - - - - @@ -405,7 +363,7 @@ const Navigation = () => { - ); -}; + ) +} -export default Navigation; +export default Navigation diff --git a/components/PanelBox.tsx b/components/PanelBox.tsx index 544c927..b638db8 100644 --- a/components/PanelBox.tsx +++ b/components/PanelBox.tsx @@ -1,30 +1,30 @@ -import { styled } from "../stitches.config"; -import Heading from "./Heading"; -import Text from "./Text"; +import { styled } from '../stitches.config' +import Heading from './Heading' +import Text from './Text' -const PanelBox = styled("div", { - display: "flex", - flexDirection: "column", - border: "1px solid $colors$mauve6", - backgroundColor: "$mauve2", - padding: "$3", - borderRadius: "$sm", - fontWeight: "lighter", - height: "auto", - cursor: "pointer", - flex: "1 1 0px", - "&:hover": { - border: "1px solid $colors$mauve9", +const PanelBox = styled('div', { + display: 'flex', + flexDirection: 'column', + border: '1px solid $colors$mauve6', + backgroundColor: '$mauve2', + padding: '$3', + borderRadius: '$sm', + fontWeight: 'lighter', + height: 'auto', + cursor: 'pointer', + flex: '1 1 0px', + '&:hover': { + border: '1px solid $colors$mauve9' }, [`& ${Heading}`]: { - fontWeight: "lighter", - mb: "$2", + fontWeight: 'lighter', + mb: '$2' }, [`& ${Text}`]: { - fontWeight: "lighter", - color: "$mauve10", - fontSize: "$sm", - }, -}); + fontWeight: 'lighter', + color: '$mauve10', + fontSize: '$sm' + } +}) -export default PanelBox; +export default PanelBox diff --git a/components/Popover.tsx b/components/Popover.tsx index 65b6231..3fa767e 100644 --- a/components/Popover.tsx +++ b/components/Popover.tsx @@ -1,92 +1,89 @@ -import React, { ReactNode } from "react"; -import * as PopoverPrimitive from "@radix-ui/react-popover"; -import { styled, keyframes } from "../stitches.config"; +import React, { ReactNode } from 'react' +import * as PopoverPrimitive from '@radix-ui/react-popover' +import { styled, keyframes } from '../stitches.config' const slideUpAndFade = keyframes({ - "0%": { opacity: 0, transform: "translateY(2px)" }, - "100%": { opacity: 1, transform: "translateY(0)" }, -}); + '0%': { opacity: 0, transform: 'translateY(2px)' }, + '100%': { opacity: 1, transform: 'translateY(0)' } +}) const slideRightAndFade = keyframes({ - "0%": { opacity: 0, transform: "translateX(-2px)" }, - "100%": { opacity: 1, transform: "translateX(0)" }, -}); + '0%': { opacity: 0, transform: 'translateX(-2px)' }, + '100%': { opacity: 1, transform: 'translateX(0)' } +}) const slideDownAndFade = keyframes({ - "0%": { opacity: 0, transform: "translateY(-2px)" }, - "100%": { opacity: 1, transform: "translateY(0)" }, -}); + '0%': { opacity: 0, transform: 'translateY(-2px)' }, + '100%': { opacity: 1, transform: 'translateY(0)' } +}) const slideLeftAndFade = keyframes({ - "0%": { opacity: 0, transform: "translateX(2px)" }, - "100%": { opacity: 1, transform: "translateX(0)" }, -}); + '0%': { opacity: 0, transform: 'translateX(2px)' }, + '100%': { opacity: 1, transform: 'translateX(0)' } +}) const StyledContent = styled(PopoverPrimitive.Content, { borderRadius: 4, - padding: "$3 $3", + padding: '$3 $3', fontSize: 12, lineHeight: 1, - color: "$text", - backgroundColor: "$background", + color: '$text', + backgroundColor: '$background', boxShadow: - "0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)", - "@media (prefers-reduced-motion: no-preference)": { - animationDuration: "400ms", - animationTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)", - willChange: "transform, opacity", + '0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)', + '@media (prefers-reduced-motion: no-preference)': { + animationDuration: '400ms', + animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)', + willChange: 'transform, opacity', '&[data-state="open"]': { '&[data-side="top"]': { animationName: slideDownAndFade }, '&[data-side="right"]': { animationName: slideLeftAndFade }, '&[data-side="bottom"]': { animationName: slideUpAndFade }, - '&[data-side="left"]': { animationName: slideRightAndFade }, - }, + '&[data-side="left"]': { animationName: slideRightAndFade } + } }, - ".dark &": { - backgroundColor: "$mauve5", - boxShadow: - "0px 5px 38px -2px rgba(22, 23, 24, 1), 0px 10px 20px 0px rgba(22, 23, 24, 1)", - }, -}); + '.dark &': { + backgroundColor: '$mauve5', + boxShadow: '0px 5px 38px -2px rgba(22, 23, 24, 1), 0px 10px 20px 0px rgba(22, 23, 24, 1)' + } +}) const StyledArrow = styled(PopoverPrimitive.Arrow, { - fill: "$colors$mauve2", - ".dark &": { - fill: "$mauve5", - }, -}); + fill: '$colors$mauve2', + '.dark &': { + fill: '$mauve5' + } +}) const StyledClose = styled(PopoverPrimitive.Close, { - all: "unset", - fontFamily: "inherit", - borderRadius: "100%", + all: 'unset', + fontFamily: 'inherit', + borderRadius: '100%', height: 25, width: 25, - display: "inline-flex", - alignItems: "center", - justifyContent: "center", - color: "$text", - position: "absolute", + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + color: '$text', + position: 'absolute', top: 5, - right: 5, -}); + right: 5 +}) // Exports -export const PopoverRoot = PopoverPrimitive.Root; -export const PopoverTrigger = PopoverPrimitive.Trigger; -export const PopoverContent = StyledContent; -export const PopoverArrow = StyledArrow; -export const PopoverClose = StyledClose; +export const PopoverRoot = PopoverPrimitive.Root +export const PopoverTrigger = PopoverPrimitive.Trigger +export const PopoverContent = StyledContent +export const PopoverArrow = StyledArrow +export const PopoverClose = StyledClose interface IPopover { - content: string | ReactNode; - open?: boolean; - defaultOpen?: boolean; - onOpenChange?: (open: boolean) => void; + content: string | ReactNode + open?: boolean + defaultOpen?: boolean + onOpenChange?: (open: boolean) => void } -const Popover: React.FC< - IPopover & React.ComponentProps -> = ({ +const Popover: React.FC> = ({ children, content, open, @@ -94,16 +91,12 @@ const Popover: React.FC< onOpenChange, ...rest }) => ( - + {children} {content} -); +) -export default Popover; +export default Popover diff --git a/components/Pre.tsx b/components/Pre.tsx index ae42326..b5bc1b3 100644 --- a/components/Pre.tsx +++ b/components/Pre.tsx @@ -1,15 +1,15 @@ -import { styled } from "../stitches.config"; +import { styled } from '../stitches.config' -const Pre = styled("span", { +const Pre = styled('span', { m: 0, - wordBreak: "break-all", + wordBreak: 'break-all', fontFamily: '$monospace', whiteSpace: 'pre-wrap', variants: { fluid: { true: { - width: "100%", - }, + width: '100%' + } }, line: { true: { @@ -21,7 +21,7 @@ const Pre = styled("span", { display: 'block' } } - }, -}); + } +}) -export default Pre; +export default Pre diff --git a/components/RunScript/index.tsx b/components/RunScript/index.tsx index c2ff32d..1ebd716 100644 --- a/components/RunScript/index.tsx +++ b/components/RunScript/index.tsx @@ -1,40 +1,35 @@ -import { Play, X } from "phosphor-react"; -import { - HTMLInputTypeAttribute, - useCallback, - useEffect, - useState, -} from "react"; -import state, { IAccount, IFile, ILog } from "../../state"; -import Button from "../Button"; -import Box from "../Box"; -import Input, { Label } from "../Input"; -import Stack from "../Stack"; +import { Play, X } from 'phosphor-react' +import { HTMLInputTypeAttribute, useCallback, useEffect, useState } from 'react' +import state, { IAccount, IFile, ILog } from '../../state' +import Button from '../Button' +import Box from '../Box' +import Input, { Label } from '../Input' +import Stack from '../Stack' import { Dialog, DialogTrigger, DialogContent, DialogTitle, DialogDescription, - DialogClose, -} from "../Dialog"; -import Flex from "../Flex"; -import { useSnapshot } from "valtio"; -import Select from "../Select"; -import Text from "../Text"; -import { saveFile } from "../../state/actions/saveFile"; -import { getErrors, getTags } from "../../utils/comment-parser"; -import toast from "react-hot-toast"; + DialogClose +} from '../Dialog' +import Flex from '../Flex' +import { useSnapshot } from 'valtio' +import Select from '../Select' +import Text from '../Text' +import { saveFile } from '../../state/actions/saveFile' +import { getErrors, getTags } from '../../utils/comment-parser' +import toast from 'react-hot-toast' const generateHtmlTemplate = (code: string, data?: Record) => { - let processString: string | undefined; - const process = { env: { NODE_ENV: "production" } } as any; + let processString: string | undefined + const process = { env: { NODE_ENV: 'production' } } as any if (data) { Object.keys(data).forEach(key => { - process.env[key] = data[key]; - }); + process.env[key] = data[key] + }) } - processString = JSON.stringify(process); + processString = JSON.stringify(process) return ` @@ -66,7 +61,7 @@ const generateHtmlTemplate = (code: string, data?: Record) => { } - var process = '${processString || "{}"}'; + var process = '${processString || '{}'}'; process = JSON.parse(process); window.process = process @@ -85,112 +80,107 @@ const generateHtmlTemplate = (code: string, data?: Record) => { - `; -}; + ` +} type Fields = Record< string, { - name: string; - value: string; - type?: "Account" | `Account.${keyof IAccount}` | HTMLInputTypeAttribute; - description?: string; - required?: boolean; + name: string + value: string + type?: 'Account' | `Account.${keyof IAccount}` | HTMLInputTypeAttribute + description?: string + required?: boolean } ->; +> const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => { - const snap = useSnapshot(state); - const [templateError, setTemplateError] = useState(""); - const [fields, setFields] = useState({}); - const [iFrameCode, setIframeCode] = useState(""); - const [isDialogOpen, setIsDialogOpen] = useState(false); + const snap = useSnapshot(state) + const [templateError, setTemplateError] = useState('') + const [fields, setFields] = useState({}) + const [iFrameCode, setIframeCode] = useState('') + const [isDialogOpen, setIsDialogOpen] = useState(false) const getFields = useCallback(() => { - const inputTags = ["input", "param", "arg", "argument"]; + const inputTags = ['input', 'param', 'arg', 'argument'] const tags = getTags(content) .filter(tag => inputTags.includes(tag.tag)) - .filter(tag => !!tag.name); + .filter(tag => !!tag.name) let _fields = tags.map(tag => ({ name: tag.name, - value: tag.default || "", + value: tag.default || '', type: tag.type, description: tag.description, - required: !tag.optional, - })); + required: !tag.optional + })) const fields: Fields = _fields.reduce((acc, field) => { - acc[field.name] = field; - return acc; - }, {} as Fields); + acc[field.name] = field + return acc + }, {} as Fields) - const error = getErrors(content); - if (error) setTemplateError(error.message); - else setTemplateError(""); + const error = getErrors(content) + if (error) setTemplateError(error.message) + else setTemplateError('') - return fields; - }, [content]); + return fields + }, [content]) const runScript = useCallback(() => { try { - let data: any = {}; + let data: any = {} Object.keys(fields).forEach(key => { - data[key] = fields[key].value; - }); - const template = generateHtmlTemplate(content, data); + data[key] = fields[key].value + }) + const template = generateHtmlTemplate(content, data) - setIframeCode(template); + setIframeCode(template) - state.scriptLogs = [ - { type: "success", message: "Started running..." }, - ]; + state.scriptLogs = [{ type: 'success', message: 'Started running...' }] } catch (err) { state.scriptLogs = [ ...snap.scriptLogs, // @ts-expect-error - { type: "error", message: err?.message || "Could not parse template" }, - ]; + { type: 'error', message: err?.message || 'Could not parse template' } + ] } - }, [content, fields, snap.scriptLogs]); + }, [content, fields, snap.scriptLogs]) useEffect(() => { const handleEvent = (e: any) => { - if (e.data.type === "log" || e.data.type === "error") { + if (e.data.type === 'log' || e.data.type === 'error') { const data: ILog[] = e.data.args.map((msg: any) => ({ type: e.data.type, - message: typeof msg === "string" ? msg : JSON.stringify(msg, null, 2), - })); - state.scriptLogs = [...snap.scriptLogs, ...data]; + message: typeof msg === 'string' ? msg : JSON.stringify(msg, null, 2) + })) + state.scriptLogs = [...snap.scriptLogs, ...data] } - }; - window.addEventListener("message", handleEvent); - return () => window.removeEventListener("message", handleEvent); - }, [snap.scriptLogs]); + } + window.addEventListener('message', handleEvent) + return () => window.removeEventListener('message', handleEvent) + }, [snap.scriptLogs]) useEffect(() => { - const defaultFields = getFields() || {}; - setFields(defaultFields); - }, [content, setFields, getFields]); + const defaultFields = getFields() || {} + setFields(defaultFields) + }, [content, setFields, getFields]) const accOptions = snap.accounts?.map(acc => ({ ...acc, label: acc.name, - value: acc.address, - })); + value: acc.address + })) - const isDisabled = Object.values(fields).some( - field => field.required && !field.value - ); + const isDisabled = Object.values(fields).some(field => field.required && !field.value) const handleRun = useCallback(() => { - if (isDisabled) - return toast.error("Please fill in all the required fields."); + if (isDisabled) return toast.error('Please fill in all the required fields.') - state.scriptLogs = []; - runScript(); - setIsDialogOpen(false); - }, [isDisabled, runScript]); + state.scriptLogs = [] + runScript() + setIsDialogOpen(false) + }, [isDisabled, runScript]) return ( <> @@ -199,8 +189,8 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => { - @@ -308,14 +287,14 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => { @@ -324,14 +303,10 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => { {iFrameCode && ( -