UNPKG

14 kBJavaScriptView Raw
1const isArray = require('lodash/isArray');
2
3module.exports = ({
4 Db,
5 Entity,
6 router,
7 authMiddleware,
8 permissionMiddleware,
9 cacheMiddleware,
10 asyncMiddleware,
11 getConfig,
12 handleResponse,
13 handleError,
14}) => {
15
16 /**
17 * @swagger
18 * definitions:
19 * Entity:
20 * type: object
21 * required:
22 * - _id
23 * - _rev
24 * properties:
25 * _id:
26 * type: string
27 * _rev:
28 * type: string
29 * schema:
30 * type: string
31 * title:
32 * type: string
33 * slug:
34 * type: string
35 * thumbnail:
36 * type: object
37 * fields:
38 * type: object
39 * published:
40 * type: boolean
41 * publishedAt:
42 * type: string
43 */
44
45 /**
46 * @swagger
47 * /entities/index:
48 * get:
49 * tags:
50 * - entities
51 * summary: Show indexes
52 * description: Show all indexes, use this to find fields available for search/query.
53 * produces:
54 * - application/json
55 * parameters: []
56 * responses:
57 * 200:
58 * description: Indexes
59 */
60 router.get(
61 '/entities/index.:ext?',
62 asyncMiddleware(async (req, res) => {
63 try {
64 handleResponse(req, res, await Db(await getConfig(req.session.slug)).indexAsync());
65 } catch (error) {
66 handleError(req, res, error);
67 }
68 })
69 );
70
71 /**
72 * @swagger
73 * /entities/search:
74 * get:
75 * tags:
76 * - entities
77 * summary: Search entities
78 * description: This endpoint extends Cloudant's Lucene based search. Learn more from Cloudant's [documentation](https://docs.cloudant.com/search.html).
79 * produces:
80 * - application/json
81 * parameters:
82 * - name: query
83 * description: Lucene search query
84 * in: query
85 * required: true
86 * type: string
87 * - name: include_docs
88 * description: Include docs in search results (ignored if `children` or `parents` is `true`)
89 * in: query
90 * required: false
91 * type: boolean
92 * default: false
93 * - name: sort
94 * description: Field to sort results by. Prefixed with `-` to reverse order. Suffixed with <`string|number`>
95 * in: query
96 * required: false
97 * type: string
98 * - name: limit
99 * description: Limit results (max 200)
100 * in: query
101 * required: false
102 * type: number
103 * - name: bookmark
104 * description: Bookmark for the next page of results
105 * in: query
106 * required: false
107 * type: string
108 * - name: group_field
109 * description: Field to group results by
110 * in: query
111 * required: false
112 * type: string
113 * - name: index
114 * description: Search index
115 * in: query
116 * required: false
117 * type: string
118 * default: all
119 * - name: children
120 * description: Get child entities
121 * in: query
122 * required: false
123 * type: boolean
124 * default: false
125 * - name: parents
126 * description: Get parent entities
127 * in: query
128 * required: false
129 * type: boolean
130 * default: false
131 * - name: trashed
132 * description: Get trashed entities
133 * in: query
134 * required: false
135 * type: boolean
136 * default: false
137 * responses:
138 * 200:
139 * description: Search result
140 * schema:
141 * type: object
142 * properties:
143 * bookmark:
144 * type: string
145 * total_rows:
146 * type: number
147 * rows:
148 * type: array
149 * items:
150 * $ref: '#/definitions/Entity'
151 */
152 router.all(
153 '/entities/search?.:ext?',
154 cacheMiddleware,
155 asyncMiddleware(async (req, res) => {
156 const include_docs = (req.query.include_docs || req.body.include_docs) !== undefined
157 ? JSON.parse(req.query.include_docs || req.body.include_docs) : false;
158
159 let children = (req.query.children || req.body.children) !== undefined
160 ? JSON.parse((req.query.children || req.body.children)) : false;
161 let parents = (req.query.parents || req.body.parents) !== undefined
162 ? JSON.parse(req.query.parents || req.body.parents) : false;
163
164 const trashed = (req.query.trashed || req.body.trashed) !== undefined
165 ? JSON.parse(req.query.trashed || req.body.trashed) : false;
166
167 const sort = (req.query.sort || req.body.sort) !== undefined
168 ? req.query.sort || req.body.sort : null;
169 const limit = (req.query.limit || req.body.limit) !== undefined
170 ? parseInt(req.query.limit || req.body.limit, 10) : null;
171
172 const bookmark = (req.query.bookmark || req.body.bookmark) !== undefined
173 ? req.query.bookmark || req.body.bookmark : null;
174
175 const group_field = (req.query.group_field || req.body.group_field) !== undefined
176 ? req.query.group_field || req.body.group_field : null;
177
178 const index = (req.query.index || req.body.index) !== undefined
179 ? req.query.index || req.body.index : null;
180
181 const q = req.query.query || req.query.q || req.body.query || req.body.q;
182
183 if (children === true) {
184 children = 1;
185 }
186 if (parents === true) {
187 parents = 1;
188 }
189
190 let query = [];
191
192 query.push(trashed ? 'trashed:true' : '!trashed:true');
193
194 if (req.session.role === 'guest') {
195 query.push('published:true');
196 }
197
198 if (q) {
199 query.push(`(${q})`);
200 }
201
202 query = query.join(' AND ');
203
204 const entity = Entity(await getConfig(req.session.slug));
205
206 try {
207 handleResponse(req, res, await entity.entitySearch({
208 query,
209 include_docs,
210 sort,
211 limit,
212 bookmark,
213 group_field,
214 index,
215 }, children, parents, req.session.role), true);
216 } catch (error) {
217 handleError(req, res, error);
218 }
219 })
220 );
221
222 /**
223 * @swagger
224 * /entities/find:
225 * get:
226 * tags:
227 * - entities
228 * summary: Query entities
229 * description: This endpoint extends CouchDB's Mango query. Learn more from Cloudant's [documentation](https://docs.cloudant.com/cloudant_query.html#finding-documents-using-an-index).
230 * produces:
231 * - application/json
232 * parameters:
233 * - name: query
234 * description: JSON query object, refer to CouchDB/Cloudant docs.
235 * in: query
236 * required: true
237 * type: string
238 * - name: children
239 * description: Get child entities
240 * in: query
241 * required: false
242 * type: boolean
243 * default: false
244 * - name: parents
245 * description: Get parent entities
246 * in: query
247 * required: false
248 * type: boolean
249 * default: false
250 * responses:
251 * 200:
252 * description: Query result
253 * schema:
254 * type: object
255 * properties:
256 * bookmark:
257 * type: string
258 * docs:
259 * type: array
260 * items:
261 * $ref: '#/definitions/Entity'
262 */
263 router.all(
264 '/entities/find.:ext?',
265 cacheMiddleware,
266 asyncMiddleware(async (req, res) => {
267 let children = (req.query.children || req.body.children) !== undefined
268 ? JSON.parse((req.query.children || req.body.children)) : false;
269 let parents = (req.query.parents || req.body.parents) !== undefined
270 ? JSON.parse(req.query.parents || req.body.parents) : false;
271 const trashed = (req.query.trashed || req.body.trashed) !== undefined
272 ? JSON.parse(req.query.trashed || req.body.trashed) : false;
273 const query = req.query.query || req.body.query
274 ? JSON.parse(req.query.query || req.body.query) : { selector: {} };
275
276 query.use_index = ['entityIndex', 'entity'];
277
278 if (children === true) {
279 children = 1;
280 }
281 if (parents === true) {
282 parents = 1;
283 }
284
285 if (!query.selector.$and) {
286 query.selector = {
287 $and: [
288 query.selector,
289 ],
290 };
291 }
292
293 if (trashed) {
294 query.selector.$and.push({ trashed: true });
295 } else {
296 query.selector.$and.push({
297 $or: [
298 {
299 trashed: {
300 $exists: false,
301 },
302 },
303 {
304 trashed: false,
305 },
306 ],
307 });
308 }
309
310 if (req.session.role === 'guest') {
311 query.selector.$and.push({ published: true });
312 }
313
314 if (req.query.limit) {
315 query.limit = parseInt(req.query.limit, 10);
316 }
317
318 const entity = Entity(await getConfig(req.session.slug));
319
320 try {
321 handleResponse(req, res, await entity.entityFind(query, children, parents, req.session.role), true);
322 } catch (error) {
323 handleError(req, res, error);
324 }
325 })
326 );
327
328 router.get(
329 '/entities/field.:ext?',
330 cacheMiddleware,
331 asyncMiddleware(async (req, res) => {
332 const entity = Entity(await getConfig(req.session.slug));
333
334 try {
335 handleResponse(req, res, await entity.fieldValues(req.query.slug || req.query.fieldSlug, req.query.searchTerm), true);
336 } catch (error) {
337 handleError(res, error);
338 }
339 })
340 );
341
342 /**
343 * @swagger
344 * /entities:
345 * get:
346 * tags:
347 * - entities
348 * summary: Get all entities
349 * description: Get all entities, optionally from an array of IDs
350 * produces:
351 * - application/json
352 * parameters:
353 * - name: id
354 * description: Entity ID
355 * in: query
356 * required: false
357 * type: string
358 * - name: ids
359 * description: Entity IDs
360 * in: query
361 * required: false
362 * type: array
363 * items:
364 * type: string
365 * - name: children
366 * description: Get child entities
367 * in: query
368 * required: false
369 * type: boolean
370 * default: false
371 * - name: parents
372 * description: Get parent entities
373 * in: query
374 * required: false
375 * type: boolean
376 * default: false
377 * responses:
378 * 200:
379 * description: Entities
380 * schema:
381 * type: array
382 * items:
383 * $ref: '#/definitions/Entity'
384 */
385 router.all(
386 '/entities.:ext?',
387 cacheMiddleware,
388 asyncMiddleware(async (req, res) => {
389 let children = (req.query.children || req.body.children) !== undefined
390 ? JSON.parse(req.query.children || req.body.children) : false;
391 let parents = (req.query.parents || req.body.parents) !== undefined
392 ? JSON.parse(req.query.parents || req.body.parents) : false;
393
394 if (children === true) {
395 children = 1;
396 }
397 if (parents === true) {
398 parents = 1;
399 }
400
401 let ids = req.query.ids || req.query.id || req.body.ids || req.body.id;
402
403 if (ids) {
404 ids = isArray(ids) ? ids : [ids];
405 }
406
407 const entity = Entity(await getConfig(req.session.slug));
408
409 try {
410 handleResponse(req, res, await entity.entityList(ids, children, parents, req.session.role), true);
411 } catch (error) {
412 handleError(req, res, error);
413 }
414 })
415 );
416
417 router.get(
418 '/entity/revisions.:ext?',
419 authMiddleware,
420 permissionMiddleware.bind(null, 'entityRead'),
421 asyncMiddleware(async (req, res) => {
422 const entity = Entity(await getConfig(req.session.slug));
423
424 try {
425 handleResponse(req, res, await entity.entityRevisions(req.query.id));
426 } catch (error) {
427 handleError(req, res, error);
428 }
429 })
430 );
431
432 router.post(
433 '/entity.:ext?',
434 authMiddleware,
435 permissionMiddleware.bind(null, 'entityCreate'),
436 asyncMiddleware(async (req, res) => {
437 const entity = Entity(await getConfig(req.session.slug));
438
439 try {
440 handleResponse(req, res, await entity.entityCreate(req.body.entity));
441 } catch (error) {
442 handleError(req, res, error);
443 }
444 })
445 );
446
447 router.get(
448 '/entity.:ext?',
449 authMiddleware,
450 permissionMiddleware.bind(null, 'entityRead'),
451 asyncMiddleware(async (req, res) => {
452 const entity = Entity(await getConfig(req.session.slug));
453
454 try {
455 handleResponse(req, res, await entity.entityRead(req.query.id));
456 } catch (error) {
457 handleError(req, res, error);
458 }
459 })
460 );
461
462 router.put(
463 '/entity.:ext?',
464 authMiddleware,
465 permissionMiddleware.bind(null, 'entityUpdate'),
466 asyncMiddleware(async (req, res) => {
467 const entity = Entity(await getConfig(req.session.slug));
468
469 try {
470 handleResponse(req, res, await entity.entityUpdate(req.body.entity || req.body.entities, req.body.restore || false));
471 } catch (error) {
472 handleError(req, res, error);
473 }
474 })
475 );
476
477 router.delete(
478 '/entity.:ext?',
479 authMiddleware,
480 permissionMiddleware.bind(null, 'entityDelete'),
481 asyncMiddleware(async (req, res) => {
482 const entity = Entity(await getConfig(req.session.slug));
483
484 try {
485 handleResponse(req, res, await entity.entityDelete(req.body.entity || req.body.entities, req.body.forever || false));
486 } catch (error) {
487 handleError(req, res, error);
488 }
489 })
490 );
491
492 router.delete(
493 '/entity/trashed.:ext?',
494 authMiddleware,
495 permissionMiddleware.bind(null, 'entityDelete'),
496 asyncMiddleware(async (req, res) => {
497 const entity = Entity(await getConfig(req.session.slug));
498
499 try {
500 handleResponse(req, res, await entity.entityDelete('trashed'));
501 } catch (error) {
502 handleError(req, res, error);
503 }
504 })
505 );
506
507};