|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- // Copyright (c) 2020 Jan Kaßel
- // Copyright (c) 2022 Gerben
- //
- // SPDX-License-Identifier: MIT
-
- import { v4 as uuid } from 'uuid';
- // import validateAnnotation from 'validate-web-annotation';
- import db from '../db.js';
- import { Container, sendAnnotation, extractAnnotationIdFromUrl } from '../ldp.js';
- import type { Request, Response } from 'express';
- import { asArray } from 'web-annotation-utils';
-
- export async function createAnnotation(req: Request, res: Response) {
- const collectionKey = `${req.params.user}/${req.params.collection}`;
- try {
- await db.get(collectionKey);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
- if (!req.body) {
- res.status(400).send('Bad request: Missing request body');
- return;
- }
-
- const annotation = req.body;
- // TODO Improve validator; it appears to disagree about the date format.
- // if (!validateAnnotation(annotation, { optionalId: true })) {
- // res.status(400).send('Bad request: Invalid body schema');
- // return;
- // }
-
- const id = uuid();
- const annotationKey = `${collectionKey}/${id}`;
- if (annotation.id) {
- annotation.via = [...asArray(annotation.via), annotation.id];
- }
- annotation.id = id;
-
- try {
- await db.get(annotationKey);
- res.status(409).send('Conflict');
- } catch (err: any) {
- if (!err.notFound) {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- return;
- }
-
- annotation.creator ??= {
- type: 'Person',
- nickname: req.params.user,
- };
-
- await db.put(annotationKey, annotation);
-
- const collectionInfo = await db.get(collectionKey);
- const containerInfo = new Container(req, collectionKey, collectionInfo);
- res
- .status(201)
- .header('Location', `/${annotationKey}`)
- .header('Content-Location', `/${annotationKey}`);
- sendAnnotation(req, res, annotation, containerInfo);
- }
- }
-
- export async function getAnnotation(req: Request, res: Response) {
- const collectionKey = `${req.params.user}/${req.params.collection}`;
-
- try {
- await db.get(collectionKey);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
-
- const annotationKey = `${collectionKey}/${req.params.annotation}`;
- try {
- const annotation = await db.get(annotationKey);
- const collectionInfo = await db.get(collectionKey);
- const containerInfo = new Container(req, collectionKey, collectionInfo);
- sendAnnotation(req, res, annotation, containerInfo);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
- }
-
- export async function updateAnnotation(req: Request, res: Response) {
- const collectionKey = `${req.params.user}/${req.params.collection}`;
- try {
- await db.get(collectionKey);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
-
- const annotation = req.body;
- if (
- !annotation ||
- // TODO Improve validator; it appears to disagree about the date format.
- // || !validateAnnotation(annotation)
- !annotation.id
- ) {
- res.status(400).send('Bad request: Invalid body schema');
- return;
- }
-
- const collectionInfo = await db.get(collectionKey);
- const containerInfo = new Container(req, collectionKey, collectionInfo);
- const normalizedId = extractAnnotationIdFromUrl(
- annotation.id,
- containerInfo.url,
- );
- if (!normalizedId) {
- res
- .status(400)
- .send(
- `Bad Request: Annotation ID did not match the expected container IRI: ${containerInfo.url}`,
- );
- return;
- }
- const contractedAnnotation = {
- ...annotation,
- id: normalizedId,
- };
- const annotationKey = `${collectionKey}/${contractedAnnotation.id}`;
- try {
- await db.get(annotationKey);
- await db.put(annotationKey, contractedAnnotation);
-
- const collectionInfo = await db.get(collectionKey);
- const containerInfo = new Container(req, collectionKey, collectionInfo);
- sendAnnotation(req, res, contractedAnnotation, containerInfo);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
- }
-
- export async function deleteAnnotation(req: Request, res: Response) {
- const collectionKey = `${req.params.user}/${req.params.collection}`;
- try {
- await db.get(collectionKey);
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
-
- const annotationKey = `${collectionKey}/${req.params.annotation}`;
- try {
- await db.get(annotationKey);
- await db.del(annotationKey);
- res.status(204).send();
- } catch (err: any) {
- if (err.notFound) {
- res.status(404).send('Not found');
- } else {
- console.error(req.method, req.path, err);
- res.status(500).send('Internal server error');
- }
- return;
- }
- }
|