initial tags api
This commit is contained in:
1 parent
11d628fd50
commit
ec2609e900
6 files changed
+156
-9
No files matched your search
@@ -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`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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>('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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export function unique<T>(items: T[], key: (item: T) => string): T[]{
|
||||
const map = new Map(items.map(x => [key(x), x]))
|
||||
|
||||
return [...map.values()]
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
const map = new Map<string, string>([
|
||||
['', '_'],
|
||||
|
||||
['А', '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('')
|
||||
}
|
||||
@@ -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}`)
|
||||
|
||||
Reference in new issue
Block a user