├── 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 | {
18 | delResource(result);
19 | setOpen(false);
20 | }}
21 | >
22 | Yes delete please !
23 |
24 | setOpen(false)}
28 | sx={{ ml: 2 }}
29 | >
30 | Cancel
31 |
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 |
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 |
21 |
22 | 404
23 |
24 |
25 | The page you’re looking for doesn’t exist.
26 |
27 | navigate("/")}
31 | >
32 | Go Home
33 |
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 |
15 | {value === index && (
16 |
17 | {children}
18 |
19 | )}
20 |
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 | setOpen(false)}
48 | sx={{
49 | p: 0.5,
50 | minWidth: 0,
51 | borderRadius: "50ex",
52 | fontSize: "1rem",
53 | }}
54 | >
55 |
56 |
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 | [](http://makeapullrequest.com)
20 | [](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 | {
81 | isMultipleDelete ? delSelected() : deleteProject(project._id);
82 | setFormData("");
83 | setDisabled(true);
84 | }}
85 | >
86 | Confirm Delete
87 |
88 | {
93 | setFormData("");
94 | setDisabled(true);
95 | setConfirmDeleteModal(false);
96 | }}
97 | >
98 | Cancel
99 |
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 |
34 | {value === index && (
35 | {children}
36 | )}
37 |
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 |
55 | Logout
56 |
57 |
58 | );
59 |
60 | const container =
61 | window !== undefined ? () => window().document.body : undefined;
62 |
63 | return (
64 |
65 | {/*
66 | */}
71 |
72 |
73 |
77 | Mocker
78 |
79 |
86 |
87 |
88 |
89 |
90 |
91 | Logout
92 |
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 | 
8 |
9 | 
10 | 
11 | 
12 | 
13 |
14 | 
15 | 
16 | 
17 | 
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 | [](http://makeapullrequest.com)
48 | [](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 | [](https://app.netlify.com/sites/mocker-gen/deploys)
69 |
70 | #### Backend
71 |
72 | 
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 |
89 | Logout
90 |
91 | );
92 | }
93 | return (
94 |
95 |
96 | Signup
97 |
98 |
106 |
119 |
126 |
132 | {loading ? : "Signup"}
133 |
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 |
96 | Logout
97 |
98 | );
99 | }
100 | return (
101 |
102 |
103 | Login
104 |
105 |
113 |
126 |
133 |
139 | {loading ? : "Login"}
140 |
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 | Option
75 | Description
76 | Default
77 |
78 |
79 |
80 |
81 | min
82 | Upper bound for milliseconds since base date. When not provided or larger than 8640000000000000, 2100-01-01 is considered as maximum generated date.
83 | 631152000000
84 |
85 |
86 | max
87 | Lower bound for milliseconds since base date. When not provided or smaller than -8640000000000000, 1990-01-01 is considered as minimum generated date.
88 | 4102444800000
89 |
90 |
91 |
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 | 
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 
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 | [](http://makeapullrequest.com)
45 | [](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 | [](https://app.netlify.com/sites/mocker-gen/deploys)
69 |
70 | #### Backend
71 |
72 | 
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 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
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 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Reset Password
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | If above button is not working, use this link:
85 |
86 | ${link}
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | Regards,
95 |
96 | Mocker
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | © https://mocker-gen.netlify.app/
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
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 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
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 |
59 |
60 |
61 |
62 |
63 |
64 | Please verify your email before login.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Verify your email
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | If above button is not working, use this link:
84 |
85 | ${link}
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 | *Link expires in 48hrs
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | Regards,
103 |
104 | Mocker
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | © https://mocker-gen.netlify.app/
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
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 |
--------------------------------------------------------------------------------