notea/pages/api/import.ts
2021-06-06 12:25:16 +08:00

77 lines
1.9 KiB
TypeScript

import { useAuth } from 'libs/server/middlewares/auth'
import { useStore } from 'libs/server/middlewares/store'
import { readFileFromRequest } from 'libs/server/file'
import AdmZip from 'adm-zip'
import { api } from 'libs/server/connect'
import { IMPORT_FILE_LIMIT_SIZE } from 'libs/shared/const'
import { extname } from 'path'
import { genId } from 'libs/shared/id'
import { ROOT_ID } from 'libs/shared/tree'
import { createNote } from 'libs/server/note'
import { NoteModel } from 'libs/shared/note'
import { parseMarkdownTitle } from 'libs/shared/markdown/parse-markdown-title'
const MARKDOWN_EXT = [
'.markdown',
'.mdown',
'.mkdn',
'.md',
'.mkd',
'.mdwn',
'.mdtxt',
'.mdtext',
'.text',
'.Rmd',
]
export const config = {
api: {
bodyParser: false,
},
}
export default api()
.use(useAuth)
.use(useStore)
.post(async (req, res) => {
const pid = (req.query.pid as string) || ROOT_ID
const file = await readFileFromRequest(req)
if (file.size > IMPORT_FILE_LIMIT_SIZE) {
return res.APIError.IMPORT_FILE_LIMIT_SIZE.throw()
}
const zip = new AdmZip(file.path)
const zipEntries = zip.getEntries()
const total = zipEntries.length
const notes: NoteModel[] = []
await Promise.all(
zipEntries.map(async (zipEntry) => {
if (!MARKDOWN_EXT.includes(extname(zipEntry.name))) {
return
}
const markdown = zipEntry.getData().toString('utf8')
const { content, title } = parseMarkdownTitle(markdown)
const note = {
title: title ?? zipEntry.name,
pid,
id: genId(),
date: zipEntry.header.time.toISOString(),
content,
} as NoteModel
notes.push(note)
return createNote(note, req.state)
})
)
await req.state.treeStore.addItems(
notes.map((n) => n.id),
pid
)
res.json({ total, imported: notes.length })
})