@indiekit/endpoint-media
Version:
Micropub media endpoint for Indiekit. Enables publishing media files (audio, photos, videos) to your website using the Micropub protocol.
104 lines (90 loc) • 3.35 kB
JavaScript
import { IndiekitError } from "@indiekit/error";
import { mediaContent } from "../media-content.js";
import { mediaData } from "../media-data.js";
import { mediaTransform } from "../media-transform.js";
import { checkScope } from "../scope.js";
/**
* Perform requested file action
* @param {object} imageProcessing - Sharp image processing options
* @returns {import("express").RequestHandler} - Next middleware
*/
export const actionController = (imageProcessing) =>
async function (request, response, next) {
const { app, body, files, query, session } = request;
const action = query.action || body?.action || "media";
const url = query.url || body?.url;
const { application, publication } = app.locals;
try {
// Check provided scope
const { scope } = session;
const hasScope = checkScope(scope);
if (!hasScope) {
throw IndiekitError.insufficientScope(
response.locals.__("ForbiddenError.insufficientScope"),
{ scope: action },
);
}
let data;
let content;
switch (action) {
case "media": {
// Check for file in request
if (!files || !files.file) {
throw IndiekitError.badRequest(
response.locals.__("BadRequestError.missingProperty", "file"),
);
}
const file = await mediaTransform(imageProcessing, files.file);
data = await mediaData.create(application, publication, file);
content = await mediaContent.upload(publication, data, file);
break;
}
case "delete": {
// Check for URL if deleting a file
if (action === "delete" && !url) {
throw IndiekitError.badRequest(
response.locals.__("BadRequestError.missingParameter", "url"),
);
}
data = await mediaData.read(application, url);
content = await mediaContent.delete(publication, data);
// Once file deleted from content store, delete data from database
await mediaData.delete(application, url);
break;
}
default:
}
response
.status(content.status)
.location(content.location)
.json(content.json);
} catch (error) {
let nextError = error;
switch (error.name) {
case "NotFoundError": {
// Hoist not found error to controller to localise response
nextError = IndiekitError.notFound(
response.locals.__("NotFoundError.record", error.message),
);
break;
}
case "UnsupportedMediaTypeError": {
// Hoist unsupported media type error to controller to localise response
nextError = IndiekitError.unsupportedMediaType(
response.locals.__("UnsupportedMediaTypeError.type", error.message),
);
break;
}
case "NotImplementedError": {
// Hoist unsupported post type error to controller to localise response
nextError = IndiekitError.notImplemented(
response.locals.__("NotImplementedError.postType", error.message),
{ uri: "https://getindiekit.com/configuration/post-types" },
);
break;
}
default:
}
return next(nextError);
}
};