Newer
Older
const { v4: uuid } = require('uuid')
const { logger } = require('@pubsweet/logger')
const find = require('lodash/find')
const BaseModel = require('../base.model')
const useTransaction = require('../useTransaction')
const {
arrayOfStrings,
stringNullable,
stringNotEmpty,
idNullable,
integerPositive,
id,
} = require('../_helpers/types')
// Type declaration
const mimetype = {
type: 'string',
pattern:
'^(application|audio|font|image|model|multipart|text|video)/[a-z0-9]+([-+.][a-z0-9]+)*$',
// if you want to know why this is default, look at
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
default: 'application/octet-stream',
}
const arrayOfStoredObjects = {
type: 'array',
items: {
type: 'object',
additionalProperties: false,
required: ['type', 'key', 'mimetype', 'extension', 'size'],
properties: {
id,
type: { type: 'string', enum: ['original', 'small', 'medium', 'full'] },
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
key: stringNotEmpty,
mimetype,
extension: stringNotEmpty,
imageMetadata: {
type: ['object', 'null'],
required: ['height', 'width'],
additionalProperties: false,
properties: {
id,
density: integerPositive,
height: integerPositive,
space: stringNotEmpty,
width: integerPositive,
},
},
size: integerPositive,
},
},
}
class File extends BaseModel {
constructor(properties) {
super(properties)
this.type = 'file'
}
static get tableName() {
return 'files'
}
static get schema() {
return {
type: 'object',
required: ['name', 'storedObjects'],
properties: {
alt: stringNullable,
caption: stringNullable,
name: stringNotEmpty,
objectId: idNullable,
storedObjects: arrayOfStoredObjects,
referenceId: idNullable,
tags: arrayOfStrings,
uploadStatus: stringNullable,
},
}
}
ensureIds() {
if (this.storedObjects) {
this.storedObjects.forEach((storedObject, index) => {
if (!storedObject.id) {
this.storedObjects[index].id = uuid()
}
if (storedObject.imageMetadata) {
if (!storedObject.imageMetadata.id) {
this.storedObjects[index].imageMetadata.id = uuid()
}
}
})
}
}
$beforeInsert(queryContext) {
super.$beforeInsert(queryContext)
this.ensureIds()
}
$beforeUpdate() {
super.$beforeUpdate()
this.ensureIds()
}
static async getEntityFiles(objectId, options = {}) {
try {
const { trx } = options
return useTransaction(
async tr => {
const { result: files } = await File.find({ objectId }, options)
return files
},
{ trx, passedTrxOnly: true },
)
} catch (e) {
logger.error('File model: getEntityFiles failed', e)
throw new Error(
`File model: Cannot get files for entity with id ${objectId}`,
)
}
}
getStoredObjectBasedOnType(type) {
try {
const found = find(this.storedObjects, { type })
if (!found) {
throw new Error('Unknown type of stored object provided')
}
return found
} catch (e) {
throw new Error(e.message)
}
}