diff --git a/lib/api/index.js b/lib/api/index.js index c587a2b..e4becfd 100644 --- a/lib/api/index.js +++ b/lib/api/index.js @@ -48,6 +48,7 @@ class Api { minioUser = null, minioPassword = null, minioBucket = null, + defaultMediaProvider = null, }) { this.jwt = jwt; this.baseUrl = baseUrl; @@ -59,11 +60,13 @@ class Api { this.usersEntity = usersEntity; this.accessTokenUserIdKey = accessTokenUserIdKey; this.softDeletes = softDeletes; - this.minioOptions = { - minioApi, - minioUser, - minioPassword, - minioBucket, + this.mediaOptions = { + [defaultMediaProvider]: { + minioApi, + minioUser, + minioPassword, + minioBucket, + }, }; } @@ -246,7 +249,7 @@ class Api { * @returns {object} The items object */ items(name) { - return new Items(name, axios, this.minioOptions); + return new Items(name, axios, this.mediaOptions); } } diff --git a/lib/api/items.js b/lib/api/items.js index 73a8088..3551a9e 100644 --- a/lib/api/items.js +++ b/lib/api/items.js @@ -15,10 +15,10 @@ export default class Items { * @param {object} axios The axios instance to be used for API requests * @param {object} preProcessorOptions global configuration object */ - constructor(name, axios, preProcessorOptions) { + constructor(name, axios, mediaOptions) { this.name = name; this.axios = axios; - this.preProcessorOptions = preProcessorOptions; + this.mediaOptions = mediaOptions; } /** @@ -240,11 +240,34 @@ export default class Items { if (opts.preProcessors) { await Promise.all( Object.keys(opts.preProcessors).map(async (prop) => { - payload[prop] = await preProcessors[opts.preProcessors[prop]]( + const provider = Object.keys(this.mediaOptions)[0]; + const data = await preProcessors[opts.preProcessors[prop]]( payload[prop], this.axios, - this.preProcessorOptions + this.mediaOptions[provider] ); + + if (!data) { + delete payload[prop]; + } + delete payload[prop].base64; + const mediaEntity = api.createEntity('media', { + url: data.url, + type: data.type, + provider, + ...payload[prop], + }); + + const foreignKey = mediaEntity['@id']; + delete mediaEntity['@id']; + await this.axios.post(`/api/media`, mediaEntity, { + headers: { + 'Content-Type': 'application/ld+json', + Accept: 'application/ld+json', + }, + }); + + payload[prop] = foreignKey; }) ); } @@ -276,15 +299,34 @@ export default class Items { if (opts.preProcessors) { await Promise.all( Object.keys(opts.preProcessors).map(async (prop) => { - payload[prop] = await preProcessors[opts.preProcessors[prop]]( + const provider = Object.keys(this.mediaOptions)[0]; + const data = await preProcessors[opts.preProcessors[prop]]( payload[prop], this.axios, - this.preProcessorOptions + this.mediaOptions[provider] ); - if (!payload[prop]) { + if (!data) { delete payload[prop]; } + delete payload[prop].base64; + const mediaEntity = api.createEntity('media', { + url: data.url, + type: data.type, + provider, + ...payload[prop], + }); + + const foreignKey = mediaEntity['@id']; + delete mediaEntity['@id']; + await this.axios.post(`/api/media`, mediaEntity, { + headers: { + 'Content-Type': 'application/ld+json', + Accept: 'application/ld+json', + }, + }); + + payload[prop] = foreignKey; }) ); } diff --git a/lib/api/preProcessors/index.js b/lib/api/preProcessors/index.js index 21e1d50..6bdfd02 100644 --- a/lib/api/preProcessors/index.js +++ b/lib/api/preProcessors/index.js @@ -1,5 +1,5 @@ -import mediaObject from './mediaObject'; +import media from './media'; export default { - mediaObject, + media, }; diff --git a/lib/api/preProcessors/mediaObject.js b/lib/api/preProcessors/media.js similarity index 97% rename from lib/api/preProcessors/mediaObject.js rename to lib/api/preProcessors/media.js index 453966a..aaa6755 100644 --- a/lib/api/preProcessors/mediaObject.js +++ b/lib/api/preProcessors/media.js @@ -85,7 +85,10 @@ export default async function (value, axios, options) { await uploadFile(client, params); - return `${options.minioBucket}/${fileID}.${fileExtension}`; + return { + url: `${options.minioBucket}/${fileID}.${fileExtension}`, + type: blob.type, + }; } else if (Array.isArray(value)) { value = await Promise.all( value.map(async (file) => { diff --git a/lib/module.js b/lib/module.js index 5183acb..68f8753 100644 --- a/lib/module.js +++ b/lib/module.js @@ -24,7 +24,7 @@ export default function (moduleOptions) { const templatesToSync = [ 'api/items.js', 'api/preProcessors/index.js', - 'api/preProcessors/mediaObject.js', + 'api/preProcessors/media.js', ]; for (const pathString of templatesToSync) { this.addTemplate({ diff --git a/lib/plugin.js b/lib/plugin.js index f4d1a19..806d9e6 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -18,6 +18,7 @@ export default async (ctx, inject) => { minioUser: options.minioUser, minioPassword: options.minioPassword, minioBucket: options.minioBucket, + defaultMediaProvider: options.defaultMediaProvider, }); const authModule = { @@ -129,8 +130,17 @@ class Auth { authError.message = 'Authentication Failure'; authError.data = 'You entered invalid credentials'; throw authError; + } + if (error.message === 'Network Error') { + const networkError = new Error('NetworkError'); + networkError.message = 'Network Failure'; + networkError.data = 'No connection to the server'; + throw networkError; } else { - throw new Error(error); + const unexpectedError = new Error('UnexpectedError'); + unexpectedError.message = 'Unexpected Failure'; + unexpectedError.data = 'An unexpected error ocurred'; + throw unexpectedError; } } }