Last active
February 6, 2023 18:29
-
-
Save lxchurbakov/4bc8977f16ced736c24618372709016d to your computer and use it in GitHub Desktop.
starters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// tsconfig | |
{ | |
"compilerOptions": { | |
"esModuleInterop": true, | |
"allowSyntheticDefaultImports": true, | |
"baseUrl": "./src", | |
"outDir": "./dist", | |
"sourceMap": true, | |
"declaration": false, | |
"downlevelIteration": true, | |
"experimentalDecorators": true, | |
"importHelpers": true, | |
"target": "es5", | |
"typeRoots": [ | |
"node_modules/@types", | |
"src/types" | |
], | |
"lib": [ | |
"es2018" | |
], | |
"paths": { | |
"/src/*": [ | |
"./*" | |
], | |
} | |
}, | |
"include": [ | |
"./**/*.ts", | |
"./**/*.tsx", | |
] | |
} | |
// package.json | |
{ | |
"scripts": { | |
"dev": "npx ts-node src/index.ts" | |
}, | |
"devDependencies": { | |
"ts-node": "^10.9.1", | |
"tslib": "^2.4.1" | |
}, | |
"dependencies": { | |
"express": "^4.18.2" | |
} | |
} | |
// index.ts | |
import express from 'express'; | |
const app = express(); | |
app.use((req, res, next) => { | |
res.setHeader('Access-Control-Allow-Origin', '*'); | |
res.setHeader('Access-Control-Allow-Headers', 'origin, content-type, accept, authorization'); | |
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, OPTIONS, DELETE'); | |
res.setHeader('Access-Control-Allow-Credentials', 'true'); | |
if (req.method === 'OPTIONS') { | |
res.sendStatus(200); | |
} else { | |
next(); | |
} | |
}); | |
app.use(express.json()); | |
// Routes go here | |
app.get('/', (req, res) => { | |
res.send('Hello World!'); | |
}); | |
// Error handling | |
app.use((err, req, res, next) => { | |
if (!!err.statusCode) { | |
res.status(err.statusCode).json(err.body || null); | |
} else { | |
console.error(err.toString()); | |
res.status(500).json('server_error'); | |
} | |
}); | |
// Start server | |
app.listen(3000, () => { | |
console.log('Server started on port 3000'); | |
}); | |
// utils.ts | |
export const route = (f) => (req, res, next) => { | |
try { | |
Promise.resolve(f(req, res)).then((d) => res.json(d)).catch((err) => next(err)); | |
} catch (e) { | |
next(e); | |
} | |
}; | |
export class HttpError extends Error { | |
constructor(public statusCode: number, public body: string, ...args: any[]) { | |
super(...args); | |
} | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// tsconfig.json | |
{ | |
"compilerOptions": { | |
"allowSyntheticDefaultImports": true, | |
"baseUrl": "./src", | |
"outDir": "./dist", | |
"sourceMap": true, | |
"declaration": false, | |
"downlevelIteration": true, | |
"experimentalDecorators": true, | |
"module": "esnext", | |
"moduleResolution": "node", | |
"importHelpers": true, | |
"target": "es2015", | |
"typeRoots": [ | |
"node_modules/@types", | |
"src/types" | |
], | |
"lib": [ | |
"es2018", | |
"dom" | |
], | |
"jsx": "react", | |
"paths": { | |
"/src/*": [ | |
"./*" | |
], | |
} | |
}, | |
"include": [ | |
"./**/*.ts", | |
"./**/*.tsx", | |
] | |
} | |
// package.json | |
"scripts": { | |
"build": "npx parcel build --public-url ./ src/index.html", | |
"dev": "npx parcel serve src/index.html" | |
}, | |
"dependencies": { | |
"parcel": "^2.8.0", | |
"react": "^18.2.0", | |
"react-dom": "^18.2.0", | |
"react-router-dom": "^6.4.3" | |
}, | |
"devDependencies": { | |
"@types/react": "^18.0.25", | |
"@types/react-dom": "^18.0.9" | |
} | |
// index.ts | |
import React from 'react'; | |
import ReactDOM from 'react-dom'; | |
import { BrowserRouter, Routes, Route } from 'react-router-dom'; | |
import SomePage from './page'; | |
const app = document.getElementById('app'); | |
ReactDOM.render(( | |
<BrowserRouter> | |
<Routes> | |
<Route path="/" element={<SomePage />} /> | |
</Routes> | |
</BrowserRouter> | |
), app); | |
// index.html | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700;900&display=swap" rel="stylesheet"> | |
<style>body { margin: 0; padding: 0 } </style> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
</head> | |
<body> | |
<div id="app"></div> | |
<script type="module" src="index.tsx"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// mongo | |
const { MongoClient, ObjectId } = require('mongodb'); | |
const URI = 'mongodb://root:example@localhost:27017/?maxPoolSize=20&w=majority'; | |
const client = new MongoClient(URI); | |
const database = client.db('learning'); | |
export { ObjectId }; | |
export const Knowledge = database.collection('knowledge'); | |
client.connect().catch((error) => { | |
console.error(error); | |
process.exit(1); | |
}); | |
// router | |
const _ = require('lodash'); | |
const express = require('express'); | |
const { route, HttpError } = require('../utils'); | |
const { Knowledge, ObjectId } = require('../mongo'); | |
const router = express.Router({ mergeParams: true }); | |
router.post('/', route(async (req) => { | |
return Knowledge.insertOne(_.pick(req.body, [ | |
'title', 'description', 'content' | |
])).then(({ insertedId }) => { | |
return insertedId; | |
}); | |
})); | |
router.get('/', route(async (req) => { | |
const skip = Number(req.query.skip); | |
const limit = Number(req.query.limit); | |
if (isNaN(skip) || isNaN(limit) || skip < 0 || limit < 1) { | |
throw new HttpError(400, 'invalid_params'); | |
} | |
return Knowledge.find({}).skip(skip).limit(limit).toArray(); | |
})); | |
router.route('/:id') | |
.all((req, res, next) => { | |
const id = req.params.id; | |
if (!id) { | |
throw new HttpError(404, 'not_found'); | |
} | |
next(); | |
}) | |
.get(route(async (req) => { | |
const knowledge = await Knowledge.findOne({ _id: ObjectId(req.params.id) }); | |
if (!knowledge) { | |
throw new HttpError(404, 'not_found'); | |
} | |
return knowledge; | |
})) | |
.put(route(async (req) => { | |
const { value } = await Knowledge.findOneAndUpdate({ | |
_id: ObjectId(req.params.id) | |
}, { | |
$set: _.pick(req.body, ['title', 'description', 'content']) | |
}); | |
if (!value) { | |
throw new HttpError(404, 'not_found'); | |
} | |
})) | |
.delete(route(async (req) => { | |
const { deletedCount } = await Knowledge.deleteOne({ _id: ObjectId(req.params.id) }) | |
if (deletedCount === 0) { | |
throw new HttpError(404, 'not_found'); | |
} | |
})); | |
export { router }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment