├── docs ├── static │ ├── .nojekyll │ ├── robots.txt │ └── img │ │ └── favicon.ico ├── docs │ ├── models │ │ ├── _category_.json │ │ ├── music.md │ │ ├── science.md │ │ ├── color.md │ │ ├── database.md │ │ ├── commerce.md │ │ ├── internet.md │ │ ├── hacker.md │ │ ├── name.md │ │ ├── lorem.md │ │ ├── image.md │ │ ├── vehicle.md │ │ ├── finance.md │ │ ├── system.md │ │ ├── random.md │ │ ├── datatype.md │ │ └── date.md │ └── intro.mdx ├── babel.config.js ├── src │ ├── pages │ │ ├── markdown-page.md │ │ ├── index.module.css │ │ └── index.js │ └── css │ │ └── custom.css ├── .gitignore ├── sidebars.js ├── package.json ├── SECURITY.md ├── README.md └── docusaurus.config.js ├── backend-go ├── .gitignore ├── models │ ├── project.go │ ├── user.go │ ├── analytics.go │ └── resource.go ├── internal │ ├── utils │ │ ├── faker.go │ │ └── telemetry.go │ ├── http │ │ └── middleware │ │ │ ├── auth.go │ │ │ └── logging.go │ ├── crud │ │ ├── mongo │ │ │ ├── project_repo.go │ │ │ ├── client.go │ │ │ └── user_repo.go │ │ └── repository.go │ ├── endpoints │ │ ├── user_endpoint.go │ │ └── project_endpoint.go │ ├── graphql │ │ └── resolver.go │ ├── config │ │ └── config.go │ ├── services │ │ └── user_service.go │ └── wire │ │ └── wire.go ├── gql │ ├── tools.go │ ├── schemas │ │ └── user │ │ │ └── user.graphql │ └── gqlgen.yml ├── pkg │ └── graphql │ │ └── models_gen.go ├── Makefile ├── cmd │ └── server │ │ └── main.go └── go.mod ├── frontend ├── public │ ├── _redirects │ ├── netlify.toml │ └── favicon.ico ├── .gitignore ├── src │ ├── assets │ │ ├── 404.png │ │ ├── images │ │ │ └── logo.png │ │ ├── fonts │ │ │ └── CalSans-SemiBold.woff2 │ │ └── home │ │ │ ├── gradient-1.svg │ │ │ └── gradient-2.svg │ ├── pages │ │ ├── dashboard │ │ │ ├── enums │ │ │ │ └── error.js │ │ │ └── components │ │ │ │ ├── DeleteResourceModal.jsx │ │ │ │ ├── ResourceModal.jsx │ │ │ │ ├── EditResourceModal.jsx │ │ │ │ ├── CloneModal.jsx │ │ │ │ ├── ResultModal.jsx │ │ │ │ ├── ConfirmDelProjectModal.jsx │ │ │ │ ├── EndpointModal.jsx │ │ │ │ └── ViewAnalytics.jsx │ │ ├── others │ │ │ └── Error404Page.jsx │ │ └── auth │ │ │ ├── EmailVerify.jsx │ │ │ ├── Signup.jsx │ │ │ └── Login.jsx │ ├── services │ │ ├── api.js │ │ ├── models │ │ │ ├── serviceModel.js │ │ │ ├── authModel.js │ │ │ ├── userModal.js │ │ │ ├── projectModel.js │ │ │ └── resourceModal.js │ │ └── utilities │ │ │ ├── response.js │ │ │ └── core.js │ ├── utils │ │ └── utils.js │ ├── styles │ │ └── style.css │ ├── components │ │ ├── CustomDisplay.jsx │ │ ├── CustomCheckbox.jsx │ │ ├── CustomButtons.jsx │ │ ├── CustomTooltip.jsx │ │ ├── CustomChartComponents.jsx │ │ ├── CustomLoading.jsx │ │ ├── CustomTabPanel.jsx │ │ ├── CustomToggle.jsx │ │ ├── CustomInputFields.jsx │ │ ├── CustomModal.jsx │ │ └── CustomTable.jsx │ ├── context │ │ └── ThemeContext.jsx │ ├── main.jsx │ ├── App.jsx │ ├── themes │ │ └── themeColors.js │ ├── layout │ │ ├── AuthGuard.jsx │ │ ├── DashboardLayout.jsx │ │ └── AuthLayout.jsx │ └── routes.jsx ├── vite.config.js ├── .eslintrc.json ├── index.html └── package.json ├── backend ├── .gitignore ├── feLink.js ├── vercel.json ├── .env.sample ├── models │ ├── Project.js │ ├── Analytics.js │ ├── User.js │ └── Resource.js ├── package.json ├── middleware │ └── authenticate.js ├── utils │ ├── customFaker.js │ └── trackAPIRequests.js ├── index.js ├── routes │ ├── project │ │ └── project.js │ ├── service │ │ └── service.js │ ├── auth │ │ └── auth.js │ └── user │ │ └── user.js └── templates │ ├── resetPwdTemplate.js │ └── verificationTemplate.js ├── .github ├── dependabot.yml ├── workflows │ ├── auto-author-assign.yml │ ├── pr-title-checker.yml │ ├── greetings.yml │ └── codeql.yml ├── PULL_REQUEST_TEMPLATE.md ├── pr-title-checker.json └── ISSUE_TEMPLATE │ ├── style.yml │ ├── bug_report.yml │ ├── feature_request.yml │ ├── other.yml │ └── doc_report.yml ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md └── README.md /docs/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /backend-go/models/project.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/models/user.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/models/analytics.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/models/resource.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/utils/faker.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/utils/telemetry.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/http/middleware/auth.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/crud/mongo/project_repo.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/endpoints/user_endpoint.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/http/middleware/logging.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend-go/internal/endpoints/project_endpoint.go: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /frontend/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | package-lock.json -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .DS_Store -------------------------------------------------------------------------------- /docs/docs/models/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Models", 3 | "position": 1 4 | } 5 | -------------------------------------------------------------------------------- /frontend/public/netlify.toml: -------------------------------------------------------------------------------- 1 | [[redirects]] 2 | from="/" 3 | to="/index.html" 4 | status=200 -------------------------------------------------------------------------------- /docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shelcia/mocker/HEAD/docs/static/img/favicon.ico -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shelcia/mocker/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/src/assets/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shelcia/mocker/HEAD/frontend/src/assets/404.png -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /frontend/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shelcia/mocker/HEAD/frontend/src/assets/images/logo.png -------------------------------------------------------------------------------- /backend-go/gql/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package tools 4 | 5 | import ( 6 | _ "github.com/99designs/gqlgen" 7 | ) 8 | -------------------------------------------------------------------------------- /frontend/src/assets/fonts/CalSans-SemiBold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shelcia/mocker/HEAD/frontend/src/assets/fonts/CalSans-SemiBold.woff2 -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /backend/feLink.js: -------------------------------------------------------------------------------- 1 | // const feLink = "http://127.0.0.1:5173/"; 2 | const feLink = "https://mocker-gen.netlify.app/"; 3 | 4 | module.exports = feLink; 5 | -------------------------------------------------------------------------------- /backend-go/pkg/graphql/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package graphql 4 | 5 | type Query struct { 6 | } 7 | -------------------------------------------------------------------------------- /docs/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | ## Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/enums/error.js: -------------------------------------------------------------------------------- 1 | export const ValidationError = { 2 | RESOURCE_NAME: "0001", 3 | LABEL_NAME: "0002", 4 | FIELD_NAME: "0003", 5 | NUMBER_OF_OBJECT: "0004", 6 | }; 7 | -------------------------------------------------------------------------------- /backend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "mocker-backend", 4 | "builds": [{ "src": "index.js", "use": "@vercel/node" }], 5 | "routes": [{ "src": "/(.*)", "dest": "/index.js" }] 6 | } 7 | -------------------------------------------------------------------------------- /backend-go/gql/schemas/user/user.graphql: -------------------------------------------------------------------------------- 1 | type User { 2 | id: ID! 3 | email: String! 4 | name: String 5 | } 6 | 7 | type Mutation { 8 | login(email: String!, password: String!): User 9 | } 10 | -------------------------------------------------------------------------------- /backend/.env.sample: -------------------------------------------------------------------------------- 1 | DB_CONNECT = "mongodb+srv://{username}:{password}@cluster0.hfdhy.mongodb.net/{collectio_name}?retryWrites=true&w=majority" 2 | 3 | TOKEN_SECRET = "{some gibberish}" 4 | 5 | EMAIL_ID = "email_id" 6 | EMAIL_PWD = "password" -------------------------------------------------------------------------------- /frontend/src/services/api.js: -------------------------------------------------------------------------------- 1 | // export const BACKEND_URL = "http://localhost:4050/api"; 2 | // export const BACKEND_URL = "https://mockapi-backend.onrender.com/api"; 3 | export const BACKEND_URL = "https://mocker-backend.vercel.app/api"; 4 | -------------------------------------------------------------------------------- /frontend/src/utils/utils.js: -------------------------------------------------------------------------------- 1 | export const copyTextToClipboard = async (text) => { 2 | if ("clipboard" in navigator) { 3 | return await navigator.clipboard.writeText(text); 4 | } else { 5 | return document.execCommand("copy", true, text); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line import/namespace 2 | import { defineConfig } from "vite"; 3 | import react from "@vitejs/plugin-react"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react()], 8 | }); 9 | -------------------------------------------------------------------------------- /backend-go/Makefile: -------------------------------------------------------------------------------- 1 | dev: 2 | \tair -Xms256m -Xmx256m # (or just) go run ./cmd/server 3 | gql: 4 | \tgo run github.com/99designs/gqlgen generate 5 | wire: 6 | \tgo run github.com/google/wire/cmd/wire ./internal/wire 7 | test: 8 | \tgo test ./... 9 | lint: 10 | \tgolangci-lint run 11 | -------------------------------------------------------------------------------- /.github/workflows/auto-author-assign.yml: -------------------------------------------------------------------------------- 1 | name: Auto Author Assign 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, reopened] 6 | 7 | permissions: 8 | pull-requests: write 9 | 10 | jobs: 11 | assign-author: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: toshimaru/auto-author-assign@v2.1.0 15 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | package-lock.json 4 | 5 | # Production 6 | /build 7 | 8 | # Generated files 9 | .docusaurus 10 | .cache-loader 11 | 12 | # Misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /frontend/src/services/models/serviceModel.js: -------------------------------------------------------------------------------- 1 | import { ApiCore } from "../utilities/core"; 2 | 3 | const url = "service"; 4 | 5 | export const apiService = new ApiCore({ 6 | getAll: true, 7 | getSingle: true, 8 | getByParams: true, 9 | post: true, 10 | put: true, 11 | putById: true, 12 | patch: true, 13 | remove: true, 14 | url: url, 15 | }); 16 | -------------------------------------------------------------------------------- /backend-go/internal/crud/repository.go: -------------------------------------------------------------------------------- 1 | package crud 2 | 3 | import "context" 4 | 5 | type User struct { 6 | ID string `bson:"_id,omitempty"` 7 | Email string `bson:"email"` 8 | Name string `bson:"name"` 9 | Password string `bson:"password,omitempty"` 10 | } 11 | 12 | type UserRepository interface { 13 | FindByID(ctx context.Context, id string) (*User, error) 14 | } 15 | -------------------------------------------------------------------------------- /frontend/src/services/models/authModel.js: -------------------------------------------------------------------------------- 1 | import { ApiCore } from "../utilities/core"; 2 | 3 | const url = "auth"; 4 | 5 | export const apiAuth = new ApiCore({ 6 | getAll: true, 7 | getSingle: true, 8 | getByParams: true, 9 | post: true, 10 | put: true, 11 | putById: true, 12 | patch: true, 13 | remove: true, 14 | url: url, 15 | // plural: plural, 16 | // single: single, 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/src/services/models/userModal.js: -------------------------------------------------------------------------------- 1 | import { ApiCore } from "../utilities/core"; 2 | 3 | const url = "user"; 4 | 5 | export const apiUser = new ApiCore({ 6 | getAll: true, 7 | getSingle: true, 8 | getByParams: true, 9 | post: true, 10 | put: true, 11 | putById: true, 12 | patch: true, 13 | remove: true, 14 | url: url, 15 | // plural: plural, 16 | // single: single, 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/src/services/models/projectModel.js: -------------------------------------------------------------------------------- 1 | import { ApiCore } from "../utilities/core"; 2 | 3 | const url = "project"; 4 | 5 | export const apiProject = new ApiCore({ 6 | getAll: true, 7 | getSingle: true, 8 | getByParams: true, 9 | post: true, 10 | put: true, 11 | putById: true, 12 | patch: true, 13 | remove: true, 14 | removeAll: true, 15 | url: url, 16 | // plural: plural, 17 | // single: single, 18 | }); 19 | -------------------------------------------------------------------------------- /frontend/src/services/models/resourceModal.js: -------------------------------------------------------------------------------- 1 | import { ApiCore } from "../utilities/core"; 2 | 3 | const url = "resource"; 4 | 5 | export const apiResource = new ApiCore({ 6 | getAll: true, 7 | getSingle: true, 8 | getByParams: true, 9 | post: true, 10 | put: true, 11 | putById: true, 12 | patch: true, 13 | remove: true, 14 | removeAll: true, 15 | url: url, 16 | // plural: plural, 17 | // single: single, 18 | }); 19 | -------------------------------------------------------------------------------- /frontend/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:react/recommended" 9 | ], 10 | "overrides": [ 11 | ], 12 | "parserOptions": { 13 | "ecmaVersion": "latest", 14 | "sourceType": "module" 15 | }, 16 | "plugins": [ 17 | "react" 18 | ], 19 | "rules": { 20 | "react/prop-types": 0 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /backend/models/Project.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const projectSchema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | }, 8 | prefix: { 9 | type: String, 10 | }, 11 | userId: { 12 | type: String, 13 | required: true, 14 | }, 15 | collaborators: { 16 | type: Array, 17 | }, 18 | date: { 19 | type: Date, 20 | default: Date.now(), 21 | }, 22 | }); 23 | 24 | module.exports = mongoose.model("Project", projectSchema); 25 | -------------------------------------------------------------------------------- /backend/models/Analytics.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const analyticsSchema = new mongoose.Schema({ 4 | userId: { 5 | type: String, 6 | }, 7 | projectId: { 8 | type: String, 9 | }, 10 | resourceId: { 11 | type: String, 12 | required: true, 13 | }, 14 | method: { 15 | type: String, 16 | required: true, 17 | }, 18 | date: { 19 | type: Date, 20 | default: Date.now(), 21 | }, 22 | }); 23 | 24 | module.exports = mongoose.model("Analytics", analyticsSchema); 25 | -------------------------------------------------------------------------------- /.github/workflows/pr-title-checker.yml: -------------------------------------------------------------------------------- 1 | name: 'PR Title Checker' 2 | on: 3 | pull_request_target: 4 | types: 5 | - opened 6 | - edited 7 | - synchronize 8 | - labeled 9 | - unlabeled 10 | 11 | jobs: 12 | check: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: thehanimo/pr-title-checker@v1.3.7 16 | with: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | pass_on_octokit_error: false 19 | configuration_path: '.github/pr-title-checker.json' 20 | -------------------------------------------------------------------------------- /docs/docs/models/music.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 11 3 | tags: [music] 4 | --- 5 | 6 | # Music 7 | 8 | ## Module to generate music related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### genre 17 | 18 | Returns a random music genre. 19 | 20 | #### output 21 | 22 | ```json 23 | Soul 24 | ``` 25 | 26 | ### songName 27 | 28 | Returns a random song name. 29 | 30 | #### output 31 | 32 | ```json 33 | Somethin' Stupid 34 | ``` 35 | -------------------------------------------------------------------------------- /frontend/src/styles/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "CalSans"; 3 | src: url("../assets/fonts/CalSans-SemiBold.woff2") format("woff2"); 4 | } 5 | 6 | code, 7 | #json-pretty, 8 | pre { 9 | font-family: "JetBrains Mono", monospace; 10 | } 11 | 12 | .lang-dark span.__json-key__ { 13 | color: #ff6b93; 14 | } 15 | 16 | .lang-dark span.__json-string__ { 17 | color: #7ad2fa; 18 | } 19 | 20 | .lang-light span.__json-key__ { 21 | color: #fd396d; 22 | } 23 | 24 | .lang-light span.__json-string__ { 25 | color: rgb(9, 33, 53); 26 | } 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Fixes Issue🛠️ 2 | 3 | 4 | 5 | Closes # 6 | 7 | # Description👨‍💻 8 | 9 | 10 | 11 | # Checklist✅ 12 | 13 | - [] My code follows the style guidelines of this project 14 | - [] I have performed a self-review of my own code 15 | - [] I have added demonstration in the form of GIF/video file 16 | - [] I am an Open Source Contributor 17 | 18 | # Screenshots/GIF📷 -------------------------------------------------------------------------------- /backend/models/User.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const userSchema = new mongoose.Schema({ 4 | email: { 5 | type: String, 6 | required: true, 7 | max: 255, 8 | min: 6, 9 | }, 10 | password: { 11 | type: String, 12 | required: true, 13 | max: 1024, 14 | min: 6, 15 | }, 16 | emailVerified: { 17 | type: Boolean, 18 | default: false, 19 | }, 20 | date: { 21 | type: Date, 22 | default: Date.now(), 23 | }, 24 | }); 25 | 26 | module.exports = mongoose.model("User", userSchema); 27 | -------------------------------------------------------------------------------- /docs/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | /** 4 | * CSS files with the .module.css suffix will be treated as CSS modules 5 | * and scoped locally. 6 | */ 7 | 8 | .heroBanner { 9 | padding: 4rem 0; 10 | text-align: center; 11 | position: relative; 12 | overflow: hidden; 13 | } 14 | 15 | @media screen and (max-width: 966px) { 16 | .heroBanner { 17 | padding: 2rem; 18 | } 19 | } 20 | 21 | .buttons { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | -------------------------------------------------------------------------------- /backend-go/internal/crud/mongo/client.go: -------------------------------------------------------------------------------- 1 | package mongo 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | "go.mongodb.org/mongo-driver/mongo" 8 | "go.mongodb.org/mongo-driver/mongo/options" 9 | ) 10 | 11 | type Client struct { 12 | DB *mongo.Database 13 | } 14 | 15 | func New(uri, dbName string) (*Client, error) { 16 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 17 | defer cancel() 18 | mc, err := mongo.Connect(ctx, options.Client().ApplyURI(uri)) 19 | if err != nil { return nil, err } 20 | return &Client{DB: mc.Database(dbName)}, nil 21 | } 22 | -------------------------------------------------------------------------------- /backend-go/internal/graphql/resolver.go: -------------------------------------------------------------------------------- 1 | package graphql 2 | 3 | import ( 4 | "context" 5 | "github.com/shelcia/mocker/backend-go/internal/services" 6 | "github.com/shelcia/mocker/backend-go/internal/crud" 7 | ) 8 | 9 | type Resolver struct { 10 | Users services.UserService 11 | } 12 | 13 | func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} } 14 | 15 | type mutationResolver struct{ *Resolver } 16 | 17 | func (m *mutationResolver) Login(ctx context.Context, email string, password string) (*repository.User, error) { 18 | return m.Users.Login(ctx, email, password) 19 | } 20 | -------------------------------------------------------------------------------- /docs/docs/models/science.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 14 3 | tags: [science] 4 | --- 5 | 6 | # Science 7 | 8 | ## Module to generate science related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### Chemical unit 17 | 18 | Returns a random periodic table element. 19 | 20 | #### output 21 | 22 | ```json 23 | { "symbol": "Tb", "name": "Terbium", "atomicNumber": 65 } 24 | ``` 25 | 26 | ### unit 27 | 28 | Returns a random scientific unit. 29 | 30 | #### output 31 | 32 | ```json 33 | { "name": "ohm", "symbol": "Ω" } 34 | ``` 35 | -------------------------------------------------------------------------------- /frontend/src/components/CustomDisplay.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Typography } from "@mui/material"; 3 | import { error, success } from "../themes/themeColors"; 4 | 5 | export const CustomTypoDisplay = ({ status, children }) => { 6 | return ( 7 | <> 8 | 19 | {children} 20 | 21 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /docs/docs/models/color.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | tags: [color] 4 | --- 5 | 6 | # Color 7 | 8 | ## Module to generate colors. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### hsl 17 | 18 | Returns an HSL color. 19 | 20 | #### output 21 | 22 | ```json 23 | [198, 0.59, 0.72] 24 | ``` 25 | 26 | ### humanColor 27 | 28 | Returns a random human readable color name. 29 | 30 | #### output 31 | 32 | ```json 33 | red 34 | ``` 35 | 36 | ### rgb 37 | 38 | Returns an **RGB** color. 39 | 40 | #### output 41 | 42 | ```json 43 | 0xffffff 44 | ``` 45 | -------------------------------------------------------------------------------- /frontend/src/components/CustomCheckbox.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Checkbox } from "@mui/material"; 3 | import { ThemeContext } from "../context/ThemeContext"; 4 | 5 | const CustomCheckbox = ({ handleChecked, id }) => { 6 | const [darkTheme] = useContext(ThemeContext); 7 | 8 | return ( 9 | <> 10 | { 16 | handleChecked(e, id); 17 | }} 18 | /> 19 | 20 | ); 21 | }; 22 | 23 | export default CustomCheckbox; 24 | -------------------------------------------------------------------------------- /backend-go/internal/crud/mongo/user_repo.go: -------------------------------------------------------------------------------- 1 | package mongo 2 | 3 | import ( 4 | "context" 5 | 6 | "go.mongodb.org/mongo-driver/bson" 7 | "go.mongodb.org/mongo-driver/bson/primitive" 8 | 9 | repo "github.com/shelcia/mocker/backend-go/internal/crud" 10 | ) 11 | 12 | type userRepo struct{ c *Client } 13 | 14 | func NewUserRepository(c *Client) repo.UserRepository { return &userRepo{c} } 15 | 16 | func (r *userRepo) FindByID(ctx context.Context, id string) (*repo.User, error) { 17 | oid, err := primitive.ObjectIDFromHex(id); if err != nil { return nil, err } 18 | var u repo.User 19 | err = r.c.DB.Collection("users").FindOne(ctx, bson.M{"_id": oid}).Decode(&u) 20 | return &u, err 21 | } -------------------------------------------------------------------------------- /backend/models/Resource.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const resourceSchema = new mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | }, 8 | schema: { 9 | type: Array, 10 | }, 11 | data: { 12 | type: Array, 13 | }, 14 | number: { 15 | type: Number, 16 | }, 17 | userId: { 18 | type: String, 19 | }, 20 | projectId: { 21 | type: String, 22 | }, 23 | analytics: [ 24 | { 25 | date: { type: Date, default: Date.now }, 26 | }, 27 | ], 28 | date: { 29 | type: Date, 30 | default: Date.now(), 31 | }, 32 | }); 33 | 34 | module.exports = mongoose.model("Resource", resourceSchema); 35 | -------------------------------------------------------------------------------- /frontend/src/context/ThemeContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, createContext, useEffect } from "react"; 2 | 3 | export const ThemeContext = createContext(); 4 | 5 | export const ThemeProvider = ({ children }) => { 6 | const [darkTheme, setDarkTheme] = useState(false); 7 | 8 | const darkThemeLocal = localStorage.getItem("mockapi-theme"); 9 | 10 | useEffect(() => { 11 | // console.log(JSON.stringify(darkThemeLocal), "true"); 12 | if (darkThemeLocal === "true") { 13 | setDarkTheme(true); 14 | } 15 | }, []); 16 | 17 | return ( 18 | 19 | {children} 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-api-backend", 3 | "version": "1.0.0", 4 | "description": "mock api backend", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Shelcia", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@faker-js/faker": "^7.6.0", 13 | "bcryptjs": "^2.4.3", 14 | "cors": "^2.8.5", 15 | "cryptr": "^6.1.0", 16 | "dotenv": "^16.0.2", 17 | "express": "^4.18.2", 18 | "express-rate-limit": "^6.7.0", 19 | "joi": "^17.8.3", 20 | "jsonwebtoken": "^9.0.0", 21 | "mongoose": "^6.10.1", 22 | "nodemailer": "^6.9.1", 23 | "uuid": "^9.0.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.github/pr-title-checker.json: -------------------------------------------------------------------------------- 1 | { 2 | "LABEL": { 3 | "name": "title needs formatting", 4 | "color": "F9D0C4" 5 | }, 6 | "CHECKS": { 7 | "prefixes": [ 8 | "build: ", 9 | "chore: ", 10 | "docs: ", 11 | "feat: ", 12 | "fix: ", 13 | "perf: ", 14 | "refactor: ", 15 | "revert: ", 16 | "style: ", 17 | "test: " 18 | ] 19 | }, 20 | "MESSAGES": { 21 | "success": "Everything is great. Status: 200", 22 | "failure": "PR title does not conform to the required format. Please use one of the specified prefixes followed by a colon and a space. Status: 400", 23 | "notice": "" 24 | } 25 | } -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | module.exports = { 13 | // By default, Docusaurus generates a sidebar from the docs folder structure 14 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 15 | 16 | // But you can create a sidebar manually 17 | /* 18 | tutorialSidebar: [ 19 | { 20 | type: 'category', 21 | label: 'Tutorial', 22 | items: ['hello'], 23 | }, 24 | ], 25 | */ 26 | }; 27 | -------------------------------------------------------------------------------- /frontend/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import { BrowserRouter } from "react-router-dom"; 4 | import { ThemeProvider } from "./context/ThemeContext"; 5 | import App from "./App"; 6 | import "@fontsource/poppins"; 7 | import "@fontsource/jetbrains-mono"; 8 | 9 | // Supports weights 100-900 10 | import "@fontsource-variable/dm-sans"; 11 | 12 | ReactDOM.createRoot(document.getElementById("root")).render( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | 22 | // const root = ReactDOM.createRoot(document.getElementById("root")); 23 | // root.render( 24 | // 25 | // 26 | // 27 | // ); 28 | -------------------------------------------------------------------------------- /backend-go/internal/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "time" 7 | ) 8 | 9 | type Config struct { 10 | Port string 11 | MongoURI string 12 | DBName string 13 | JWTSecret string 14 | Env string 15 | ReadTimeout time.Duration 16 | } 17 | 18 | func FromEnv() *Config { 19 | c := &Config{ 20 | Port: get("PORT", "8080"), 21 | MongoURI: must("MONGO_URI"), 22 | DBName: get("MONGO_DB", "mocker"), 23 | JWTSecret: must("JWT_SECRET"), 24 | Env: get("ENV", "dev"), 25 | ReadTimeout: 15 * time.Second, 26 | } 27 | return c 28 | } 29 | 30 | func get(k, def string) string { if v := os.Getenv(k); v != "" { return v }; return def } 31 | func must(k string) string { v := os.Getenv(k); if v == "" { log.Fatalf("%s required", k) }; return v } 32 | -------------------------------------------------------------------------------- /backend-go/internal/services/user_service.go: -------------------------------------------------------------------------------- 1 | package services 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/shelcia/mocker/backend-go/internal/crud" 7 | ) 8 | 9 | type UserService interface { 10 | Login(ctx context.Context, email, password string) (*repository.User, error) 11 | } 12 | 13 | type userService struct { 14 | repo repository.UserRepository 15 | } 16 | 17 | func NewUserService(r repository.UserRepository) UserService { 18 | return &userService{repo: r} 19 | } 20 | 21 | func (s *userService) Login(ctx context.Context, email, password string) (*repository.User, error) { 22 | u, _ := s.repo.FindByEmail(ctx, email) 23 | if u == nil { 24 | return nil, errors.New("email not found") 25 | } 26 | if u.Password != password { 27 | return nil, errors.New("invalid password") 28 | } 29 | return u, nil 30 | } 31 | -------------------------------------------------------------------------------- /backend/middleware/authenticate.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | 3 | /** 4 | * @description 5 | * Act as a middleware that provide a user 6 | * authentication for performing various 7 | * sensitive activity 8 | */ 9 | const userAuth = (req, res, next) => { 10 | const token = req.headers["auth-token"]; 11 | 12 | if (!token) { 13 | return res.status(401).send({ 14 | status: "401", 15 | message: "Token is needed", 16 | }); 17 | } 18 | jwt.verify(token, process.env.TOKEN_SECRET, (err, payload) => { 19 | if (err) { 20 | return res.status(400).send({ 21 | status: "400", 22 | message: "Something wrong", 23 | }); 24 | } 25 | //SET USER INFO 26 | req.body.user = payload; 27 | return next(); 28 | }); 29 | 30 | }; 31 | 32 | module.exports = userAuth; 33 | -------------------------------------------------------------------------------- /frontend/src/components/CustomButtons.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button, styled } from "@mui/material"; 3 | import { blue, green } from "@mui/material/colors"; 4 | import { ColorRing } from "react-loader-spinner"; 5 | 6 | export const CopyButton = styled(Button)(({ theme }) => ({ 7 | minWidth: 0, 8 | padding: "1px 5px", 9 | fontSize: "0.8rem", 10 | background: theme.palette.mode === "dark" ? blue[500] : blue[400], 11 | color: "white", 12 | "&:hover": { 13 | backgroundColor: theme.palette.mode === "dark" ? blue[900] : blue[500], 14 | }, 15 | "&:disabled": { 16 | backgroundColor: theme.palette.mode === "dark" ? green[800] : green[500], 17 | color: green[50], 18 | }, 19 | })); 20 | 21 | export const CustomLoaderButton = () => { 22 | return ; 23 | }; 24 | -------------------------------------------------------------------------------- /backend/utils/customFaker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {{ 4 | * length: string | number | undefined, 5 | * whitelist: string | undefined, 6 | * }} options 7 | * @returns 8 | */ 9 | module.exports.specialCharacter = (options = {}) => { 10 | options.length = options.length || 5; 11 | options.whitelist = options.whitelist || "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~\\"; 12 | 13 | let newSetOfChars = ""; 14 | 15 | for (let i = 0; i < options.length; i++) { 16 | newSetOfChars += 17 | options.whitelist[generateRandom(0, options.whitelist.length)]; 18 | } 19 | 20 | return newSetOfChars; 21 | }; 22 | 23 | /** 24 | * 25 | * @param {number} min 26 | * @param {number} max 27 | * @description Returns random number between min(inclusive) and max(exclusive). 28 | */ 29 | const generateRandom = (min, max) => { 30 | min = Math.ceil(min); 31 | max = Math.floor(max - 1); 32 | return Math.floor(Math.random() * (max - min + 1)) + min; 33 | }; 34 | -------------------------------------------------------------------------------- /frontend/src/components/CustomTooltip.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Tooltip, { tooltipClasses } from "@mui/material/Tooltip"; 3 | import { styled } from "@mui/material/styles"; 4 | import { secondary } from "../themes/themeColors"; 5 | 6 | export const CustomTooltip = styled(({ className, ...props }) => ( 7 | 8 | ))(({ theme }) => ({ 9 | [`& .${tooltipClasses.arrow}`]: { 10 | color: 11 | theme.palette.mode === "dark" 12 | ? theme.palette.common.white 13 | : secondary[900], 14 | }, 15 | [`& .${tooltipClasses.tooltip}`]: { 16 | backgroundColor: 17 | theme.palette.mode === "dark" 18 | ? theme.palette.common.white 19 | : secondary[900], 20 | color: 21 | theme.palette.mode === "dark" 22 | ? secondary[900] 23 | : theme.palette.common.white, 24 | boxShadow: theme.shadows[2], 25 | fontSize: 11, 26 | }, 27 | })); 28 | -------------------------------------------------------------------------------- /docs/docs/models/database.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 17 3 | tags: [database] 4 | --- 5 | 6 | # Database 7 | 8 | ## Module to generate database related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### collation 17 | 18 | Returns a random database collation. 19 | 20 | #### output 21 | 22 | ```json 23 | utf8_unicode_ci 24 | ``` 25 | 26 | ### column 27 | 28 | Returns a random database column name. 29 | 30 | #### output 31 | 32 | ```json 33 | createdAt 34 | ``` 35 | 36 | ### engine 37 | 38 | Returns a random database engine. 39 | 40 | #### output 41 | 42 | ```json 43 | CSV 44 | ``` 45 | 46 | ### mongodbObjectId 47 | 48 | Returns a MongoDB ObjectId string. 49 | 50 | #### output 51 | 52 | ```json 53 | cdfcdcbc9de896d1f58abbba 54 | ``` 55 | 56 | ### type 57 | 58 | Returns a random database column type. 59 | 60 | #### output 61 | 62 | ```json 63 | timestamp 64 | ``` 65 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: 'Greetings' 2 | 3 | on: 4 | issues: 5 | types: [opened] 6 | pull_request_target: 7 | types: [opened] 8 | 9 | jobs: 10 | welcome: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v1 14 | - uses: EddieHubCommunity/gh-action-community/src/welcome@main 15 | with: 16 | github-token: ${{ secrets.GITHUB_TOKEN }} 17 | issue-message: 'Congratulations, @${{ github.actor }}! 🎉 Thank you for creating your issue for mocker project. Your contribution is greatly appreciated and we look forward to working with you to resolve the issue. Keep up the great work! Should you have any queries or require guidance, do not hesitate to ask.' 18 | pr-message: 'Great job, @${{ github.actor }}! 🎉 Thank you for submitting your pull request for mocker project. Our dedicated team will review it diligently.Your contribution is valuable and we appreciate your efforts to improve our project.' 19 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 12 | MOCKER 13 | 14 | 18 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /backend-go/cmd/server/main.go: -------------------------------------------------------------------------------- 1 | 2 | package main 3 | 4 | import ( 5 | "log" 6 | "net/http" 7 | 8 | "github.com/99designs/gqlgen/graphql/handler" 9 | "github.com/99designs/gqlgen/graphql/playground" 10 | 11 | gen "github.com/shelcia/mocker/backend-go/internal/graphql/gql_generated/generated" 12 | "github.com/shelcia/mocker/backend-go/internal/graphql" 13 | "github.com/shelcia/mocker/backend-go/internal/services" 14 | "github.com/shelcia/mocker/backend-go/internal/crud" 15 | ) 16 | 17 | func main() { 18 | // memory repo with a test user 19 | userRepo := repository.NewMemoryUserRepo() 20 | userService := services.NewUserService(userRepo) 21 | 22 | res := &graphql.Resolver{Users: userService} 23 | srv := handler.NewDefaultServer(gen.NewExecutableSchema(gen.Config{Resolvers: res})) 24 | 25 | http.Handle("/query", srv) 26 | http.Handle("/", playground.Handler("GraphQL playground", "/query")) 27 | 28 | log.Println("server started on :8080") 29 | log.Fatal(http.ListenAndServe(":8080", nil)) 30 | } 31 | -------------------------------------------------------------------------------- /backend-go/internal/wire/wire.go: -------------------------------------------------------------------------------- 1 | //go:build wireinject 2 | // +build wireinject 3 | 4 | package wire 5 | 6 | import ( 7 | "github.com/google/wire" 8 | "github.com/shelcia/mocker/backend-go/internal/config" 9 | "github.com/shelcia/mocker/backend-go/internal/services" 10 | "github.com/shelcia/mocker/backend-go/internal/crud/mongo" 11 | repo "github.com/shelcia/mocker/backend-go/internal/crud" 12 | ) 13 | 14 | type Container struct { 15 | Config *config.Config 16 | UserService services.UserService 17 | RepoClient *mongo.Client 18 | } 19 | 20 | func Init() (*Container, error) { 21 | wire.Build( 22 | config.FromEnv, 23 | provideMongoClient, 24 | provideUserRepo, 25 | services.NewUserService, 26 | wire.Struct(new(Container), "*"), 27 | ) 28 | return nil, nil 29 | } 30 | 31 | func provideMongoClient(c *config.Config) (*mongo.Client, error) { 32 | return mongo.New(c.MongoURI, c.DBName) 33 | } 34 | func provideUserRepo(c *mongo.Client) repo.UserRepository { return mongo.NewUserRepository(c) } 35 | -------------------------------------------------------------------------------- /frontend/src/services/utilities/response.js: -------------------------------------------------------------------------------- 1 | // response.js 2 | 3 | // import toast from "react-hot-toast"; 4 | 5 | // This is kept separate to keep our files lean and allow a clean separation 6 | // for any response and error logic you may want to handle here for all API calls. 7 | // Maybe you want to log an error here or create custom actions for authorization based 8 | // on the response header. 9 | 10 | export function handleResponse(response) { 11 | if (response.results) { 12 | return response.results; 13 | } 14 | 15 | if (response.data) { 16 | return response.data; 17 | } 18 | 19 | if (response.message) { 20 | return response.message; 21 | } 22 | 23 | return response; 24 | } 25 | 26 | export function handleError(error) { 27 | if (error.data) { 28 | // toast.error(error.data); 29 | return error.data; 30 | } 31 | if (error.message) { 32 | // toast.error(error.message); 33 | return error.message; 34 | } 35 | // toast.error(error); 36 | return error; 37 | } 38 | -------------------------------------------------------------------------------- /frontend/src/components/CustomChartComponents.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Box, Typography } from "@mui/material"; 3 | import { ThemeContext } from "../context/ThemeContext"; 4 | import { secondary } from "../themes/themeColors"; 5 | 6 | export const CustomTooltip = ({ active, payload, label }) => { 7 | const [darkTheme] = useContext(ThemeContext); 8 | 9 | // console.log(active, payload, label); 10 | 11 | if (active && payload && payload.length) { 12 | return ( 13 | 22 | 23 | {`${label} : ${payload[0].value}`} {payload[0]?.name} 24 | 25 | 26 | ); 27 | } 28 | 29 | return null; 30 | }; 31 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/DeleteResourceModal.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import CustomModal from "../../../components/CustomModal"; 3 | import { Button, Stack } from "@mui/material"; 4 | 5 | const DeleteResourceModal = ({ open, setOpen, result, delResource }) => ( 6 | 12 | Are you sure you want to delete resource ? 13 | 14 | 24 | 32 | 33 | 34 | ); 35 | 36 | export default DeleteResourceModal; 37 | -------------------------------------------------------------------------------- /frontend/src/components/CustomLoading.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box } from "@mui/material"; 3 | import { Rings } from "react-loader-spinner"; 4 | 5 | const Loading = ({ children }) => { 6 | return ( 7 | 16 | 26 | {children} 27 | 28 | ); 29 | }; 30 | 31 | export default Loading; 32 | 33 | export const PartLoader = ({ children }) => ( 34 | 35 | 45 | {children} 46 | 47 | ); 48 | -------------------------------------------------------------------------------- /docs/docs/models/commerce.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | tags: [commerce] 4 | --- 5 | 6 | # Commerce 7 | 8 | ## Module to generate commerce and product related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### product 17 | 18 | Returns a short product name. 19 | 20 | #### output 21 | 22 | ```json 23 | Computer 24 | ``` 25 | 26 | ### productDescription 27 | 28 | Returns a product description. 29 | 30 | #### output 31 | 32 | ```json 33 | The Football Is Good For Training And Recreati... 34 | ``` 35 | 36 | ### price 37 | 38 | Generates a price between min and max (inclusive). 39 | 40 | | Option | Description | 41 | | :----: | ------------------ | 42 | | min | The minimum price. | 43 | | max | The maximum price. | 44 | 45 | #### Input: 46 | 47 | | min | max | 48 | | :-: | :-: | 49 | | 100 | 200 | 50 | 51 | #### output 52 | 53 | ```json 54 | 114 55 | ``` 56 | 57 | ### productAdjective 58 | 59 | Returns an adjective describing a product. 60 | 61 | #### output 62 | 63 | ```json 64 | Handcrafted 65 | ``` 66 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/style.yml: -------------------------------------------------------------------------------- 1 | name: Style Changing Request 👯‍♂️ 2 | description: Suggest a style design 3 | title: '[Style]' 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this template! 9 | - type: textarea 10 | id: style-idea 11 | attributes: 12 | label: What's the style idea? 13 | placeholder: Add descriptions 14 | value: 'We need to improve' 15 | 16 | - type: checkboxes 17 | id: no-duplicate-issues 18 | attributes: 19 | label: "Checklist" 20 | options: 21 | - label: "I have checked the existing issues." 22 | required: true 23 | 24 | - label: "I follow [Contributing Guidelines](https://github.com/shelcia/mocker/blob/master/CONTRIBUTING.md) of this project." 25 | required: true 26 | 27 | - type: question 28 | id: specific-program 29 | attributes: 30 | label: "Do you contribute under a specific program?" 31 | description: "If yes, please mention the program. If not, you can skip this question." 32 | validations: 33 | required: false -------------------------------------------------------------------------------- /docs/docs/models/internet.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 9 3 | tags: [internet] 4 | --- 5 | 6 | # Internet 7 | 8 | ## Module to generate internet related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### Domain nane 17 | 18 | Generates a random domain name. 19 | 20 | #### output 21 | 22 | ```json 23 | muddy-news.net 24 | ``` 25 | 26 | ### Domain nane 27 | 28 | Generates an email address using the given person's name as base. 29 | 30 | | Option | Description | 31 | | :-------: | ---------------------------------------------------------------------------------------------- | 32 | | firstName | The optional first name to use. If not specified, a random one will be chosen. | 33 | | lastName | The optional last name to use. If not specified, a random one will be chosen. | 34 | | provider | The mail provider domain to use. If not specified, a random free mail provider will be chosen. | 35 | 36 | #### output 37 | 38 | ```json 39 | romeo_juliet@gmail.com 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/docs/models/hacker.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | tags: [hacker] 4 | --- 5 | 6 | # Hacker 7 | 8 | ## Module to generate hacker/IT words and phrases. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### abbreviation 17 | 18 | Returns a random hacker/IT abbreviation. 19 | 20 | #### output 21 | 22 | ```json 23 | RAM 24 | ``` 25 | 26 | ### adjective 27 | 28 | Returns a random hacker/IT adjective. 29 | 30 | #### output 31 | 32 | ```json 33 | cross-platform 34 | ``` 35 | 36 | ### ingverb 37 | 38 | Returns a random hacker/IT verb for continuous actions (en: ing suffix; e.g. hacking). 39 | 40 | #### output 41 | 42 | ```json 43 | connecting 44 | ``` 45 | 46 | ### noun 47 | 48 | Returns a random hacker/IT noun. 49 | 50 | #### output 51 | 52 | ```json 53 | hard drive 54 | ``` 55 | 56 | ### phrase 57 | 58 | Generates a random hacker/IT phrase. 59 | 60 | #### output 61 | 62 | ```json 63 | If we override the card, we can get to the HDD feed through the back-end HDD sensor! 64 | ``` 65 | 66 | ### verb 67 | 68 | Returns a random hacker/IT verb. 69 | 70 | #### output 71 | 72 | ```json 73 | generate 74 | ``` 75 | -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { 3 | CssBaseline, 4 | StyledEngineProvider, 5 | ThemeProvider, 6 | } from "@mui/material"; 7 | import { useRoutes } from "react-router-dom"; 8 | import routes from "./routes"; 9 | import { customTheme } from "./themes"; 10 | import { Toaster } from "react-hot-toast"; 11 | import { ThemeContext } from "./context/ThemeContext"; 12 | import "./styles/style.css"; 13 | 14 | const App = () => { 15 | const allPages = useRoutes(routes); 16 | 17 | const toasterOptions = { 18 | style: { 19 | fontWeight: 500, 20 | fontFamily: "'DM Sans Variable', sans-serif", 21 | }, 22 | }; 23 | 24 | const [darkTheme] = useContext(ThemeContext); 25 | 26 | const appTheme = customTheme({ 27 | theme: darkTheme ? "dark" : "light", 28 | direction: "ltr", 29 | }); 30 | 31 | return ( 32 | 33 | 34 | 35 | 36 | 37 | {allPages} 38 | 39 | 40 | 41 | ); 42 | }; 43 | 44 | export default App; 45 | -------------------------------------------------------------------------------- /docs/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import clsx from "clsx"; 3 | import Layout from "@theme/Layout"; 4 | import Link from "@docusaurus/Link"; 5 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; 6 | import styles from "./index.module.css"; 7 | 8 | function HomepageHeader() { 9 | const { siteConfig } = useDocusaurusContext(); 10 | return ( 11 |
12 |
13 |

