diff options
author | glenn-louarn <34347121+glenn-louarn@users.noreply.github.com> | 2020-07-20 10:40:51 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-20 10:40:51 +0300 |
commit | e492542428a42200d6f33abc3c73b95d386bc7ca (patch) | |
tree | e47632c339d61e997192fbb15c4e04182f415f4a /server | |
parent | 55c2beafdd72262dd3f559aeb9ef32cbfc9c4afe (diff) |
feat: Add description for links fix #51 (#342)
* ✨ Add description for links fix #51
* feat: show description under original link
* feat: make advanced options input full-width
* fix: showing newly created link in the table
* fix: improve edit form style
* feat: add description migration
* fix: make description type optional
Co-authored-by: poeti8 <ezzati.upt@gmail.com>
Diffstat (limited to 'server')
-rw-r--r-- | server/handlers/links.ts | 6 | ||||
-rw-r--r-- | server/handlers/types.d.ts | 1 | ||||
-rw-r--r-- | server/handlers/validators.ts | 12 | ||||
-rw-r--r-- | server/migrations/20200718124944_description.ts | 10 | ||||
-rw-r--r-- | server/models/link.ts | 1 | ||||
-rw-r--r-- | server/queries/link.ts | 16 |
6 files changed, 38 insertions, 8 deletions
diff --git a/server/handlers/links.ts b/server/handlers/links.ts index f14db01..a3fc9d1 100644 --- a/server/handlers/links.ts +++ b/server/handlers/links.ts @@ -42,7 +42,7 @@ export const get: Handler = async (req, res) => { }; export const create: Handler = async (req: CreateLinkReq, res) => { - const { reuse, password, customurl, target, domain } = req.body; + const { reuse, password, customurl, description, target, domain } = req.body; const domain_id = domain ? domain.id : null; const targetDomain = URL.parse(target).hostname; @@ -85,6 +85,7 @@ export const create: Handler = async (req: CreateLinkReq, res) => { password, address, domain_id, + description, target, user_id: req.user && req.user.id }); @@ -99,7 +100,7 @@ export const create: Handler = async (req: CreateLinkReq, res) => { }; export const edit: Handler = async (req, res) => { - const { address, target } = req.body; + const { address, target, description } = req.body; if (!address && !target) { throw new CustomError("Should at least update one field."); @@ -142,6 +143,7 @@ export const edit: Handler = async (req, res) => { }, { ...(address && { address }), + ...(description && { description }), ...(target && { target }) } ); diff --git a/server/handlers/types.d.ts b/server/handlers/types.d.ts index e35ecf1..2a092da 100644 --- a/server/handlers/types.d.ts +++ b/server/handlers/types.d.ts @@ -5,6 +5,7 @@ export interface CreateLinkReq extends Request { reuse?: boolean; password?: string; customurl?: string; + description?: string; domain?: Domain; target: string; }; diff --git a/server/handlers/validators.ts b/server/handlers/validators.ts index f3c1261..9e15cfd 100644 --- a/server/handlers/validators.ts +++ b/server/handlers/validators.ts @@ -81,6 +81,12 @@ export const createLink = [ .withMessage("Only users can use this field.") .isBoolean() .withMessage("Reuse must be boolean."), + body("description") + .optional() + .isString() + .trim() + .isLength({ min: 0, max: 2040 }) + .withMessage("Description length must be between 0 and 2040."), body("domain") .optional() .custom(checkUser) @@ -132,6 +138,12 @@ export const editLink = [ .withMessage("Custom URL is not valid") .custom(value => !preservedUrls.some(url => url.toLowerCase() === value)) .withMessage("You can't use this custom URL."), + body("description") + .optional() + .isString() + .trim() + .isLength({ min: 0, max: 2040 }) + .withMessage("Description length must be between 0 and 2040."), param("id", "ID is invalid.") .exists({ checkFalsy: true, checkNull: true }) .isLength({ min: 36, max: 36 }) diff --git a/server/migrations/20200718124944_description.ts b/server/migrations/20200718124944_description.ts new file mode 100644 index 0000000..5e6b8ce --- /dev/null +++ b/server/migrations/20200718124944_description.ts @@ -0,0 +1,10 @@ +import * as Knex from "knex"; + +export async function up(knex: Knex): Promise<any> { + const hasDescription = await knex.schema.hasColumn("links", "description"); + if (!hasDescription) { + await knex.schema.alterTable("links", table => { + table.string("description"); + }); + } +} diff --git a/server/models/link.ts b/server/models/link.ts index 89e46db..6fe997b 100644 --- a/server/models/link.ts +++ b/server/models/link.ts @@ -9,6 +9,7 @@ export async function createLinkTable(knex: Knex) { knex.raw('create extension if not exists "uuid-ossp"'); table.increments("id").primary(); table.string("address").notNullable(); + table.string("description"); table .boolean("banned") .notNullable() diff --git a/server/queries/link.ts b/server/queries/link.ts index 0deba0a..47cd102 100644 --- a/server/queries/link.ts +++ b/server/queries/link.ts @@ -12,6 +12,7 @@ const selectable = [ "links.domain_id", "links.updated_at", "links.password", + "links.description", "links.target", "links.visit_count", "links.user_id", @@ -52,9 +53,10 @@ export const total = async (match: Match<Link>, params: TotalParams = {}) => { }); if (params.search) { - query.andWhereRaw("links.address || ' ' || target ILIKE '%' || ? || '%'", [ - params.search - ]); + query.andWhereRaw( + "links.description || ' ' || links.address || ' ' || target ILIKE '%' || ? || '%'", + [params.search] + ); } const [{ count }] = await query.count("id"); @@ -77,9 +79,10 @@ export const get = async (match: Partial<Link>, params: GetParams) => { .orderBy("created_at", "desc"); if (params.search) { - query.andWhereRaw("links.address || ' ' || target ILIKE '%' || ? || '%'", [ - params.search - ]); + query.andWhereRaw( + "links.description || ' ' || links.address || ' ' || target ILIKE '%' || ? || '%'", + [params.search] + ); } query.leftJoin("domains", "links.domain_id", "domains.id"); @@ -131,6 +134,7 @@ export const create = async (params: Create) => { domain_id: params.domain_id || null, user_id: params.user_id || null, address: params.address, + description: params.description || null, target: params.target }, "*" |