diff --git a/modules/hudozka-api/src/controllers/tag.ts b/modules/hudozka-api/src/controllers/tag.ts new file mode 100644 index 00000000..6daf0469 --- /dev/null +++ b/modules/hudozka-api/src/controllers/tag.ts @@ -0,0 +1,48 @@ +import Article from '../core/Article' +import { Request, Response } from 'express' +import { unique } from '../lib/array' + +export async function getAll(req: Request, res: Response) { + const data = await Article.find({}) + const tags = data + .flatMap(x => x.tags) + .filter(x => x.isValid()) + const items = unique(tags, t => t.slug) + + if (data) { + res.json({ + items, + }) + } else { + res.status(404) + res.json({ + error: `Not found` + }) + } +} + +export async function findItems(req: Request, res: Response) { + const slug = req.params.slug + + const data = await Article.find({ + tags: { + + } + + }) + const tags = data + .flatMap(x => x.tags) + .filter(x => x.isValid()) + const items = unique(tags, t => t.slug) + + if (data) { + res.json({ + items, + }) + } else { + res.status(404) + res.json({ + error: `Not found` + }) + } +} diff --git a/modules/hudozka-api/src/core/Article.ts b/modules/hudozka-api/src/core/Article.ts index c279f325..6b868781 100644 --- a/modules/hudozka-api/src/core/Article.ts +++ b/modules/hudozka-api/src/core/Article.ts @@ -2,6 +2,7 @@ import Data from './Data' import Image from './Image' import Config from './Config' import { find, findOne, total } from '../lib/store' +import { Tag } from './Tag' const store = () => Data.getStore
('Article') @@ -44,7 +45,7 @@ export default class Article { public date: any public title: any public until: any - public tags: any + public tags: Tag[] public content: any public hash: any public type: any @@ -96,14 +97,6 @@ export default class Article { } } -class Tag { - public name: string - - constructor(tag) { - this.name = tag; - } -} - const previewFromImage = (imgs = []) => imgs.length ? imgs[0] : null diff --git a/modules/hudozka-api/src/core/Tag.ts b/modules/hudozka-api/src/core/Tag.ts new file mode 100644 index 00000000..1e6dae59 --- /dev/null +++ b/modules/hudozka-api/src/core/Tag.ts @@ -0,0 +1,18 @@ +import { translit } from '../lib/translit' + +export class Tag { + public name: string + public slug: string + + constructor(tag: string) { + this.name = tag + + if (tag) { + this.slug = translit(tag).toLowerCase() + } + } + + public isValid() { + return !!this.slug + } +} diff --git a/modules/hudozka-api/src/lib/array.ts b/modules/hudozka-api/src/lib/array.ts new file mode 100644 index 00000000..65031f2a --- /dev/null +++ b/modules/hudozka-api/src/lib/array.ts @@ -0,0 +1,5 @@ +export function unique(items: T[], key: (item: T) => string): T[]{ + const map = new Map(items.map(x => [key(x), x])) + + return [...map.values()] +} diff --git a/modules/hudozka-api/src/lib/translit.ts b/modules/hudozka-api/src/lib/translit.ts new file mode 100644 index 00000000..87c24347 --- /dev/null +++ b/modules/hudozka-api/src/lib/translit.ts @@ -0,0 +1,80 @@ +const map = new Map([ + ['', '_'], + + ['А', 'A'], + ['а', 'a'], + ['Б', 'B'], + ['б', 'b'], + ['В', 'V'], + ['в', 'v'], + ['Г', 'G'], + ['г', 'g'], + ['Д', 'D'], + ['д', 'd'], + ['Е', 'E'], + ['е', 'e'], + ['Ё', 'E'], + ['ё', 'e'], + ['Ж', 'Zh'], + ['ж', 'zh'], + ['З', 'Z'], + ['з', 'z'], + ['И', 'I'], + ['и', 'i'], + ['Й', 'Y'], + ['й', 'y'], + ['К', 'K'], + ['к', 'k'], + ['Л', 'L'], + ['л', 'l'], + ['М', 'M'], + ['м', 'm'], + ['Н', 'N'], + ['н', 'n'], + ['О', 'O'], + ['о', 'o'], + ['П', 'P'], + ['п', 'p'], + ['Р', 'R'], + ['р', 'r'], + ['С', 'S'], + ['с', 's'], + ['Т', 'T'], + ['т', 't'], + ['У', 'U'], + ['у', 'u'], + ['Ф', 'F'], + ['ф', 'f'], + ['Х', 'Kh'], + ['х', 'kh'], + ['Ц', 'Ts'], + ['ц', 'ts'], + ['Ч', 'Ch'], + ['ч', 'ch'], + ['Ш', 'Sh'], + ['ш', 'sh'], + ['Щ', 'Sch'], + ['щ', 'sch'], + ['ь', ''], + ['Ы', 'Y'], + ['ы', 'y'], + ['ъ', ''], + ['Э', 'E'], + ['э', 'e'], + ['Ю', 'Yu'], + ['ю', 'yu'], + ['Я', 'Ya'], + ['я', 'ya'], +]) + +export function translit(sample: string): string { + return [...sample] + .map(char => { + if (map.has(char)) { + return map.get(char) + } + + return '' + }) + .join('') +} diff --git a/modules/hudozka-api/src/server.ts b/modules/hudozka-api/src/server.ts index 7002bf6f..86f717f8 100644 --- a/modules/hudozka-api/src/server.ts +++ b/modules/hudozka-api/src/server.ts @@ -8,6 +8,7 @@ import * as schedule from './controllers/schedule' import * as file from './controllers/file' import * as page from './controllers/page' import * as image from './controllers/image' +import * as tag from './controllers/tag' async function main() { const port = parseInt(process.env.PORT, 10) || 3000 @@ -47,6 +48,8 @@ async function main() { app.get('/images/:slug', image.getItem) app.get('/schedule', schedule.getItem) + app.get('/tags', tag.getAll) + app.get('/tags/:slug', tag.findItems) app.listen(port, () => { console.log(`> Ready on http://localhost:${port}`)