@@ -6,6 +6,7 @@ This plugin allows you to upload files to Amazon S3 bucket.
6
6
7
7
```
8
8
npm i @adminforth/upload --save
9
+ npm i @adminforth/storage-adapter-amazon-s3 --save
9
10
```
10
11
11
12
## S3
@@ -58,6 +59,16 @@ AWS_ACCESS_KEY_ID=your_access_key_id
58
59
AWS_SECRET_ACCESS_KEY=your_secret_access_key
59
60
```
60
61
62
+ 8 . Add credentials in your ` .env.local ` file:
63
+
64
+ ``` ts title=".env.local"
65
+ ...
66
+ // diff-add
67
+ AWS_REGION = your_bucket_region
68
+ // diff-add
69
+ AWS_BUCKET_NAME = your_bucket_name
70
+ ```
71
+
61
72
Now add a column for storing the path to the file in the database, add this statement to the ` ./schema.prisma ` :
62
73
63
74
``` ts title="./schema.prisma"
@@ -89,6 +100,8 @@ Add column to `aparts` resource configuration:
89
100
// diff-add
90
101
import UploadPlugin from ' @adminforth/upload' ;
91
102
// diff-add
103
+ import AdminForthAdapterS3Storage from ' @adminforth/storage-adapter-amazon-s3'
104
+ // diff-add
92
105
import { v4 as uuid } from ' uuid' ;
93
106
94
107
export const admin = new AdminForth ({
@@ -108,27 +121,31 @@ export const admin = new AdminForth({
108
121
],
109
122
plugins: [
110
123
...
111
- // diff-add
124
+ // diff-add
112
125
new UploadPlugin ({
113
- // diff-add
126
+ // diff-add
127
+ storageAdapter: new AdminForthAdapterS3Storage ({
128
+ // diff-add
129
+ bucket: process .env .AWS_BUCKET_NAME ,
130
+ // diff-add
131
+ region: process .env .AWS_REGION ,
132
+ // diff-add
133
+ accessKeyId: process .env .AWS_ACCESS_KEY_ID ,
134
+ // diff-add
135
+ secretAccessKey: process .env .AWS_SECRET_ACCESS_KEY ,
136
+ // diff-add
137
+ }),
138
+ // diff-add
114
139
pathColumnName: ' apartment_image' ,
115
- // diff-add
116
- s3Bucket: ' my-bucket' , // ❗ Your bucket name
117
- // diff-add
118
- s3Region: ' us-east-1' , // ❗ Selected region
119
- // diff-add
120
- s3AccessKeyId: process .env .AWS_ACCESS_KEY_ID ,
121
- // diff-add
122
- s3SecretAccessKey: process .env .AWS_SECRET_ACCESS_KEY ,
123
- // diff-add
140
+ // diff-add
124
141
allowedFileExtensions: [' jpg' , ' jpeg' , ' png' , ' gif' , ' webm' , ' webp' ],
125
- // diff-add
142
+ // diff-add
126
143
maxFileSize: 1024 * 1024 * 20 , // 20 MB
127
- // diff-add
128
- s3Path : ({originalFilename , originalExtension , contentType }) =>
129
- // diff-add
144
+ // diff-add
145
+ filePath : ({originalFilename , originalExtension , contentType }) =>
146
+ // diff-add
130
147
` aparts/${new Date ().getFullYear ()}/${uuid ()}-${originalFilename }.${originalExtension } ` ,
131
- // diff-add
148
+ // diff-add
132
149
})
133
150
// diff-add
134
151
]
@@ -153,13 +170,13 @@ which are generated by plugin:
153
170

154
171
155
172
156
- > ☝ When upload feature is used on record which already exists in database (from 'edit' page), s3path callback will
173
+ > ☝ When upload feature is used on record which already exists in database (from 'edit' page), filePath callback will
157
174
> receive additional parameter ` record ` with all values of record. Generally we don't recommend denormalizing any state
158
175
> of record into s3 path (and instead store links to unique path on s3 in the record field, like in example above).
159
176
> But if you are 100% sure this kind of sate will be static, you might link to it:
160
177
>
161
178
> ` ` ` ts
162
- > s3Path : ({originalExtension , record }) => ` game_images/${record .static_game_code }.${originalExtension } `
179
+ > filePath : ({originalExtension , record }) => ` game_images/${record .static_game_code }.${originalExtension } `
163
180
> ` ` `
164
181
>
165
182
> ! Please note that when upload is done from create view, record will be ` undefined ` .
@@ -196,27 +213,29 @@ Then you can change ACL in plugin configuration:
196
213
197
214
` ` ` ts title = " ./index.ts"
198
215
199
- new UploadPlugin ({
200
- pathColumnName: ' apartment_image ' ,
201
- s3Bucket: ' my-bucket ' ,
202
- s3Region: ' us-east-1 ' ,
203
- s3AccessKeyId : process .env .AWS_ACCESS_KEY_ID ,
204
- s3SecretAccessKey : process .env .AWS_SECRET_ACCESS_KEY ,
216
+ new UploadPlugin ({
217
+ storageAdapter: new AdminForthAdapterS3Storage ({
218
+ bucket: process . env . AWS_BUCKET_NAME ,
219
+ region: process . env . AWS_REGION ,
220
+ accessKeyId : process .env .AWS_ACCESS_KEY_ID ,
221
+ secretAccessKey : process .env .AWS_SECRET_ACCESS_KEY ,
205
222
// diff-add
206
223
s3ACL: ' public-read' ,
207
- allowedFileExtensions: [' jpg' , ' jpeg' , ' png' , ' gif' , ' webm' ],
208
- maxFileSize: 1024 * 1024 * 20 , // 5MB
209
- s3Path : ({originalFilename , originalExtension , contentType }) =>
210
- ` aparts/${new Date ().getFullYear ()}/${uuid ()}-${originalFilename }.${originalExtension } ` ,
211
- })
224
+ }),
225
+ pathColumnName: ' apartment_image' ,
226
+ allowedFileExtensions: [' jpg' , ' jpeg' , ' png' , ' gif' , ' webm' , ' webp' ],
227
+ maxFileSize: 1024 * 1024 * 20 , // 20 MB
228
+ filePath : ({originalFilename , originalExtension , contentType }) =>
229
+ ` aparts/${new Date ().getFullYear ()}/${uuid ()}-${originalFilename }.${originalExtension } ` ,
230
+ })
212
231
213
232
` ` `
214
233
215
- Now every uploaded file will be public so in your custom app you can easily concatenate bucket URL with ` s3Path ` to get public URL:
234
+ Now every uploaded file will be public so in your custom app you can easily concatenate bucket URL with ` filePath ` to get public URL:
216
235
217
236
` ` ` ts
218
- export async function getPublicUrl(s3Path : string ): string {
219
- return ` https://my-bucket.s3.${region }.amazonaws.com/${s3Path } `
237
+ export async function getPublicUrl(filePath : string ): string {
238
+ return ` https://my-bucket.s3.${region }.amazonaws.com/${filePath } `
220
239
}
221
240
` ` `
222
241
@@ -226,7 +245,7 @@ For preview in AdminForth plugin will still use presigned URLs, but you can chan
226
245
227
246
preview : {
228
247
// diff-add
229
- previewUrl : ({s3Path }) => ` https://my-bucket.s3.us-east-1.amazonaws.com/${s3Path } ` ,
248
+ previewUrl : ({filePath }) => ` https://my-bucket.s3.us-east-1.amazonaws.com/${filePath } ` ,
230
249
}
231
250
` ` `
232
251
> Make sure that you change "my-bucket" and "us-east-1" to your own settings.
@@ -240,10 +259,10 @@ If for example your domain is `my-domain.com` and you bucket has name `static.my
240
259
241
260
preview : {
242
261
// diff-remove
243
- previewUrl : ({s3Path }) => ` https://my-bucket.s3.us-east-1.amazonaws.com/${s3Path } ` ,
262
+ previewUrl : ({filePath }) => ` https://my-bucket.s3.us-east-1.amazonaws.com/${filePath } ` ,
244
263
245
264
// diff-add
246
- previewUrl : ({s3Path }) => ` https://static.my-domain.com/${s3Path } ` ,
265
+ previewUrl : ({filePath }) => ` https://static.my-domain.com/${filePath } ` ,
247
266
}
248
267
` ` `
249
268
@@ -339,6 +358,59 @@ generation: {
339
358
}
340
359
` ` `
341
360
361
+ ` attachFiles ` function can return an array of URLs to images which will be used as input for image generation.
362
+ URLs can be absolute HTTP URLs (should be public in this case) or data-URLs ( ` data : image / png ;base64 ,<base64 content of image >` ).
363
+
364
+ For example you can use ` getKeyAsDataURL ` function from any storage adapter to get image as data-URL:
365
+
366
+ ` ` ` ts title = " ./apartments.ts"
367
+
368
+ import { StorageAdapter } from ' adminforth'
369
+
370
+ let sourceAdapter : StorageAdapter = null ;
371
+
372
+ columns : [
373
+ ...
374
+ {
375
+ name: ' source_image' ,
376
+ },
377
+ {
378
+ name: ' destination_image' ,
379
+ }
380
+ ],
381
+ plugins : [
382
+ ...
383
+ new UploadPlugin ({
384
+ pathColumnName: ' apartment_source' ,
385
+ storageAdapter: (sourcesAdapter = new AdminForthStorageAdapterLocalFilesystem ({
386
+ fileSystemFolder: " ./db/uploads" ,
387
+ mode: " public" ,
388
+ signingSecret: process .env .ADMINFORTH_SECRET , // secret used to generate presigned URLs
389
+ }), sourcesAdapter ),
390
+ }),
391
+ new UploadPlugin ({
392
+ pathColumnName: ' apartment_image' ,
393
+ storageAdapter: new AdminForthAdapterLocalFilesystem ({
394
+ fileSystemFolder: " ./db/uploads" ,
395
+ mode: " public" ,
396
+ signingSecret: process .env .ADMINFORTH_SECRET , // secret used to generate presigned URLs
397
+ }),
398
+ generation: {
399
+ attachFiles : ({ record }) => {
400
+ // get picture stored in apartment_source column as data-URL
401
+ return [sourceAdapter .getKeyAsDataURL (record .apartment_source )];
402
+ },
403
+ generationPrompt: " Remove text from the image" ,
404
+ countToGenerate: 3 ,
405
+ outputSize: ' 1024x1024' ,
406
+ }
407
+ })
408
+ ]
409
+ ` ` `
410
+
411
+ With thus setup you can upload image to ` apartment_source ` column, save entity and then generate new image by clicking on ` Generate ` button in the ` apartment_image ` to remove any text from the image.
412
+
413
+
342
414
### Rate limits
343
415
344
416
You can set rate limits for image generation per IP address:
@@ -364,14 +436,17 @@ You can set the maximum width for the preview image in the `./resources/apartmen
364
436
` ` ` ts title = " ./resources/apartments.ts"
365
437
...
366
438
new UploadPlugin ({
439
+ storageAdapter: new AdminForthAdapterS3Storage ({
440
+ bucket: process .env .AWS_BUCKET_NAME ,
441
+ region: process .env .AWS_REGION ,
442
+ accessKeyId: process .env .AWS_ACCESS_KEY_ID ,
443
+ secretAccessKey: process .env .AWS_SECRET_ACCESS_KEY ,
444
+ s3ACL: " public-read" ,
445
+ }),
367
446
pathColumnName: ' apartment_image' ,
368
- s3Bucket: ' my-bucket' , // ❗ Your bucket name
369
- s3Region: ' us-east-1' , // ❗ Selected region
370
- s3AccessKeyId: process .env .AWS_ACCESS_KEY_ID ,
371
- s3SecretAccessKey: process .env .AWS_SECRET_ACCESS_KEY ,
372
447
allowedFileExtensions: [' jpg' , ' jpeg' , ' png' , ' gif' , ' webm' , ' webp' ],
373
- maxFileSize: 1024 * 1024 * 20 , // 20 MB
374
- s3Path : ({originalFilename , originalExtension , contentType }) =>
448
+ maxFileSize: 5 * 1024 * 1024 , // 5MB
449
+ filePath : ({originalFilename , originalExtension , contentType }) =>
375
450
` aparts/${new Date ().getFullYear ()}/${uuid ()}-${originalFilename }.${originalExtension } ` ,
376
451
preview: {
377
452
// Global width settings (applies to all views if specific view settings not provided)
0 commit comments