34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
import { setHeader } from 'h3'
|
|
import { prisma } from '../../utils/db'
|
|
import { requireUser } from '../../utils/auth'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event)
|
|
const rows = await prisma.transaction.findMany({
|
|
where: { userId: user.id },
|
|
include: { asset: true, category: { include: { parent: true } } },
|
|
orderBy: { occurredAt: 'desc' }
|
|
})
|
|
|
|
const escape = (value: unknown) => `"${String(value ?? '').replaceAll('"', '""')}"`
|
|
const lines = [
|
|
['id', 'type', 'occurredAt', 'asset', 'category', 'amount', 'title', 'memo', 'latitude', 'longitude'].map(escape).join(','),
|
|
...rows.map(row => [
|
|
row.id,
|
|
row.type,
|
|
row.occurredAt.toISOString(),
|
|
row.asset.name,
|
|
row.category.parent ? `${row.category.parent.name} > ${row.category.name}` : row.category.name,
|
|
row.amount,
|
|
row.title,
|
|
row.memo,
|
|
row.latitude,
|
|
row.longitude
|
|
].map(escape).join(','))
|
|
]
|
|
|
|
setHeader(event, 'content-type', 'text/csv; charset=utf-8')
|
|
setHeader(event, 'content-disposition', 'attachment; filename="transactions.csv"')
|
|
return lines.join('\n')
|
|
})
|