Skip to content

Commit

Permalink
Merge pull request #1 from chtgupta/feature/folders
Browse files Browse the repository at this point in the history
Feature/folders
  • Loading branch information
chtgupta authored Apr 24, 2024
2 parents b69c922 + 626c2c1 commit 1c8cd88
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 15 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "",
"main": "main.ts",
"scripts": {
"start": "tsc && node ./dist/index.js"
"start": "tsc && node ./dist/index.js",
"run": "node ./dist/index.js"
},
"author": "Chahat Gupta",
"license": "ISC",
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Mock API Manager
# MockModel API Manager

Welcome to my hobby project - the Mock API Manager! This TypeScript-based tool simplifies the creation and management of mock APIs for your development and testing needs.
Welcome to my hobby project - the MockModel API Manager! This TypeScript-based tool simplifies the creation and management of mock APIs for your development and testing needs.

<img width="1440" alt="Screenshot 2023-09-16 at 11 13 59 PM" src="https://github.com/chtgupta/mock_api_backend/assets/22120812/8a5cbab6-bb82-48d5-b1dc-4037367fac94">

Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default class Constants {
static rootPath: string = 'root'
}
14 changes: 14 additions & 0 deletions src/helper/mock.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {MockModel} from "../models/mock.model";

export default class MockHelper {

static toJson(model: MockModel) {
return {
id: model._id,
parentId: model.parentId,
name: model.name,
response: model.response
}
}

}
17 changes: 17 additions & 0 deletions src/helper/mock_folder.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {MockFolder, MockFolderModel} from "../models/mock_folder.model";
import {MockModel} from "../models/mock.model";
import MockHelper from "./mock.helper";

