├── .env.example ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── prisma └── schema.prisma ├── src ├── api │ ├── configs │ │ ├── controller.ts │ │ ├── route.ts │ │ └── service.ts │ └── index.ts ├── config.ts ├── index.ts ├── middlewares │ └── logger.ts └── utils │ └── helper.util.ts └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | DATABASE_URL="mysql://username:password@host:port/database" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Cloud configuration System 2 | 3 | Cloud configuration system written in MySQL, ExpressJS & NodeJS made for other developers. 4 | 5 | ## 🔧 Installation 6 | 7 | Install packages with npm. 8 | 9 | ```bash 10 | > cd cloud-configs-master 11 | > npm install 12 | ``` 13 | 14 | Upload tables to database. 15 | 16 | ```bash 17 | > npm run db:push 18 | ``` 19 | 20 | ## 💻 API Reference 21 | 22 | #### Get all items 23 | 24 | ``` 25 | GET /api/get 26 | ``` 27 | 28 | | Parameter | Type | Description | 29 | | :-------- | :------- | :-------------------------- | 30 | | `user` | `string` | **Required**. Your username | 31 | 32 | #### Get item 33 | 34 | ``` 35 | GET /api/get/${id} 36 | ``` 37 | 38 | | Parameter | Type | Description | 39 | | :-------- | :------- | :-------------------------------- | 40 | | `id` | `string` | **Required**. Id of item to fetch | 41 | 42 | ``` 43 | POST /api/create 44 | ``` 45 | 46 | | Parameter | Type | Description | 47 | | :-------- | :------- | :---------------------------------- | 48 | | `user` | `string` | **Required**. Your username | 49 | | `name` | `string` | **Required**. Your config name | 50 | | `content` | `string` | **Required**. Your config's content | 51 | 52 | #### Get item 53 | 54 | ``` 55 | PUT /api/update/ 56 | ``` 57 | 58 | | Parameter | Type | Description | 59 | | :-------- | :------- | :--------------------------------- | 60 | | `id` | `string` | **Required**. Id of item to update | 61 | | `content` | `string` | **Required**. Content to update to | 62 | 63 | ``` 64 | DELETE /api/delete/ 65 | ``` 66 | 67 | | Parameter | Type | Description | 68 | | :-------- | :------- | :--------------------------------- | 69 | | `id` | `string` | **Required**. Id of item to delete | 70 | 71 | ## 🥇 Credits 72 | 73 | - ExpressJS file structure - https://github.com/geshan/expressjs-structure 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expressjs-structure", 3 | "version": "0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "db:push": "npx prisma db push", 8 | "dev": "nodemon src/index.ts", 9 | "prod:build": "npx tsc", 10 | "prod:run": "node dist/index.js" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/Jasmisek/cloud-configs/issues" 17 | }, 18 | "dependencies": { 19 | "@prisma/client": "^4.5.0", 20 | "dotenv": "^16.0.3", 21 | "express": "^4.17.1", 22 | "express-validator": "^6.14.2", 23 | "fs": "^0.0.1-security", 24 | "i": "^0.3.7", 25 | "morgan": "^1.10.0", 26 | "mysql2": "^2.3.3", 27 | "npm": "^8.19.3", 28 | "prisma": "^4.5.0", 29 | "sequelize": "^6.25.3", 30 | "source-map-loader": "^4.0.1", 31 | "sqlite3": "^5.1.2", 32 | "ts-loader": "^9.4.1", 33 | "typescript": "^4.8.4", 34 | "uuid": "^9.0.0" 35 | }, 36 | "devDependencies": { 37 | "@types/express": "^4.17.14", 38 | "@types/jsonwebtoken": "^8.5.9", 39 | "@types/morgan": "^1.9.4", 40 | "@types/uuid": "^8.3.4" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | generator client { 2 | provider = "prisma-client-js" 3 | } 4 | 5 | datasource db { 6 | provider = "mysql" 7 | url = env("DATABASE_URL") 8 | } 9 | 10 | model configs { 11 | id String @id @default(uuid()) 12 | name String 13 | user String 14 | content String 15 | } -------------------------------------------------------------------------------- /src/api/configs/controller.ts: -------------------------------------------------------------------------------- 1 | /*import { config } from "../services/config-service" 2 | 3 | async function getMultiple(req, res, next) { 4 | try { 5 | res.status(200).send(await config.getMultiple(req.query)) 6 | } catch (err) { 7 | console.error(`Error while getting configs`, err.message) 8 | next(err) 9 | } 10 | } 11 | 12 | async function getSingle(req, res, next) { 13 | try { 14 | res.status(200).send(await config.getSingle(req.params.id)) 15 | } catch (err) { 16 | console.error(`Error while getting configs`, err.message) 17 | next(err) 18 | } 19 | } 20 | 21 | async function create(req, res, next) { 22 | try { 23 | res.json(await config.create(req.body)) 24 | } catch (err) { 25 | console.error(`Error while creating config`, err.message) 26 | next(err) 27 | } 28 | } 29 | 30 | async function update(req, res, next) { 31 | try { 32 | res.json(await config.update(req.params.id, req.body)) 33 | } catch (err) { 34 | console.error(`Error while updating config`, err.message) 35 | next(err) 36 | } 37 | } 38 | 39 | async function remove(req, res, next) { 40 | try { 41 | res.json(await config.remove(req.params.id)) 42 | } catch (err) { 43 | console.error(`Error while deleting config`, err.message) 44 | next(err) 45 | } 46 | } 47 | 48 | module.exports = { 49 | getMultiple, 50 | getSingle, 51 | create, 52 | update, 53 | remove, 54 | } 55 | */ 56 | 57 | import service from "./service" 58 | import { Request, Response } from "express" 59 | 60 | export default { 61 | getMultiple: async (req: Request, res: Response) => { 62 | const config = await service.getMultiple(req.body) 63 | res.json({ response: config }) 64 | }, 65 | 66 | getSingle: async (req: Request, res: Response) => { 67 | const id: string = req.params.id 68 | 69 | const config = await service.getSingle(id) 70 | res.json({ response: config }) 71 | }, 72 | 73 | create: async (req: Request, res: Response) => { 74 | const config = await service.create(req.body) 75 | res.json({ response: config }) 76 | }, 77 | 78 | update: async (req: Request, res: Response) => { 79 | const config = await service.update(req.body) 80 | res.json({ response: config }) 81 | }, 82 | 83 | delete: async (req: Request, res: Response) => { 84 | const config = await service.delete(req.body) 85 | res.json({ response: config }) 86 | }, 87 | } 88 | -------------------------------------------------------------------------------- /src/api/configs/route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express" 2 | import controller from "./controller" 3 | 4 | /** 5 | * Config Routes 6 | */ 7 | const router = Router() 8 | 9 | router.get("/get", controller.getMultiple) 10 | router.get("/get/:id", controller.getSingle) 11 | router.post("/create", controller.create) 12 | router.put("/update/", controller.update) 13 | router.delete("/delete/", controller.delete) 14 | 15 | export default router 16 | -------------------------------------------------------------------------------- /src/api/configs/service.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client" 2 | import { v4 as uuidv4 } from "uuid" 3 | import { emptyOrRows } from "../../utils/helper.util" 4 | const prisma = new PrismaClient() 5 | 6 | interface config { 7 | id: string 8 | user: string 9 | name: string 10 | content: string 11 | } 12 | 13 | export default { 14 | /* 15 | Get config logic. 16 | */ 17 | getMultiple: async ({ user }: config) => { 18 | const config = prisma.configs.findMany({ 19 | where: { 20 | user: user, 21 | }, 22 | }) 23 | 24 | return emptyOrRows(config) 25 | }, 26 | 27 | getSingle: async (id: any) => { 28 | const config = prisma.configs.findUnique({ 29 | where: { 30 | id: id, 31 | }, 32 | }) 33 | return config 34 | }, 35 | 36 | create: async ({ user, name, content }: config) => { 37 | const config = await prisma.configs.create({ 38 | data: { 39 | id: uuidv4(), 40 | user: user, 41 | name: name, 42 | content: content, 43 | }, 44 | }) 45 | return config 46 | }, 47 | 48 | update: async ({ id, content }: config) => { 49 | const config = await prisma.configs.update({ 50 | where: { 51 | id: id, 52 | }, 53 | data: { 54 | content: content, 55 | }, 56 | }) 57 | return config 58 | }, 59 | 60 | delete: async ({ id }: config) => { 61 | await prisma.configs.delete({ 62 | where: { 63 | id: id, 64 | }, 65 | }) 66 | return "Succesfully deleted config!" 67 | }, 68 | } 69 | -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | export { default as config } from "./configs/route" 2 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv" 2 | 3 | const envObj = dotenv.config().parsed 4 | if (!envObj) process.exit(1) 5 | 6 | const config = { 7 | env: envObj, 8 | } 9 | 10 | export default config 11 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from "express" 2 | import bodyParser from "body-parser" 3 | import { config } from "./api" 4 | import { logger } from "./middlewares/logger" 5 | 6 | const app = express() 7 | 8 | const port = 3000 9 | 10 | app.use(bodyParser.json()) 11 | app.use( 12 | bodyParser.urlencoded({ 13 | extended: true, 14 | }) 15 | ) 16 | 17 | app.use("/api", logger, config) 18 | 19 | app.listen(port, "0.0.0.0", () => { 20 | console.log(`Example app listening at http://localhost:${port}`) 21 | }) 22 | -------------------------------------------------------------------------------- /src/middlewares/logger.ts: -------------------------------------------------------------------------------- 1 | import morgan from "morgan" 2 | 3 | const logger = morgan(function (tokens, req, res) { 4 | return [ 5 | tokens.method(req, res), 6 | tokens.url(req, res), 7 | tokens.status(req, res), 8 | tokens.res(req, res, 'content-length'), '-', 9 | tokens['response-time'](req, res), 'ms' 10 | ].join(' ') 11 | }) 12 | 13 | export { logger } -------------------------------------------------------------------------------- /src/utils/helper.util.ts: -------------------------------------------------------------------------------- 1 | function emptyOrRows(rows: any) { 2 | if (!rows) { 3 | return [] 4 | } 5 | return rows 6 | } 7 | 8 | export { emptyOrRows } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Language and Environment */ 4 | "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 5 | 6 | /* Modules */ 7 | "module": "commonjs" /* Specify what module code is generated. */, 8 | "rootDir": "./src" /* Specify the root folder within your source files. */, 9 | "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, 10 | "resolveJsonModule": true /* Enable importing .json files */, 11 | 12 | /* JavaScript Support */ 13 | "allowJs": true /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */, 14 | 15 | /* Emit */ 16 | "sourceMap": true /* Create source map files for emitted JavaScript files. */, 17 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 18 | "removeComments": true /* Disable emitting comments. */, 19 | "noEmitOnError": true /* Disable emitting files if any type checking errors are reported. */, 20 | 21 | /* Interop Constraints */ 22 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 23 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 24 | 25 | /* Type Checking */ 26 | "strict": true /* Enable all strict type-checking options. */, 27 | "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied `any` type.. */, 28 | 29 | /* Completeness */ 30 | "skipLibCheck": true, /* Skip type checking all .d.ts files. */ 31 | "lib": ["esnext"] 32 | } 33 | } 34 | --------------------------------------------------------------------------------