mirror of
https://github.com/pawelmalak/snippet-box.git
synced 2025-12-21 21:33:10 +01:00
Split snippet controllers into separate files
This commit is contained in:
@@ -1,298 +0,0 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { QueryTypes, Op } from 'sequelize';
|
||||
import { sequelize } from '../db';
|
||||
import { asyncWrapper } from '../middleware';
|
||||
import { SnippetModel, Snippet_TagModel, TagModel } from '../models';
|
||||
import { ErrorResponse, tagParser, Logger, createTags } from '../utils';
|
||||
import { Body, SearchQuery } from '../typescript/interfaces';
|
||||
|
||||
/**
|
||||
* @description Create new snippet
|
||||
* @route /api/snippets
|
||||
* @request POST
|
||||
*/
|
||||
export const createSnippet = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
// Get tags from request body
|
||||
const { language, tags: requestTags } = <Body>req.body;
|
||||
const parsedRequestTags = tagParser([
|
||||
...requestTags,
|
||||
language.toLowerCase()
|
||||
]);
|
||||
|
||||
// Create snippet
|
||||
const snippet = await SnippetModel.create({
|
||||
...req.body,
|
||||
tags: [...parsedRequestTags].join(',')
|
||||
});
|
||||
|
||||
// Create tags
|
||||
await createTags(parsedRequestTags, snippet.id);
|
||||
|
||||
// Get raw snippet values
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
res.status(201).json({
|
||||
data: {
|
||||
...rawSnippet,
|
||||
tags: [...parsedRequestTags]
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Get all snippets
|
||||
* @route /api/snippets
|
||||
* @request GET
|
||||
*/
|
||||
export const getAllSnippets = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const snippets = await SnippetModel.findAll({
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const populatedSnippets = snippets.map(snippet => {
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
return {
|
||||
...rawSnippet,
|
||||
tags: rawSnippet.tags?.map(tag => tag.name)
|
||||
};
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
data: populatedSnippets
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Get single snippet by id
|
||||
* @route /api/snippets/:id
|
||||
* @request GET
|
||||
*/
|
||||
export const getSnippet = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id },
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
const populatedSnippet = {
|
||||
...rawSnippet,
|
||||
tags: rawSnippet.tags?.map(tag => tag.name)
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
data: populatedSnippet
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Update snippet
|
||||
* @route /api/snippets/:id
|
||||
* @request PUT
|
||||
*/
|
||||
export const updateSnippet = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
let snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id }
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Get tags from request body
|
||||
const { language, tags: requestTags } = <Body>req.body;
|
||||
let parsedRequestTags = tagParser([...requestTags, language.toLowerCase()]);
|
||||
|
||||
// Update snippet
|
||||
snippet = await snippet.update({
|
||||
...req.body,
|
||||
tags: [...parsedRequestTags].join(',')
|
||||
});
|
||||
|
||||
// Delete old tags and create new ones
|
||||
await Snippet_TagModel.destroy({ where: { snippet_id: req.params.id } });
|
||||
await createTags(parsedRequestTags, snippet.id);
|
||||
|
||||
// Get raw snippet values
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
res.status(200).json({
|
||||
data: {
|
||||
...rawSnippet,
|
||||
tags: [...parsedRequestTags]
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Delete snippet
|
||||
* @route /api/snippets/:id
|
||||
* @request DELETE
|
||||
*/
|
||||
export const deleteSnippet = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id }
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await Snippet_TagModel.destroy({ where: { snippet_id: req.params.id } });
|
||||
await snippet.destroy();
|
||||
|
||||
res.status(200).json({
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Count tags
|
||||
* @route /api/snippets/statistics/count
|
||||
* @request GET
|
||||
*/
|
||||
export const countTags = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const result = await sequelize.query(
|
||||
`SELECT
|
||||
COUNT(tags.name) as count,
|
||||
tags.name
|
||||
FROM snippets_tags
|
||||
INNER JOIN tags ON snippets_tags.tag_id = tags.id
|
||||
GROUP BY tags.name
|
||||
ORDER BY name ASC`,
|
||||
{
|
||||
type: QueryTypes.SELECT
|
||||
}
|
||||
);
|
||||
|
||||
res.status(200).json({
|
||||
data: result
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Get raw snippet code
|
||||
* @route /api/snippets/raw/:id
|
||||
* @request GET
|
||||
*/
|
||||
export const getRawCode = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id },
|
||||
raw: true
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
res.status(200).send(snippet.code);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @description Search snippets
|
||||
* @route /api/snippets/search
|
||||
* @request POST
|
||||
*/
|
||||
export const searchSnippets = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const { query, tags, languages } = <SearchQuery>req.body;
|
||||
|
||||
// Check if query is empty
|
||||
if (query === '' && !tags.length && !languages.length) {
|
||||
res.status(200).json({
|
||||
data: []
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const languageFilter = languages.length
|
||||
? { [Op.in]: languages }
|
||||
: { [Op.notIn]: languages };
|
||||
|
||||
const tagFilter = tags.length ? { [Op.in]: tags } : { [Op.notIn]: tags };
|
||||
|
||||
const snippets = await SnippetModel.findAll({
|
||||
where: {
|
||||
[Op.and]: [
|
||||
{
|
||||
[Op.or]: [
|
||||
{ title: { [Op.substring]: `${query}` } },
|
||||
{ description: { [Op.substring]: `${query}` } }
|
||||
]
|
||||
},
|
||||
{
|
||||
language: languageFilter
|
||||
}
|
||||
]
|
||||
},
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
where: {
|
||||
name: tagFilter
|
||||
},
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
data: snippets
|
||||
});
|
||||
}
|
||||
);
|
||||
31
src/controllers/snippets/countTags.ts
Normal file
31
src/controllers/snippets/countTags.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import { QueryTypes } from 'sequelize';
|
||||
import { sequelize } from '../../db';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
|
||||
/**
|
||||
* @description Count tags
|
||||
* @route /api/snippets/statistics/count
|
||||
* @request GET
|
||||
* @access Private
|
||||
*/
|
||||
export const countTags = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const result = await sequelize.query(
|
||||
`SELECT
|
||||
COUNT(tags.name) as count,
|
||||
tags.name
|
||||
FROM snippets_tags
|
||||
INNER JOIN tags ON snippets_tags.tag_id = tags.id
|
||||
GROUP BY tags.name
|
||||
ORDER BY name ASC`,
|
||||
{
|
||||
type: QueryTypes.SELECT
|
||||
}
|
||||
);
|
||||
|
||||
res.status(200).json({
|
||||
data: result
|
||||
});
|
||||
}
|
||||
);
|
||||
48
src/controllers/snippets/createSnippet.ts
Normal file
48
src/controllers/snippets/createSnippet.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel } from '../../models';
|
||||
import { Snippet, UserInfoRequest } from '../../typescript/interfaces';
|
||||
import { tagParser, createTags } from '../../utils';
|
||||
|
||||
interface RequestBody extends Snippet {}
|
||||
|
||||
/**
|
||||
* @description Create new snippet
|
||||
* @route /api/snippets
|
||||
* @request POST
|
||||
* @access Private
|
||||
*/
|
||||
export const createSnippet = asyncWrapper(
|
||||
async (
|
||||
req: UserInfoRequest<RequestBody>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
// Get tags from request body
|
||||
const { language, tags: requestTags = [] } = req.body;
|
||||
|
||||
const parsedRequestTags = tagParser([
|
||||
...requestTags,
|
||||
language.toLowerCase()
|
||||
]);
|
||||
|
||||
// Create snippet
|
||||
const snippet = await SnippetModel.create({
|
||||
...req.body,
|
||||
createdBy: req.user.id
|
||||
});
|
||||
|
||||
// Create tags
|
||||
await createTags(parsedRequestTags, snippet.id);
|
||||
|
||||
// Get raw snippet values
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
res.status(201).json({
|
||||
data: {
|
||||
...rawSnippet,
|
||||
tags: [...parsedRequestTags]
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
50
src/controllers/snippets/deleteSnippet.ts
Normal file
50
src/controllers/snippets/deleteSnippet.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel, Snippet_TagModel } from '../../models';
|
||||
import { Snippet, UserInfoRequest } from '../../typescript/interfaces';
|
||||
import { tagParser, createTags, ErrorResponse } from '../../utils';
|
||||
|
||||
interface Params {
|
||||
id: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Delete snippet
|
||||
* @route /api/snippets/:id
|
||||
* @request DELETE
|
||||
* @access Private
|
||||
*/
|
||||
export const deleteSnippet = asyncWrapper(
|
||||
async (
|
||||
req: UserInfoRequest<{}, Params>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id }
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with the id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (snippet.createdBy != req.user.id && !req.user.isAdmin) {
|
||||
return next(
|
||||
new ErrorResponse(401, `You are not authorized to modify this resource`)
|
||||
);
|
||||
}
|
||||
|
||||
// Delete all snippet <> tag relations
|
||||
await Snippet_TagModel.destroy({ where: { snippet_id: req.params.id } });
|
||||
await snippet.destroy();
|
||||
|
||||
res.status(200).json({
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
);
|
||||
43
src/controllers/snippets/getAllSnippets.ts
Normal file
43
src/controllers/snippets/getAllSnippets.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel, TagModel } from '../../models';
|
||||
|
||||
/**
|
||||
* @description Get all snippets
|
||||
* @route /api/snippets
|
||||
* @request GET
|
||||
*/
|
||||
export const getAllSnippets = asyncWrapper(
|
||||
async (req: Request, res: Response, next: NextFunction): Promise<void> => {
|
||||
const snippets = await SnippetModel.findAll({
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const populatedSnippets = snippets.map(snippet => {
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
let tags: string[] = [];
|
||||
|
||||
if (rawSnippet.tags) {
|
||||
// @ts-ignore
|
||||
const rawTags = rawSnippet.tags as { name: string }[];
|
||||
tags = rawTags.map(tag => tag.name);
|
||||
}
|
||||
|
||||
return {
|
||||
...rawSnippet,
|
||||
tags
|
||||
};
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
data: populatedSnippets
|
||||
});
|
||||
}
|
||||
);
|
||||
38
src/controllers/snippets/getRawCode.ts
Normal file
38
src/controllers/snippets/getRawCode.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel } from '../../models';
|
||||
import { ErrorResponse } from '../../utils';
|
||||
|
||||
interface Params {
|
||||
id: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get raw snippet code
|
||||
* @route /api/snippets/raw/:id
|
||||
* @request GET
|
||||
* @access Private
|
||||
*/
|
||||
export const getRawCode = asyncWrapper(
|
||||
async (
|
||||
req: Request<Params>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id },
|
||||
raw: true
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with the id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
res.status(200).send(snippet.code);
|
||||
}
|
||||
);
|
||||
66
src/controllers/snippets/getSnippet.ts
Normal file
66
src/controllers/snippets/getSnippet.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel, TagModel } from '../../models';
|
||||
import { UserInfoRequest } from '../../typescript/interfaces';
|
||||
import { ErrorResponse } from '../../utils';
|
||||
|
||||
interface Params {
|
||||
id: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Get single snippet by id
|
||||
* @route /api/snippets/:id
|
||||
* @request GET
|
||||
* @access Private
|
||||
*/
|
||||
export const getSnippet = asyncWrapper(
|
||||
async (
|
||||
req: UserInfoRequest<{}, Params>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
const snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id },
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with the id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (snippet.createdBy != req.user.id && !req.user.isAdmin) {
|
||||
return next(
|
||||
new ErrorResponse(401, `You are not authorized to access this resource`)
|
||||
);
|
||||
}
|
||||
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
if (rawSnippet.tags) {
|
||||
// @ts-ignore
|
||||
const rawTags = rawSnippet.tags as { name: string }[];
|
||||
|
||||
const populatedSnippet = {
|
||||
...rawSnippet,
|
||||
tags: rawTags.map(tag => tag.name)
|
||||
};
|
||||
|
||||
res.status(200).json({
|
||||
data: populatedSnippet
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
8
src/controllers/snippets/index.ts
Normal file
8
src/controllers/snippets/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './createSnippet';
|
||||
export * from './getAllSnippets';
|
||||
export * from './getSnippet';
|
||||
export * from './deleteSnippet';
|
||||
export * from './countTags';
|
||||
export * from './getRawCode';
|
||||
export * from './searchSnippets';
|
||||
export * from './updateSnippet';
|
||||
72
src/controllers/snippets/searchSnippets.ts
Normal file
72
src/controllers/snippets/searchSnippets.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel, TagModel } from '../../models';
|
||||
import { Op } from 'sequelize';
|
||||
|
||||
interface Body {
|
||||
query: string;
|
||||
tags: string[];
|
||||
languages: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Search snippets
|
||||
* @route /api/snippets/search
|
||||
* @request POST
|
||||
* @access Private
|
||||
*/
|
||||
export const searchSnippets = asyncWrapper(
|
||||
async (
|
||||
req: Request<{}, {}, Body>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
const { query, tags, languages } = req.body;
|
||||
|
||||
// Check if query is empty
|
||||
if (query === '' && !tags.length && !languages.length) {
|
||||
res.status(200).json({
|
||||
data: []
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const languageFilter = languages.length
|
||||
? { [Op.in]: languages }
|
||||
: { [Op.notIn]: languages };
|
||||
|
||||
const tagFilter = tags.length ? { [Op.in]: tags } : { [Op.notIn]: tags };
|
||||
|
||||
const snippets = await SnippetModel.findAll({
|
||||
where: {
|
||||
[Op.and]: [
|
||||
{
|
||||
[Op.or]: [
|
||||
{ title: { [Op.substring]: `${query}` } },
|
||||
{ description: { [Op.substring]: `${query}` } }
|
||||
]
|
||||
},
|
||||
{
|
||||
language: languageFilter
|
||||
}
|
||||
]
|
||||
},
|
||||
include: {
|
||||
model: TagModel,
|
||||
as: 'tags',
|
||||
attributes: ['name'],
|
||||
where: {
|
||||
name: tagFilter
|
||||
},
|
||||
through: {
|
||||
attributes: []
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
data: snippets
|
||||
});
|
||||
}
|
||||
);
|
||||
70
src/controllers/snippets/updateSnippet.ts
Normal file
70
src/controllers/snippets/updateSnippet.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Response, NextFunction } from 'express';
|
||||
import { asyncWrapper } from '../../middleware';
|
||||
import { SnippetModel, Snippet_TagModel } from '../../models';
|
||||
import { ErrorResponse, tagParser, createTags } from '../../utils';
|
||||
import { Snippet, UserInfoRequest } from '../../typescript/interfaces';
|
||||
|
||||
interface Body extends Snippet {}
|
||||
|
||||
interface Params {
|
||||
id: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Update snippet
|
||||
* @route /api/snippets/:id
|
||||
* @request PUT
|
||||
* @access Private
|
||||
*/
|
||||
export const updateSnippet = asyncWrapper(
|
||||
async (
|
||||
req: UserInfoRequest<Body, Params>,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<void> => {
|
||||
let snippet = await SnippetModel.findOne({
|
||||
where: { id: req.params.id }
|
||||
});
|
||||
|
||||
if (!snippet) {
|
||||
return next(
|
||||
new ErrorResponse(
|
||||
404,
|
||||
`Snippet with the id of ${req.params.id} was not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (snippet.createdBy != req.user.id && !req.user.isAdmin) {
|
||||
return next(
|
||||
new ErrorResponse(401, `You are not authorized to modify this resource`)
|
||||
);
|
||||
}
|
||||
|
||||
// Get tags from request body
|
||||
const { language, tags: requestTags = [] } = req.body;
|
||||
let parsedRequestTags = tagParser([...requestTags, language.toLowerCase()]);
|
||||
|
||||
// todo
|
||||
// check if tags and/or lang was changed
|
||||
|
||||
// Update snippet
|
||||
snippet = await snippet.update({
|
||||
...req.body
|
||||
});
|
||||
|
||||
// Delete old tags and create new ones
|
||||
await Snippet_TagModel.destroy({ where: { snippet_id: req.params.id } });
|
||||
await createTags(parsedRequestTags, snippet.id);
|
||||
|
||||
// Get raw snippet values
|
||||
const rawSnippet = snippet.get({ plain: true });
|
||||
|
||||
res.status(200).json({
|
||||
data: {
|
||||
...rawSnippet,
|
||||
tags: [...parsedRequestTags]
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -1,28 +1,33 @@
|
||||
import { Router } from 'express';
|
||||
import { authenticate, requireBody } from '../middleware';
|
||||
|
||||
import {
|
||||
countTags,
|
||||
createSnippet,
|
||||
deleteSnippet,
|
||||
getAllSnippets,
|
||||
getRawCode,
|
||||
getSnippet,
|
||||
deleteSnippet,
|
||||
countTags,
|
||||
getRawCode,
|
||||
searchSnippets,
|
||||
updateSnippet
|
||||
} from '../controllers/snippets';
|
||||
import { requireBody } from '../middleware';
|
||||
} from '../controllers/snippets/';
|
||||
|
||||
export const snippetRouter = Router();
|
||||
|
||||
snippetRouter
|
||||
.route('/')
|
||||
.post(requireBody('title', 'language', 'code'), createSnippet)
|
||||
.post(
|
||||
authenticate,
|
||||
requireBody('title', 'language', 'code', 'tags'),
|
||||
createSnippet
|
||||
)
|
||||
.get(getAllSnippets);
|
||||
|
||||
snippetRouter
|
||||
.route('/:id')
|
||||
.get(getSnippet)
|
||||
.put(updateSnippet)
|
||||
.delete(deleteSnippet);
|
||||
.get(authenticate, getSnippet)
|
||||
.put(authenticate, updateSnippet)
|
||||
.delete(authenticate, deleteSnippet);
|
||||
|
||||
snippetRouter.route('/statistics/count').get(countTags);
|
||||
snippetRouter.route('/raw/:id').get(getRawCode);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Request } from 'express';
|
||||
|
||||
export interface UserInfoRequest<body = {}> extends Request<{}, {}, body> {
|
||||
export interface UserInfoRequest<body = {}, params = {}>
|
||||
extends Request<params, {}, body> {
|
||||
user: {
|
||||
id: number;
|
||||
email: string;
|
||||
|
||||
@@ -8,9 +8,9 @@ export interface Snippet extends Model {
|
||||
code: string;
|
||||
docs: string;
|
||||
isPinned: number;
|
||||
tags?: { name: string }[];
|
||||
tags?: string[];
|
||||
createdBy: number;
|
||||
}
|
||||
|
||||
export interface SnippetCreationAttributes
|
||||
extends Optional<Snippet, 'id' | 'createdAt' | 'updatedAt'> {}
|
||||
extends Optional<Snippet, 'id' | 'createdAt' | 'updatedAt' | 'tags'> {}
|
||||
|
||||
@@ -5,7 +5,7 @@ export const signToken = (data: Token): string => {
|
||||
const secret = process.env.JWT_SECRET || 'secret';
|
||||
|
||||
const token = sign(data, secret, {
|
||||
expiresIn: '30d'
|
||||
expiresIn: '14d'
|
||||
});
|
||||
|
||||
return token;
|
||||
|
||||
Reference in New Issue
Block a user