You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
4.5 KiB
159 lines
4.5 KiB
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<Server, IncomingMessage, ServerResponse>) {
|
|
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<DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody>('/v1/sas', options, async () => {
|
|
return {
|
|
sas: generateSAS('arcw', 5),
|
|
blobUrl: getBlobUrl(),
|
|
id: createId(),
|
|
}
|
|
})
|
|
}
|
|
|
|
function addRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
|
|
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<DefaultQuery, DefaultParams, DefaultHeaders, Body>('/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<Media>({
|
|
container,
|
|
id: name,
|
|
partitionKey: MEDIA_PARTITION_KEY,
|
|
})
|
|
|
|
reply.code(204)
|
|
|
|
if (item) return
|
|
|
|
await container.items.create<Media>({
|
|
id: name,
|
|
pk: MEDIA_PARTITION_KEY,
|
|
size,
|
|
type,
|
|
originalName,
|
|
attached: false,
|
|
created: Date.now(),
|
|
})
|
|
})
|
|
}
|
|
|
|
function deleteRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
|
|
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<DefaultQuery, Params, DefaultHeaders, DefaultBody>('/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<Media>()
|
|
|
|
if (!media) return badRequestError(reply)
|
|
|
|
reply.code(204)
|
|
|
|
if (media.attached) return
|
|
|
|
await mediaItem.delete()
|
|
await deleteMedia(request.body.name)
|
|
})
|
|
}
|
|
|
|
const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = async server => {
|
|
getSASRoute(server)
|
|
addRoute(server)
|
|
deleteRoute(server)
|
|
}
|
|
|
|
export default plugin
|