├── .gitignore
├── .DS_Store
├── public
├── Logo.png
├── Diagram.png
├── LogoWord.png
├── monarq32.ico
├── readMeImages
│ ├── ManifestBuilderPart1.png
│ ├── ManifestBuilderPart2.png
│ ├── ManifestBuilderPart3.png
│ ├── ManifestBuilderPart4.png
│ ├── ManifestBuilderPart5.png
│ └── ManifestBuilderPart6.png
├── index.js
└── highlight.css
├── .babelrc
├── Dockerfile
├── theme.js
├── index.html
├── .eslintrc.json
├── components
├── mainPage
│ ├── Footer.jsx
│ ├── Bio.jsx
│ ├── Header.jsx
│ ├── CodeBlockCopy.jsx
│ ├── Intro.jsx
│ ├── LinkToManifest.jsx
│ ├── DeveloperBios.jsx
│ ├── NavBar.jsx
│ └── HomePage.jsx
├── visualizer
│ ├── ConfigVis.jsx
│ ├── Tabs.jsx
│ ├── Instructions.jsx
│ ├── EndpointInput.jsx
│ ├── TabsPane.jsx
│ ├── Operations.jsx
│ └── Visualizer.jsx
└── App.jsx
├── LICENSE
├── server
└── server.js
├── package.json
├── webpack.config.js
├── .ebextensions
└── alb-http-to-https-redirection.config
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/.DS_Store
--------------------------------------------------------------------------------
/public/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/Logo.png
--------------------------------------------------------------------------------
/public/Diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/Diagram.png
--------------------------------------------------------------------------------
/public/LogoWord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/LogoWord.png
--------------------------------------------------------------------------------
/public/monarq32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/monarq32.ico
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-react"],
3 | "plugins": ["@babel/plugin-transform-runtime"],
4 | }
5 |
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart1.png
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart2.png
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart3.png
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart4.png
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart5.png
--------------------------------------------------------------------------------
/public/readMeImages/ManifestBuilderPart6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/MONARQ_home/HEAD/public/readMeImages/ManifestBuilderPart6.png
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14.16
2 | WORKDIR /usr/src/app
3 | COPY . /usr/src/app
4 | RUN npm install
5 | RUN npm run build
6 | EXPOSE 3000
7 | CMD ["node", "./server/server.js"]
8 |
--------------------------------------------------------------------------------
/public/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-expressions */
2 | /* eslint-disable import/extensions */
3 | import React from "react";
4 | import ReactDOM from "react-dom";
5 | import App from "../components/App.jsx";
6 | import "core-js/stable";
7 |
8 | require("regenerator-runtime/path").path;
9 |
10 | ReactDOM.render( , document.getElementById("root"));
11 |
--------------------------------------------------------------------------------
/theme.js:
--------------------------------------------------------------------------------
1 | import { extendTheme } from "@chakra-ui/react";
2 |
3 | const theme = extendTheme({
4 | styles: {
5 | global: {},
6 | },
7 | colors: {
8 | brand: {
9 | mainO: "#f7931e",
10 | lightO: "#FBD38D",
11 | darkO: "#DD6B20",
12 | mainBl: "#2C5282",
13 | lightBl: "#BEE3F8",
14 | darkBl: "#2A4365",
15 | mainBr: "#744210",
16 | whiteT: "#EDF2F7",
17 | gray: "#2D3748",
18 | },
19 | },
20 | });
21 |
22 | export default theme;
23 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | MONARQ
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true
5 | },
6 | "extends": [
7 | "plugin:react/recommended",
8 | "airbnb",
9 | "plugin:prettier/recommended"
10 | ],
11 | "parserOptions": {
12 | "ecmaFeatures": {
13 | "jsx": true
14 | },
15 | "ecmaVersion": 12,
16 | "sourceType": "module"
17 | },
18 | "plugins": [
19 | "react"
20 | ],
21 | "rules": {
22 | "react/jsx-filename-extension": [1, {
23 | "extensions": [".js", ".jsx"]}
24 | ]}
25 | }
26 |
--------------------------------------------------------------------------------
/components/mainPage/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Button, Flex, Spacer, Box } from "@chakra-ui/react";
3 | import { ImLab } from "react-icons/im";
4 |
5 | const Footer = () => {
6 | const year = new Date();
7 | return (
8 |
16 |
17 | PATH Developers {year.getFullYear()}
18 |
19 |
20 |
21 |
22 | } variant="link">
23 | OS-Labs
24 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default Footer;
32 |
--------------------------------------------------------------------------------
/components/mainPage/Bio.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/destructuring-assignment */
2 | /* eslint-disable react/prop-types */
3 | import React from "react";
4 | import { Button, Flex } from "@chakra-ui/react";
5 | import { GrLinkedin, GrGithub } from "react-icons/gr";
6 |
7 | const Bio = (props) => {
8 | return (
9 |
10 | {props.name}
11 | {props.title}
12 |
13 | } colorScheme="white" variant="link">
14 | LinkedIn
15 |
16 |
17 |
18 | } colorScheme="white" variant="link">
19 | Github
20 |
21 |
22 |
23 | );
24 | };
25 |
26 | export default Bio;
27 |
--------------------------------------------------------------------------------
/components/visualizer/ConfigVis.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React, { useEffect } from "react";
3 | import "../../public/highlight.css";
4 | import hljs from "highlight.js/lib/core";
5 | import javascript from "highlight.js/lib/languages/javascript";
6 |
7 | hljs.registerLanguage("javascript", javascript);
8 |
9 | const ConfigVis = (props) => {
10 | const { configString } = props;
11 | const outputArray = [
12 | `export const manifest = {
13 | ${configString}
14 | }`,
15 | ];
16 | useEffect(() => {
17 | hljs.highlightAll();
18 | }, [configString]);
19 |
20 | return (
21 |
22 |
28 | {outputArray[0]}
29 |
30 |
31 | );
32 | };
33 | export default ConfigVis;
34 |
--------------------------------------------------------------------------------
/components/visualizer/Tabs.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React from "react";
3 | import { Button } from "@chakra-ui/react";
4 |
5 | const Tabs = (props) => {
6 | const { types } = props;
7 | const { setCurrentTab } = props;
8 | const tabsArray = [];
9 | const handleClick = (id) => {
10 | setCurrentTab(id);
11 | };
12 |
13 | Object.values(types).forEach((type) => {
14 | if (type) {
15 | tabsArray.push(
16 | handleClick(e.currentTarget.id)}
20 | marginRight={5}
21 | variant="ghost"
22 | colorScheme="orange"
23 |
24 | >
25 | {Object.values(type)}
26 |
27 | );
28 | }
29 | });
30 |
31 | return {tabsArray}
;
32 | };
33 |
34 | export default Tabs;
35 |
--------------------------------------------------------------------------------
/components/mainPage/Header.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { Flex, Spacer, Box, Heading } from "@chakra-ui/react";
4 | import NavBar from "./NavBar";
5 |
6 | const Header = () => {
7 | return (
8 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
26 | MONARQ
27 |
28 |
29 |
30 |
31 |
32 | );
33 | };
34 |
35 | export default Header;
36 |
--------------------------------------------------------------------------------
/components/mainPage/CodeBlockCopy.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { GridItem, Text, Code } from "@chakra-ui/react";
3 |
4 | const CodeBlockNPM = () => {
5 | return (
6 |
21 |
28 | Download the NPM Package
29 |
30 |
36 | npm install monarq
37 |
38 |
39 | );
40 | };
41 |
42 | export default CodeBlockNPM;
43 |
--------------------------------------------------------------------------------
/components/visualizer/Instructions.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React, { useState, useEffect, useImperativeHandle } from "react";
3 | import {
4 | Box,
5 | Flex,
6 | Button,
7 | } from "@chakra-ui/react";
8 |
9 | const Instructions = (props) => {
10 | return (
11 |
12 | A Manifest Object is required in order to use MONARQ. It allows you to specify which REST endpoints you would like to expose, as well as the corresponding GraphQL query/mutation operation that should be executed when a request is received at that endpoint.
13 | Once you are done building your Manifest Object, simply add it into your repository as a manifest.js file.
14 | {props.setStarted(true)}} colorScheme="orange">Get Started
15 |
16 | )
17 | }
18 |
19 | export default Instructions;
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 OSLabs Beta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/components/visualizer/EndpointInput.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | /* eslint-disable react/jsx-boolean-value */
3 | import React from "react";
4 | import { Input, Select } from "@chakra-ui/react";
5 |
6 | const EndpointInput = (props) => {
7 | const { setMethod } = props;
8 | const { setEndpoint } = props;
9 | const methodHandler = (evt) => {
10 | setMethod(evt.target.value);
11 | };
12 | const endpointHandler = (evt) => {
13 | setEndpoint(evt.target.value);
14 | };
15 | return (
16 |
17 | endpointHandler(evt)}
21 | />
22 | methodHandler(evt)}
27 | >
28 | GET
29 | POST
30 | PUT
31 | DELETE
32 | PATCH
33 |
34 |
35 | );
36 | };
37 | export default EndpointInput;
38 |
--------------------------------------------------------------------------------
/components/mainPage/Intro.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { GridItem, Text, Heading } from "@chakra-ui/react";
3 |
4 | const Intro = () => {
5 | return (
6 |
20 |
27 | Enjoy the benefits of both GraphQL and REST
28 |
29 |
37 | MONARQ is a lightweight NPM package that enables a GraphQL server to accept REST requests
38 |
39 |
40 | );
41 | };
42 |
43 | export default Intro;
44 |
--------------------------------------------------------------------------------
/components/mainPage/LinkToManifest.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Button, GridItem, Text } from "@chakra-ui/react";
3 | import { Link } from "react-router-dom";
4 |
5 | const LinkToManifest = () => {
6 | return (
7 |
23 |
24 |
31 | Need Help Making Your Manifest Object?
32 |
33 |
41 | Manifest Builder
42 |
43 |
44 |
45 | );
46 | };
47 |
48 | export default LinkToManifest;
49 |
--------------------------------------------------------------------------------
/public/highlight.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Obsidian style
3 | * ported by Alexander Marenin (http://github.com/ioncreature)
4 | */
5 |
6 | .hljs {
7 | display: block;
8 | overflow-x: auto;
9 | padding: 0.5em;
10 | background: #282b2e;
11 | }
12 |
13 | .hljs-keyword,
14 | .hljs-selector-tag,
15 | .hljs-literal,
16 | .hljs-selector-id {
17 | color: #93c763;
18 | }
19 |
20 | .hljs-number {
21 | color: #ffcd22;
22 | }
23 |
24 | .hljs {
25 | color: #e0e2e4;
26 | }
27 |
28 | .hljs-attribute {
29 | color: #668bb0;
30 | }
31 |
32 | .hljs-code,
33 | .hljs-class .hljs-title,
34 | .hljs-section {
35 | color: white;
36 | }
37 |
38 | .hljs-regexp,
39 | .hljs-link {
40 | color: #d39745;
41 | }
42 |
43 | .hljs-meta {
44 | color: #557182;
45 | }
46 |
47 | .hljs-tag,
48 | .hljs-name,
49 | .hljs-bullet,
50 | .hljs-subst,
51 | .hljs-emphasis,
52 | .hljs-type,
53 | .hljs-built_in,
54 | .hljs-selector-attr,
55 | .hljs-selector-pseudo,
56 | .hljs-addition,
57 | .hljs-variable,
58 | .hljs-template-tag,
59 | .hljs-template-variable {
60 | color: #8cbbad;
61 | }
62 |
63 | .hljs-string,
64 | .hljs-symbol {
65 | color: #ec7600;
66 | }
67 |
68 | .hljs-comment,
69 | .hljs-quote,
70 | .hljs-deletion {
71 | color: #818e96;
72 | }
73 |
74 | .hljs-selector-class {
75 | color: #A082BD
76 | }
77 |
78 | .hljs-keyword,
79 | .hljs-selector-tag,
80 | .hljs-literal,
81 | .hljs-doctag,
82 | .hljs-title,
83 | .hljs-section,
84 | .hljs-type,
85 | .hljs-name,
86 | .hljs-strong {
87 | font-weight: bold;
88 | }
--------------------------------------------------------------------------------
/components/mainPage/DeveloperBios.jsx:
--------------------------------------------------------------------------------
1 | import { Flex } from "@chakra-ui/react";
2 | import React from "react";
3 | import Bio from "./Bio";
4 |
5 | const DeveloperBios = () => {
6 | const outputBios = [];
7 |
8 | const developer = [
9 | {
10 | name: "Peter Baniuszewicz",
11 | title: "Fullstack Engineer",
12 | linkedIn: "https://www.linkedin.com/in/peterbaniuszewicz/",
13 | github: "https://github.com/Peter-Ba",
14 | },
15 |
16 | {
17 | name: "Amy Chen",
18 | title: "Fullstack Engineer",
19 | linkedIn: "https://www.linkedin.com/in/amyechen",
20 | github: "https://github.com/designal46",
21 | },
22 |
23 | {
24 | name: "Tyler Kneidl",
25 | title: "Fullstack Engineer",
26 | linkedIn: "https://www.linkedin.com/in/tylerkneidl/",
27 | github: "https://github.com/tylerkneidl",
28 | },
29 |
30 | {
31 | name: "Helen Regula",
32 | title: "Fullstack Engineer",
33 | linkedIn: "https://www.linkedin.com/in/helen-regula/",
34 | github: "https://github.com/helenregula",
35 | },
36 | ];
37 |
38 | developer.forEach((person) => {
39 | outputBios.push(
40 |
46 | );
47 | });
48 |
49 | return (
50 |
51 | {outputBios}
52 |
53 | );
54 | };
55 |
56 | export default DeveloperBios;
57 |
--------------------------------------------------------------------------------
/components/mainPage/NavBar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Button } from "@chakra-ui/react";
3 | import { GrLinkedin, GrGithub, GrMedium } from "react-icons/gr";
4 | import { ImNpm } from "react-icons/im";
5 |
6 |
7 | const NavBar = () => {
8 | return (
9 |
55 | );
56 | };
57 |
58 | export default NavBar;
59 |
--------------------------------------------------------------------------------
/components/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { BrowserRouter, Switch, Route } from "react-router-dom";
3 | import { ChakraProvider, Grid, GridItem } from "@chakra-ui/react";
4 | import Header from "./mainPage/Header";
5 | import Footer from "./mainPage/Footer";
6 | import HomePage from "./mainPage/HomePage";
7 | import Visualizer from "./visualizer/Visualizer";
8 | import theme from "../theme";
9 |
10 | const App = () => {
11 | const [isLoaded, setIsLoaded] = useState();
12 |
13 | return (
14 |
15 |
16 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 | );
51 | }
52 |
53 | export default App;
54 |
--------------------------------------------------------------------------------
/components/mainPage/HomePage.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Box, Grid, GridItem, Heading, Image } from "@chakra-ui/react";
3 | import DeveloperBios from "./DeveloperBios";
4 | import Intro from "./Intro";
5 | import LinkToManifest from "./LinkToManifest";
6 | import CodeBlockNPM from "./CodeBlockCopy";
7 |
8 | const HomePage = () => {
9 | return (
10 |
15 |
25 |
34 |
35 |
36 |
37 |
38 |
50 | CONTRIBUTORS
51 |
52 |
53 |
54 | );
55 | };
56 |
57 | export default HomePage;
58 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | /* eslint-disable no-console */
3 | const path = require("path");
4 |
5 | const express = require("express");
6 |
7 | const app = express();
8 | const PORT = 3000;
9 |
10 | // global middleware
11 | app.use(express.json());
12 | app.use(express.urlencoded({ extended: true }));
13 |
14 | // serving Index File\
15 | // app.get('/dist', (req, res) => {
16 | // return res.status(200).sendFile(path.resolve(__dirname, '../dist/bundle.js'));
17 | // });
18 |
19 | app.use("/dist", express.static(path.resolve(__dirname, "../dist")));
20 | app.get("/", (req, res) => {
21 | return res.sendFile(path.resolve(__dirname, "../index.html"));
22 | });
23 |
24 | app.get("/public/Logo.png", (req, res) => {
25 | return res
26 | .status(200)
27 | .sendFile(path.resolve(__dirname, "../public/Logo.png"));
28 | });
29 |
30 | app.get("/public/Diagram.png", (req, res) => {
31 | return res
32 | .status(200)
33 | .sendFile(path.resolve(__dirname, "../public/Diagram.png"));
34 | });
35 |
36 | app.get("/public/monarq32.ico", (req, res) => {
37 | return res
38 | .status(200)
39 | .sendFile(path.resolve(__dirname, "../public/monarq32.ico"));
40 | });
41 | // serving bundle.js files from dist folder
42 |
43 | // if request is made to no defined endpoint
44 | app.use("*", (req, res) => res.status(404).json("Not Found"));
45 |
46 | // global middleware handler
47 | // eslint-disable-next-line no-unused-vars
48 | app.use((err, req, res, next) => {
49 | // set locals, only providing error in development
50 | res.locals.message = err.message;
51 | res.locals.error = req.app.get("env") === "development" ? err : {};
52 |
53 | console.error(err);
54 | res.status(err.status || 500).send(res.locals.message);
55 | });
56 |
57 | // starts the server
58 | app.listen(PORT, () => {
59 | console.log(`Server listening on port: ${PORT}`);
60 | });
61 |
--------------------------------------------------------------------------------
/components/visualizer/TabsPane.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React, { useState, useEffect } from "react";
3 | import {
4 | Box,
5 | Center,
6 | Flex,
7 | Radio,
8 | RadioGroup,
9 | Stack,
10 | Spinner,
11 | } from "@chakra-ui/react";
12 |
13 | const TabsPane = (props) => {
14 | const { currentTab, operations, setOperation, isLoaded } = props;
15 |
16 | const [value, setValue] = useState("");
17 |
18 | useEffect(() => {}, [currentTab]);
19 | useEffect(() => {
20 | setOperation(value);
21 | }, [value]);
22 |
23 | const operationsObject = {};
24 |
25 | operations.forEach((el) => {
26 | if (el) operationsObject[el.name] = el.fields;
27 | });
28 |
29 | const displayArray = [];
30 | const display = () => {
31 | if (isLoaded === false)
32 | return (
33 |
34 | {" "}
35 | {" "}
36 |
37 | );
38 | if (isLoaded === true) return displayArray;
39 | return Enter GraphQL URL above to view operations
;
40 | };
41 |
42 | Object.keys(operationsObject).forEach((key) => {
43 | if (key === currentTab) {
44 | displayArray.push(
45 | operationsObject[key].forEach((operation) => {
46 | if (key === currentTab)
47 | displayArray.push(
48 |
54 | {operation.name}
55 |
56 | );
57 | })
58 | );
59 | }
60 | });
61 | return (
62 |
63 |
64 |
65 | {display()}
66 |
67 |
68 |
69 | );
70 | };
71 |
72 | export default TabsPane;
73 |
--------------------------------------------------------------------------------
/components/visualizer/Operations.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React, { useState, useEffect, useImperativeHandle } from "react";
3 | import { Flex } from "@chakra-ui/react";
4 |
5 | import Tabs from "./Tabs";
6 | import TabsPane from "./TabsPane";
7 |
8 | const Operations = (props) => {
9 | const { setOperation, gqlURL, passedRef, isLoaded, setIsLoaded } = props;
10 | const introspectionQuery = {
11 | query:
12 | "{__schema {queryType {name fields {name}}mutationType {name fields {name}}}}",
13 | };
14 | const [introspectedTypes, setIntrospectedTypes] = useState({});
15 | const [currentTab, setCurrentTab] = useState("");
16 |
17 | const getIntrospection = async () => {
18 | setIsLoaded(false);
19 | const rawResponse = await fetch(`${gqlURL}`, {
20 | method: "POST",
21 | headers: {
22 | Accept: "application/json",
23 | "Content-Type": "application/json",
24 | },
25 | body: JSON.stringify(introspectionQuery),
26 | });
27 | const response = await rawResponse.json();
28 | setIsLoaded(true);
29 | // eslint-disable-next-line no-underscore-dangle
30 | setIntrospectedTypes(response.data.__schema);
31 | };
32 |
33 | useImperativeHandle(passedRef, () => ({
34 | getIntrospection,
35 | }));
36 |
37 | useEffect(() => {}, [currentTab, isLoaded]);
38 |
39 | // useEffect(() => {
40 | // getIntrospection();
41 | // }, [gqlURL]);
42 |
43 | const types = [];
44 | // for (const key in introspectedTypes) {
45 | // types.push(introspectedTypes[key].name);
46 | // }
47 | Object.keys(introspectedTypes).forEach((key) => {
48 | if (introspectedTypes[key]) types.push(introspectedTypes[key].name);
49 | });
50 | const operations = Object.values(introspectedTypes);
51 |
52 | return (
53 |
54 |
55 |
61 |
62 | );
63 | };
64 |
65 | export default Operations;
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "monarq-vis",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "nodemon server/server.js",
8 | "build": "NODE_ENV=production webpack",
9 | "dev": "nodemon server/server.js & NODE_ENV=development webpack serve --open",
10 | "dockerprod": "docker run --name monarq-prod -p 3000:3000 monarqpath/monarq-prod",
11 | "dockerdev": "docker-compose -f docker-compose-dev.yml up",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "dependencies": {
18 | "@babel/runtime": "^7.14.0",
19 | "@chakra-ui/icons": "^1.0.13",
20 | "@chakra-ui/react": "^1.6.3",
21 | "@emotion/react": "^11.4.0",
22 | "@emotion/styled": "^11.3.0",
23 | "@fontsource/manjari": "^4.4.2",
24 | "@fontsource/sansita": "^4.4.2",
25 | "core-js": "^3.12.1",
26 | "express": "^4.17.1",
27 | "framer-motion": "^4.1.17",
28 | "highlight.js": "^10.7.2",
29 | "react": "^17.0.2",
30 | "react-dom": "^17.0.2",
31 | "react-icons": "^4.2.0",
32 | "react-router-dom": "^5.2.0",
33 | "regenerator-runtime": "^0.13.7",
34 | "use-undo": "^1.0.3"
35 | },
36 | "devDependencies": {
37 | "@babel/core": "^7.14.3",
38 | "@babel/plugin-transform-runtime": "^7.14.3",
39 | "@babel/preset-env": "^7.14.2",
40 | "@babel/preset-react": "^7.13.13",
41 | "babel-loader": "^8.2.2",
42 | "css-loader": "^5.2.6",
43 | "eslint": "^7.27.0",
44 | "eslint-config-airbnb": "^18.2.1",
45 | "eslint-config-prettier": "^8.3.0",
46 | "eslint-plugin-import": "^2.23.3",
47 | "eslint-plugin-jsx-a11y": "^6.4.1",
48 | "eslint-plugin-prettier": "^3.4.0",
49 | "eslint-plugin-react": "^7.23.2",
50 | "eslint-plugin-react-hooks": "^4.2.0",
51 | "nodemon": "^2.0.7",
52 | "path": "^0.12.7",
53 | "prettier": "^2.3.0",
54 | "source-map-loader": "^2.0.2",
55 | "style-loader": "^2.0.0",
56 | "webpack": "^5.37.1",
57 | "webpack-cli": "^4.7.0",
58 | "webpack-dev-server": "^3.11.2"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-dupe-keys */
2 | const path = require("path");
3 | const webpack = require("webpack");
4 |
5 | module.exports = {
6 | entry: "./public/index.js",
7 | output: {
8 | path: path.resolve(__dirname, "./dist"),
9 | publicPath: "/dist/",
10 | filename: "bundle.js",
11 | },
12 | mode: process.env.NODE_ENV,
13 | plugins: [
14 | new webpack.ProvidePlugin({
15 | process: "process/browser",
16 | }),
17 | new webpack.SourceMapDevToolPlugin({
18 | filename: "[file].map",
19 | }),
20 | ],
21 | devtool: "source-map",
22 | devServer: {
23 | host: "localhost",
24 | port: 8080,
25 | publicPath: "/dist/",
26 | // contentBase: path.resolve(__dirname, "./build"),
27 | hot: true,
28 | historyApiFallback: true,
29 | headers: {
30 | "Access-Control-Allow-Origin": "*",
31 | "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
32 | "Access-Control-Allow-Headers": "*",
33 | https: true,
34 | },
35 | proxy: {
36 | "/api/**": {
37 | target: "http://localhost:3000/",
38 | secure: false,
39 | },
40 | },
41 | },
42 | node: {
43 | __dirname: true,
44 | },
45 | module: {
46 | rules: [
47 | {
48 | test: /\.jsx?$/, // compilation to es6
49 | enforce: "pre",
50 | use: ["source-map-loader"],
51 | exclude: /node_modules/,
52 | use: {
53 | loader: "babel-loader",
54 | options: {
55 | presets: ["@babel/react"],
56 | },
57 | },
58 | },
59 | {
60 | test: /(\.css)$/,
61 | use: ["style-loader", "css-loader"],
62 | },
63 | {
64 | test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
65 | use: [
66 | {
67 | loader: "file-loader",
68 | options: {
69 | name: "[name].[ext]",
70 | outputPath: "fonts/",
71 | },
72 | },
73 | ],
74 | },
75 | ],
76 | },
77 | resolve: {
78 | extensions: [".js", ".jsx"],
79 | },
80 | };
81 |
--------------------------------------------------------------------------------
/.ebextensions/alb-http-to-https-redirection.config:
--------------------------------------------------------------------------------
1 | ###################################################################################################
2 | #### Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | ####
4 | #### Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file
5 | #### except in compliance with the License. A copy of the License is located at
6 | ####
7 | #### http://aws.amazon.com/apache2.0/
8 | ####
9 | #### or in the "license" file accompanying this file. This file is distributed on an "AS IS"
10 | #### BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 | #### License for the specific language governing permissions and limitations under the License.
12 | ###################################################################################################
13 |
14 | ###################################################################################################
15 | #### This configuration file modifies the default port 80 listener attached to an Application Load Balancer
16 | #### to automatically redirect incoming connections on HTTP to HTTPS.
17 | #### This will not work with an environment using the load balancer type Classic or Network.
18 | #### A prerequisite is that the 443 listener has already been created.
19 | #### Please use the below link for more information about creating an Application Load Balancer on
20 | #### the Elastic Beanstalk console.
21 | #### https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-alb.html#environments-cfg-alb-console
22 | ###################################################################################################
23 |
24 | Resources:
25 | AWSEBV2LoadBalancerListener:
26 | Type: AWS::ElasticLoadBalancingV2::Listener
27 | Properties:
28 | LoadBalancerArn:
29 | Ref: AWSEBV2LoadBalancer
30 | Port: 80
31 | Protocol: HTTP
32 | DefaultActions:
33 | - Type: redirect
34 | RedirectConfig:
35 | Host: "#{host}"
36 | Path: "/#{path}"
37 | Port: "443"
38 | Protocol: "HTTPS"
39 | Query: "#{query}"
40 | StatusCode: "HTTP_301"
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MONARQ Companion Application
2 |
3 | **MONARQ** is a lightweight NPM Package which expands your Express/GraphQL server to accept REST requests. This application contains a user friendly GUI to easily create the required Manifest Object. Due to the specification, here the user can take the guess work out of creating their own Manifest Obejct. Simply use the input fields, add to the accompanying object, then copy and paste the completed Manifest Object into your application.
4 |
5 | Visit our website [MONARQ.io](http://monarq.io/) to see the application code in action, create the Manifest Object, and learn more about the NPM Package.
6 |
7 | Visit [MONARQ](https://github.com/oslabs-beta/MONARQ)'s GitHub or [MONARQ](https://www.npmjs.com/package/monarq)'s NPM page for further information on **MONARQ**.
8 |
9 | # How To Use
10 |
11 | ## _Step 1:_
12 | Navigate to the Manifest Builder within [MONARQ.io](http://monarq.io/). Then press 'Get Started'.
13 |
14 |
15 |
16 |
17 | ## _Step 2:_
18 | Simply add your GraphQL URL to the first input box. This will allow for the application to access your schema which is integral to creating the Manifest Object.
19 |
20 |
21 |
22 |
23 | ## _Step 3:_
24 | Once your schema has loaded, declare the REST endpoints and the REST request method that will be open to the client. Select the query or mutation that will be run within these designated endpoints.
25 |
26 |
27 |
28 |
29 | Then click "Add to Manifest"
30 |
31 |
32 |
33 |
34 | ## _Step: 4_
35 | Now your Manifest Object is populated with your inputs! Keep adding endpoints and/or methods that you want to open to the client sending REST Requests.
36 |
37 |
38 |
39 |
40 | ## _Step: 5_
41 | Once you have populated the Manifest Object with the desired endpoints and methods, copy and paste the code into a file within your application.
42 |
43 |
44 |
45 |
46 | ## _Step 6:_
47 | Import the Manifest Object into your top level server file and invoke the functions within [MONARQ](https://www.npmjs.com/package/monarq)'s NPM package. Pass in this created Manifest Object into both functions based on the instructions. Now you will not run the risk of having a Manifest Object that is incorrect.
48 |
49 | # Contributors
50 |
51 | [Peter Baniuszewicz](https://www.linkedin.com/in/peterbaniuszewicz/) [@Peter-Ba](https://github.com/Peter-Ba)
52 |
53 | [Amy Chen](https://www.linkedin.com/in/amyechen) [@designal46](https://github.com/designal46)
54 |
55 | [Tyler Kneidl](https://www.linkedin.com/in/tylerkneidl/) [@tylerkneidl](https://github.com/tylerkneidl)
56 |
57 | [Helen Regula](https://www.linkedin.com/in/helen-regula/) [@helenregula](https://github.com/helenregula)
58 |
--------------------------------------------------------------------------------
/components/visualizer/Visualizer.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable consistent-return */
2 | /* eslint-disable no-prototype-builtins */
3 | import React, { useState, useRef, useEffect } from "react";
4 | import useUndo from "use-undo";
5 | import {
6 | Alert,
7 | AlertIcon,
8 | AlertTitle,
9 | AlertDescription,
10 | Box,
11 | CloseButton,
12 | Flex,
13 | Grid,
14 | GridItem,
15 | Heading,
16 | Input,
17 | Button,
18 | HStack,
19 | } from "@chakra-ui/react";
20 | import Operations from "./Operations";
21 | import EndpointInput from "./EndpointInput";
22 | import ConfigVis from "./ConfigVis";
23 | import Instructions from "./Instructions";
24 |
25 | const Visualizer = (props) => {
26 | const [operation, setOperation] = useState("");
27 | const [endpoint, setEndpoint] = useState("");
28 | const [method, setMethod] = useState("");
29 | const [configString, setConfigString] = useState([]);
30 | const [gqlURL, setGqlURL] = useState("");
31 | const [defaultParams, setDefaultParams] = useState("");
32 | const [error, setError] = useState(false);
33 | const [configArray, { set: setConfigArray, undo: undoConfigArray, canUndo }] =
34 | useUndo([]);
35 | const { present: presentConfigArray } = configArray;
36 | const [getStarted, setStarted] = useState(false);
37 | const { isLoaded, setIsLoaded } = props;
38 | const getSchema = useRef(null);
39 |
40 | const configArrayBuilder = () => {
41 | if (!endpoint || !method || !operation) return setError(true);
42 | const newConfigArray = [...presentConfigArray];
43 | if (newConfigArray.some((el) => el[0].endpoint === endpoint)) {
44 | const idx = newConfigArray.findIndex((el) => el[0].endpoint === endpoint);
45 | newConfigArray[idx][0].method.push([
46 | method,
47 | { operation, defaultParams },
48 | ]);
49 | setConfigArray(newConfigArray);
50 | } else {
51 | newConfigArray.push([
52 | { endpoint, method: [[method, { operation, defaultParams }]] },
53 | ]);
54 | setConfigArray(newConfigArray);
55 | }
56 | };
57 | const configStringBuilder = () => {
58 | const newConfigString = [];
59 | presentConfigArray.forEach((point) => {
60 | newConfigString.push(`\n\t'${point[0].endpoint}': {`);
61 | point[0].method.forEach((meth) => {
62 | if (meth[1].defaultParams !== "") {
63 | newConfigString.push(
64 | `\n\t\t${meth[0]}: {\n\t\t\toperation: ${meth[1].operation},\n\t\t\tdefaultParams: {${meth[1].defaultParams}}\n\t\t},`
65 | );
66 | } else {
67 | newConfigString.push(`\n\t\t${meth[0]}: {\n\t\t\toperation: ${meth[1].operation},\n\t\t},`);
68 | }
69 | });
70 | newConfigString.push(`\n\t},`);
71 | });
72 | const joinedConfigString = newConfigString.join("");
73 | setConfigString(joinedConfigString);
74 | };
75 | const errorBox = () => {
76 | return (
77 |
78 |
79 | Missing Form Information
80 |
81 | Endpoints, methods, and operations are required fields.
82 |
83 | {
88 | setError(false);
89 | }}
90 | />
91 |
92 | );
93 | };
94 |
95 | useEffect(() => {
96 | if (configArray.length !== 0) {
97 | configStringBuilder();
98 | }
99 | }, [configArray]);
100 | useEffect(() => {}, [error]);
101 |
102 | return (
103 |
110 | {error ? (
111 | {errorBox()}
112 | ) : (
113 |
114 |
119 | Manifest Builder
120 |
121 |
122 | )}
123 |
133 | {!getStarted ? (
134 |
135 | ) : (
136 |
143 |
144 |
145 | Step 1: Enter your GraphQL URL to access the
146 | schema
147 |
148 |
149 | setGqlURL(e.target.value)}
154 | />
155 | {
158 | getSchema.current.getIntrospection();
159 | }}
160 | colorScheme="orange"
161 | paddingRight={10}
162 | paddingLeft={10}
163 | >
164 | Load Schema
165 |
166 |
167 |
168 |
169 |
170 | Step 2: Enter a desired REST API endpoint
171 |
172 |
173 |
174 |
175 |
176 |
177 | Step 3: Select the GraphQL operation to be
178 | executed for requests received at the endpoint
179 |
180 |
187 | {isLoaded ? (
188 |
189 |
190 |
191 | Optional:
192 | {" "}
193 | if the selected operation has default parameters, enter them
194 | below in key-value pair format
195 |
196 | setDefaultParams(e.target.value)}
201 | />
202 |
203 | configArrayBuilder()}
206 | marginRight={5}
207 | colorScheme="orange"
208 | >
209 | Add to Manifest
210 |
211 |
217 | Undo
218 |
219 |
220 |
221 | ) : (
222 |
223 | )}
224 |
225 |
226 | )}
227 |
228 |
229 |
236 |
237 | {" "}
238 |
239 |
240 |
241 |
242 | );
243 | };
244 | export default Visualizer;
245 |
--------------------------------------------------------------------------------