directus
222 строки · 5.2 Кб
1import { ErrorCode, isDirectusError } from '@directus/errors';
2import type { PrimaryKey } from '@directus/types';
3import express from 'express';
4import { UUID_REGEX } from '../constants.js';
5import { getFlowManager } from '../flows.js';
6import { respond } from '../middleware/respond.js';
7import useCollection from '../middleware/use-collection.js';
8import { validateBatch } from '../middleware/validate-batch.js';
9import { FlowsService } from '../services/flows.js';
10import { MetaService } from '../services/meta.js';
11import asyncHandler from '../utils/async-handler.js';
12import { sanitizeQuery } from '../utils/sanitize-query.js';
13
14const router = express.Router();
15
16router.use(useCollection('directus_flows'));
17
18const webhookFlowHandler = asyncHandler(async (req, res, next) => {
19const flowManager = getFlowManager();
20
21const { result, cacheEnabled } = await flowManager.runWebhookFlow(
22`${req.method}-${req.params['pk']}`,
23{
24path: req.path,
25query: req.query,
26body: req.body,
27method: req.method,
28headers: req.headers,
29},
30{
31accountability: req.accountability,
32schema: req.schema,
33},
34);
35
36if (!cacheEnabled) {
37res.locals['cache'] = false;
38}
39
40res.locals['payload'] = result;
41return next();
42});
43
44router.get(`/trigger/:pk(${UUID_REGEX})`, webhookFlowHandler, respond);
45router.post(`/trigger/:pk(${UUID_REGEX})`, webhookFlowHandler, respond);
46
47router.post(
48'/',
49asyncHandler(async (req, res, next) => {
50const service = new FlowsService({
51accountability: req.accountability,
52schema: req.schema,
53});
54
55const savedKeys: PrimaryKey[] = [];
56
57if (Array.isArray(req.body)) {
58const keys = await service.createMany(req.body);
59savedKeys.push(...keys);
60} else {
61const key = await service.createOne(req.body);
62savedKeys.push(key);
63}
64
65try {
66if (Array.isArray(req.body)) {
67const items = await service.readMany(savedKeys, req.sanitizedQuery);
68res.locals['payload'] = { data: items };
69} else {
70const item = await service.readOne(savedKeys[0]!, req.sanitizedQuery);
71res.locals['payload'] = { data: item };
72}
73} catch (error: any) {
74if (isDirectusError(error, ErrorCode.Forbidden)) {
75return next();
76}
77
78throw error;
79}
80
81return next();
82}),
83respond,
84);
85
86const readHandler = asyncHandler(async (req, res, next) => {
87const service = new FlowsService({
88accountability: req.accountability,
89schema: req.schema,
90});
91
92const metaService = new MetaService({
93accountability: req.accountability,
94schema: req.schema,
95});
96
97const records = await service.readByQuery(req.sanitizedQuery);
98const meta = await metaService.getMetaForQuery(req.collection, req.sanitizedQuery);
99
100res.locals['payload'] = { data: records || null, meta };
101return next();
102});
103
104router.get('/', validateBatch('read'), readHandler, respond);
105router.search('/', validateBatch('read'), readHandler, respond);
106
107router.get(
108'/:pk',
109asyncHandler(async (req, res, next) => {
110const service = new FlowsService({
111accountability: req.accountability,
112schema: req.schema,
113});
114
115const record = await service.readOne(req.params['pk']!, req.sanitizedQuery);
116
117res.locals['payload'] = { data: record || null };
118return next();
119}),
120respond,
121);
122
123router.patch(
124'/',
125validateBatch('update'),
126asyncHandler(async (req, res, next) => {
127const service = new FlowsService({
128accountability: req.accountability,
129schema: req.schema,
130});
131
132let keys: PrimaryKey[] = [];
133
134if (Array.isArray(req.body)) {
135keys = await service.updateBatch(req.body);
136} else if (req.body.keys) {
137keys = await service.updateMany(req.body.keys, req.body.data);
138} else {
139const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
140keys = await service.updateByQuery(sanitizedQuery, req.body.data);
141}
142
143try {
144const result = await service.readMany(keys, req.sanitizedQuery);
145res.locals['payload'] = { data: result };
146} catch (error: any) {
147if (isDirectusError(error, ErrorCode.Forbidden)) {
148return next();
149}
150
151throw error;
152}
153
154return next();
155}),
156respond,
157);
158
159router.patch(
160'/:pk',
161asyncHandler(async (req, res, next) => {
162const service = new FlowsService({
163accountability: req.accountability,
164schema: req.schema,
165});
166
167const primaryKey = await service.updateOne(req.params['pk']!, req.body);
168
169try {
170const item = await service.readOne(primaryKey, req.sanitizedQuery);
171res.locals['payload'] = { data: item || null };
172} catch (error: any) {
173if (isDirectusError(error, ErrorCode.Forbidden)) {
174return next();
175}
176
177throw error;
178}
179
180return next();
181}),
182respond,
183);
184
185router.delete(
186'/',
187asyncHandler(async (req, _res, next) => {
188const service = new FlowsService({
189accountability: req.accountability,
190schema: req.schema,
191});
192
193if (Array.isArray(req.body)) {
194await service.deleteMany(req.body);
195} else if (req.body.keys) {
196await service.deleteMany(req.body.keys);
197} else {
198const sanitizedQuery = sanitizeQuery(req.body.query, req.accountability);
199await service.deleteByQuery(sanitizedQuery);
200}
201
202return next();
203}),
204respond,
205);
206
207router.delete(
208'/:pk',
209asyncHandler(async (req, _res, next) => {
210const service = new FlowsService({
211accountability: req.accountability,
212schema: req.schema,
213});
214
215await service.deleteOne(req.params['pk']!);
216
217return next();
218}),
219respond,
220);
221
222export default router;
223