{siteConfig.title}

14 |

{siteConfig.tagline}

15 |
16 | 20 | Check out now ! 📝 21 | 22 |
23 |
24 |
25 | ); 26 | } 27 | 28 | export default function Home() { 29 | const { siteConfig } = useDocusaurusContext(); 30 | return ( 31 | 35 | 36 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /frontend/src/pages/others/Error404Page.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box, Button, Typography, CardContent } from "@mui/material"; 3 | import { useNavigate } from "react-router-dom"; 4 | import Img from "../../assets/404.png"; 5 | 6 | const Error404Page = () => { 7 | const navigate = useNavigate(); 8 | return ( 9 | 10 | 11 | 20 | 404 error information 21 | 22 | 404 23 | 24 | 25 | The page you’re looking for doesn’t exist. 26 | 27 | 34 | 35 | 36 | 37 | ); 38 | }; 39 | 40 | export default Error404Page; 41 | -------------------------------------------------------------------------------- /frontend/src/pages/auth/EmailVerify.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { Container, Paper } from "@mui/material"; 3 | import { useNavigate, useParams } from "react-router-dom"; 4 | import { apiAuth } from "../../services/models/authModel"; 5 | import { CustomTypoDisplay } from "../../components/CustomDisplay"; 6 | 7 | const EmailVerify = () => { 8 | const { id } = useParams(); 9 | 10 | const [message, setMessage] = useState(""); 11 | const [status, setStatus] = useState("200"); 12 | 13 | const navigate = useNavigate(); 14 | 15 | useEffect(() => { 16 | apiAuth.put({}, `verification/${id}`).then((res) => { 17 | // console.log(res); 18 | if (res.status === "200") { 19 | setMessage("Verified Sucessfully"); 20 | setTimeout(() => { 21 | navigate("/"); 22 | }, 3000); 23 | } else { 24 | setStatus(res.status); 25 | setMessage("Verification Failed"); 26 | } 27 | }); 28 | }, []); 29 | 30 | return ( 31 | 32 | 33 | 34 | {message} 35 | 36 | 37 | 38 | ); 39 | }; 40 | 41 | export default EmailVerify; 42 | -------------------------------------------------------------------------------- /backend/utils/trackAPIRequests.js: -------------------------------------------------------------------------------- 1 | const Resource = require("../models/Resource"); 2 | 3 | // module.exports.trackAPIRequest = async (id, newAnalytics) => { 4 | // try { 5 | // const resource = await Resource.findById(id); 6 | // // console.log("Response", resource); 7 | // const existingAnalytics = resource.analytics || []; 8 | // resource.set({ 9 | // ...resource, 10 | // analytics: [...existingAnalytics, newAnalytics], 11 | // }); 12 | // await resource.save(); 13 | // } catch (err) { 14 | // console.log(err); 15 | // } 16 | // }; 17 | 18 | // Middleware to track API requests 19 | app.use((req, res, next) => { 20 | const endpoint = req.originalUrl; 21 | const fieldName = req.query.fieldName; // Assuming fieldName is passed as a query parameter 22 | EndpointRequest.findOneAndUpdate( 23 | { fieldName, endpoint }, 24 | { $push: { requestHistory: { date: new Date() } } }, 25 | { upsert: true, new: true } 26 | ).exec((err, endpointRequest) => { 27 | if (err) { 28 | console.error("Error updating request history:", err); 29 | } else { 30 | console.log( 31 | `Request history for ${endpointRequest.fieldName}.${endpoint}:`, 32 | endpointRequest.requestHistory 33 | ); 34 | } 35 | }); 36 | next(); 37 | }); 38 | -------------------------------------------------------------------------------- /frontend/src/components/CustomTabPanel.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box, Tab, Tabs, Typography } from "@mui/material"; 3 | 4 | export const CustomTabPanel = (props) => { 5 | const { children, value, index, ...other } = props; 6 | 7 | return ( 8 | 21 | ); 22 | }; 23 | 24 | export const CustomTabs = ({ value, handleChange, items = [] }) => { 25 | function a11yProps(index) { 26 | return { 27 | id: `simple-tab-${index}`, 28 | "aria-controls": `simple-tabpanel-${index}`, 29 | }; 30 | } 31 | return ( 32 | 33 | 34 | {items.map((item, idx) => ( 35 | 41 | ))} 42 | 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-api", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "lint": "eslint . --ext .js,.jsx" 11 | }, 12 | "dependencies": { 13 | "@emotion/react": "^11.10.6", 14 | "@emotion/styled": "^11.10.6", 15 | "@fontsource-variable/dm-sans": "^5.0.6", 16 | "@fontsource/jetbrains-mono": "^4.5.12", 17 | "@fontsource/poppins": "^4.5.10", 18 | "@mui/material": "^5.11.11", 19 | "@mui/x-date-pickers": "^6.0.0", 20 | "axios": "^1.3.4", 21 | "dayjs": "^1.11.7", 22 | "formik": "^2.2.9", 23 | "json-beautify": "^1.1.1", 24 | "lodash.merge": "^4.6.2", 25 | "react": "^18.2.0", 26 | "react-dom": "^18.2.0", 27 | "react-hot-toast": "^2.4.0", 28 | "react-icons": "^4.8.0", 29 | "react-json-pretty": "^2.2.0", 30 | "react-loader-spinner": "^5.3.4", 31 | "react-router-dom": "^6.8.2", 32 | "recharts": "^2.4.3", 33 | "yup": "^1.0.2" 34 | }, 35 | "devDependencies": { 36 | "@types/react": "^18.0.28", 37 | "@types/react-dom": "^18.0.11", 38 | "@vitejs/plugin-react": "^3.1.0", 39 | "eslint": "^8.35.0", 40 | "eslint-plugin-react": "^7.32.2", 41 | "vite": "^4.1.4" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocker-docs", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docsearch/js": "^3.3.0", 18 | "@docusaurus/core": "3.0.0", 19 | "@docusaurus/preset-classic": "3.0.0", 20 | "@docusaurus/theme-search-algolia": "^3.1.0", 21 | "@mdx-js/react": "^3.0.0", 22 | "@svgr/webpack": "^6.3.1", 23 | "clsx": "^1.1.1", 24 | "file-loader": "^6.2.0", 25 | "prism-react-renderer": "^2.1.0", 26 | "react": "^18.2.0", 27 | "react-dom": "^18.2.0", 28 | "react-player": "^2.11.0", 29 | "url-loader": "^4.1.1", 30 | "yarn-install": "^1.0.0" 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.5%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /frontend/src/components/CustomToggle.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { Stack } from "@mui/material"; 3 | import { FaMoon, FaSun } from "react-icons/fa"; 4 | import { ThemeContext } from "../context/ThemeContext"; 5 | 6 | const CustomToggle = () => { 7 | const [darkTheme, setDarkTheme] = useContext(ThemeContext); 8 | 9 | return ( 10 | 11 | 19 | {darkTheme ? ( 20 | { 22 | setDarkTheme(!darkTheme); 23 | localStorage.setItem("mockapi-theme", false); 24 | }} 25 | size={"1.2rem"} 26 | style={{ cursor: "pointer" }} 27 | /> 28 | ) : ( 29 | { 31 | setDarkTheme(!darkTheme); 32 | localStorage.setItem("mockapi-theme", true); 33 | }} 34 | size={"1.2rem"} 35 | color="rgb(255,214,0)" 36 | style={{ cursor: "pointer" }} 37 | /> 38 | )} 39 | 40 | 41 | ); 42 | }; 43 | 44 | export default CustomToggle; 45 | -------------------------------------------------------------------------------- /docs/docs/models/name.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 12 3 | tags: [name] 4 | --- 5 | 6 | # Name 7 | 8 | ## Module to generate people's names and titles. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### firstName 17 | 18 | Returns a random first name. 19 | 20 | | Option | Description | 21 | | :----: | --------------------------------- | 22 | | sex | Can be either 'female' or 'male'. | 23 | 24 | #### Input: 25 | 26 | | sex | 27 | | :--: | 28 | | male | 29 | 30 | #### output 31 | 32 | ```json 33 | Tom 34 | ``` 35 | 36 | ### lastName 37 | 38 | Returns a random last name. 39 | 40 | | Option | Description | 41 | | :----: | --------------------------------- | 42 | | sex | Can be either 'female' or 'male'. | 43 | 44 | #### Input: 45 | 46 | | sex | 47 | | :--: | 48 | | male | 49 | 50 | #### output 51 | 52 | ```json 53 | Barton 54 | ``` 55 | 56 | ### sex 57 | 58 | Returns a random sex. 59 | 60 | #### output 61 | 62 | ```json 63 | male 64 | ``` 65 | 66 | ### jobArea 67 | 68 | Generates a random job area. 69 | 70 | #### output 71 | 72 | ```json 73 | Infrastructure 74 | ``` 75 | 76 | ### jobTitle 77 | 78 | Generates a random job title. 79 | 80 | #### output 81 | 82 | ```json 83 | Global Accounts Engineer 84 | ``` 85 | -------------------------------------------------------------------------------- /frontend/src/themes/themeColors.js: -------------------------------------------------------------------------------- 1 | export const primary = { 2 | 100: "#D3F5FE", 3 | 200: "#A7E7FD", 4 | 300: "#7AD2FA", 5 | 400: "#59BCF5", 6 | 500: "#2499EF", 7 | main: "#2499EF", 8 | // 100: "#E2EEFF", 9 | // 200: "#D1E0FC", 10 | // 300: "#BBD1FB", 11 | // 400: "#A4C1FA", 12 | // 500: "#4983F5", 13 | // main: "#4983F5", 14 | light: "#D3F5FE", 15 | dark: "#1A77CD", 16 | // main: "#3f51b5", 17 | // light: "#757de8", 18 | // red: "#FF6B93", 19 | red: "#E02424", 20 | purple: "#A798FF", 21 | yellow: "#FF9777", 22 | }; 23 | export const secondary = { 24 | 100: "#F9F9F9", 25 | 200: "#ECEFF5", 26 | 300: "#E5EAF2", 27 | // outline or border 28 | 400: "#94A4C4", 29 | // text muted 30 | 500: "#1d2438", 31 | 900: "rgb(9, 33, 53)", 32 | // main text 33 | // main: "#1d2438", 34 | main: "#FFFFFF", 35 | // main text 36 | light: "#F9F9F9", 37 | red: "#FF6B93", 38 | purple: "#A798FF", 39 | yellow: "#FF9777", 40 | }; 41 | export const error = { 42 | main: "#FD396D", 43 | }; 44 | export const success = { 45 | main: "#2CC5BD", 46 | }; 47 | export const warning = { 48 | main: "#FFE91F", 49 | dark: "#FFD600", 50 | }; 51 | export const info = { 52 | main: "#A798FF", 53 | }; 54 | export const text = { 55 | primary: secondary[500], 56 | secondary: secondary[400], 57 | disabled: secondary[300], 58 | }; 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug 🐞 2 | description: Report an issue to help us improve the project. 3 | title: "[Bug] " 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Description 9 | description: A brief description of the issue or bug you are facing, also include what you tried and what didn't work. 10 | validations: 11 | required: false 12 | 13 | - type: textarea 14 | id: screenshots 15 | attributes: 16 | label: Screenshots 17 | description: Please add screenshots if applicable. 18 | validations: 19 | required: false 20 | 21 | - type: checkboxes 22 | id: no-duplicate-issues 23 | attributes: 24 | label: "Checklist" 25 | options: 26 | - label: "I have checked the existing issues." 27 | required: true 28 | 29 | - label: "I follow [Contributing Guidelines](https://github.com/shelcia/mocker/blob/master/CONTRIBUTING.md) of this project." 30 | required: true 31 | 32 | - type: question 33 | id: specific-program 34 | attributes: 35 | label: "Do you contribute under a specific program?" 36 | description: "If yes, please mention the program. If not, you can skip this question." 37 | validations: 38 | required: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 💡 2 | description: Have any new idea or new feature? Please suggest! 3 | title: "[Feature] " 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Description 9 | description: A clear and concise description of any alternative solution or features you've considered. 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | id: screenshots 15 | attributes: 16 | label: Screenshots 17 | description: Please add screenshots if applicable. 18 | validations: 19 | required: false 20 | 21 | - type: checkboxes 22 | id: no-duplicate-issues 23 | attributes: 24 | label: "Checklist" 25 | options: 26 | - label: "I have checked the existing issues." 27 | required: true 28 | 29 | - label: "I follow [Contributing Guidelines](https://github.com/shelcia/mocker/blob/master/CONTRIBUTING.md) of this project." 30 | required: true 31 | 32 | - type: question 33 | id: specific-program 34 | attributes: 35 | label: "Do you contribute under a specific program?" 36 | description: "If yes, please mention the program. If not, you can skip this question." 37 | validations: 38 | required: false -------------------------------------------------------------------------------- /backend-go/gql/gqlgen.yml: -------------------------------------------------------------------------------- 1 | # Where are all the schema files located? globs are supported eg src/**/*.graphqls 2 | schema: 3 | - gql/schemas/user/user.graphql 4 | # - gql/schemas/**/*.graphql 5 | # - gql/schemas/*.graphql 6 | 7 | # Where should the generated server code go? 8 | exec: 9 | filename: ../internal/graphql/gql_generated/generated.go 10 | package: gql_generated 11 | 12 | # Where should any generated models go? 13 | model: 14 | filename: ../pkg/graphql/models_gen.go 15 | package: graphql 16 | 17 | # Where should the resolver implementations go? 18 | resolver: 19 | layout: follow-schema 20 | dir: ../internal/graphql/gql_resolvers 21 | package: gql_resolvers 22 | 23 | # This section declares type mapping between the GraphQL and go type systems 24 | # 25 | # The first line in each type will be used as defaults for resolver arguments and 26 | # modelgen, the others will be allowed when binding to fields. Configure them to 27 | # your liking 28 | models: 29 | ID: 30 | model: 31 | - github.com/99designs/gqlgen/graphql.ID 32 | - github.com/99designs/gqlgen/graphql.Int 33 | - github.com/99designs/gqlgen/graphql.Int64 34 | - github.com/99designs/gqlgen/graphql.Int32 35 | Int: 36 | model: 37 | - github.com/99designs/gqlgen/graphql.Int 38 | - github.com/99designs/gqlgen/graphql.Int64 39 | - github.com/99designs/gqlgen/graphql.Int32 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.yml: -------------------------------------------------------------------------------- 1 | name: Other 🤔 2 | description: Use this for any other issues. PLEASE do not create blank issues 3 | title: "[Other]" 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: "# Other issue" 8 | 9 | - type: textarea 10 | id: issuedescription 11 | attributes: 12 | label: What would you like to share? 13 | description: Provide a clear and concise explanation of your issue. 14 | validations: 15 | required: true 16 | 17 | - type: textarea 18 | id: extrainfo 19 | attributes: 20 | label: Additional information 21 | description: Is there anything else we should know about this issue? 22 | validations: 23 | required: false 24 | 25 | - type: checkboxes 26 | id: no-duplicate-issues 27 | attributes: 28 | label: "Checklist" 29 | options: 30 | - label: "I have checked the existing issues." 31 | required: true 32 | 33 | - label: "I follow [Contributing Guidelines](https://github.com/shelcia/mocker/blob/master/CONTRIBUTING.md) of this project." 34 | required: true 35 | 36 | - type: question 37 | id: specific-program 38 | attributes: 39 | label: "Do you contribute under a specific program?" 40 | description: "If yes, please mention the program. If not, you can skip this question." 41 | validations: 42 | required: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/doc_report.yml: -------------------------------------------------------------------------------- 1 | name: Documentation Request 📃 2 | description: Change regarding improving the docs to be more accessible 3 | title: '[Docs]' 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Category of documentation update 8 | description: | 9 | What category does this change fall under. For example Typo error, New category addition, Rephrasing the sentences, fixing broken links etc. 10 | validations: 11 | required: true 12 | 13 | - type: textarea 14 | attributes: 15 | label: Describe the change you think might work 16 | description: Please describe the change & need of change in atmost detail possible. 17 | validations: 18 | required: false 19 | 20 | - type: checkboxes 21 | id: no-duplicate-issues 22 | attributes: 23 | label: "Checklist" 24 | options: 25 | - label: "I have checked the existing issues." 26 | required: true 27 | 28 | - label: "I follow [Contributing Guidelines](https://github.com/shelcia/mocker/blob/master/CONTRIBUTING.md) of this project." 29 | required: true 30 | 31 | - type: question 32 | id: specific-program 33 | attributes: 34 | label: "Do you contribute under a specific program?" 35 | description: "If yes, please mention the program. If not, you can skip this question." 36 | validations: 37 | required: false -------------------------------------------------------------------------------- /docs/docs/models/lorem.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 10 3 | tags: [lorem] 4 | --- 5 | 6 | # Lorem 7 | 8 | ## Module to generate random texts and words. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### Lines 17 | 18 | Generates the given number lines of lorem separated by '\n'. 19 | 20 | | Option | Description | 21 | | :-----: | ----------------------------------------------------------------------------- | 22 | | Line no | The number of lines to generate. Defaults to a random number between 1 and 5. | 23 | 24 | #### Input: 25 | 26 | | Line no | 27 | | :-----: | 28 | | 2 | 29 | 30 | #### output 31 | 32 | ```json 33 | Rerum quia aliquam pariatur \n explicabo sint minima eos 34 | ``` 35 | 36 | ### Sentences 37 | 38 | Generates a space separated list of words beginning a capital letter and ending with a dot. 39 | 40 | | Option | Description | 41 | | :------------: | -------------------------------------------------------------------------------------------------- | 42 | | Sentence count | The number of words, that should be in the sentence. Defaults to a random number between 3 and 10. | 43 | 44 | #### Input: 45 | 46 | | Sentence count | 47 | | :------------: | 48 | | 5 | 49 | 50 | #### output 51 | 52 | ```json 53 | Laborum voluptatem officiis est et. 54 | ``` 55 | -------------------------------------------------------------------------------- /backend-go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/shelcia/mocker/backend-go 2 | 3 | go 1.22 4 | 5 | require ( 6 | github.com/99designs/gqlgen v0.17.48 7 | github.com/google/wire v0.6.0 8 | go.mongodb.org/mongo-driver v1.17.4 9 | ) 10 | 11 | require ( 12 | github.com/agnivade/levenshtein v1.1.1 // indirect 13 | github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect 14 | github.com/golang/snappy v0.0.4 // indirect 15 | github.com/google/uuid v1.6.0 // indirect 16 | github.com/gorilla/websocket v1.5.0 // indirect 17 | github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect 18 | github.com/klauspost/compress v1.16.7 // indirect 19 | github.com/mitchellh/mapstructure v1.5.0 // indirect 20 | github.com/montanaflynn/stats v0.7.1 // indirect 21 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 22 | github.com/sosodev/duration v1.3.1 // indirect 23 | github.com/urfave/cli/v2 v2.27.2 // indirect 24 | github.com/vektah/gqlparser/v2 v2.5.12 // indirect 25 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 26 | github.com/xdg-go/scram v1.1.2 // indirect 27 | github.com/xdg-go/stringprep v1.0.4 // indirect 28 | github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect 29 | github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect 30 | golang.org/x/crypto v0.26.0 // indirect 31 | golang.org/x/mod v0.17.0 // indirect 32 | golang.org/x/sync v0.8.0 // indirect 33 | golang.org/x/text v0.17.0 // indirect 34 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect 35 | gopkg.in/yaml.v3 v3.0.1 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /frontend/src/assets/home/gradient-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/src/components/CustomInputFields.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { IconButton, InputAdornment, TextField } from "@mui/material"; 3 | import { MdVisibility, MdVisibilityOff } from "react-icons/md"; 4 | 5 | export const CustomPwdField = ({ 6 | field = "password", 7 | label = "password", 8 | handleBlur = () => {}, 9 | handleChange = () => {}, 10 | values, 11 | touched, 12 | errors, 13 | }) => { 14 | const [showPassword, setShowPassword] = useState(false); 15 | const handleClickShowPassword = () => setShowPassword(!showPassword); 16 | const handleMouseDownPassword = () => setShowPassword(!showPassword); 17 | 18 | return ( 19 | 33 | 38 | {showPassword ? : } 39 | 40 | 41 | ), 42 | }} 43 | /> 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /docs/docs/models/image.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 8 3 | tags: [image] 4 | --- 5 | 6 | # Image 7 | 8 | ## Module to generate placeholder images. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### avatar 17 | 18 | Generates a random avatar image url. 19 | 20 | #### output 21 | 22 | ```json 23 | "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/170.jpg" 24 | ``` 25 | 26 | ### fashion 27 | 28 | Generates a random fashion image url. 29 | Use imageUrl instead with category `fashion` to customize the width and height of the generated image 30 | 31 | Default width and height of image generated from this schema is 640 and 480 respectively. 32 | 33 | #### output 34 | 35 | ```json 36 | "https://loremflickr.com/640/480/fashion" 37 | ``` 38 | 39 | ### imageUrl 40 | 41 | | Option | Default | Description | 42 | | :------: | ------------------------------------------ | ------------------------- | 43 | | width | 640 | The width of the image. | 44 | | height | 480 | The height of the image. | 45 | | category | By default, a random one will be selected. | The category of the image | 46 | 47 | #### Input: 48 | 49 | | width | height | category | 50 | | :---: | :----: | :------: | 51 | | 1234 | 2345 | cat | 52 | 53 | #### output 54 | 55 | ```json 56 | "https://loremflickr.com/1234/2345/cat" 57 | ``` 58 | -------------------------------------------------------------------------------- /docs/docs/models/vehicle.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 16 3 | tags: [vehicle] 4 | --- 5 | 6 | # Vehicle 7 | 8 | ## Module to generate vehicle related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### bicycle 17 | 18 | Returns a type of bicycle. 19 | 20 | #### Output: 21 | 22 | ```json 23 | Hybrid Bicycle 24 | ``` 25 | 26 | ### color 27 | 28 | Returns a vehicle color. 29 | 30 | #### Output: 31 | 32 | ```json 33 | red 34 | ``` 35 | 36 | ### fuel 37 | 38 | Returns a fuel type. 39 | 40 | #### Output: 41 | 42 | ```json 43 | Electric 44 | ``` 45 | 46 | ### manufacturer 47 | 48 | Returns a manufacturer name. 49 | 50 | #### Output: 51 | 52 | ```json 53 | Lamborghini 54 | ``` 55 | 56 | ### model 57 | 58 | Returns a vehicle model. 59 | 60 | #### Output: 61 | 62 | ```json 63 | Explorer 64 | ``` 65 | 66 | ### type 67 | 68 | Returns a vehicle type. 69 | 70 | #### Output: 71 | 72 | ```json 73 | Minivan 74 | ``` 75 | 76 | ### vehicle 77 | 78 | Returns a random vehicle. 79 | 80 | #### Output: 81 | 82 | ```json 83 | Lamborghini Model Y 84 | ``` 85 | 86 | ### vin 87 | 88 | Returns a vehicle identification number (VIN). 89 | 90 | #### Output: 91 | 92 | ```json 93 | JKPUKVHUDLRC49382 94 | ``` 95 | 96 | ### vrm 97 | 98 | Returns a vehicle registration number (Vehicle Registration Mark - VRM) 99 | 100 | #### Output: 101 | 102 | ```json 103 | OP78PWO 104 | ``` 105 | -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const app = express(); 3 | const dotenv = require("dotenv"); 4 | const mongoose = require("mongoose"); 5 | const cors = require("cors"); 6 | const rateLimit = require('express-rate-limit') 7 | const PORT = process.env.PORT || 4050; 8 | 9 | //IMPORT ROUTES 10 | 11 | const authRoute = require("./routes/auth/auth"); 12 | const projectRoute = require("./routes/project/project"); 13 | const resourceRoute = require("./routes/resource/resource"); 14 | const userRoute = require("./routes/user/user"); 15 | const serviceRouter = require("./routes/service/service"); 16 | 17 | dotenv.config(); 18 | 19 | //IMPORT MIDDLEWARE 20 | const authenticate = require("./middleware/authenticate"); 21 | 22 | //CONNECTION TO DATABASE 23 | 24 | mongoose.connect( 25 | process.env.DB_CONNECT, 26 | // { useUnifiedTopology: true, useNewUrlParser: true, useFindAndModify: true }, 27 | () => console.log("connected to db") 28 | ); 29 | //MIDDLEWARE 30 | 31 | app.use(cors()) 32 | app.use(rateLimit({ 33 | windowMs: 1*60*1000, // 120 request per 1 minute 34 | max: 120, 35 | })) 36 | app.use(express.json()); 37 | 38 | //ROUTE MIDDLEWARE 39 | 40 | app.use("/api/auth", authRoute); 41 | app.use("/api/project", projectRoute); 42 | app.use("/api/resource", resourceRoute); 43 | app.use("/api/user", userRoute); 44 | // app.use("/api/service", authenticate, serviceRouter) 45 | app.use("/api/service", serviceRouter); 46 | 47 | app.get("/", (req, res) => { 48 | res.send(`

Hey! Mock API Backend is up !

`); 49 | }); 50 | 51 | app.listen(PORT, () => console.log(`server up and running at ${PORT}`)); 52 | -------------------------------------------------------------------------------- /frontend/src/components/CustomModal.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Box, 4 | Button, 5 | Modal, 6 | Stack, 7 | Typography, 8 | useMediaQuery, 9 | } from "@mui/material"; 10 | import { MdClose } from "react-icons/md"; 11 | 12 | const CustomModal = ({ open, setOpen, title = "", width = 400, children }) => { 13 | const mobileMatches = useMediaQuery("(max-width:425px)"); 14 | 15 | const style = { 16 | position: "absolute", 17 | top: "50%", 18 | left: "50%", 19 | transform: "translate(-50%, -50%)", 20 | width: mobileMatches ? "80%" : width, 21 | bgcolor: "background.paper", 22 | boxShadow: 24, 23 | p: mobileMatches ? 1 : 4, 24 | maxHeight: "80vh", 25 | overflowY: "auto", 26 | }; 27 | 28 | return ( 29 | setOpen(false)}> 30 | 31 | 35 | 41 | {title} 42 | 43 | 44 | 57 | 58 | 59 | {children} 60 | 61 | 62 | ); 63 | }; 64 | 65 | export default CustomModal; 66 | -------------------------------------------------------------------------------- /docs/docs/models/finance.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | tags: [finance] 4 | --- 5 | 6 | # Finance 7 | 8 | ## Module to generate finance related entries. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### amount 17 | 18 | Generates a random amount between the given bounds (inclusive). 19 | 20 | #### output 21 | 22 | ```json 23 | 548.81 24 | ``` 25 | 26 | ### bitcoinAddress 27 | 28 | Generates a random Bitcoin address. 29 | 30 | #### output 31 | 32 | ```json 33 | 3HQARxRqCDoriT4XgotMPwtyoVQ5k6D2nQ 34 | ``` 35 | 36 | ### creditCardCVV 37 | 38 | Generates a random credit card CVV. 39 | 40 | #### output 41 | 42 | ```json 43 | 557 44 | ``` 45 | 46 | ### creditCardIssuer 47 | 48 | Returns a random credit card issuer. 49 | 50 | #### output 51 | 52 | ```json 53 | maestro 54 | ``` 55 | 56 | ### creditCardNumber 57 | 58 | Generates a random credit card number. 59 | 60 | #### output 61 | 62 | ```json 63 | 5020868584663428099 64 | ``` 65 | 66 | ### currencyName 67 | 68 | Returns a random currency name. 69 | 70 | #### output 71 | 72 | ```json 73 | US Dollar 74 | ``` 75 | 76 | ### currencySymbol 77 | 78 | Returns a random currency symbol. 79 | 80 | #### output 81 | 82 | ```json 83 | $ 84 | ``` 85 | 86 | ### ethereumAddress 87 | 88 | Generates a random Ethereum address. 89 | 90 | #### output 91 | 92 | ```json 93 | 0xcdfcdcbc9de896d1f58abbbac8ec171e08cfb3dd 94 | ``` 95 | 96 | ### transactionDescription 97 | 98 | Generates a random transaction description. 99 | 100 | #### output 101 | 102 | ```json 103 | payment transaction at Rau - Sporer using card 104 | ``` 105 | 106 | ### transactionType 107 | 108 | Returns a random transaction type. 109 | 110 | #### output 111 | 112 | ```json 113 | payment 114 | ``` 115 | -------------------------------------------------------------------------------- /docs/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | - This document outlines security policies for the `mocker-docs` project. 4 | 5 | - [Supported Versions](#supported-versions) 6 | - [Reporting a Vulnerability](#reporting-a-vulnerability) 7 | - [Disclosure Policy](#disclosure-policy) 8 | - [Comments on this Policy](#comments-on-this-policy) 9 | 10 | ## Supported Versions 11 | 12 | | Node Version | Supported | 13 | | ------------ | ------------------ | 14 | | 17.0.2 | :white_check_mark: | 15 | | 18.2.0 | :white_check_mark: | 16 | | < 16.0.0 | :x: | 17 | 18 | ## Reporting a Vulnerability 19 | 20 | The `mocker-docs` team and community take all security bugs in `mocker-docs` seriously. 21 | Thank you for improving the security of `mocker-docs`. We appreciate your efforts and 22 | responsible disclosure and will make every effort to acknowledge your 23 | contributions. 24 | 25 | Report security bugs by emailing the lead maintainer 26 | 27 | The lead maintainer will acknowledge your email within 48 hours, and will send a 28 | more detailed response within 48 hours indicating the next steps in handling 29 | your report. After the initial reply to your report, the security team will 30 | endeavor to keep you informed of the progress towards a fix and full 31 | announcement, and may ask for additional information or guidance. 32 | 33 | Report security bugs in third-party modules to the person or team maintaining 34 | the module. 35 | 36 | ## Disclosure Policy 37 | 38 | When the security team receives a security bug report, they will assign it to a 39 | primary handler. This person will coordinate the fix and release process, 40 | involving the following steps: 41 | 42 | - Confirm the problem and determine the affected versions. 43 | - Audit code to find any potential similar problems. 44 | - Prepare fixes for all releases still under maintenance. These fixes will be 45 | released as fast as possible to npm. 46 | 47 | ## Comments on this Policy 48 | 49 | If you have suggestions on how this process could be improved please submit a 50 | pull request. 51 | -------------------------------------------------------------------------------- /frontend/src/components/CustomTable.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { 3 | Box, 4 | Table, 5 | TableBody, 6 | TableCell, 7 | TableHead, 8 | TableRow, 9 | } from "@mui/material"; 10 | import { ThemeContext } from "../context/ThemeContext"; 11 | import { secondary } from "../themes/themeColors"; 12 | import { grey } from "@mui/material/colors"; 13 | 14 | export const CustomJSONTable = ({ keys = [], data }) => { 15 | // console.table(keys); 16 | const [darkTheme] = useContext(ThemeContext); 17 | 18 | return ( 19 | 26 | 32 | 33 | {keys != [] && ( 34 | 35 | {keys.map((key) => ( 36 | 37 | {key} 38 | 39 | ))} 40 | 41 | )} 42 | 43 | 44 | {data.map((row, idx) => ( 45 | 46 | {keys.map((key) => ( 47 | 59 | {row?.[key]} 60 | 61 | ))} 62 | 63 | ))} 64 | 65 |
66 |
67 | ); 68 | }; 69 | -------------------------------------------------------------------------------- /backend/routes/project/project.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | const Project = require("../../models/Project"); 3 | const Resource = require("../../models/Resource"); 4 | 5 | router.post("/", async (req, res) => { 6 | try { 7 | const project = new Project(req.body); 8 | await project.save(); 9 | res 10 | .status(200) 11 | .send({ status: "200", message: "Successfully created Project" }); 12 | } catch (err) { 13 | res.status(200).send({ status: "500", message: err }); 14 | } 15 | }); 16 | 17 | router.get("/:id", async (req, res) => { 18 | try { 19 | const projects = await Project.find({ userId: req.params.id }); 20 | res.status(200).send({ status: "200", message: projects }); 21 | } catch (err) { 22 | res.status(200).send({ status: "500", message: err }); 23 | } 24 | }); 25 | 26 | router.get("/single/:id", async (req, res) => { 27 | try { 28 | const projects = await Project.findById(req.params.id); 29 | res.status(200).send({ status: "200", message: projects }); 30 | } catch (err) { 31 | res.status(200).send({ status: "500", message: err }); 32 | } 33 | }); 34 | 35 | router.delete("/:id", async (req, res) => { 36 | try { 37 | await Project.findByIdAndDelete(req.params.id); 38 | await Resource.deleteMany({ projectId: req.params.id }) 39 | res.status(200).send({ status: "200", message: "Successful" }); 40 | } catch (err) { 41 | res.status(200).send({ status: "500", message: err }); 42 | } 43 | }); 44 | 45 | router.delete("/", async (req, res)=>{ 46 | for (const id of req.body.projects) { 47 | try { 48 | await Project.findOneAndDelete({_id: { $eq: id }}) 49 | await Resource.deleteMany({ projectId: { $eq: id } }) 50 | } catch (error) { 51 | res.status(200).send({ status: "500", message: "Failed to delete" }); 52 | return; 53 | } 54 | } 55 | res.status(200).send({ status: "200", message: "Deleted" }); 56 | }) 57 | 58 | router.put("/single/:id", async (req ,res)=>{ 59 | try { 60 | await Project.findByIdAndUpdate(req.params.id, { 61 | $set: { name: req.body.name } 62 | }) 63 | return res.status(200).send({ status: "200", message: "Successfully renamed!" }) 64 | } catch (error) { 65 | return res.status(200).send({ status: "500",message: error }) 66 | } 67 | }) 68 | 69 | module.exports = router; 70 | -------------------------------------------------------------------------------- /frontend/src/layout/AuthGuard.jsx: -------------------------------------------------------------------------------- 1 | import React, { Fragment, useEffect, useState } from "react"; 2 | import { Navigate, useLocation, useNavigate } from "react-router-dom"; // component props interface 3 | import { apiService } from "../services/models/serviceModel"; 4 | import Login from "../pages/auth/Login"; 5 | import AuthLayout from "./AuthLayout"; 6 | 7 | const AuthGuard = ({ children }) => { 8 | const [isExpired, setIsExpired] = useState(false); 9 | 10 | useEffect(() => { 11 | const ac = new AbortController(); 12 | const token = localStorage.getItem("MockAPI-Token"); 13 | if (token) { 14 | apiService 15 | .getSingle(`auth-token/${token}`) 16 | .then((res) => { 17 | // console.log(res); 18 | if (res.status === "200") { 19 | setIsExpired(false); 20 | } else { 21 | setIsExpired(true); 22 | } 23 | }) 24 | .catch(() => setIsExpired(true)); 25 | } 26 | return () => ac.abort(); 27 | }, []); 28 | 29 | function isAuthenticate() { 30 | return localStorage.getItem("MockAPI-Token") ? true : false; 31 | } 32 | 33 | function useAuth() { 34 | if (!isAuthenticate()) { 35 | return false; 36 | } else if (isExpired) { 37 | return false; 38 | } else { 39 | return true; 40 | } 41 | } 42 | 43 | const navigate = useNavigate(); 44 | 45 | const isAuthenticated = useAuth(); 46 | const { pathname } = useLocation(); 47 | const [requestedLocation, setRequestedLocation] = useState(null); 48 | 49 | useEffect(() => { 50 | const ac = new AbortController(); 51 | if (!isAuthenticated) { 52 | if (pathname !== requestedLocation) { 53 | setRequestedLocation(pathname); 54 | } 55 | navigate("/"); 56 | } 57 | return () => { 58 | ac.abort(); 59 | }; 60 | }, []); 61 | 62 | if (!isAuthenticated) { 63 | if (pathname !== requestedLocation) { 64 | setRequestedLocation(pathname); 65 | } 66 | return ( 67 | 68 | 69 | 70 | ); 71 | } 72 | 73 | if (requestedLocation && pathname !== requestedLocation) { 74 | setRequestedLocation(null); 75 | return ; 76 | } 77 | 78 | return {children}; 79 | }; 80 | 81 | export default AuthGuard; 82 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/ResourceModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Stack, Typography } from "@mui/material"; 3 | import LinearProgress from "@mui/material/LinearProgress"; 4 | import { useParams } from "react-router-dom"; 5 | import { toast } from "react-hot-toast"; 6 | import { apiResource } from "../../../services/models/resourceModal"; 7 | import CommonResourceModal from "./CommonResourceModal"; 8 | 9 | const ResourceModal = ({ 10 | open, 11 | setOpen, 12 | fetchResource, 13 | loading, 14 | setLoading, 15 | }) => { 16 | const { userId, projectId } = useParams(); 17 | 18 | const [inputs, setInputs] = useState({ 19 | name: "", 20 | number: 1, 21 | userId: userId, 22 | projectId: projectId, 23 | }); 24 | 25 | const [schema, setSchema] = useState([]); 26 | 27 | const createProject = () => { 28 | setLoading(true); 29 | toast("Adding"); 30 | 31 | const body = { 32 | name: inputs.name, 33 | number: parseInt(inputs.number), 34 | userId: userId, 35 | projectId: projectId, 36 | schema: schema, 37 | }; 38 | 39 | apiResource.post(body).then((res) => { 40 | // console.log(res); 41 | if (res.status === "200") { 42 | toast.success("Added Successfully"); 43 | fetchResource(); 44 | setSchema([]); 45 | setInputs({ 46 | name: "", 47 | number: 1, 48 | userId: userId, 49 | projectId: projectId, 50 | }); 51 | setLoading(false); 52 | setOpen(false); 53 | } else { 54 | setOpen(false); 55 | toast.error("Error"); 56 | } 57 | }); 58 | }; 59 | 60 | return ( 61 | 71 | {loading && ( 72 | 73 | 74 | 75 | Generating Data... 76 | 77 | 78 | )} 79 | 80 | ); 81 | }; 82 | 83 | export default ResourceModal; 84 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## 📌 Introduction 2 | 3 | This is documentation of Mocker. 4 | 5 | This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. 6 | 7 | ## ⭐ How to get started? 8 | 9 | You can refer to the following articles on the basics of Git and Github and also contact the Project Mentors, in case you are stuck: 10 | 11 | - [Watch this video to get started, if you have no clue about open source](https://youtu.be/SL5KKdmvJ1U) 12 | - [Forking a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) 13 | - [Cloning a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) 14 | - [How to create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github) 15 | - [Getting started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6) 16 | 17 | ## 💥 How to Contribute? 18 | 19 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 20 | [![Open Source Love svg2](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 21 | 22 | - Take a look at the Existing [Issues](https://github.com/shelcia/mocker/issues) or create your own Issues! 23 | - Wait for the Issue to be assigned to you after which you can start working on it. 24 | - Fork the Repo and create a Branch for any Issue that you are working upon. 25 | - Read the [Code of Conduct]() 26 | - Create a Pull Request which will be promptly reviewed and suggestions would be added to improve it. 27 | - Add Screenshots to help us know what this Script is all about. 28 | 29 | ## ⭐ Issues: 30 | 31 | For major changes, you are welcome to open an issue to discuss what you would like to change. Enhancements will be appreciated. 32 | 33 | ## Installation 34 | 35 | ```console 36 | npm install or yarn install 37 | ``` 38 | 39 | ## Local Development 40 | 41 | ```console 42 | npm start or yarn start 43 | ``` 44 | 45 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 46 | 47 | ## Build 48 | 49 | ```console 50 | npm build or yarn build 51 | ``` 52 | 53 | ## 💼 Code of Conduct 54 | 55 | We want to facilitate a healthy and constructive community behavior by adopting and enforcing our code of conduct. 56 | Please adhere toward our [Code-of-Conduct](code-of-conduct.md). 57 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "master" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "master" ] 20 | schedule: 21 | - cron: '15 22 * * 2' # time zone to match your requirements 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Use only 'java' to analyze code written in Java, Kotlin or both 38 | # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both 39 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 40 | 41 | steps: 42 | - name: Checkout repository 43 | uses: actions/checkout@v3 44 | 45 | # Initializes the CodeQL tools for scanning. 46 | - name: Initialize CodeQL 47 | uses: github/codeql-action/init@v2 48 | with: 49 | languages: ${{ matrix.language }} 50 | # If you wish to specify a custom CodeQL database, you can do so here or in a config file. 51 | # database: my-custom-codeql-database 52 | 53 | # If you wish to specify custom queries, you can do so here or in a config file. 54 | # By default, queries listed here will override any specified in a config file. 55 | # Prefix the list here with "+" to use these queries and those in the config file. 56 | 57 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 58 | queries: security-extended,security-and-quality 59 | 60 | # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). 61 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to mocker 2 | 3 | ## Thank you for considering contributing to mocker! 4 | 5 | Whether it's fixing a `bug` , `proposing a new feature` , or `improving documentation`, your contributions are greatly appreciated. 6 | 7 | ## Code of Conduct 8 | 9 | Please make sure to read and follow our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing to the project. 10 | 11 | ## Getting Started 12 | 13 | 1. Fork the repository: 14 | * Create a personal copy of the `mocker` repository on Github. 15 | * You can do this by clicking the "Fork" button on the `mocker` repository page. 16 | 17 | 2. Clone the repository locally: 18 | * After forking the repository, clone it locally on your computer so that you can work on the code and make changes. 19 | * `git clone https://github.com//mocker.git` 20 | 21 | 3. Create a new branch: 22 | * Before making any changes, create a new branch in your local repository. 23 | * This is done to ensure that your changes are isolated from the main branch and can be easily reviewed and merged later. 24 | * `git checkout -b ` 25 | 26 | 27 | 4. Make changes: 28 | * Start making changes to the code, fixing bugs, adding new features, etc. 29 | 30 | 5. Push changes to the fork: 31 | * Once the changes have been made, push them to your fork on Github. 32 | * `git add .` 33 | * `git commit -m "Description of changes"` 34 | * `git push origin ` 35 | 36 | ## Submitting a Pull Request 37 | 38 | 1. Make sure your changes are well-documented and include relevant tests. 39 | 40 | 2. If you've added new functionality, include appropriate documentation. 41 | 42 | 3. Follow the coding conventions used in the project. 43 | 44 | 4. Before submitting your pull request, make sure the following items have been checked: 45 | - All tests pass and the build is successful. 46 | - Your changes do not produce any new warnings or errors. 47 | - Your changes have been thoroughly tested on different platforms and browsers. 48 | - Your changes do not break backward compatibility. 49 | 50 | 5. When you're ready, submit a pull request and include a descriptive title and a detailed description of your changes. 51 | 52 | ## Additional Resources 53 | 54 | - [Project documentation](https://github.com/shelcia/mocker/blob/master/README.md) 55 | - [Issue tracker](https://github.com/shelcia/mocker/issues) 56 | 57 | # 58 | 59 | Thank you again for your interest in contributing to mocker. 60 | 61 | We look forward to working with you! 62 | 63 | 64 | -------------------------------------------------------------------------------- /frontend/src/routes.jsx: -------------------------------------------------------------------------------- 1 | import React, { lazy, Suspense } from "react"; 2 | import { Outlet } from "react-router-dom"; 3 | import Loading from "./components/CustomLoading"; 4 | 5 | // Layouts 6 | import AuthLayout from "./layout/AuthLayout"; 7 | import DashboardLayout from "./layout/DashboardLayout"; 8 | import AuthGuard from "./layout/AuthGuard"; 9 | 10 | // eslint-disable-next-line react/display-name 11 | const Loadable = (Component) => (props) => 12 | ( 13 | }> 14 | 15 | 16 | ); 17 | 18 | const LoginPage = Loadable(lazy(() => import("./pages/auth/Login"))); 19 | const SignupPage = Loadable(lazy(() => import("./pages/auth/Signup"))); 20 | const EmailVerify = Loadable(lazy(() => import("./pages/auth/EmailVerify"))); 21 | const ForgotPassword = Loadable( 22 | lazy(() => import("./pages/auth/ForgotPassword")) 23 | ); 24 | 25 | const ProjectsPage = Loadable( 26 | lazy(() => import("./pages/dashboard/Dashboard")) 27 | ); 28 | const CollectionPage = Loadable( 29 | lazy(() => import("./pages/dashboard/Collection")) 30 | ); 31 | 32 | const Error404Page = Loadable( 33 | lazy(() => import("./pages/others/Error404Page")) 34 | ); 35 | 36 | const routes = [ 37 | { 38 | path: "", 39 | element: ( 40 | 41 | 42 | 43 | ), 44 | children: [ 45 | { 46 | path: "", 47 | element: , 48 | }, 49 | { 50 | path: "/signup", 51 | element: , 52 | }, 53 | { 54 | path: "/verification/:id", 55 | element: , 56 | }, 57 | // { 58 | // path: "/email-verify", 59 | // element: , 60 | // }, 61 | { 62 | path: "/reset-password", 63 | element: , 64 | }, 65 | { 66 | path: "/reset-password/:id", 67 | element: , 68 | }, 69 | ], 70 | }, 71 | { 72 | path: "dashboard/:userId", 73 | element: ( 74 | 75 | 76 | 77 | 78 | 79 | ), 80 | children: [ 81 | { 82 | path: "", 83 | element: , 84 | }, 85 | { 86 | path: ":projectId", 87 | element: , 88 | }, 89 | ], 90 | }, 91 | { 92 | path: "*", 93 | element: , 94 | children: [ 95 | { 96 | path: "*", 97 | element: , 98 | }, 99 | ], 100 | }, 101 | ]; 102 | 103 | export default routes; 104 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/EditResourceModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { apiResource } from "../../../services/models/resourceModal"; 3 | import CommonResourceModal from "./CommonResourceModal"; 4 | import { useParams } from "react-router-dom"; 5 | import { toast } from "react-hot-toast"; 6 | import { Stack, LinearProgress, Typography } from "@mui/material"; 7 | 8 | const EditResourceModal = ({ open, setOpen, result, fetchResult }) => { 9 | const { userId, projectId } = useParams(); 10 | const [loading, setLoading] = useState(false); 11 | 12 | const [inputs, setInputs] = useState({ 13 | name: "", 14 | number: 1, 15 | userId: userId, 16 | projectId: projectId, 17 | }); 18 | 19 | const [schema, setSchema] = useState([]); 20 | 21 | const fetchResource = (signal) => { 22 | apiResource.getSingle(result, signal).then((res) => { 23 | // console.log(res.data); 24 | if (res.status === "200") { 25 | setInputs({ 26 | name: res.message?.name, 27 | number: res.message?.number, 28 | userId: userId, 29 | projectId: projectId, 30 | id: res.message._id, 31 | }); 32 | setSchema(res.message?.schema); 33 | } 34 | }); 35 | }; 36 | 37 | useEffect(() => { 38 | const ac = new AbortController(); 39 | fetchResource(ac.signal); 40 | return () => ac.abort(); 41 | }, []); 42 | 43 | const updateResource = () => { 44 | setLoading(true); 45 | const body = { 46 | name: inputs.name, 47 | number: parseInt(inputs.number), 48 | userId: userId, 49 | projectId: projectId, 50 | schema: schema, 51 | }; 52 | 53 | apiResource 54 | .putById(result, body) 55 | .then((res) => { 56 | if (res.status === "200") { 57 | toast.success("Edited Successfully"); 58 | setOpen(false); 59 | // fetchResource(); 60 | fetchResult(); 61 | } else { 62 | toast.error("Error"); 63 | setOpen(false); 64 | } 65 | }) 66 | .finally(() => { 67 | setLoading(false); 68 | }); 69 | }; 70 | 71 | return ( 72 | 83 | {loading && ( 84 | 85 | 86 | 87 | Updating Data... 88 | 89 | 90 | )} 91 | 92 | ); 93 | }; 94 | 95 | export default EditResourceModal; 96 | -------------------------------------------------------------------------------- /frontend/src/assets/home/gradient-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/CloneModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { apiResource } from "../../../services/models/resourceModal"; 3 | import CommonResourceModal from "./CommonResourceModal"; 4 | import { useParams } from "react-router-dom"; 5 | import { toast } from "react-hot-toast"; 6 | import { Stack, LinearProgress, Typography } from "@mui/material"; 7 | 8 | const CloneModal = ({ open, setOpen, result, fetchResources }) => { 9 | const { userId, projectId } = useParams(); 10 | const [loading, setLoading] = useState(false); 11 | 12 | const [inputs, setInputs] = useState({ 13 | name: "", 14 | number: 1, 15 | userId: userId, 16 | projectId: projectId, 17 | }); 18 | 19 | const [schema, setSchema] = useState([]); 20 | 21 | const fetchResource = (signal) => { 22 | apiResource.getSingle(result, signal).then((res) => { 23 | // console.log(res.data); 24 | if (res.status === "200") { 25 | setInputs({ 26 | name: res.message?.name, 27 | number: res.message?.number, 28 | userId: userId, 29 | projectId: projectId, 30 | id: res.message._id, 31 | }); 32 | setSchema(res.message?.schema); 33 | } 34 | }); 35 | }; 36 | 37 | useEffect(() => { 38 | const ac = new AbortController(); 39 | fetchResource(ac.signal); 40 | return () => ac.abort(); 41 | }, []); 42 | 43 | const cloneResource = () => { 44 | setLoading(true); 45 | const body = { 46 | name: inputs.name, 47 | number: parseInt(inputs.number), 48 | userId: userId, 49 | projectId: projectId, 50 | schema: schema, 51 | }; 52 | 53 | apiResource 54 | .post(body) 55 | .then((res) => { 56 | // console.log(res); 57 | if (res.status === "200") { 58 | toast.success("Cloned Successfully"); 59 | setOpen(false); 60 | fetchResources(); 61 | } else { 62 | setOpen(false); 63 | toast.error("Error"); 64 | } 65 | }) 66 | .catch((err) => { 67 | console.log(err); 68 | toast.error("Error"); 69 | }) 70 | .finally(() => { 71 | setLoading(false); 72 | }); 73 | }; 74 | 75 | return ( 76 | 87 | {loading && ( 88 | 89 | 90 | 91 | Cloning Data... 92 | 93 | 94 | )} 95 | 96 | ); 97 | }; 98 | 99 | export default CloneModal; 100 | -------------------------------------------------------------------------------- /docs/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | const { themes } = require("prism-react-renderer"); 2 | const lightCodeTheme = themes.lightCodeTheme; 3 | const darkCodeTheme = themes.darkCodeTheme; 4 | const nightOwlTheme = themes.nightOwlTheme; 5 | 6 | /** @type {import('@docusaurus/types').DocusaurusConfig} */ 7 | module.exports = { 8 | title: "Mocker Docs", 9 | tagline: "Documentation of Mocker", 10 | onBrokenLinks: "throw", 11 | onBrokenMarkdownLinks: "warn", 12 | favicon: "img/favicon.ico", 13 | url: "https://mocker-docs.netlify.app/", // Your website URL 14 | baseUrl: "/", 15 | projectName: "Mocker Docs", 16 | organizationName: "Mocker", 17 | trailingSlash: false, 18 | themeConfig: { 19 | metadata: [ 20 | { 21 | name: "keywords", 22 | content: "mocker, documentation", 23 | }, 24 | ], 25 | prism: { 26 | theme: nightOwlTheme, 27 | }, 28 | navbar: { 29 | title: "Mocker Docs", 30 | logo: { 31 | alt: "Mocker docs Logo", 32 | src: "img/favicon.ico", 33 | }, 34 | items: [ 35 | { 36 | type: "doc", 37 | docId: "intro", 38 | position: "left", 39 | label: "Documentation", 40 | }, 41 | { 42 | href: "https://github.com/shelcia/mocker", 43 | label: "GitHub", 44 | position: "right", 45 | }, 46 | ], 47 | }, 48 | footer: { 49 | style: "dark", 50 | links: [ 51 | { 52 | title: "Docs", 53 | items: [ 54 | { 55 | label: "Documentation", 56 | to: "/docs/intro", 57 | }, 58 | ], 59 | }, 60 | { 61 | title: "More", 62 | items: [ 63 | { 64 | label: "GitHub", 65 | href: "https://github.com/shelcia/mocker", 66 | }, 67 | ], 68 | }, 69 | ], 70 | copyright: `Copyright © ${new Date().getFullYear()} Mocker Docs. Built with Docusaurus.`, 71 | }, 72 | prism: { 73 | theme: lightCodeTheme, 74 | darkTheme: darkCodeTheme, 75 | }, 76 | }, 77 | presets: [ 78 | [ 79 | "@docusaurus/preset-classic", 80 | { 81 | googleAnalytics: { 82 | trackingID: "G-E02ZGV8TT4", 83 | anonymizeIP: true, 84 | }, 85 | docs: { 86 | sidebarPath: require.resolve("./sidebars.js"), 87 | editUrl: "https://github.com/shelcia/mocker/edit/master/docs", 88 | }, 89 | // blog: { 90 | // showReadingTime: true, 91 | // editUrl: "https://github.com/shelcia/mocker/docs/edit/master", 92 | // }, 93 | theme: { 94 | customCss: require.resolve("./src/css/custom.css"), 95 | }, 96 | }, 97 | ], 98 | ], 99 | stylesheets: [ 100 | "https://fonts.googleapis.com/css2?family=Inconsolata:wght@200;300;400;500;600;700;800;900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,500;1,600;1,700;1,800;1,900&display=swap", 101 | ], 102 | }; 103 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/ResultModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import { Box } from "@mui/material"; 3 | import JSONPretty from "react-json-pretty"; 4 | import CustomModal from "../../../components/CustomModal"; 5 | import { grey } from "@mui/material/colors"; 6 | import { ThemeContext } from "../../../context/ThemeContext"; 7 | import { CopyButton } from "../../../components/CustomButtons"; 8 | import { toast } from "react-hot-toast"; 9 | import { secondary } from "../../../themes/themeColors"; 10 | import { copyTextToClipboard } from "../../../utils/utils"; 11 | import { PartLoader } from "../../../components/CustomLoading"; 12 | import { CustomTabs, CustomTabPanel } from "../../../components/CustomTabPanel"; 13 | import { CustomJSONTable } from "../../../components/CustomTable"; 14 | import json_beutify from "json-beautify"; 15 | 16 | const ResultModal = ({ open, setOpen, result = [], loading }) => { 17 | const [darkTheme] = useContext(ThemeContext); 18 | // const [isCopied, setIsCopied] = useState(false); 19 | const [isBeautifyCopied, setIsBeautifyCopied] = useState(false); 20 | 21 | const copyJsonBeautify = () => { 22 | const jsonBeautify = json_beutify(result, null, 1, 1); 23 | copyTextToClipboard(jsonBeautify) 24 | .then(() => { 25 | setIsBeautifyCopied(true); 26 | toast.success("Copied !"); 27 | setTimeout(() => { 28 | setIsBeautifyCopied(false); 29 | }, 5000); 30 | }) 31 | .catch((err) => { 32 | console.log(err); 33 | toast.error("Couldn't copy !"); 34 | }); 35 | }; 36 | 37 | const [value, setValue] = React.useState(0); 38 | 39 | const handleChange = (event, newValue) => { 40 | setValue(newValue); 41 | }; 42 | 43 | return ( 44 | 45 | 50 | 51 | 58 | 63 | {isBeautifyCopied ? "Done" : "Copy"} 64 | 65 | {loading ? ( 66 | 67 | ) : ( 68 | 69 | 70 | 71 | )} 72 | 73 | 74 | 75 | 83 | 84 | 85 | ); 86 | }; 87 | 88 | export default ResultModal; 89 | -------------------------------------------------------------------------------- /docs/docs/models/system.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 15 3 | tags: [system] 4 | --- 5 | 6 | # System 7 | 8 | ## Generates fake data for many computer systems properties. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### commonFileExt 17 | 18 | Returns a commonly used file extension. 19 | 20 | #### output 21 | 22 | ```json 23 | jpg 24 | ``` 25 | 26 | ### commonFileName 27 | 28 | Returns a random file name with a given extension or a commonly used extension. 29 | 30 | | Option | Description | 31 | | :----: | ---------------------------------------------------- | 32 | | ext | Extension. Empty string is considered to be not set. | 33 | 34 | #### Input: 35 | 36 | | ext | 37 | | :-: | 38 | | txt | 39 | 40 | #### output 41 | 42 | ```json 43 | global_borders_wyoming.txt 44 | ``` 45 | 46 | ### commonFileType 47 | 48 | Returns a commonly used file type. 49 | 50 | #### output 51 | 52 | ```json 53 | image 54 | ``` 55 | 56 | ### cron 57 | 58 | Returns a random cron expression. 59 | 60 | #### output 61 | 62 | ```json 63 | * 14 * * SAT 64 | ``` 65 | 66 | ### directoryPath 67 | 68 | Returns a directory path. 69 | 70 | #### output 71 | 72 | ```json 73 | /etc/mail 74 | ``` 75 | 76 | ### fileExt 77 | 78 | Returns a file extension. 79 | 80 | #### output 81 | 82 | ```json 83 | json 84 | ``` 85 | 86 | ### fileName 87 | 88 | Returns a random file name with extension. 89 | 90 | | Option | Description | 91 | | :------------: | --------------------------------------------------------------------------------------------- | 92 | | extensionCount | Define how many extensions the file name should have. A negative number will be treated as 0. | 93 | 94 | #### Input: 95 | 96 | | extensionCount | 97 | | :------------: | 98 | | 2 | 99 | 100 | #### output 101 | 102 | ```json 103 | bike_table.res.vcs 104 | ``` 105 | 106 | ### filePath 107 | 108 | Returns a file path. 109 | 110 | #### output 111 | 112 | ```json 113 | /root/male_woman.silo 114 | ``` 115 | 116 | ### fileType 117 | 118 | Returns a file type. 119 | 120 | #### output 121 | 122 | ```json 123 | message 124 | ``` 125 | 126 | ### mimeType 127 | 128 | mimeType 129 | 130 | #### output 131 | 132 | ```json 133 | application/vnd.patientecommsdoc 134 | ``` 135 | 136 | ### networkInterface 137 | 138 | Returns a random network interface. 139 | 140 | | Option | Description | 141 | | :-------------: | ---------------------------------------------------------- | 142 | | interfaceSchema | The interface schema. Can be one of index, slot, mac, pci. | 143 | | interfaceType | The interface type. Can be one of en, wl, ww. | 144 | 145 | #### Input: 146 | 147 | | interfaceSchema | interfaceType | 148 | | :-------------: | :-----------: | 149 | | en | pci | 150 | 151 | #### output 152 | 153 | ```json 154 | enp5s0f1d0 155 | ``` 156 | 157 | ### semver 158 | 159 | Returns a semantic version. 160 | 161 | #### output 162 | 163 | ```json 164 | 5.5.7 165 | ``` 166 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/ConfirmDelProjectModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import CustomModal from "../../../components/CustomModal"; 3 | import { Button, Stack, TextField, Typography } from "@mui/material"; 4 | 5 | const ConfirmDeleteModal = ({ 6 | confirmDeleteModal, 7 | setConfirmDeleteModal, 8 | project, 9 | deleteProject, 10 | isMultipleDelete = false, 11 | setIsMultipleDelete, 12 | delSelected = () => {}, 13 | }) => { 14 | const [formData, setFormData] = useState(""); 15 | const [disabled, setDisabled] = useState(true); 16 | 17 | const checkProjectName = () => { 18 | if (isMultipleDelete) { 19 | if ("DELETE" === formData) { 20 | setDisabled(false); 21 | } else { 22 | setDisabled(true); 23 | } 24 | return; 25 | } 26 | if (project.name === formData) { 27 | setDisabled(false); 28 | } else { 29 | setDisabled(true); 30 | } 31 | }; 32 | 33 | useEffect(() => { 34 | checkProjectName(); 35 | }, [formData]); 36 | 37 | useEffect(() => { 38 | //Set multiple delete to false on closing 39 | confirmDeleteModal || setIsMultipleDelete(false); 40 | }, [confirmDeleteModal]); 41 | 42 | return ( 43 | 48 | 49 | This action cannot be undone. This will permanently delete the{" "} 50 | {isMultipleDelete ? "selected" : {project.name}}{" "} 51 | {/* eslint-disable-next-line react/no-unescaped-entities */} 52 | project and it's associated resources. 53 | 54 | 55 | Please type{" "} 56 | 57 | {isMultipleDelete ? "DELETE" : project.name} 58 | {" "} 59 | to confirm. 60 | 61 | 62 | { 69 | setFormData(e.target.value); 70 | checkProjectName(); 71 | }} 72 | /> 73 | 74 | 75 | 88 | 100 | 101 | 102 | ); 103 | }; 104 | 105 | export default ConfirmDeleteModal; 106 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/EndpointModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from "react"; 2 | import { Box, Table, TableBody, TableCell, TableRow } from "@mui/material"; 3 | import CustomModal from "../../../components/CustomModal"; 4 | import { green, grey } from "@mui/material/colors"; 5 | import { ThemeContext } from "../../../context/ThemeContext"; 6 | import { secondary } from "../../../themes/themeColors"; 7 | import { CopyButton } from "../../../components/CustomButtons"; 8 | import { toast } from "react-hot-toast"; 9 | import { copyTextToClipboard } from "../../../utils/utils"; 10 | import { BACKEND_URL } from "../../../services/api"; 11 | 12 | const EndpointModal = ({ open, setOpen, result }) => { 13 | const [darkTheme] = useContext(ThemeContext); 14 | const [isCopied, setIsCopied] = useState(false); 15 | 16 | const points = [ 17 | { 18 | method: "GET", 19 | endpoint: "", 20 | }, 21 | { 22 | method: "GET", 23 | endpoint: "/:id", 24 | }, 25 | { 26 | method: "POST", 27 | endpoint: "", 28 | }, 29 | { 30 | method: "PUT", 31 | endpoint: "/:id", 32 | }, 33 | { 34 | method: "DELETE", 35 | endpoint: "/:id", 36 | }, 37 | ]; 38 | 39 | // onClick handler function for the copy button 40 | const handleCopyClick = (data, idx) => { 41 | // Asynchronously call copyTextToClipboard 42 | copyTextToClipboard(data) 43 | .then(() => { 44 | // If successful, update the isCopied state value 45 | setIsCopied(idx); 46 | toast.success("Copied !"); 47 | setTimeout(() => { 48 | setIsCopied(false); 49 | }, 5000); 50 | }) 51 | .catch((err) => { 52 | console.log(err); 53 | toast.error("Couldn't copy !"); 54 | }); 55 | }; 56 | 57 | return ( 58 | 59 | 66 | 67 | 68 | {points.map((point, idx) => ( 69 | 70 | 71 | {point.method} 72 | 73 | 74 | /{result} 75 | {point.endpoint} 76 | 77 | 78 | 80 | handleCopyClick( 81 | `${BACKEND_URL}/user/${result}${point.endpoint}`, 82 | idx 83 | ) 84 | } 85 | disabled={isCopied === idx ? true : false} 86 | > 87 | {isCopied === idx ? "Done" : "Copy"} 88 | 89 | 90 | 91 | ))} 92 | 93 |
94 |
95 |
96 | ); 97 | }; 98 | 99 | export default EndpointModal; 100 | -------------------------------------------------------------------------------- /docs/docs/models/random.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 13 3 | tags: [random] 4 | --- 5 | 6 | # Random 7 | 8 | ### Generates random values of different kinds. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### alpha 17 | 18 | Generating a string consisting of letters in the English alphabet. 19 | 20 | | Option | Description | 21 | | :-----------------: | ------------------------------------- | 22 | | number of character | The number of characters to generate. | 23 | 24 | #### Input: 25 | 26 | | number of character | 27 | | :-----------------: | 28 | | 10 | 29 | 30 | #### output 31 | 32 | ```json 33 | qccrabobaf 34 | ``` 35 | 36 | ### alphaNumeric 37 | 38 | Generating a string consisting of alpha characters and digits. 39 | 40 | | Option | Description | 41 | | :------------------------------: | ------------------------------------------------ | 42 | | number of alphaNumeric character | The number of characters and digits to generate. | 43 | 44 | #### Input: 45 | 46 | | number of alphaNumeric character | 47 | | :------------------------------: | 48 | | 5 | 49 | 50 | #### output 51 | 52 | ```json 53 | 3e5v7 54 | ``` 55 | 56 | ### locale 57 | 58 | Returns a random locale 59 | 60 | #### output 61 | 62 | ```json 63 | el 64 | ``` 65 | 66 | ### numeric 67 | 68 | Generates a given length string of digits. 69 | 70 | | Option | Description | 71 | | :-------------: | --------------------------------- | 72 | | Number of digit | The number of digits to generate. | 73 | 74 | #### Input: 75 | 76 | | Number of digit | 77 | | :-------------: | 78 | | 42 | 79 | 80 | #### output 81 | 82 | ```json 83 | 56434563150765416546479875435481513188548 84 | ``` 85 | 86 | ### word 87 | 88 | Returns random word. 89 | 90 | #### output 91 | 92 | ```json 93 | quantify 94 | ``` 95 | 96 | ### words 97 | 98 | Returns string with set of random words 99 | 100 | | Option | Description | 101 | | :------------: | -------------------- | 102 | | Number of word | Returns random word. | 103 | 104 | #### Input: 105 | 106 | | Number of word | 107 | | :------------: | 108 | | 5 | 109 | 110 | #### output 111 | 112 | ```json 113 | copy Handcrafted bus client-server Point 114 | ``` 115 | 116 | ### Special character 117 | 118 | Generates a given length string of special character. 119 | 120 | | Option | Default | Description | 121 | | :------------: | :---------------------------------------: | -------------------------------------------------------------------- | 122 | | Number of word | 5 | The number of character to generate. | 123 | | Whitelist | !"#$%&'()\*+,-./:;\<\=\>?@[]^\_`\{\|\}~\ | Set of characters that are allowed to include in the generated data. | 124 | 125 | #### Input: 126 | 127 | | Number of word | Whitelist | 128 | | :------------: | :-------: | 129 | | 20 | %^&\* | 130 | 131 | #### Output: 132 | 133 | ```json 134 | %&%^^%^&*&^****%%^%% 135 | ``` 136 | 137 | Special character schema can also be used to generate any character and numeric data as shown: 138 | 139 | | Number of word | Whitelist | Output | 140 | | :------------: | :--------: | :------------------: | 141 | | 20 | qwerty1234 | 1eyw4tww3trew11eyqt1 | 142 | -------------------------------------------------------------------------------- /docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | /** 3 | * Any CSS included here will be global. The classic template 4 | * bundles Infima by default. Infima is a CSS framework designed to 5 | * work well for content-centric websites. 6 | */ 7 | 8 | /* You can override the default Infima variables here. */ 9 | 10 | /* @import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&family=JetBrains+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap"); */ 11 | 12 | @import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,500;1,600;1,700;1,800;1,900&display=swap"); 13 | 14 | :root { 15 | --ifm-color-primary: #005c9e; 16 | --ifm-color-primary-dark: #00538e; 17 | --ifm-color-primary-darker: #004e86; 18 | --ifm-color-primary-darkest: #00406f; 19 | --ifm-color-primary-light: #0065ae; 20 | --ifm-color-primary-lighter: #006ab6; 21 | --ifm-color-primary-lightest: #0078cd; 22 | --ifm-code-font-size: 95%; 23 | } 24 | 25 | [data-theme="dark"] { 26 | --ifm-color-primary: #47b3ff; 27 | --ifm-color-primary-dark: #26a6ff; 28 | --ifm-color-primary-darker: #169fff; 29 | --ifm-color-primary-darkest: #0086e4; 30 | --ifm-color-primary-light: #68c0ff; 31 | --ifm-color-primary-lighter: #78c7ff; 32 | --ifm-color-primary-lightest: #a9dbff; 33 | } 34 | 35 | .docusaurus-highlight-code-line { 36 | background-color: rgba(0, 0, 0, 0.1); 37 | display: block; 38 | margin: 0 calc(-1 * var(--ifm-pre-padding)); 39 | padding: 0 var(--ifm-pre-padding); 40 | } 41 | 42 | html[data-theme="dark"] .docusaurus-highlight-code-line { 43 | background-color: rgba(0, 0, 0, 0.3); 44 | } 45 | 46 | html[data-theme="dark"] { 47 | background-color: #0a141c; 48 | } 49 | 50 | html[data-theme="dark"] #__docusaurus { 51 | --ifm-navbar-background-color: #0a141cb5; 52 | } 53 | 54 | html[data-theme="dark"] .footer { 55 | border-top: 1px solid var(--ifm-color-emphasis-300); 56 | background-color: #0a141c !important; 57 | } 58 | 59 | html[data-theme="light"] #__docusaurus { 60 | --ifm-navbar-background-color: rgba(255, 255, 255, 0.85); 61 | } 62 | 63 | html[data-theme="light"] .footer { 64 | border-top: 1px solid var(--ifm-color-emphasis-300); 65 | background-color: var(--ifm-background-surface-color) !important; 66 | } 67 | 68 | html[data-theme="light"] .footer .footer__title { 69 | color: var(--ifm-color-emphasis-1000); 70 | } 71 | 72 | html[data-theme="light"] .footer .footer__link-item { 73 | color: var(--ifm-color-emphasis-800); 74 | } 75 | 76 | html[data-theme="light"] .footer .footer__link-item:hover { 77 | color: var(--ifm-color-primary-dark); 78 | } 79 | 80 | html[data-theme="light"] .footer .footer__copyright { 81 | color: var(--ifm-color-emphasis-900); 82 | } 83 | 84 | h1, 85 | h2, 86 | h3, 87 | h4, 88 | h5, 89 | h6, 90 | a, 91 | p, 92 | b, 93 | span, 94 | li, 95 | ul, 96 | div { 97 | font-family: "Poppins", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 98 | } 99 | 100 | code, 101 | pre, 102 | kbd, 103 | .codeBlockLines_3Jct, 104 | .prism-code { 105 | font-family: "JetBrains Mono", "Courier New", Courier, monospace; 106 | } 107 | 108 | code, 109 | pre, 110 | kbd, 111 | .codeBlockLines_3Jct, 112 | .prism-code span { 113 | font-family: "JetBrains Mono", "Courier New", Courier, monospace; 114 | } 115 | 116 | .mainWrapper_node_modules-\@docusaurus-theme-classic-lib-theme-Layout-styles-module { 117 | flex: 0 auto !important; 118 | } 119 | -------------------------------------------------------------------------------- /frontend/src/pages/dashboard/components/ViewAnalytics.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Box, Tab, Tabs } from "@mui/material"; 3 | import CustomModal from "../../../components/CustomModal"; 4 | import { 5 | XAxis, 6 | YAxis, 7 | CartesianGrid, 8 | Tooltip, 9 | Legend, 10 | ResponsiveContainer, 11 | BarChart, 12 | Bar, 13 | } from "recharts"; 14 | import { CustomTooltip } from "../../../components/CustomChartComponents"; 15 | 16 | function a11yProps(index) { 17 | return { 18 | id: `simple-tab-${index}`, 19 | "aria-controls": `simple-tabpanel-${index}`, 20 | }; 21 | } 22 | 23 | const TabPanel = (props) => { 24 | const { children, value, index, ...other } = props; 25 | 26 | return ( 27 | 38 | ); 39 | }; 40 | 41 | const ViewAnalytics = ({ open, setOpen }) => { 42 | const [value, setValue] = React.useState(0); 43 | 44 | const handleChange = (event, newValue) => { 45 | setValue(newValue); 46 | }; 47 | 48 | const data = [ 49 | { 50 | date: "22/10", 51 | requests: 1, 52 | }, 53 | { 54 | date: "23/10", 55 | requests: 2, 56 | }, 57 | { 58 | date: "24/10", 59 | requests: 4, 60 | }, 61 | { 62 | date: "25/10", 63 | requests: 1, 64 | }, 65 | { 66 | date: "26/10", 67 | requests: 3, 68 | }, 69 | { 70 | date: "27/10", 71 | requests: 4, 72 | }, 73 | { 74 | date: "28/10", 75 | requests: 5, 76 | }, 77 | ]; 78 | 79 | const tabData = [ 80 | { 81 | method: "GET", 82 | data: data, 83 | color: "#82ca9d", 84 | }, 85 | { 86 | method: "GET Single", 87 | data: data, 88 | color: "#A798FF", 89 | }, 90 | { 91 | method: "POST", 92 | data: data, 93 | color: "#FF9777", 94 | }, 95 | { 96 | method: "PUT", 97 | data: data, 98 | color: "#2499EF", 99 | }, 100 | { 101 | method: "DELETE", 102 | data: data, 103 | color: "#3f51b5", 104 | }, 105 | ]; 106 | 107 | return ( 108 | 109 | 110 | 111 | 116 | {tabData.map((tab, idx) => ( 117 | 118 | ))} 119 | 120 | 121 | {tabData.map((tab, idx) => ( 122 | 128 | 129 | 130 | 131 | 132 | 133 | } /> 134 | 135 | 136 | 137 | 138 | 139 | ))} 140 | 141 | 142 | ); 143 | }; 144 | 145 | export default ViewAnalytics; 146 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our 6 | project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, 7 | gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual 8 | identity and orientation. 9 | 10 | ## Our Standards 11 | 12 | Examples of behavior that contributes to a positive environment include: 13 | 14 | * Demonstrating empathy and kindness toward other people 15 | * Being respectful of differing opinions, viewpoints, and experiences 16 | * Giving and gracefully accepting constructive feedback 17 | * Accepting responsibility and apologizing to those affected by our mistakes, 18 | and learning from the experience 19 | * Focusing on what is best not just for us as individuals, but for the 20 | overall community 21 | 22 | Examples of unacceptable behavior include: 23 | 24 | * The use of sexualized language or imagery, and sexual attention or 25 | advances of any kind 26 | * Trolling, insulting or derogatory comments, and personal or political attacks 27 | * Public or private harassment 28 | * Publishing others' private information, such as a physical or email 29 | address, without their explicit permission 30 | * Other conduct which could reasonably be considered inappropriate in a 31 | professional setting 32 | 33 | ## Our Responsibilities 34 | 35 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective 36 | action in response to any instances of unacceptable behavior. 37 | 38 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions 39 | that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, 40 | threatening, offensive, or harmful. 41 | 42 | ## Scope 43 | 44 | This Code of Conduct applies within all project spaces, and also applies when 45 | an individual is officially representing the project in public spaces. 46 | 47 | Examples of representing our project include using an official e-mail address, 48 | posting via an official social media account, or acting as an appointed 49 | representative at an online or offline event. 50 | 51 | ## Enforcement 52 | 53 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer. 54 | 55 | All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. 56 | 57 | The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement 58 | policies may be posted separately. 59 | 60 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined 61 | by other members of the project's leadership. 62 | 63 | 64 | ## Attribution 65 | 66 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 67 | version 2.0, available at 68 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 69 | 70 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 71 | enforcement ladder](https://github.com/mozilla/diversity). 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see the FAQ at 76 | https://www.contributor-covenant.org/faq. Translations are available at 77 | https://www.contributor-covenant.org/translations. 78 | -------------------------------------------------------------------------------- /frontend/src/services/utilities/core.js: -------------------------------------------------------------------------------- 1 | // core.js 2 | 3 | import { apiProvider } from "./provider"; 4 | 5 | export class ApiCore { 6 | constructor(options) { 7 | if (options.getAll) { 8 | this.getAll = (signal, additionalParam, isAuthorized) => { 9 | return apiProvider.getAll( 10 | options.url, 11 | signal, 12 | additionalParam, 13 | isAuthorized 14 | ); 15 | }; 16 | } 17 | 18 | if (options.getSingle) { 19 | this.getSingle = (id, signal, additionalParam, isAuthorized) => { 20 | return apiProvider.getSingle( 21 | options.url, 22 | id, 23 | signal, 24 | additionalParam, 25 | isAuthorized 26 | ); 27 | }; 28 | } 29 | 30 | if (options.getByParams) { 31 | this.getByParams = (params, signal, additionalParam, isAuthorized) => { 32 | return apiProvider.getByParams( 33 | options.url, 34 | signal, 35 | params, 36 | additionalParam, 37 | isAuthorized 38 | ); 39 | }; 40 | } 41 | 42 | if (options.post) { 43 | this.post = (model, additionalParam, isAuthorized) => { 44 | return apiProvider.post( 45 | options.url, 46 | model, 47 | additionalParam, 48 | isAuthorized 49 | ); 50 | }; 51 | } 52 | 53 | if (options.postFormData) { 54 | this.postFormData = (model, additionalParam, isAuthorized) => { 55 | return apiProvider.postFormData( 56 | options.url, 57 | model, 58 | additionalParam, 59 | isAuthorized 60 | ); 61 | }; 62 | } 63 | 64 | if (options.put) { 65 | this.put = (model, additionalParam, isAuthorized) => { 66 | return apiProvider.put( 67 | options.url, 68 | model, 69 | additionalParam, 70 | isAuthorized 71 | ); 72 | }; 73 | } 74 | 75 | if (options.putById) { 76 | this.putById = (id, model, signal, additionalParam, isAuthorized) => { 77 | return apiProvider.putById( 78 | options.url, 79 | id, 80 | model, 81 | signal, 82 | additionalParam, 83 | isAuthorized 84 | ); 85 | }; 86 | } 87 | 88 | if (options.putFormData) { 89 | this.putFormData = (model, additionalParam, isAuthorized) => { 90 | return apiProvider.putFormData( 91 | options.url, 92 | model, 93 | additionalParam, 94 | isAuthorized 95 | ); 96 | }; 97 | } 98 | 99 | if (options.patch) { 100 | this.patch = (model, signal, additionalParam, isAuthorized) => { 101 | return apiProvider.patch( 102 | options.url, 103 | model, 104 | signal, 105 | additionalParam, 106 | isAuthorized 107 | ); 108 | }; 109 | } 110 | 111 | if (options.patchByParams) { 112 | this.patchByParams = (additionalParams, queryParams, isAuthorized) => { 113 | return apiProvider.patchByParams( 114 | options.url, 115 | additionalParams, 116 | queryParams, 117 | isAuthorized 118 | ); 119 | }; 120 | } 121 | 122 | if (options.remove) { 123 | this.remove = (id, additionalParams, isAuthorized) => { 124 | return apiProvider.remove( 125 | options.url, 126 | id, 127 | additionalParams, 128 | isAuthorized 129 | ); 130 | }; 131 | } 132 | 133 | if (options.removeAll) { 134 | this.removeAll = (model, additionalParams, isAuthorized) => { 135 | return apiProvider.removeAll( 136 | options.url, 137 | model, 138 | additionalParams, 139 | isAuthorized 140 | ); 141 | }; 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /frontend/src/layout/DashboardLayout.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { 3 | AppBar, 4 | Box, 5 | Drawer, 6 | IconButton, 7 | Toolbar, 8 | Typography, 9 | Divider, 10 | Card, 11 | Button, 12 | useMediaQuery, 13 | Stack, 14 | } from "@mui/material"; 15 | import { HiMenuAlt3 } from "react-icons/hi"; 16 | import { useNavigate } from "react-router-dom"; 17 | import CustomToggle from "../components/CustomToggle"; 18 | // import Grad1 from "../assets/home/gradient-1.svg"; 19 | // import Grad2 from "../assets/home/gradient-2.svg"; 20 | import Logo from "../assets/images/logo.png"; 21 | 22 | const drawerWidth = 240; 23 | 24 | const DashboardLayout = ({ children }, props) => { 25 | const mobileMatches = useMediaQuery("(max-width:425px)"); 26 | 27 | const { window } = props; 28 | const [mobileOpen, setMobileOpen] = useState(false); 29 | 30 | const handleDrawerToggle = () => { 31 | setMobileOpen(!mobileOpen); 32 | }; 33 | 34 | const navigate = useNavigate(""); 35 | 36 | const logout = () => { 37 | localStorage.clear(); 38 | navigate("/"); 39 | }; 40 | 41 | const drawer = ( 42 | 43 | 44 | 48 | Mocker 49 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | ); 59 | 60 | const container = 61 | window !== undefined ? () => window().document.body : undefined; 62 | 63 | return ( 64 | 65 | {/* 66 | */} 71 | 72 | 73 | 77 | logo Mocker 78 | 79 | 86 | 87 | 88 | 89 | 90 | 93 | 94 | 95 | 96 | 97 | 113 | {drawer} 114 | 115 | 116 | 117 | 118 | 119 | 120 | {children} 121 | 122 | 123 | 124 | 125 | ); 126 | }; 127 | 128 | export default DashboardLayout; 129 | -------------------------------------------------------------------------------- /frontend/src/layout/AuthLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | AppBar, 4 | Box, 5 | Card, 6 | CardContent, 7 | Container, 8 | Grid, 9 | IconButton, 10 | Link, 11 | List, 12 | ListItem, 13 | ListItemIcon, 14 | ListItemText, 15 | Toolbar, 16 | Typography, 17 | } from "@mui/material"; 18 | import CustomToggle from "../components/CustomToggle"; 19 | import { MdStarRate } from "react-icons/md"; 20 | import { FiGithub } from "react-icons/fi"; 21 | import Grad1 from "../assets/home/gradient-1.svg"; 22 | import Grad2 from "../assets/home/gradient-2.svg"; 23 | 24 | const AuthLayout = ({ children }) => { 25 | return ( 26 | 27 | 28 | 33 | 34 | 35 | 39 | Mocker 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 52 | Docs 53 | 54 | 55 | 56 | 57 | 58 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {children} 73 | 74 | 75 | 76 | 77 | 87 | Developed by 88 | 89 | Shelcia 90 | 91 | 92 | 93 | ); 94 | }; 95 | 96 | export default AuthLayout; 97 | 98 | const Intro = () => { 99 | const featureList = [ 100 | { 101 | key: 1, 102 | name: "Unlimited Resources", 103 | }, 104 | { 105 | key: 2, 106 | name: "Unlimited Projects", 107 | }, 108 | { 109 | key: 3, 110 | name: "Readymade Endpoints", 111 | }, 112 | { 113 | key: 4, 114 | name: "Customise Schema Options", 115 | }, 116 | ]; 117 | 118 | return ( 119 | <> 120 | 129 | Mocker 130 | 131 | 132 | 133 | Mocker can generate mock data with API endpoints, powered by{" "} 134 | 135 | faker.js 136 | 137 | 138 | 139 | {featureList.map((feature) => ( 140 | 141 | 142 | 143 | 144 | 145 | 146 | ))} 147 | 148 | 149 | ); 150 | }; 151 | -------------------------------------------------------------------------------- /docs/docs/intro.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Mocker 6 | 7 | ![Mocker Generator](https://socialify.git.ci/shelcia/mocker/image?description=1&font=KoHo&forks=1&issues=1&language=1&owner=1&pattern=Brick%20Wall&pulls=1&stargazers=1&theme=Dark) 8 | 9 | ![PRs Welcome](https://img.shields.io/badge/language-React-blue?style=for-the-badge) 10 | ![PRs Welcome](https://img.shields.io/badge/language-MongoDB-blue?style=for-the-badge) 11 | ![PRs Welcome](https://img.shields.io/badge/language-Express-blue?style=for-the-badge) 12 | ![PRs Welcome](https://img.shields.io/badge/language-Nodejs-blue?style=for-the-badge) 13 | 14 | ![PRs Welcome](https://img.shields.io/github/stars/shelcia/mocker?style=for-the-badge) 15 | ![PRs Welcome](https://img.shields.io/github/forks/shelcia/mocker?style=for-the-badge) 16 | ![PRs Welcome](https://img.shields.io/github/issues-raw/shelcia/mocker?style=for-the-badge) 17 | ![PRs Welcome](https://img.shields.io/github/issues-pr-closed-raw/shelcia/mocker?style=for-the-badge) 18 | 19 | ## 📌 Introduction 20 | 21 | A Web app which lets you generate data with API endpoints 22 | 23 | # Demo 24 | 25 | 26 | 27 | import ReactPlayer from "react-player"; 28 | 29 | 34 | 35 | ## ⭐ How to get started? 36 | 37 | You can refer to the following articles on the basics of Git and Github and also contact the Project Mentors, in case you are stuck: 38 | 39 | - [Watch this video to get started, if you have no clue about open source](https://youtu.be/SL5KKdmvJ1U) 40 | - [Forking a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) 41 | - [Cloning a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) 42 | - [How to create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github) 43 | - [Getting started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6) 44 | 45 | ## 💥 How to Contribute? 46 | 47 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 48 | [![Open Source Love svg2](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 49 | 50 | - Take a look at the Existing [Issues](https://github.com/shelcia/mocker/issues) or create your own Issues! 51 | - Wait for the Issue to be assigned to you after which you can start working on it. 52 | - Fork the Repo and create a Branch for any Issue that you are working upon. 53 | - Create a Pull Request which will be promptly reviewed and suggestions would be added to improve it. 54 | - Add Screenshots to help us know what this Script is all about. 55 | 56 | ## ⭐ Issues: 57 | 58 | For major changes, you are welcome to open an issue to discuss what you would like to change. Enhancements will be appreciated. 59 | 60 | ## Deployement 61 | 62 | ### Web App 63 | 64 | #### Frontend 65 | 66 | https://mocker-gen.netlify.app/ 67 | 68 | [![Netlify Status](https://api.netlify.com/api/v1/badges/26eb34f4-5250-4bf3-86f4-dcb70b2cd822/deploy-status)](https://app.netlify.com/sites/mocker-gen/deploys) 69 | 70 | #### Backend 71 | 72 | ![Vercel Status](https://vercelbadge.vercel.app/api/shelcia/mocker?style=for-the-badge) 73 | 74 | #### Demo 75 | 76 | ``` 77 | email: demo@gmail.com 78 | password: password 79 | ``` 80 | 81 | ### To work with this repo 82 | 83 | - Clone this repo 84 | 85 | - To start backend cd backend 86 | 87 | - Run npm install 88 | 89 | - Then run node index.js or nodemon index.js 90 | 91 | - To start frontend cd frontend 92 | 93 | - Run npm install 94 | 95 | - Then run npm run dev 96 | 97 | Addtionally within BE folder you will have to include MongoDB URL and Token in .env for local work 98 | 99 | ```md 100 | DB_CONNECT = mongodb+srv://{username}:{password}@cluster0.hfdhy.mongodb.net/{collectio_name}?retryWrites=true&w=majority 101 | 102 | TOKEN_SECRET = {some gibberish} 103 | 104 | EMAIL_ID={email} 105 | 106 | EMAIL_PWD={password} 107 | ``` 108 | 109 | ## 💼 Code of Conduct 110 | 111 | We want to facilitate a healthy and constructive community behavior by adopting and enforcing our code of conduct. 112 | -------------------------------------------------------------------------------- /frontend/src/pages/auth/Signup.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import axios from "axios"; 3 | import { Box, Button, TextField, Typography } from "@mui/material"; 4 | import { Link, useNavigate } from "react-router-dom"; 5 | import { apiAuth } from "../../services/models/authModel"; 6 | import { toast } from "react-hot-toast"; 7 | import * as Yup from "yup"; 8 | import { useFormik } from "formik"; 9 | import { CustomLoaderButton } from "../../components/CustomButtons"; 10 | import { CustomPwdField } from "../../components/CustomInputFields"; 11 | 12 | const Signup = () => { 13 | let [hasToken, setHasToken] = useState(false); 14 | useEffect(() => { 15 | const userToken = localStorage.getItem("MockAPI-Token"); 16 | const headers = { 17 | "auth-token": `${userToken}`, 18 | }; 19 | axios 20 | .get("https://mocker-backend.vercel.app/api/auth/verify", { 21 | headers, 22 | }) 23 | .then((res) => { 24 | if (res.data.message === "ok") { 25 | setHasToken(true); 26 | } 27 | }) 28 | .catch((err) => { 29 | setHasToken(false); 30 | }); 31 | }, []); 32 | const navigate = useNavigate(); 33 | const [loading, setLoading] = useState(false); 34 | 35 | const initialValues = { 36 | email: "", 37 | password: "", 38 | submit: null, 39 | }; // form field value validation schema 40 | 41 | const validationSchema = Yup.object().shape({ 42 | email: Yup.string() 43 | .email("Must be a valid email") 44 | .max(255) 45 | .required("Email is required"), 46 | password: Yup.string() 47 | .min(6, "Minimum 6 characters required") 48 | .required("Password is required"), 49 | }); 50 | 51 | const { errors, values, touched, handleBlur, handleChange, handleSubmit } = 52 | useFormik({ 53 | initialValues, 54 | validationSchema, 55 | onSubmit: (values) => { 56 | setLoading(true); 57 | registerUser(values.email, values.password); 58 | }, 59 | }); 60 | 61 | const registerUser = (email, password) => { 62 | const body = { 63 | email: email, 64 | password: password, 65 | }; 66 | 67 | apiAuth.post(body, "register").then((res) => { 68 | if (res.status === "200") { 69 | navigate("/"); 70 | toast.success( 71 | "We have sent you verification mail. Please verify and come back" 72 | ); 73 | } else if (res.status === "400") { 74 | toast.error(res.message); 75 | } else { 76 | toast.error("Error"); 77 | } 78 | setLoading(false); 79 | }); 80 | }; 81 | const logout = () => { 82 | localStorage.clear(); 83 | setHasToken(false); 84 | navigate("/"); 85 | }; 86 | if (hasToken) { 87 | return ( 88 | 91 | ); 92 | } 93 | return ( 94 | 95 | 96 | Signup 97 | 98 | 106 | 119 | 126 | 134 | 135 | Have an account already ? Then{" "} 136 | 137 | Login 138 | 139 | 140 | 141 | 142 | ); 143 | }; 144 | 145 | export default Signup; 146 | -------------------------------------------------------------------------------- /backend/routes/service/service.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | 3 | const User = require("../../models/User"); 4 | 5 | const bcrypt = require("bcryptjs"); 6 | 7 | const nodemailer = require("nodemailer"); 8 | const feLink = require("../../feLink"); 9 | const resetPwdTemplate = require("../../templates/resetPwdTemplate"); 10 | 11 | const Cryptr = require("cryptr"); 12 | const cryptr = new Cryptr("myTotallySecretKey"); 13 | 14 | const Joi = require("joi"); 15 | 16 | const jwt = require("jsonwebtoken"); 17 | 18 | //GENERATE PASSWORD RESET LINK AND SEND THROUGH EMAIL 19 | router.post("/reset-password", async (req, res) => { 20 | try { 21 | const { email } = req.body; 22 | //CHECK IF EMAIL EXIST 23 | const user = await User.findOne({ email: {$eq: req.body.email} }); 24 | if (!user) { 25 | res.status(200).send({ 26 | status: "400", 27 | message: "Email does not exist", 28 | }); 29 | return; 30 | } 31 | 32 | //GENERATE TOKEN 33 | const encryptedString = cryptr.encrypt(req.body.email); 34 | 35 | const link = `${feLink}reset-password/${encryptedString}`; 36 | // console.log(process.env.EMAIL, process.env.PASSWORD); 37 | 38 | const transporter = await nodemailer.createTransport({ 39 | service: "gmail", 40 | auth: { 41 | user: process.env.EMAIL_ID, 42 | pass: process.env.EMAIL_PWD, 43 | }, 44 | }); 45 | 46 | const mailOptions = { 47 | from: process.env.EMAIL_ID, 48 | to: req.body.email, 49 | subject: `Reset Password for Mocker`, 50 | html: resetPwdTemplate(link), 51 | }; 52 | 53 | transporter.sendMail(mailOptions, function (error, info) { 54 | if (error) { 55 | console.log(error); 56 | // res.status(401).send("error"); 57 | res.status(200).send({ status: "401", message: "Error" }); 58 | } else { 59 | console.log("Email sent: " + info.response); 60 | res.status(200).send({ 61 | status: "200", 62 | message: `Verification link sent to ${email}. \nCheck your inbox`, 63 | }); 64 | } 65 | }); 66 | } catch (err) { 67 | res.status(200).send({ 68 | status: "500", 69 | message: "Something went wrong", 70 | }); 71 | } 72 | }); 73 | 74 | const pwdResetSchema = Joi.object({ 75 | password: Joi.string().min(6).required(), 76 | }); 77 | 78 | //GET TOKEN AND CHANGE PASSWORD OF THE USER 79 | //IF TOKEN IS VERIFIED 80 | router.post("/change-password/:token", async (req, res) => { 81 | // const auth_token = req.params.token; 82 | 83 | try { 84 | //VALIDATION OF USER INPUTS 85 | 86 | const { error } = await pwdResetSchema.validateAsync(req.body); 87 | if (error) { 88 | res.status(200).send({ 89 | status: "400", 90 | message: error, 91 | }); 92 | } 93 | 94 | const decryptedString = cryptr.decrypt(req.params.token); 95 | const query = await User.where({ email: decryptedString }); 96 | if (query.length === 0) { 97 | res.status(200).send({ status: "400", message: "Invalid String" }); 98 | return; 99 | } 100 | const user = await User.findById(query[0]._id).exec(); 101 | 102 | //HASHING THE PASSWORD 103 | 104 | const salt = await bcrypt.genSalt(10); 105 | const hashedPassword = await bcrypt.hash(req.body.password, salt); 106 | 107 | user.set({ password: hashedPassword }); 108 | // console.log("verified"); 109 | await user.save(); 110 | res 111 | .status(200) 112 | .send({ status: "200", message: "Password Changed Successfully!" }); 113 | } catch (error) { 114 | res.status(200).send({ status: "500", message: "Password Change failed" }); 115 | } 116 | }); 117 | 118 | router.get("/auth-token/:token", async (req, res) => { 119 | // console.log(req.params.token); 120 | var payload = await new Promise(async (resolve, reject) => { 121 | try { 122 | let _payload = jwt.verify(req.params.token, process.env.TOKEN_SECRET); 123 | resolve(_payload); 124 | } catch (error) { 125 | console.log(error); 126 | res.send({ 127 | status: "400", 128 | message: "Something wrong here", 129 | }); 130 | return; 131 | } 132 | }); 133 | 134 | const user = await User.findById(payload._id); 135 | 136 | if (!user) { 137 | res.status(200).send({ 138 | status: "400", 139 | message: 'Email doesn"t exist', 140 | }); 141 | return; 142 | } 143 | res.send({ 144 | status: "200", 145 | message: "Verified", 146 | }); 147 | }); 148 | 149 | module.exports = router; 150 | -------------------------------------------------------------------------------- /frontend/src/pages/auth/Login.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import axios from "axios"; 3 | import { Box, Button, TextField, Typography } from "@mui/material"; 4 | import { Link, useNavigate } from "react-router-dom"; 5 | import { apiAuth } from "../../services/models/authModel"; 6 | import { toast } from "react-hot-toast"; 7 | import * as Yup from "yup"; 8 | import { useFormik } from "formik"; 9 | import { apiProvider } from "../../services/utilities/provider"; 10 | import { CustomLoaderButton } from "../../components/CustomButtons"; 11 | import { CustomPwdField } from "../../components/CustomInputFields"; 12 | const Login = () => { 13 | let [hasToken, setHasToken] = useState(false); 14 | useEffect(() => { 15 | const userToken = localStorage.getItem("MockAPI-Token"); 16 | const headers = { 17 | "auth-token": `${userToken}`, 18 | }; 19 | axios 20 | .get("https://mocker-backend.vercel.app/api/auth/verify", { 21 | headers, 22 | }) 23 | .then((res) => { 24 | if (res.data.message === "ok") { 25 | setHasToken(true); 26 | } 27 | }) 28 | .catch((err) => { 29 | setHasToken(false); 30 | }); 31 | }, []); 32 | const navigate = useNavigate(); 33 | const [loading, setLoading] = useState(false); 34 | 35 | const initialValues = { 36 | email: "", 37 | password: "", 38 | submit: null, 39 | }; // form field value validation schema 40 | 41 | const validationSchema = Yup.object().shape({ 42 | email: Yup.string() 43 | .email("Must be a valid email") 44 | .max(255) 45 | .required("Email is required"), 46 | password: Yup.string() 47 | .min(6, "Minimum 6 characters required") 48 | .required("Password is required"), 49 | }); 50 | 51 | const { errors, values, touched, handleBlur, handleChange, handleSubmit } = 52 | useFormik({ 53 | initialValues, 54 | validationSchema, 55 | onSubmit: (values) => { 56 | setLoading(true); 57 | loginUser(values.email, values.password); 58 | }, 59 | }); 60 | 61 | const loginUser = (email, password) => { 62 | const body = { 63 | email: email, 64 | password: password, 65 | }; 66 | 67 | apiAuth.post(body, "signin").then((res) => { 68 | if (res.status === "200") { 69 | if (!res.message.emailVerified) { 70 | toast.error( 71 | "Email not verified yet !. Please check you inbox for verification" 72 | ); 73 | setLoading(false); 74 | return; 75 | } 76 | localStorage.setItem("MockAPI-Token", res.message.token); 77 | apiProvider.updateToken(); 78 | navigate(`/dashboard/${res.message.userId}`); 79 | toast.success("Login successful"); 80 | } else if (res.status === "400") { 81 | toast.error(res.message); 82 | } else { 83 | toast.error("Error"); 84 | } 85 | setLoading(false); 86 | }); 87 | }; 88 | const logout = () => { 89 | localStorage.clear(); 90 | setHasToken(false); 91 | navigate("/"); 92 | }; 93 | if (hasToken) { 94 | return ( 95 | 98 | ); 99 | } 100 | return ( 101 | 102 | 103 | Login 104 | 105 | 113 | 126 | 133 | 141 | 142 | {/* eslint-disable-next-line react/no-unescaped-entities */} 143 | Don't have an account ? Then{" "} 144 | 145 | Signup 146 | 147 | 148 | 149 | 150 | Forgot password ? 151 | 152 | 153 | 154 | 155 | ); 156 | }; 157 | 158 | export default Login; 159 | -------------------------------------------------------------------------------- /backend/routes/auth/auth.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | 3 | const bcrypt = require("bcryptjs"); 4 | const jwt = require("jsonwebtoken"); 5 | 6 | const User = require("../../models/User"); 7 | 8 | const nodemailer = require("nodemailer"); 9 | const feLink = require("../../feLink"); 10 | const verificationTemplate = require("../../templates/verificationTemplate"); 11 | 12 | const Cryptr = require("cryptr"); 13 | const cryptr = new Cryptr("myTotallySecretKey"); 14 | 15 | //VALIDATION OF USER INPUTS PREREQUISITES 16 | const Joi = require("joi"); 17 | let authMiddleWare = require("../../middleware/authenticate"); 18 | //AUTHORISATION RELATED API 19 | 20 | const registerSchema = Joi.object({ 21 | email: Joi.string().min(6).required().email(), 22 | password: Joi.string().min(6).required(), 23 | }); 24 | 25 | const loginSchema = Joi.object({ 26 | email: Joi.string().min(6).required().email(), 27 | password: Joi.string().min(6).required(), 28 | }); 29 | // adding another route to check that the user has a valid json web token 30 | router.get("/verify", authMiddleWare, (req, res) => { 31 | res.status(200).json({ 32 | message: "ok", 33 | }); 34 | }); 35 | router.post("/register", async (req, res) => { 36 | try { 37 | //CHECK IF MAIL ALREADY EXISTS 38 | const emailExist = await User.findOne({ email: { $eq: req.body.email } }); 39 | if (emailExist) { 40 | res.status(200).send({ status: "400", message: "Email Already Exists" }); 41 | return; 42 | } 43 | 44 | //HASHING THE PASSWORD 45 | 46 | const salt = await bcrypt.genSalt(10); 47 | const hashedPassword = await bcrypt.hash(req.body.password, salt); 48 | 49 | const user = new User({ 50 | email: req.body.email, 51 | password: hashedPassword, 52 | }); 53 | 54 | //VALIDATION OF USER INPUTS 55 | 56 | const { error } = await registerSchema.validateAsync(req.body); 57 | if (error) { 58 | res.status(200).send({ status: "500", message: error }); 59 | } 60 | //THE USER IS ADDED 61 | await user.save(); 62 | //GENERATE TOKEN 63 | const encryptedString = cryptr.encrypt(req.body.email); 64 | 65 | const link = `${feLink}verification/${encryptedString}`; 66 | // console.log(process.env.EMAIL, process.env.PASSWORD); 67 | 68 | const transporter = await nodemailer.createTransport({ 69 | service: "gmail", 70 | auth: { 71 | user: process.env.EMAIL_ID, 72 | pass: process.env.EMAIL_PWD, 73 | }, 74 | }); 75 | 76 | const mailOptions = { 77 | from: process.env.EMAIL_ID, 78 | to: req.body.email, 79 | subject: `Activation mail for Mocker`, 80 | html: verificationTemplate(link), 81 | }; 82 | 83 | transporter.sendMail(mailOptions, function (error, info) { 84 | if (error) { 85 | console.log(error); 86 | // res.status(401).send("error"); 87 | res.status(200).send({ status: "401", message: "Error" }); 88 | } else { 89 | console.log("Email sent: " + info.response); 90 | res.status(200).send({ status: "200", message: "User Created" }); 91 | } 92 | }); 93 | } catch (error) { 94 | res.status(200).send({ status: "500", message: error }); 95 | } 96 | }); 97 | 98 | //SIGNIN USER 99 | 100 | router.post("/signin", async (req, res) => { 101 | //CHECKING IF EMAIL EXISTS 102 | 103 | const user = await User.findOne({ email: { $eq: req.body.email } }); 104 | if (!user) { 105 | res.status(200).send({ status: "400", message: 'Email doesn"t exist' }); 106 | return; 107 | } 108 | 109 | const validPassword = await bcrypt.compare(req.body.password, user.password); 110 | 111 | if (!validPassword) { 112 | res.status(200).send({ status: "400", message: "Incorrect Password !!!" }); 113 | return; 114 | } 115 | 116 | try { 117 | const { error } = await loginSchema.validateAsync(req.body); 118 | if (error) { 119 | res.status(200).send({ status: "400", message: error }); 120 | return; 121 | } else { 122 | //CREATE TOKEN 123 | const token = jwt.sign( 124 | { 125 | _id: user._id, 126 | email: user.email, 127 | exp: Math.floor(Date.now() / 1000) + 14 * 24 * 60 * 60, // exp after 14 days 128 | }, 129 | process.env.TOKEN_SECRET 130 | ); 131 | 132 | res 133 | .status(200) 134 | .header("auth-token", token) 135 | .send({ 136 | status: "200", 137 | message: { 138 | token: token, 139 | userId: user._id, 140 | email: user.email, 141 | emailVerified: user.emailVerified, 142 | }, 143 | }); 144 | } 145 | } catch (error) { 146 | res.status(200).send({ status: "500", error }); 147 | } 148 | }); 149 | 150 | router.put("/verification/:id", async (req, res) => { 151 | // console.log(req.params.id); 152 | const decryptedString = cryptr.decrypt(req.params.id); 153 | const query = await User.where({ email: decryptedString }); 154 | try { 155 | if (query.length === 0) { 156 | res.status(200).send({ status: "400", message: "Invalid String" }); 157 | return; 158 | } 159 | const activate = await User.findById(query[0]._id).exec(); 160 | activate.set({ emailVerified: true }); 161 | // console.log("verified"); 162 | await activate.save(); 163 | res.status(200).send({ status: "200", message: "Account Verified !" }); 164 | } catch (error) { 165 | res.status(200).send({ status: "400", message: "Verification failed" }); 166 | } 167 | }); 168 | 169 | module.exports = router; 170 | -------------------------------------------------------------------------------- /docs/docs/models/datatype.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | tags: [datatype] 4 | --- 5 | 6 | # Datatype 7 | 8 | ## Module to generate various primitive values and data types. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### array 17 | 18 | Returns an array with random strings and numbers. 19 | 20 | | Option | Description | 21 | | :----: | --------------------------- | 22 | | length | Size of the returned array. | 23 | 24 | #### Input: 25 | 26 | | length | 27 | | :----: | 28 | | 3 | 29 | 30 | #### output 31 | 32 | ```json 33 | [61845, "SK7H$W3:d*", "m[%7N8*GVK"] 34 | ``` 35 | 36 | ### bigInt 37 | 38 | Returns a BigInt number. 39 | 40 | | Option | Description | 41 | | :----: | -------------------------------- | 42 | | min | Lower bound for generated bigint | 43 | | max | Upper bound for generated bigint | 44 | 45 | #### Input: 46 | 47 | | min | max | 48 | | :------: | :--------: | 49 | | 11111111 | 1111111111 | 50 | 51 | #### output 52 | 53 | ```json 54 | 524872478 55 | ``` 56 | 57 | ### boolean 58 | 59 | Returns the boolean value true or false. 60 | 61 | #### output 62 | 63 | ```json 64 | true 65 | ``` 66 | 67 | ### datetime 68 | 69 | Returns a Date object using a random number of milliseconds since the Unix Epoch (1 January 1970 UTC). 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 |
OptionDescriptionDefault
minUpper bound for milliseconds since base date. When not provided or larger than 8640000000000000, 2100-01-01 is considered as maximum generated date.631152000000
maxLower bound for milliseconds since base date. When not provided or smaller than -8640000000000000, 1990-01-01 is considered as minimum generated date. 4102444800000
92 | 93 | 97 | 98 | #### Input: 99 | 100 | | min | max | 101 | | :-----------: | :-----------: | 102 | | 1577836800000 | 1893456000000 | 103 | 104 | #### output 105 | 106 | ```json 107 | "2021-09-12T07:13:00.255Z" 108 | ``` 109 | 110 | ### float 111 | 112 | Returns a single random floating-point number for the given precision or range and precision. 113 | 114 | | Option | Description | 115 | | :-------: | ---------------------------------- | 116 | | min | Lower bound for generated number. | 117 | | max | Upper bound for generated number. | 118 | | precision | Precision of the generated number. | 119 | 120 | #### Input: 121 | 122 | | min | max | precision | 123 | | :-: | :-: | :-------: | 124 | | 10 | 100 | 0.001 | 125 | 126 | #### output 127 | 128 | ```json 129 | 57.315 130 | ``` 131 | 132 | ### hexadecimal 133 | 134 | Returns a hexadecimal number. 135 | 136 | | Option | Description | 137 | | :----: | -------------------------------- | 138 | | length | Length of the generated number. | 139 | | case | Case of the generated number. | 140 | | prefix | Prefix for the generated number. | 141 | 142 | #### Input: 143 | 144 | | length | case | prefix | 145 | | :----: | :---: | :----: | 146 | | 10 | mixed | 0x | 147 | 148 | #### output 149 | 150 | ```json 151 | 0xade330a4d1 152 | ``` 153 | 154 | ### json 155 | 156 | Returns a string representing JSON object with 7 pre-defined properties. 157 | 158 | #### output 159 | 160 | ```json 161 | { 162 | "foo": "mxz.v8ISij", 163 | "bar": 29154, 164 | "bike": 8658, 165 | "a": "GxTlw$nuC:", 166 | "b": 40693, 167 | "name": "%'77" 169 | } 170 | ``` 171 | 172 | ### number 173 | 174 | Returns a single random number between zero and the given max value or the given range with the specified precision. The bounds are inclusive. 175 | 176 | | Option | Description | 177 | | :-------: | ---------------------------------- | 178 | | min | Lower bound for generated number. | 179 | | max | Upper bound for generated number. | 180 | | precision | Precision of the generated number. | 181 | 182 | #### Input: 183 | 184 | | min | max | precision | 185 | | :-: | :-: | :-------: | 186 | | 10 | 100 | 0.01 | 187 | 188 | #### output 189 | 190 | ```json 191 | 36.94 192 | ``` 193 | 194 | ### string 195 | 196 | Returns a string containing UTF-16 chars between 33 and 125 (! to }). 197 | 198 | | Option | Description | 199 | | :----: | --------------------------------------------------- | 200 | | length | Length of the generated string. Max length is 2^20. | 201 | 202 | #### Input: 203 | 204 | | length | 205 | | :----: | 206 | | 5 | 207 | 208 | #### output 209 | 210 | ```json 211 | 6Bye8 212 | ``` 213 | 214 | ### uuid 215 | 216 | Returns a UUID v4 217 | 218 | #### output 219 | 220 | ```json 221 | 4136cd0b-d90b-4af7-b485-5d1ded8db252 222 | ``` 223 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mocker 2 | 3 | ![Mocker Generator](https://socialify.git.ci/shelcia/mocker/image?description=1&font=KoHo&forks=1&issues=1&language=1&owner=1&pattern=Brick%20Wall&pulls=1&stargazers=1&theme=Dark) 4 | 5 | 6 | 7 |

8 | 9 | 10 | 11 | 12 |

13 | 14 |

15 | 16 | 17 | 18 | 19 |

20 | 21 | 22 | ![Mocker Generator](https://github.com/shelcia/mocker/blob/master/mocker.svg) 23 | 24 | ## 📌 Introduction 25 | 26 | A Web app which lets you generate data with API endpoints 27 | 28 | # Demo 29 | 30 | https://user-images.githubusercontent.com/31156685/204107605-ab2c71b3-a2dd-4542-acd3-b09fd5d180ea.mov 31 | 32 | ## ⭐ How to get started? 33 | 34 | You can refer to the following articles on the basics of Git and Github and also contact the Project Mentors, in case you are stuck: 35 | 36 | - [Watch this video to get started, if you have no clue about open source](https://youtu.be/SL5KKdmvJ1U) 37 | - [Forking a Repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) 38 | - [Cloning a Repo](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) 39 | - [How to create a Pull Request](https://opensource.com/article/19/7/create-pull-request-github) 40 | - [Getting started with Git and GitHub](https://towardsdatascience.com/getting-started-with-git-and-github-6fcd0f2d4ac6) 41 | 42 | ## 💥 How to Contribute? 43 | 44 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 45 | [![Open Source Love svg2](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 46 | 47 | - Take a look at the Existing [Issues](https://github.com/shelcia/mocker/issues) or create your own Issues! 48 | - Wait for the Issue to be assigned to you after which you can start working on it. 49 | - Fork the Repo and create a Branch for any Issue that you are working upon. 50 | 51 | - Create a Pull Request which will be promptly reviewed and suggestions would be added to improve it. 52 | - Add Screenshots to help us know what this Script is all about. 53 | 54 | ## ⭐ Issues: 55 | 56 | For major changes, you are welcome to open an issue to discuss what you would like to change. Enhancements will be appreciated. 57 | 58 |

59 | 60 | ## Deployement 61 | 62 | ### Web App 63 | 64 | #### Frontend 65 | 66 | https://mocker-gen.netlify.app/ 67 | 68 | [![Netlify Status](https://api.netlify.com/api/v1/badges/26eb34f4-5250-4bf3-86f4-dcb70b2cd822/deploy-status)](https://app.netlify.com/sites/mocker-gen/deploys) 69 | 70 | #### Backend 71 | 72 | ![Vercel Status](https://vercelbadge.vercel.app/api/shelcia/mocker?style=for-the-badge) 73 | 74 | #### Demo 75 | 76 | ``` 77 | email: demo@gmail.com 78 | password: password 79 | ``` 80 | 81 | ### To work with this repo 82 | 83 | - Clone this repo 84 | 85 | - To start backend cd backend 86 | 87 | - Run npm install 88 | 89 | - Then run node index.js or nodemon index.js 90 | 91 | - To start frontend cd frontend 92 | 93 | - Run npm install 94 | 95 | - Then run npm run dev 96 | 97 | Addtionally within BE folder you will have to include MongoDB URL and Token in .env for local work 98 | 99 | ``` 100 | DB_CONNECT = mongodb+srv://{username}:{password}@cluster0.hfdhy.mongodb.net/{collectio_name}?retryWrites=true&w=majority 101 | 102 | TOKEN_SECRET = {some gibberish} 103 | 104 | EMAIL_ID={email} 105 | 106 | EMAIL_PWD={password} 107 | 108 | ``` 109 | 110 | ## 💼 Code of Conduct 111 | 112 | We want to facilitate a healthy and constructive community behavior by adopting and enforcing our code of conduct. 113 | 114 | #

🧑‍💻 CONTRIBUTION 👏

115 | 116 | - Contributions make the open source community such an amazing place to learn, inspire, and create. 117 | - Any contributions you make are greatly appreciated. 118 | - Check out our [contribution guidelines](/CONTRIBUTING.md) for more information. 119 | 120 |
121 | 122 |

Project Admin 💻

123 | 124 |

125 | 126 | 127 | 128 |

Our Amazing Contributors 👨‍👨‍👦‍👦❤️

129 | 130 | Thanks to all the contributors who worked for this project to stay alive! 😊😎 131 | 132 | 133 | 134 | 135 | 136 |
137 | 138 | --- 139 |
140 |

Take a moment to star ⭐ the project if you like it

141 |

Do checkout the other repos 💫

142 |
143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /backend/templates/resetPwdTemplate.js: -------------------------------------------------------------------------------- 1 | const resetPwdTemplate = (link) => 2 | ` 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Mocker Reset Password 12 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 117 | 118 |
28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 104 | 105 | 106 | 107 | 108 | 111 | 112 | 113 | 114 | 115 |
 
34 |
 
41 | 42 | 43 | 44 | 45 | 46 | 63 | 64 | 65 | 67 | 68 | 69 | 70 | 78 | 79 | 80 | 81 | 89 | 90 | 91 | 98 | 99 | 100 | 101 | 102 |
 
47 |

Reset Password 48 | 49 |

50 | 51 |

Hi,

52 |
53 |

54 | 55 | There was a request to change your password! 56 | 57 | If you did not make this request then please ignore this email. 58 | 59 | Otherwise, please click below to change your password: 60 | 61 |

62 |
66 |
71 | 72 | 75 | 76 | 77 |
82 |

83 |
84 | If above button is not working, use this link: 85 |
86 | ${link} 87 |

88 |
92 | 93 |

94 | Regards, 95 |

96 |

Mocker

97 |
 
103 |
 
109 | © https://mocker-gen.netlify.app/ 110 |
 
116 |
119 | 120 | 121 | 122 | `; 123 | 124 | module.exports = resetPwdTemplate; 125 | -------------------------------------------------------------------------------- /backend/templates/verificationTemplate.js: -------------------------------------------------------------------------------- 1 | const verificationEmailTemplate = (link) => 2 | ` 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Verify Email 12 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 125 | 126 |
28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 112 | 113 | 114 | 115 | 116 | 119 | 120 | 121 | 122 | 123 |
 
34 |
 
41 | 42 | 43 | 44 | 45 | 46 | 59 | 60 | 61 | 67 | 68 | 69 | 70 | 77 | 78 | 79 | 80 | 88 | 89 | 90 | 97 | 98 | 99 | 106 | 107 | 108 | 109 | 110 |
 
47 |

Verify your email 48 | 49 |

50 | 51 |

Hi,

52 |
53 |

54 | 55 | Mocker is happy to have onboard. You are just one step away from exploring mocker features. 56 | 57 |

58 |
62 |

63 |
64 | Please verify your email before login. 65 |

66 |
71 | 72 | 75 | 76 |
81 |

82 |
83 | If above button is not working, use this link: 84 |
85 | ${link} 86 |

87 |
91 |

92 |
93 | *Link expires in 48hrs 94 |
95 |

96 |
100 | 101 |

102 | Regards, 103 |

104 |

Mocker

105 |
 
111 |
 
117 | © https://mocker-gen.netlify.app/ 118 |
 
124 |
127 | 128 | 129 | 130 | `; 131 | 132 | module.exports = verificationEmailTemplate; 133 | -------------------------------------------------------------------------------- /docs/docs/models/date.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | tags: [date] 4 | --- 5 | 6 | # Date 7 | 8 | ## Module to generate dates. 9 | 10 | :::info 11 | 12 | For more **schema options** refer, [faker.js documentation](https://fakerjs.dev/). 13 | 14 | ::: 15 | 16 | ### between 17 | 18 | Generates a random date between the given boundaries. 19 | 20 | | Option | Description | 21 | | :----: | ------------------------ | 22 | | from | The early date boundary. | 23 | | to | The late date boundary. | 24 | 25 | #### Input: 26 | 27 | | from | to | 28 | | :-----------------: | :-----------------: | 29 | | 2020-01-01 00:00:00 | 2030-01-01 00:00:00 | 30 | 31 | #### output 32 | 33 | ```json 34 | 2026-05-16T02:22:53.002Z 35 | ``` 36 | 37 | ### betweens 38 | 39 | Generates a random date between the given boundaries. 40 | 41 | | Option | Description | 42 | | :-------------: | -------------------------------- | 43 | | from | The early date boundary. | 44 | | to | The late date boundary. | 45 | | number of dates | The number of dates to generate. | 46 | 47 | #### Input: 48 | 49 | | from | to | number of dates | 50 | | :-----------------: | :-----------------: | :-------------: | 51 | | 2020-01-01 00:00:00 | 2030-01-01 00:00:00 | 2 | 52 | 53 | #### output 54 | 55 | ```json 56 | [ 2023-05-02T16:00:00.000Z, 2026-09-01T08:00:00.000Z ] 57 | ``` 58 | 59 | ### birthdate 60 | 61 | Returns a random birthdate. 62 | 63 | | Option | Description | 64 | | :---------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 65 | | minimum age | The minimum age or year to generate a birthdate. | 66 | | maximum age | The maximum age or year to generate a birthdate. | 67 | | mode | The mode to generate the birthdate. Supported modes are 'age' and 'year' .
There are two modes available 'age' and 'year':
'age': The min and max options define the age of the person (e.g. 18 - 42).
'year': The min and max options define the range the birthdate may be in (e.g. 1900 - 2000). | 68 | 69 | #### Input: 70 | 71 | | minimum age | maximum age | mode | Output | 72 | | :---------: | :---------: | :----: | :----------------------: | 73 | | 18 | 65 | "age" | 2003-11-02T20:03:20.116Z | 74 | | 1900 | 2000 | "year" | 1940-08-20T08:53:07.538Z | 75 | 76 | ### future 77 | 78 | Generates a random date in the future. 79 | 80 | | Option | Description | 81 | | :----: | ------------------------------------------------- | 82 | | years | The range of years the date may be in the future. | 83 | 84 | #### Input: 85 | 86 | | years | 87 | | :---: | 88 | | 10 | 89 | 90 | #### output 91 | 92 | ```json 93 | 2030-11-23T09:38:28.710Z 94 | ``` 95 | 96 | ### month 97 | 98 | Returns a random name of a month. 99 | 100 | | Option | Description | 101 | | :----: | ---------------------------------- | 102 | | abbr | Whether to return an abbreviation. | 103 | 104 | #### Input: 105 | 106 | | abbr | Output | 107 | | :------------: | :-----: | 108 | | "abbreviation" | Feb | 109 | | "long form" | October | 110 | 111 | ### past 112 | 113 | Generates a random date in the past. 114 | 115 | | Option | Description | 116 | | :--------: | ----------------------------------------------- | 117 | | past years | The range of years the date may be in the past. | 118 | 119 | #### Input: 120 | 121 | | past years | 122 | | :--------: | 123 | | 10 | 124 | 125 | #### output 126 | 127 | ```json 128 | 2017-10-25T21:34:19.488Z 129 | ``` 130 | 131 | ### recent 132 | 133 | Generates a random date in the recent past. 134 | 135 | | Option | Description | 136 | | :-------------: | --------------------------------------------------------------------------------- | 137 | | days | The range of days the date may be in the past. | 138 | | reference point | The date to use as reference point for the newly generated date. Defaults to now. | 139 | 140 | #### Input: 141 | 142 | | days | reference point | 143 | | :--: | :-----------------: | 144 | | 10 | 2020-01-01 00:00:00 | 145 | 146 | #### output 147 | 148 | ```json 149 | 2019-12-27T18:11:19.117Z 150 | ``` 151 | 152 | ### soon 153 | 154 | Generates a random date in the near future. 155 | 156 | | Option | Description | 157 | | :-------------: | --------------------------------------------------------------------------------- | 158 | | days | The range of days the date may be in the future. | 159 | | reference point | The date to use as reference point for the newly generated date. Defaults to now. | 160 | 161 | #### Input: 162 | 163 | | days | reference point | 164 | | :--: | :-----------------: | 165 | | 10 | 2020-01-01 00:00:00 | 166 | 167 | #### output 168 | 169 | ```json 170 | 2020-01-01T02:40:44.990Z 171 | ``` 172 | 173 | ### weekday 174 | 175 | Returns a random day of the week. 176 | 177 | | Option | Description | 178 | | :----: | ---------------------------------- | 179 | | abbr | Whether to return an abbreviation. | 180 | 181 | #### Input: 182 | 183 | | abbr | output | 184 | | :----------: | :------: | 185 | | long form | Thursday | 186 | | abbreviation | Thu | 187 | -------------------------------------------------------------------------------- /backend/routes/user/user.js: -------------------------------------------------------------------------------- 1 | const router = require("express").Router(); 2 | // const Joi = require("joi"); 3 | const Resource = require("../../models/Resource"); 4 | const { v4: uuidv4 } = require("uuid"); 5 | // const { trackAPIRequest } = require("../../utils/trackAPIRequests"); 6 | 7 | router.use((req, res, next) => { 8 | const endpoint = req.originalUrl; 9 | Resource.findOneAndUpdate( 10 | { _id: req.params.id }, 11 | { $push: { analytics: { date: new Date() } } }, 12 | { upsert: true, new: true } 13 | ).exec((err, endpointRequest) => { 14 | if (err) { 15 | console.error("Error updating request history:", err); 16 | } else { 17 | console.log( 18 | `Request history for ${endpointRequest}.${endpoint}:`, 19 | endpointRequest.analytics 20 | ); 21 | } 22 | }); 23 | next(); 24 | }); 25 | 26 | router.get("/:id", async (req, res) => { 27 | try { 28 | const resource = await Resource.findById(req.params.id); 29 | if (resource === null) { 30 | res.status(200).send({ 31 | status: "400", 32 | message: 'Seems like resourceId doesn"t exist !', 33 | }); 34 | return; 35 | } 36 | res.status(200).send({ status: "200", message: resource.data }); 37 | } catch (err) { 38 | res.status(200).send({ status: "500", message: err }); 39 | } 40 | }); 41 | 42 | router.get("/:id/:objectId", async (req, res) => { 43 | try { 44 | const resource = await Resource.findById(req.params.id); 45 | if (resource === null) { 46 | res.status(200).send({ 47 | status: "400", 48 | message: 'Seems like resourceId doesn"t exist !', 49 | }); 50 | return; 51 | } 52 | const response = resource.data.filter( 53 | (item) => item.id === req.params.objectId 54 | ); 55 | if (response.length === 0) { 56 | res.status(200).send({ 57 | status: "400", 58 | message: 'Seems like objectId doesn"t exist !', 59 | }); 60 | return; 61 | } 62 | res.status(200).send({ status: "200", message: response }); 63 | } catch (err) { 64 | res.status(200).send({ status: "500", message: err }); 65 | } 66 | }); 67 | 68 | router.post("/:id", async (req, res) => { 69 | try { 70 | if (typeof req.body !== "object") { 71 | res.status(200).send({ 72 | status: "400", 73 | message: "Wrong format", 74 | }); 75 | return; 76 | } 77 | 78 | const resource = await Resource.findById(req.params.id); 79 | if (resource === null) { 80 | res.status(200).send({ 81 | status: "400", 82 | message: 'Seems like resourceId doesn"t exist !', 83 | }); 84 | return; 85 | } 86 | const requiredLabel = resource.schema.map((item) => item.label); 87 | 88 | const reqLabel = Object.keys(req.body); 89 | 90 | if ( 91 | requiredLabel 92 | .map((label) => (reqLabel.includes(label) ? true : false)) 93 | .includes(false) 94 | ) { 95 | res.status(200).send({ 96 | status: "400", 97 | message: "Some fields appear to be mismatched (check the schema)", 98 | }); 99 | return; 100 | } 101 | 102 | if (reqLabel.length !== requiredLabel.length) { 103 | res.status(200).send({ 104 | status: "400", 105 | message: "Some fields seems to be extra/missing", 106 | }); 107 | } 108 | 109 | const newData = { ...req.body, id: uuidv4() }; 110 | 111 | const body = { 112 | name: resource.name, 113 | schema: resource.schema, 114 | data: [...resource.data, newData], 115 | number: resource.number + 1, 116 | userId: resource.userId, 117 | projectId: resource.projectId, 118 | }; 119 | 120 | resource.set(body); 121 | await resource.save(); 122 | res.status(200).send({ status: "200", message: "Successfully Added !" }); 123 | } catch (err) { 124 | res.status(200).send({ status: "500", message: err }); 125 | } 126 | }); 127 | 128 | router.put("/:id/:objectId", async (req, res) => { 129 | try { 130 | if (typeof req.body !== "object") { 131 | res.status(200).send({ 132 | status: "400", 133 | message: "Wrong format", 134 | }); 135 | return; 136 | } 137 | 138 | const resource = await Resource.findById(req.params.id); 139 | if (resource === null) { 140 | res.status(200).send({ 141 | status: "400", 142 | message: 'Seems like resourceId doesn"t exist !', 143 | }); 144 | return; 145 | } 146 | const requiredLabel = resource.schema.map((item) => item.label); 147 | 148 | const reqLabel = Object.keys(req.body); 149 | 150 | if ( 151 | requiredLabel 152 | .map((label) => (reqLabel.includes(label) ? true : false)) 153 | .includes(false) 154 | ) { 155 | res.status(200).send({ 156 | status: "400", 157 | message: "Some fields appear to be mismatched (check the schema)", 158 | }); 159 | return; 160 | } 161 | 162 | if (reqLabel.length !== requiredLabel.length) { 163 | res.status(200).send({ 164 | status: "400", 165 | message: "Some fields seems to be extra/missing", 166 | }); 167 | } 168 | 169 | const response = resource.data.map((item) => { 170 | if (item.id === req.params.objectId) { 171 | return { ...req.body, id: uuidv4() }; 172 | } 173 | return item; 174 | }); 175 | 176 | if (response.length === 0) { 177 | res.status(200).send({ 178 | status: "400", 179 | message: 'Seems like objectId doesn"t exist !', 180 | }); 181 | return; 182 | } 183 | 184 | const body = { 185 | name: resource.name, 186 | schema: resource.schema, 187 | data: response, 188 | number: resource.number, 189 | userId: resource.userId, 190 | projectId: resource.projectId, 191 | }; 192 | 193 | resource.set(body); 194 | await resource.save(); 195 | res.status(200).send({ status: "200", message: "Successfully Edited !" }); 196 | // res.status(200).send({ status: "200", message: body }); 197 | } catch (err) { 198 | res.status(200).send({ status: "500", message: err }); 199 | } 200 | }); 201 | 202 | router.delete("/:id/:objectId", async (req, res) => { 203 | try { 204 | const resource = await Resource.findById(req.params.id); 205 | if (resource === null) { 206 | res.status(200).send({ 207 | status: "400", 208 | message: 'Seems like resourceId doesn"t exist !', 209 | }); 210 | return; 211 | } 212 | const required = resource.data.filter( 213 | (item) => item.id !== req.params.objectId 214 | ); 215 | 216 | if (required.length === resource.data.length) { 217 | res.status(200).send({ 218 | status: "400", 219 | message: 'Seems like objectId doesn"t exist !', 220 | }); 221 | return; 222 | } 223 | 224 | const body = { 225 | name: resource.name, 226 | schema: resource.schema, 227 | data: required, 228 | number: resource.number, 229 | userId: resource.userId, 230 | projectId: resource.projectId, 231 | }; 232 | resource.set(body); 233 | await resource.save(); 234 | 235 | // res.status(200).send({ status: "200", message: body }); 236 | res.status(200).send({ status: "200", message: "Successfully Deleted" }); 237 | } catch (err) { 238 | res.status(200).send({ status: "500", message: err }); 239 | } 240 | }); 241 | 242 | module.exports = router; 243 | --------------------------------------------------------------------------------