mirror of
https://github.com/directus/directus.git
synced 2026-02-15 21:55:04 -05:00
* Rework cache handler to be function export * Add default schema caching * Add schema cache * Auto purge schema cache on schema change from api * Only set last_access value on login * Add note on schema cache setting
92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
import { RequestHandler } from 'express';
|
|
import { Transform, transforms } from 'json2csv';
|
|
import ms from 'ms';
|
|
import { PassThrough } from 'stream';
|
|
import { getCache } from '../cache';
|
|
import env from '../env';
|
|
import asyncHandler from '../utils/async-handler';
|
|
import { getCacheKey } from '../utils/get-cache-key';
|
|
import { parse as toXML } from 'js2xmlparser';
|
|
import { getCacheControlHeader } from '../utils/get-cache-headers';
|
|
|
|
export const respond: RequestHandler = asyncHandler(async (req, res) => {
|
|
const { cache } = getCache();
|
|
|
|
if (
|
|
req.method.toLowerCase() === 'get' &&
|
|
env.CACHE_ENABLED === true &&
|
|
cache &&
|
|
!req.sanitizedQuery.export &&
|
|
res.locals.cache !== false
|
|
) {
|
|
const key = getCacheKey(req);
|
|
await cache.set(key, res.locals.payload, ms(env.CACHE_TTL as string));
|
|
await cache.set(`${key}__expires_at`, Date.now() + ms(env.CACHE_TTL as string));
|
|
res.setHeader('Cache-Control', getCacheControlHeader(req, ms(env.CACHE_TTL as string)));
|
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
} else {
|
|
// Don't cache anything by default
|
|
res.setHeader('Cache-Control', 'no-cache');
|
|
res.setHeader('Vary', 'Origin, Cache-Control');
|
|
}
|
|
|
|
if (req.sanitizedQuery.export) {
|
|
let filename = '';
|
|
|
|
if (req.collection) {
|
|
filename += req.collection;
|
|
} else {
|
|
filename += 'Export';
|
|
}
|
|
|
|
filename += ' ' + getDateFormatted();
|
|
|
|
if (req.sanitizedQuery.export === 'json') {
|
|
res.attachment(`${filename}.json`);
|
|
res.set('Content-Type', 'application/json');
|
|
return res.status(200).send(JSON.stringify(res.locals.payload?.data || null, null, '\t'));
|
|
}
|
|
|
|
if (req.sanitizedQuery.export === 'xml') {
|
|
res.attachment(`${filename}.xml`);
|
|
res.set('Content-Type', 'text/xml');
|
|
return res.status(200).send(toXML('data', res.locals.payload?.data));
|
|
}
|
|
|
|
if (req.sanitizedQuery.export === 'csv') {
|
|
res.attachment(`${filename}.csv`);
|
|
res.set('Content-Type', 'text/csv');
|
|
const stream = new PassThrough();
|
|
|
|
if (!res.locals.payload?.data || res.locals.payload.data.length === 0) {
|
|
stream.end(Buffer.from(''));
|
|
return stream.pipe(res);
|
|
} else {
|
|
stream.end(Buffer.from(JSON.stringify(res.locals.payload.data), 'utf-8'));
|
|
const json2csv = new Transform({
|
|
transforms: [transforms.flatten({ separator: '.' })],
|
|
});
|
|
return stream.pipe(json2csv).pipe(res);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Buffer.isBuffer(res.locals.payload)) {
|
|
return res.end(res.locals.payload);
|
|
} else {
|
|
return res.json(res.locals.payload);
|
|
}
|
|
});
|
|
|
|
function getDateFormatted() {
|
|
const date = new Date();
|
|
|
|
let month = String(date.getMonth() + 1);
|
|
if (month.length === 1) month = '0' + month;
|
|
|
|
let day = String(date.getDate());
|
|
if (day.length === 1) day = '0' + day;
|
|
|
|
return `${date.getFullYear()}-${month}-${day} at ${date.getHours()}.${date.getMinutes()}.${date.getSeconds()}`;
|
|
}
|