export default class MockFolderHelper {

static toJson(model: MockFolderModel, folders: MockFolderModel[] | null = null, files: MockModel[] | null = null) : any {
return {
id: model._id,
parentId: model.parentId,
name: model.name,
folders: folders?.map((e) => MockFolderHelper.toJson(e)),
files: files?.map((e) => MockHelper.toJson(e))
}
}

}
8 changes: 6 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ function configureServer(): void {
app.use(express.urlencoded({extended: true}))
app.use(express.json())

const routes = require('./routes')
app.use('/', routes)
const mockRoutes = require('./routes/mock.routes')
const mockFolderRoutes = require('./routes/mock_folder.routes')
const allRoutes = require('./routes/all.routes')

app.use('/folder', mockFolderRoutes) // do not move this below '/' else it clashes with /:id
app.use('/', mockRoutes)

app.listen(process.env.PORT, (): void => {
console.log(`Server running on port ${process.env.PORT}..`)
Expand Down
15 changes: 12 additions & 3 deletions src/models/mock.ts → src/models/mock.model.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { Schema, Model, model } from 'mongoose'
import Constants from "../common/constants";

export type MockModel = {
name: string,
_id: string
parentId: string | null
name: string
response: string
};
}

const MockSchema: Schema<MockModel> = new Schema<MockModel>({
_id: Schema.Types.ObjectId,
parentId: {
type: String,
required: false,
default: Constants.rootPath
},
name: {
type: String,
required: true
Expand All @@ -14,6 +23,6 @@ const MockSchema: Schema<MockModel> = new Schema<MockModel>({
type: String,
required: true
}
});
})

export const Mock: Model<MockModel> = model('Mock', MockSchema)
23 changes: 23 additions & 0 deletions src/models/mock_folder.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Schema, Model, model } from 'mongoose'
import Constants from "../common/constants";

export type MockFolderModel = {
_id: string
parentId: string | null
name: string
}

const MockFolderSchema: Schema<MockFolderModel> = new Schema<MockFolderModel>({
_id: Schema.Types.ObjectId,
parentId: {
type: String,
required: false,
default: Constants.rootPath
},
name: {
type: String,
required: true
}
})

export const MockFolder: Model<MockFolderModel> = model('MockFolder', MockFolderSchema)
18 changes: 11 additions & 7 deletions src/routes.ts → src/routes/mock.routes.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import express, { Request, Response } from 'express'
import { Mock, MockModel } from './models/mock'
import { ApiResponse } from './models/api_response'
import { Mock, MockModel } from '../models/mock.model'
import { ApiResponse } from '../common/api_response'
import mongoose from 'mongoose'
import MockHelper from "../helper/mock.helper";
import { Types } from "mongoose";

const router = express.Router()

router.get('/', async (req: Request, res: Response): Promise<void> => {
try {
const mocks: MockModel[] = await Mock.find()
const response: ApiResponse = ApiResponse.success(mocks)
const response: ApiResponse = ApiResponse.success(mocks.map((e) => MockHelper.toJson(e)))
res.status(200).json(response)
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
Expand All @@ -20,14 +22,14 @@ router.get('/:id', async (req: Request, res: Response): Promise<void> => {
try {
const mock: MockModel | null = await Mock.findById(req.params.id)
if (mock != null) {
const response: ApiResponse = ApiResponse.success(mock)
const response: ApiResponse = ApiResponse.success(MockHelper.toJson(mock))
res.status(200).json(response)
} else {
const response: ApiResponse = ApiResponse.error(`No document found with id ${req.params.id}`)
res.status(404).json(response)
}
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error('An error occured')
const response: ApiResponse = ApiResponse.error('An error occurred')
res.status(500).json(response)
}
})
Expand All @@ -42,20 +44,22 @@ router.get('/mock/:id', async (req: Request, res: Response): Promise<void> => {
res.status(404).json(response)
}
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error('An error occured')
const response: ApiResponse = ApiResponse.error('An error occurred')
res.status(500).json(response)
}
})

router.post('/', async (req: Request, res: Response): Promise<void> => {

const data = new Mock({
_id: new Types.ObjectId(),
parentId: req.body.parentId,
name: req.body.name,
response: req.body.response
})
try {
const mock: MockModel = await data.save()
const response: ApiResponse = ApiResponse.success(mock, 'Document created')
const response: ApiResponse = ApiResponse.success(MockHelper.toJson(mock), 'Document created')
res.status(201).json(response)
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
Expand Down
119 changes: 119 additions & 0 deletions src/routes/mock_folder.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import express, { Request, Response } from 'express'
import { MockFolder, MockFolderModel } from '../models/mock_folder.model'
import { ApiResponse } from '../common/api_response'
import mongoose, {Types} from 'mongoose'
import {Mock, MockModel} from "../models/mock.model";
import MockFolderHelper from "../helper/mock_folder.helper";
import Constants from "../common/constants";

const router = express.Router()

router.get('/', async (req: Request, res: Response): Promise<void> => {
try {
const root: MockFolderModel = {
_id: Constants.rootPath,
parentId: null,
name: 'Root'
}
const mockFolders: MockFolderModel[] = await MockFolder.find({ parentId: Constants.rootPath })
const mocks: MockModel[] = await Mock.find({ parentId: Constants.rootPath })
const response: ApiResponse = ApiResponse.success(MockFolderHelper.toJson(root, mockFolders, mocks))
res.status(200).json(response)
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
res.status(500).json(response)
}
})

router.get('/:id', async (req: Request, res: Response): Promise<void> => {
try {
const mockFolder: MockFolderModel | null = await MockFolder.findById(req.params.id)
if (mockFolder != null) {
const subFolders: MockFolderModel[] = await MockFolder.find({ parentId: req.params.id })
const mocks: MockModel[] = await Mock.find({ parentId: req.params.id })
const response: ApiResponse = ApiResponse.success(MockFolderHelper.toJson(mockFolder, subFolders, mocks))
res.status(200).json(response)
} else {
const response: ApiResponse = ApiResponse.error(`No document found with id ${req.params.id}`)
res.status(404).json(response)
}
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error('An error occurred')
res.status(500).json(response)
}
})

router.post('/', async (req: Request, res: Response): Promise<void> => {

const data = new MockFolder({
_id: new Types.ObjectId(),
parentId: req.body.parentId,
name: req.body.name
})
try {
const mockFolder: MockFolderModel = await data.save()
const response: ApiResponse = ApiResponse.success(MockFolderHelper.toJson(mockFolder), 'Document created')
res.status(201).json(response)
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
res.status(401).json(response)
}
})

router.put('/:id', async (req: Request, res: Response): Promise<void> => {
try {

const newName: string | null = req.body.name

const query: mongoose.UpdateQuery<MockFolderModel> = { name: newName }

MockFolder.findByIdAndUpdate(req.params.id, query, (updateError: mongoose.CallbackError) => {
if (updateError) {
const response: ApiResponse = ApiResponse.error((updateError as Error).message)
res.status(500).json(response)
} else {
const response: ApiResponse = ApiResponse.success(null, 'Document updated successfully')
res.status(200).json(response)
}
})
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
res.status(500).json(response)
}
})

router.delete('/:id', async (req: Request, res: Response): Promise<void> => {

try {
await deleteChildren(req.params.id)
const response: ApiResponse = ApiResponse.success(null, `Document with id ${req.params.id} removed`)
res.status(200).json(response)
} catch (error: unknown) {
const response: ApiResponse = ApiResponse.error((error as Error).message)
res.status(500).json(response)
}

})

async function deleteChildren(folderId: string): Promise<void> {

// deleting folder
await MockFolder.findByIdAndDelete(folderId)

// deleting child files
await Mock.deleteMany({ parentId: folderId })

// getting child folders
const childFolders: MockFolderModel[] = await MockFolder.find({ parentId: folderId })

// deleting child folders
await MockFolder.deleteMany({ parentId: folderId })

// recursively deleting children folder contents
for (const childFolder of childFolders) {
await deleteChildren(childFolder._id);
}

}

module.exports = router

0 comments on commit 1c8cd88

Please sign in to comment.