monastery 1.36.3 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +12 -0
- package/docs/image-plugin.md +11 -10
- package/docs/manager/index.md +2 -0
- package/docs/readme.md +4 -4
- package/lib/index.js +12 -11
- package/lib/model-crud.js +1 -1
- package/lib/model-validate.js +3 -2
- package/lib/model.js +1 -1
- package/package.json +2 -2
- package/plugins/images/index.js +79 -45
- package/test/assets/house.jpg +0 -0
- package/test/crud.js +2 -2
- package/test/model.js +1 -2
- package/test/plugin-images.js +637 -384
package/changelog.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.37.0](https://github.com/boycce/monastery/compare/1.36.3...1.37.0) (2022-06-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* added manager options (path, params, getSignedUrl, filesize, awsAcl) ([3e95609](https://github.com/boycce/monastery/commit/3e95609385820ecfd606500676fa87f8c9b4f02d))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* warnings printing by default ([e1dc442](https://github.com/boycce/monastery/commit/e1dc442f20c78fcc65e19afaf5f0f8410bbcc31d))
|
|
16
|
+
|
|
5
17
|
### [1.36.3](https://github.com/boycce/monastery/compare/1.36.2...1.36.3) (2022-05-27)
|
|
6
18
|
|
|
7
19
|
|
package/docs/image-plugin.md
CHANGED
|
@@ -10,11 +10,15 @@ To use the default image plugin shipped with monastery, you need to use the opti
|
|
|
10
10
|
```js
|
|
11
11
|
let db = monastery('localhost/mydb', {
|
|
12
12
|
imagePlugin: {
|
|
13
|
+
awsAcl: 'public-read', // default
|
|
13
14
|
awsBucket: 'your-bucket-name',
|
|
14
15
|
awsAccessKeyId: 'your-key-here',
|
|
15
16
|
awsSecretAccessKey: 'your-key-here',
|
|
16
|
-
|
|
17
|
-
formats: ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'tiff'] //
|
|
17
|
+
filesize: undefined, // default (max filesize in bytes)
|
|
18
|
+
formats: ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'tiff'], // default (use 'any' to allow all extensions)
|
|
19
|
+
getSignedUrl: false, // default (get a S3 signed url after `model.find()`, can be defined per request)
|
|
20
|
+
path: (uid, basename, ext, file) => `/full/${uid}.${ext}`, // default
|
|
21
|
+
params: {}, // upload params (https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property)
|
|
18
22
|
}
|
|
19
23
|
})
|
|
20
24
|
```
|
|
@@ -25,15 +29,12 @@ Then in your model definition, e.g.
|
|
|
25
29
|
let user = db.model('user', {
|
|
26
30
|
fields: {
|
|
27
31
|
logo: {
|
|
28
|
-
type: 'image',
|
|
29
|
-
|
|
30
|
-
filename: 'avatar',
|
|
31
|
-
filesize: 1000 * 1000 * 5, // max size in bytes
|
|
32
|
-
getSignedUrl: true, // get a s3 signed url after every `find()` operation (can be overridden per request)
|
|
33
|
-
params: {}, // upload params, https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
|
32
|
+
type: 'image',
|
|
33
|
+
// ...any imagePlugin option, excluding awsAccessKeyId and awsSecretAccessKey
|
|
34
34
|
},
|
|
35
35
|
logos: [{
|
|
36
|
-
type: 'image'
|
|
36
|
+
type: 'image',
|
|
37
|
+
// ...any imagePlugin option, excluding awsAccessKeyId and awsSecretAccessKey
|
|
37
38
|
}],
|
|
38
39
|
}
|
|
39
40
|
})
|
|
@@ -61,6 +62,6 @@ user.update({
|
|
|
61
62
|
|
|
62
63
|
### File types
|
|
63
64
|
|
|
64
|
-
Due to known limitations, we are
|
|
65
|
+
Due to known limitations, we are not able to verify the contents of non-binary files, only the filename extension (e.g. .txt, .svg) before uploading to S3
|
|
65
66
|
|
|
66
67
|
...to be continued
|
package/docs/manager/index.md
CHANGED
|
@@ -13,6 +13,8 @@ Monastery constructor, same as the [monk constructor](https://automattic.github.
|
|
|
13
13
|
`uri` *(string\|array)*: A [mongo connection string URI](https://docs.mongodb.com/manual/reference/connection-string/). Replica sets can be an array or comma separated.
|
|
14
14
|
|
|
15
15
|
[`options`] *(object)*:
|
|
16
|
+
- [`hideWarnings=false`] *(boolean)*: hide monastery warnings
|
|
17
|
+
- [`hideErrors=false`] *(boolean)*: hide monastery errors
|
|
16
18
|
- [`defaultObjects=false`] *(boolean)*: when [inserting](../model/insert.html#defaults-example), undefined embedded documents and arrays are defined
|
|
17
19
|
- [`nullObjects=false`] *(boolean)*: embedded documents and arrays can be set to null or an empty string (which gets converted to null). You can override this per field via `nullObject: true`.
|
|
18
20
|
- [`timestamps=true`] *(boolean)*: whether to use [`createdAt` and `updatedAt`](../definition), this can be overridden per operation
|
package/docs/readme.md
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* Custom error messages can be defined in your model definition
|
|
11
11
|
* Normalised error responses ready for client consumption
|
|
12
12
|
* Automatic mongodb index setup
|
|
13
|
+
* CRUD operations can accept bracket (multipart/form-data) and dot notation data formats, you can also mix these together
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
## Install
|
|
15
17
|
|
|
@@ -63,12 +65,10 @@ db.user.insert({
|
|
|
63
65
|
```
|
|
64
66
|
## Debugging
|
|
65
67
|
|
|
66
|
-
This package uses [
|
|
68
|
+
This package uses [debug](https://github.com/visionmedia/debug) which allows you to set different levels of output via the `DEBUG` environment variable. Due to known limations `monastery:warning` and `monastery:error` are forced on, you can however disable these via [manager settings](./manager).
|
|
67
69
|
|
|
68
70
|
```bash
|
|
69
|
-
$ DEBUG=monastery:info
|
|
70
|
-
# or show all levels of output, currently shows the same output as above
|
|
71
|
-
$ DEBUG=monastery:*
|
|
71
|
+
$ DEBUG=monastery:info # shows operation information
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
To run isolated tests with Jest:
|
package/lib/index.js
CHANGED
|
@@ -16,13 +16,19 @@ module.exports = function(uri, opts, fn) {
|
|
|
16
16
|
* @param {object} opts
|
|
17
17
|
* @return monk manager
|
|
18
18
|
*/
|
|
19
|
+
if (!opts) opts = {}
|
|
19
20
|
let monasteryOpts = [
|
|
20
|
-
'defaultObjects', '
|
|
21
|
+
'defaultObjects', 'hideWarnings', 'hideErrors', 'imagePlugin', 'limit', 'nullObjects',
|
|
22
|
+
'timestamps', 'useMilliseconds',
|
|
21
23
|
]
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
// Note: Debug doesn't allow debuggers to be enabled by default
|
|
26
|
+
let info = debug('monastery:info')
|
|
27
|
+
let warn = debug('monastery:warn' + (opts.hideWarnings ? '' : '*'))
|
|
28
|
+
let error = debug('monastery:error' + (opts.hideErrors ? '' : '*'))
|
|
29
|
+
|
|
24
30
|
if (util.isDefined(opts.defaultFields)) {
|
|
25
|
-
|
|
31
|
+
warn('opts.defaultFields has been depreciated in favour of opts.timestamps')
|
|
26
32
|
opts.timestamps = opts.defaultFields
|
|
27
33
|
delete opts.defaultFields
|
|
28
34
|
}
|
|
@@ -44,20 +50,15 @@ module.exports = function(uri, opts, fn) {
|
|
|
44
50
|
manager.model = require('./model')
|
|
45
51
|
manager.models = models
|
|
46
52
|
manager.parseData = util.parseData.bind(util)
|
|
47
|
-
manager.
|
|
48
|
-
manager.
|
|
49
|
-
manager.
|
|
53
|
+
manager.info = info
|
|
54
|
+
manager.warn = warn
|
|
55
|
+
manager.error = error
|
|
50
56
|
|
|
51
57
|
// Add opts onto manager
|
|
52
58
|
for (let key of monasteryOpts) {
|
|
53
59
|
manager[key] = opts[key]
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
// Depreciation warnings
|
|
57
|
-
if (depreciationWarningDefaultField) {
|
|
58
|
-
manager.error('opts.defaultFields has been depreciated in favour of opts.timestamps')
|
|
59
|
-
}
|
|
60
|
-
|
|
61
62
|
// Initiate any plugins
|
|
62
63
|
if (manager.imagePlugin) {
|
|
63
64
|
manager.imagePluginFile.setup(manager, util.isObject(manager.imagePlugin)? manager.imagePlugin : {})
|
package/lib/model-crud.js
CHANGED
|
@@ -238,7 +238,7 @@ module.exports = {
|
|
|
238
238
|
await util.runSeries(this.beforeUpdate.map(f => f.bind(opts, data||{})))
|
|
239
239
|
|
|
240
240
|
if (data && operators['$set']) {
|
|
241
|
-
this.
|
|
241
|
+
this.info(`'$set' fields take precedence over the data fields for \`${this.name}.${type}()\``)
|
|
242
242
|
}
|
|
243
243
|
if (data || operators['$set']) {
|
|
244
244
|
operators['$set'] = { ...data, ...(operators['$set'] || {}) }
|
package/lib/model-validate.js
CHANGED
|
@@ -266,8 +266,9 @@ module.exports = {
|
|
|
266
266
|
|
|
267
267
|
_ignoredRules: [ // todo: change name? i.e. 'specialFields'
|
|
268
268
|
// Need to remove filesize and formats..
|
|
269
|
-
'
|
|
270
|
-
'model', 'nullObject', 'params', '
|
|
269
|
+
'awsAcl', 'awsBucket', 'default', 'defaultOverride', 'filename', 'filesize', 'fileSize', 'formats',
|
|
270
|
+
'image', 'index', 'insertOnly', 'model', 'nullObject', 'params', 'path', 'getSignedUrl', 'timestampField',
|
|
271
|
+
'type', 'virtual',
|
|
271
272
|
]
|
|
272
273
|
|
|
273
274
|
}
|
package/lib/model.js
CHANGED
|
@@ -86,7 +86,7 @@ let Model = module.exports = function(name, opts, manager) {
|
|
|
86
86
|
if (typeof this.manager[name] === 'undefined' || typeof this.manager.model[name] !== 'undefined') {
|
|
87
87
|
this.manager[name] = this
|
|
88
88
|
} else {
|
|
89
|
-
this.warn(`Your model name '${name}' is conflicting, you are only able to
|
|
89
|
+
this.warn(`Your model name '${name}' is conflicting with an builtin manager property, you are only able to
|
|
90
90
|
access this model via \`db.model.${name}\``)
|
|
91
91
|
}
|
|
92
92
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "monastery",
|
|
3
3
|
"description": "⛪ A straight forward MongoDB ODM built around Monk",
|
|
4
4
|
"author": "Ricky Boyce",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.37.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "github:boycce/monastery",
|
|
8
8
|
"homepage": "https://boycce.github.io/monastery/",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"mongo odm"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
-
"dev": "npm run lint &
|
|
20
|
+
"dev": "npm run lint & jest --watchAll --runInBand --verbose=false",
|
|
21
21
|
"docs": "cd docs && bundle exec jekyll serve --livereload --livereload-port 4001",
|
|
22
22
|
"lint": "eslint ./lib ./plugins ./test",
|
|
23
23
|
"mong": "nodemon resources/mong.js",
|
package/plugins/images/index.js
CHANGED
|
@@ -18,13 +18,24 @@ let plugin = module.exports = {
|
|
|
18
18
|
* @this plugin
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
// Depreciation warnings
|
|
22
|
+
if (options.bucketDir) { // > 1.36.2
|
|
23
|
+
manager.warn('imagePlugin.bucketDir has been depreciated in favour of imagePlugin.path')
|
|
24
|
+
options.path = function (uid, basename, ext, file) { `${options.bucketDir}/${uid}.${ext}` }
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
// Settings
|
|
28
|
+
this.awsAcl = options.awsAcl || 'public-read'
|
|
22
29
|
this.awsBucket = options.awsBucket
|
|
23
30
|
this.awsAccessKeyId = options.awsAccessKeyId
|
|
24
31
|
this.awsSecretAccessKey = options.awsSecretAccessKey
|
|
25
|
-
this.bucketDir = options.bucketDir || 'full'
|
|
32
|
+
this.bucketDir = options.bucketDir || 'full' // depreciated > 1.36.2
|
|
33
|
+
this.filesize = options.filesize
|
|
26
34
|
this.formats = options.formats || ['bmp', 'gif', 'jpg', 'jpeg', 'png', 'tiff']
|
|
35
|
+
this.getSignedUrl = options.getSignedUrl
|
|
27
36
|
this.manager = manager
|
|
37
|
+
this.params = options.params ? util.deepCopy(options.params) : {},
|
|
38
|
+
this.path = options.path || function (uid, basename, ext, file) { return `full/${uid}.${ext}` }
|
|
28
39
|
|
|
29
40
|
if (!options.awsBucket || !options.awsAccessKeyId || !options.awsSecretAccessKey) {
|
|
30
41
|
manager.error('Monastery imagePlugin: awsBucket, awsAccessKeyId, or awsSecretAccessKey is not defined')
|
|
@@ -34,7 +45,7 @@ let plugin = module.exports = {
|
|
|
34
45
|
|
|
35
46
|
// Create s3 'service' instance
|
|
36
47
|
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#constructor-property
|
|
37
|
-
manager.
|
|
48
|
+
manager._getSignedUrl = this._getSignedUrl
|
|
38
49
|
this.s3 = new S3({
|
|
39
50
|
credentials: {
|
|
40
51
|
accessKeyId: this.awsAccessKeyId,
|
|
@@ -114,9 +125,13 @@ let plugin = module.exports = {
|
|
|
114
125
|
if (util.isArray(data)) {
|
|
115
126
|
return Promise.reject('Adding images to mulitple data objects is not supported.')
|
|
116
127
|
|
|
128
|
+
// We currently don't support an array of data objects.
|
|
129
|
+
} else if (!util.isObject(data)) {
|
|
130
|
+
return Promise.reject('No creat e/ update data object passed to addImages?')
|
|
131
|
+
|
|
117
132
|
// We require the update query OR data object to contain _id. This is because non-id queries
|
|
118
133
|
// will not suffice when updating the document(s) against the same query again.
|
|
119
|
-
} else if (!data._id && (!query || !query._id)) {
|
|
134
|
+
} else if (!(data||{})._id && (!query || !query._id)) {
|
|
120
135
|
return Promise.reject('Adding images requires the update operation to query via _id\'s.')
|
|
121
136
|
}
|
|
122
137
|
|
|
@@ -126,36 +141,36 @@ let plugin = module.exports = {
|
|
|
126
141
|
return Promise.all(filesArr.map(file => {
|
|
127
142
|
return new Promise((resolve, reject) => {
|
|
128
143
|
let uid = nanoid.nanoid()
|
|
129
|
-
let
|
|
144
|
+
let path = filesArr.imageField.path || plugin.path
|
|
130
145
|
let image = {
|
|
131
|
-
bucket: plugin.awsBucket,
|
|
146
|
+
bucket: filesArr.imageField.awsBucket || plugin.awsBucket,
|
|
132
147
|
date: plugin.manager.useMilliseconds? Date.now() : Math.floor(Date.now() / 1000),
|
|
133
148
|
filename: file.name,
|
|
134
149
|
filesize: file.size,
|
|
135
|
-
path:
|
|
150
|
+
path: path(uid, file.name, file.ext, file),
|
|
136
151
|
// sizes: ['large', 'medium', 'small'],
|
|
137
152
|
uid: uid,
|
|
138
153
|
}
|
|
154
|
+
let s3Options = {
|
|
155
|
+
// ACL: Some IAM permissions "s3:PutObjectACL" must be included in the policy
|
|
156
|
+
// params: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
|
157
|
+
ACL: filesArr.imageField.awsAcl || plugin.awsAcl,
|
|
158
|
+
Body: file.data,
|
|
159
|
+
Bucket: image.bucket,
|
|
160
|
+
Key: image.path,
|
|
161
|
+
...(filesArr.imageField.params || plugin.params),
|
|
162
|
+
}
|
|
139
163
|
plugin.manager.info(
|
|
140
164
|
`Uploading '${image.filename}' to '${image.bucket}/${image.path}'`
|
|
141
165
|
)
|
|
142
166
|
if (test) {
|
|
143
167
|
plugin._addImageObjectsToData(filesArr.inputPath, data, image)
|
|
144
|
-
resolve()
|
|
168
|
+
resolve(s3Options)
|
|
145
169
|
} else {
|
|
146
|
-
plugin.s3.upload({
|
|
147
|
-
Bucket: plugin.awsBucket,
|
|
148
|
-
Key: image.path,
|
|
149
|
-
Body: file.data,
|
|
150
|
-
// The IAM permission "s3:PutObjectACL" must be included in the appropriate policy
|
|
151
|
-
ACL: 'public-read',
|
|
152
|
-
// upload params,https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property
|
|
153
|
-
...filesArr.imageField.params,
|
|
154
|
-
|
|
155
|
-
}, (err, response) => {
|
|
170
|
+
plugin.s3.upload(s3Options, (err, response) => {
|
|
156
171
|
if (err) return reject(err)
|
|
157
172
|
plugin._addImageObjectsToData(filesArr.inputPath, data, image)
|
|
158
|
-
resolve()
|
|
173
|
+
resolve(s3Options)
|
|
159
174
|
})
|
|
160
175
|
}
|
|
161
176
|
})
|
|
@@ -163,11 +178,11 @@ let plugin = module.exports = {
|
|
|
163
178
|
}))
|
|
164
179
|
|
|
165
180
|
// Save the data against the matching document(s)
|
|
166
|
-
}).then(() => {
|
|
167
|
-
// Remove update's _output object
|
|
181
|
+
}).then((s3Options) => {
|
|
168
182
|
let prunedData = { ...data }
|
|
183
|
+
// Remove update's _output object
|
|
169
184
|
delete prunedData._output
|
|
170
|
-
if (test) return [prunedData]
|
|
185
|
+
if (test) return [prunedData, s3Options]
|
|
171
186
|
return model._update(
|
|
172
187
|
idquery,
|
|
173
188
|
{ '$set': prunedData },
|
|
@@ -196,10 +211,11 @@ let plugin = module.exports = {
|
|
|
196
211
|
// Find all image objects in data
|
|
197
212
|
for (let doc of util.toArray(data)) {
|
|
198
213
|
for (let imageField of this.imageFields) {
|
|
199
|
-
if (options.getSignedUrls
|
|
214
|
+
if (options.getSignedUrls
|
|
215
|
+
|| (util.isDefined(imageField.getSignedUrl) ? imageField.getSignedUrl : plugin.getSignedUrl)) {
|
|
200
216
|
let images = plugin._findImagesInData(doc, imageField, 0, '').filter(o => o.image)
|
|
201
217
|
for (let image of images) {
|
|
202
|
-
image.image.signedUrl = plugin._getSignedUrl(image.image.path)
|
|
218
|
+
image.image.signedUrl = plugin._getSignedUrl(image.image.path, 3600, imageField.awsBucket)
|
|
203
219
|
}
|
|
204
220
|
}
|
|
205
221
|
}
|
|
@@ -346,7 +362,10 @@ let plugin = module.exports = {
|
|
|
346
362
|
// the file doesnt get deleted, we only delete from plugin.awsBucket.
|
|
347
363
|
if (!unused.length) return
|
|
348
364
|
await new Promise((resolve, reject) => {
|
|
349
|
-
plugin.s3.deleteObjects({
|
|
365
|
+
plugin.s3.deleteObjects({
|
|
366
|
+
Bucket: plugin.awsBucket,
|
|
367
|
+
Delete: { Objects: unused }
|
|
368
|
+
}, (err, data) => {
|
|
350
369
|
if (err) reject(err)
|
|
351
370
|
resolve()
|
|
352
371
|
})
|
|
@@ -410,7 +429,7 @@ let plugin = module.exports = {
|
|
|
410
429
|
return Promise.all(filesArr.map((file, i) => {
|
|
411
430
|
return new Promise((resolve, reject) => {
|
|
412
431
|
fileType.fromBuffer(file.data).then(res => {
|
|
413
|
-
let
|
|
432
|
+
let filesize = filesArr.imageField.filesize || plugin.filesize
|
|
414
433
|
let formats = filesArr.imageField.formats || plugin.formats
|
|
415
434
|
let allowAny = util.inArray(formats, 'any')
|
|
416
435
|
file.format = res? res.ext : ''
|
|
@@ -421,9 +440,9 @@ let plugin = module.exports = {
|
|
|
421
440
|
title: filesArr.inputPath + (i? `.${i}` : ''),
|
|
422
441
|
detail: `The file size for '${file.nameClipped}' is too big.`
|
|
423
442
|
})
|
|
424
|
-
else if (
|
|
443
|
+
else if (filesize && filesize < file.size) reject({ // file.size == bytes
|
|
425
444
|
title: filesArr.inputPath + (i? `.${i}` : ''),
|
|
426
|
-
detail: `The file size for '${file.nameClipped}' is bigger than ${(
|
|
445
|
+
detail: `The file size for '${file.nameClipped}' is bigger than ${(filesize/1000/1000).toFixed(1)}MB.`
|
|
427
446
|
})
|
|
428
447
|
else if (file.ext == 'unknown') reject({
|
|
429
448
|
title: filesArr.inputPath + (i? `.${i}` : ''),
|
|
@@ -446,8 +465,10 @@ let plugin = module.exports = {
|
|
|
446
465
|
* @param {object|array} fields
|
|
447
466
|
* @param {string} path
|
|
448
467
|
* @return [{}, ...]
|
|
468
|
+
* @this plugin
|
|
449
469
|
*/
|
|
450
470
|
let list = []
|
|
471
|
+
let that = this
|
|
451
472
|
util.forEach(fields, (field, fieldName) => {
|
|
452
473
|
let path2 = `${path}.${fieldName}`.replace(/^\./, '')
|
|
453
474
|
// let schema = field.schema || {}
|
|
@@ -464,11 +485,28 @@ let plugin = module.exports = {
|
|
|
464
485
|
|
|
465
486
|
// Image field. Test for field.image as field.type may be 'any'
|
|
466
487
|
} else if (field.type == 'image' || field.image) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
488
|
+
if (field.fileSize) { // > v1.31.7
|
|
489
|
+
this.manager.warn(`${path2}.fileSize has been depreciated in favour of ${path2}.filesize`)
|
|
490
|
+
field.filesize = field.filesize || field.fileSize
|
|
491
|
+
}
|
|
492
|
+
if (field.filename) { // > v1.36.3
|
|
493
|
+
this.manager.warn(`${path2}.filename has been depreciated in favour of ${path2}.path()`)
|
|
494
|
+
field.path = field.path
|
|
495
|
+
|| function(uid, basename, ext, file) { return `${that.bucketDir}/${uid}/${field.filename}.${ext}` }
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
list.push({
|
|
499
|
+
awsAcl: field.awsAcl,
|
|
500
|
+
awsBucket: field.awsBucket,
|
|
501
|
+
filename: field.filename,
|
|
502
|
+
filesize: field.filesize,
|
|
503
|
+
formats: field.formats,
|
|
504
|
+
fullPath: path2,
|
|
505
|
+
fullPathRegex: new RegExp('^' + path2.replace(/\.[0-9]+/g, '.[0-9]+').replace(/\./g, '\\.') + '$'),
|
|
506
|
+
getSignedUrl: field.getSignedUrl,
|
|
507
|
+
path: field.path,
|
|
508
|
+
params: field.params ? util.deepCopy(field.params) : undefined,
|
|
509
|
+
})
|
|
472
510
|
// Convert image field to subdocument
|
|
473
511
|
fields[fieldName] = {
|
|
474
512
|
bucket: { type: 'string' },
|
|
@@ -479,15 +517,6 @@ let plugin = module.exports = {
|
|
|
479
517
|
schema: { image: true, nullObject: true, isImageObject: true },
|
|
480
518
|
uid: { type: 'string' },
|
|
481
519
|
}
|
|
482
|
-
list.push({
|
|
483
|
-
fullPath: path2,
|
|
484
|
-
fullPathRegex: new RegExp('^' + path2.replace(/\.[0-9]+/g, '.[0-9]+').replace(/\./g, '\\.') + '$'),
|
|
485
|
-
formats: formats,
|
|
486
|
-
filesize: filesize,
|
|
487
|
-
filename: filename,
|
|
488
|
-
getSignedUrl: getSignedUrl,
|
|
489
|
-
params: params,
|
|
490
|
-
})
|
|
491
520
|
}
|
|
492
521
|
})
|
|
493
522
|
return list
|
|
@@ -537,12 +566,17 @@ let plugin = module.exports = {
|
|
|
537
566
|
return list
|
|
538
567
|
},
|
|
539
568
|
|
|
540
|
-
_getSignedUrl: (path, expires=3600) => {
|
|
541
|
-
|
|
569
|
+
_getSignedUrl: (path, expires=3600, bucket) => {
|
|
570
|
+
/**
|
|
571
|
+
* @param {string} path - aws file path
|
|
572
|
+
* @param {number} <expires> - seconds
|
|
573
|
+
* @param {number} <bucket>
|
|
574
|
+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
|
|
575
|
+
*/
|
|
542
576
|
let signedUrl = plugin.s3.getSignedUrl('getObject', {
|
|
543
|
-
Bucket: plugin.awsBucket,
|
|
577
|
+
Bucket: bucket || plugin.awsBucket,
|
|
578
|
+
Expires: expires,
|
|
544
579
|
Key: path,
|
|
545
|
-
Expires: expires
|
|
546
580
|
})
|
|
547
581
|
return signedUrl
|
|
548
582
|
},
|
|
Binary file
|
package/test/crud.js
CHANGED
|
@@ -345,7 +345,7 @@ module.exports = function(monastery, opendb) {
|
|
|
345
345
|
importance: 'low'
|
|
346
346
|
}
|
|
347
347
|
]
|
|
348
|
-
// Key order maintained (not always guaranteed)
|
|
348
|
+
// Key order maintained (not always guaranteed in browsers)
|
|
349
349
|
await consignment.update({
|
|
350
350
|
query: inserted._id,
|
|
351
351
|
data: {
|
|
@@ -361,7 +361,7 @@ module.exports = function(monastery, opendb) {
|
|
|
361
361
|
specialInstructions: specialInstructions,
|
|
362
362
|
})
|
|
363
363
|
|
|
364
|
-
// Key order maintained (not always guaranteed)
|
|
364
|
+
// Key order maintained (not always guaranteed in browsers)
|
|
365
365
|
await consignment.update({
|
|
366
366
|
query: inserted._id,
|
|
367
367
|
data: {
|
package/test/model.js
CHANGED
|
@@ -117,8 +117,7 @@ module.exports = function(monastery, opendb) {
|
|
|
117
117
|
|
|
118
118
|
test('model reserved rules', async () => {
|
|
119
119
|
// Setup
|
|
120
|
-
let db = (await opendb(false, {})).db
|
|
121
|
-
db.error = () => {} // hiding debug error
|
|
120
|
+
let db = (await opendb(false, { hideErrors: true })).db // hide debug error
|
|
122
121
|
let user = db.model('user', {
|
|
123
122
|
fields: {
|
|
124
123
|
name: {
|