import { FastifyInstance, Plugin, DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody, RouteShorthandOptions, } from 'fastify' import { Server, IncomingMessage, ServerResponse } from 'http' import { MEDIA_PARTITION_KEY } from '../../constants' import { errorSchema } from '../../schemas' import { containerFor, getItem } from '../../lib/database' import { badRequestError, serverError } from '../../lib/errors' import { deleteMedia, generateSAS, getBlobUrl } from '../../lib/media' import { createId } from '../../lib/utils' import { Media } from '../../types/collections' import { PluginOptions } from '../../types' function getSASRoute(server: FastifyInstance) { const options: RouteShorthandOptions = { schema: { description: 'Get a shared access signature.', tags: ['media'], response: { 200: { type: 'object', properties: { sas: { type: 'string' }, blobUrl: { type: 'string' }, id: { type: 'string' }, }, }, }, }, } server.get('/v1/sas', options, async () => { return { sas: generateSAS('arcw', 5), blobUrl: getBlobUrl(), id: createId(), } }) } function addRoute(server: FastifyInstance) { interface Body { name: string size: number type: string originalName: string } const options: RouteShorthandOptions = { schema: { description: 'Create a Media item.', tags: ['media'], body: { type: 'object', required: ['name', 'size', 'type', 'originalName'], properties: { name: { type: 'string' }, size: { type: 'number' }, type: { type: 'string' }, originalName: { type: 'string' }, }, }, response: { 204: { description: 'Media item created.', type: 'object', }, 400: errorSchema, }, }, } server.post('/v1/media', options, async (request, reply) => { if (!server.database) return serverError(reply) const { name, size, type, originalName } = request.body const container = containerFor(server.database.client, 'Media') const item = await getItem({ container, id: name, partitionKey: MEDIA_PARTITION_KEY, }) reply.code(204) if (item) return await container.items.create({ id: name, pk: MEDIA_PARTITION_KEY, size, type, originalName, attached: false, created: Date.now(), }) }) } function deleteRoute(server: FastifyInstance) { interface Params { name: string } const options: RouteShorthandOptions = { schema: { description: 'Delete a media item.', tags: ['media'], querystring: { type: 'object', required: ['name'], properties: { name: { type: 'string' }, }, }, response: { 204: { description: 'Media item deleted.', type: 'object', }, 400: errorSchema, }, }, } server.delete('/v1/media', options, async (request, reply) => { if (!server.database) return serverError(reply) const mediaItem = containerFor(server.database.client, 'Media').item(request.query.name, MEDIA_PARTITION_KEY) const { resource: media } = await mediaItem.read() if (!media) return badRequestError(reply) reply.code(204) if (media.attached) return await mediaItem.delete() await deleteMedia(request.body.name) }) } const plugin: Plugin = async server => { getSASRoute(server) addRoute(server) deleteRoute(server) } export default plugin