@candlerip/shared3 0.0.133 → 0.0.134
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +3 -2
- package/src/aws/http/configs/cache-control/index.d.ts +1 -0
- package/src/aws/http/configs/cache-control/index.js +1 -0
- package/src/aws/http/configs/cache-control/max-age/index.d.ts +1 -0
- package/src/aws/http/configs/cache-control/max-age/index.js +1 -0
- package/src/aws/http/configs/index.d.ts +1 -0
- package/src/aws/http/configs/index.js +1 -0
- package/src/aws/http/index.d.ts +1 -0
- package/src/aws/http/index.js +1 -0
- package/src/aws/image/convert-base-64-image/index.d.ts +1 -0
- package/src/aws/image/convert-base-64-image/index.js +1 -0
- package/src/aws/image/convert-base-64-image/type.d.ts +1 -0
- package/src/aws/image/convert-base-64-image/type.js +1 -0
- package/src/aws/image/convert-base-64-image/util.d.ts +2 -0
- package/src/aws/image/convert-base-64-image/util.js +1 -0
- package/src/aws/image/index.d.ts +1 -0
- package/src/aws/image/index.js +1 -0
- package/src/aws/index.d.ts +1 -0
- package/src/aws/index.js +1 -0
- package/src/aws/s3/index.d.ts +2 -0
- package/src/aws/s3/index.js +2 -0
- package/src/aws/s3/person-image-worker/index.d.ts +2 -0
- package/src/aws/s3/person-image-worker/index.js +106 -0
- package/src/aws/s3/person-image-worker/types.d.ts +35 -0
- package/src/aws/s3/person-image-worker/types.js +1 -0
- package/src/aws/s3/worker/index.d.ts +13 -0
- package/src/aws/s3/worker/index.js +89 -0
- package/src/aws/s3/worker/types.d.ts +23 -0
- package/src/aws/s3/worker/types.js +1 -0
- package/src/image/image/index.d.ts +1 -0
- package/src/image/image/index.js +1 -0
- package/src/image/image/type.d.ts +5 -0
- package/src/image/image/type.js +1 -0
- package/src/image/image-dimension/index.d.ts +1 -0
- package/src/image/image-dimension/index.js +1 -0
- package/src/image/image-dimension/type.d.ts +5 -0
- package/src/image/image-dimension/type.js +1 -0
- package/src/image/index.d.ts +2 -0
- package/src/image/index.js +2 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/person/index.d.ts +1 -0
- package/src/person/index.js +1 -0
- package/src/person/person-image/file-name/config.d.ts +1 -0
- package/src/person/person-image/file-name/config.js +2 -0
- package/src/person/person-image/file-name/index.d.ts +2 -0
- package/src/person/person-image/file-name/index.js +2 -0
- package/src/person/person-image/file-name/type.d.ts +2 -0
- package/src/person/person-image/file-name/type.js +1 -0
- package/src/person/person-image/index.d.ts +3 -0
- package/src/person/person-image/index.js +3 -0
- package/src/person/person-image/type.d.ts +10 -0
- package/src/person/person-image/type.js +1 -0
- package/src/person/person-image/width/config.d.ts +1 -0
- package/src/person/person-image/width/config.js +1 -0
- package/src/person/person-image/width/index.d.ts +2 -0
- package/src/person/person-image/width/index.js +2 -0
- package/src/person/person-image/width/type.d.ts +2 -0
- package/src/person/person-image/width/type.js +1 -0
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@candlerip/shared3",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.134",
|
4
4
|
"type": "module",
|
5
5
|
"exports": {
|
6
6
|
".": "./src/index.js",
|
@@ -52,6 +52,7 @@
|
|
52
52
|
"dotenv": "^16.4.5",
|
53
53
|
"express": "^4.21.1",
|
54
54
|
"mongoose": "^8.8.0",
|
55
|
-
"redis": "^4.7.0"
|
55
|
+
"redis": "^4.7.0",
|
56
|
+
"sharp": "^0.33.5"
|
56
57
|
}
|
57
58
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './max-age/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './max-age/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const HTTP_CACHE_CONTROL_MAX_AGE = 7776000;
|
@@ -0,0 +1 @@
|
|
1
|
+
export const HTTP_CACHE_CONTROL_MAX_AGE = 7776000;
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './cache-control/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './cache-control/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './configs/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './configs/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './util.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './util.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export type ConvertBase64ToImage = (base64Image: string) => string;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export const convertBase64ToImage = (base64Image) => base64Image.replace(/^data:image\/\w+;base64,/, '');
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './convert-base-64-image/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './convert-base-64-image/index.js';
|
package/src/aws/index.d.ts
CHANGED
package/src/aws/index.js
CHANGED
package/src/aws/s3/index.d.ts
CHANGED
package/src/aws/s3/index.js
CHANGED
@@ -0,0 +1,106 @@
|
|
1
|
+
import sharp from 'sharp';
|
2
|
+
import { composeCustomError } from '../../../error/index.js';
|
3
|
+
import { S3Worker } from '../worker/index.js';
|
4
|
+
import { convertBase64ToImage } from '../../image/index.js';
|
5
|
+
export const PersonImageWorker = (() => {
|
6
|
+
let s3Worker;
|
7
|
+
const init = (bucketName) => {
|
8
|
+
s3Worker = new S3Worker(bucketName);
|
9
|
+
};
|
10
|
+
const deleteImage = async (personId, imageName, fileName) => s3Worker.deleteFile(`persons/${personId}/${imageName}/${fileName}`);
|
11
|
+
const deleteImages = async (personId, personImages) => {
|
12
|
+
const promises = [];
|
13
|
+
personImages.forEach((personImage) => {
|
14
|
+
['original', ...personImage.dimensions.resized.map((it) => it.width)].forEach((it) => {
|
15
|
+
promises.push(deleteImage(personId, personImage.name, `${it.toString()}.${personImage.extension}`));
|
16
|
+
});
|
17
|
+
});
|
18
|
+
const resp = await Promise.all(promises);
|
19
|
+
const errors = resp.filter((it) => it);
|
20
|
+
if (errors.length > 0) {
|
21
|
+
return {
|
22
|
+
customError: composeCustomError('Errors during delete person images', 'backend', {
|
23
|
+
errors,
|
24
|
+
personImages,
|
25
|
+
personId,
|
26
|
+
}),
|
27
|
+
};
|
28
|
+
}
|
29
|
+
return;
|
30
|
+
};
|
31
|
+
const getImage = async (personId, imageName, fileName, extension) => s3Worker.getImage(`persons/${personId}/${imageName}/${fileName}`, extension);
|
32
|
+
const getImages = async (personId, personImages, personImageFileName) => {
|
33
|
+
const promises = [];
|
34
|
+
personImages.forEach((personImage) => {
|
35
|
+
promises.push(getImage(personId, personImage.name, `${personImageFileName}.${personImage.extension}`, personImage.extension));
|
36
|
+
});
|
37
|
+
const resp = await Promise.all(promises);
|
38
|
+
const errors = resp.filter((it) => 'customError' in it);
|
39
|
+
if (errors.length > 0) {
|
40
|
+
return {
|
41
|
+
customError: composeCustomError('Errors during get person images', 'backend', {
|
42
|
+
errors,
|
43
|
+
personImages,
|
44
|
+
personId,
|
45
|
+
}),
|
46
|
+
};
|
47
|
+
}
|
48
|
+
return {
|
49
|
+
base64Images: resp.filter((it) => 'base64Image' in it).map((it) => it.base64Image),
|
50
|
+
};
|
51
|
+
};
|
52
|
+
const uploadImage = async (fileBuffer, personId, imageName, fileName, extension) => s3Worker.uploadImage(`persons/${personId}/${imageName}/${fileName}`, fileBuffer, extension);
|
53
|
+
const uploadImages = async (personId, images) => {
|
54
|
+
const promises = [];
|
55
|
+
for (let i = 0; i < images.length; i++) {
|
56
|
+
const image = images[i];
|
57
|
+
const { base64Image, personImage } = image;
|
58
|
+
const originalBuffer = Buffer.from(convertBase64ToImage(base64Image), 'base64');
|
59
|
+
const imageResizePromises = personImage.dimensions.resized.map((dimension) => sharp(originalBuffer).resize({ width: dimension.width }).withMetadata().toBuffer());
|
60
|
+
let resp;
|
61
|
+
try {
|
62
|
+
resp = await Promise.all(imageResizePromises);
|
63
|
+
}
|
64
|
+
catch (err) {
|
65
|
+
return {
|
66
|
+
customError: composeCustomError('Error during image convertion', 'backend', {
|
67
|
+
err,
|
68
|
+
}),
|
69
|
+
};
|
70
|
+
}
|
71
|
+
[
|
72
|
+
{
|
73
|
+
buffer: originalBuffer,
|
74
|
+
width: 'original',
|
75
|
+
},
|
76
|
+
...resp.map((it, i) => ({
|
77
|
+
buffer: it,
|
78
|
+
width: personImage.dimensions.resized[i].width,
|
79
|
+
})),
|
80
|
+
].forEach((it) => {
|
81
|
+
promises.push(uploadImage(it.buffer, personId, personImage.name, `${it.width.toString()}.${personImage.extension}`, personImage.extension));
|
82
|
+
});
|
83
|
+
}
|
84
|
+
const resp = await Promise.all(promises);
|
85
|
+
const errors = resp.filter((it) => it);
|
86
|
+
if (errors.length > 0) {
|
87
|
+
return {
|
88
|
+
customError: composeCustomError('Errors during update person images', 'backend', {
|
89
|
+
errors,
|
90
|
+
images,
|
91
|
+
personId,
|
92
|
+
}),
|
93
|
+
};
|
94
|
+
}
|
95
|
+
return;
|
96
|
+
};
|
97
|
+
return {
|
98
|
+
deleteImage,
|
99
|
+
deleteImages,
|
100
|
+
getImage,
|
101
|
+
getImages,
|
102
|
+
init,
|
103
|
+
uploadImage,
|
104
|
+
uploadImages,
|
105
|
+
};
|
106
|
+
})();
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { CustomError } from '../../../error/index.js';
|
2
|
+
import { Image } from '../../../image/index.js';
|
3
|
+
import { PersonImage, PersonImageFileName } from '../../../person/index.js';
|
4
|
+
export interface IPersonImageWorker {
|
5
|
+
deleteImage: DeleteImage;
|
6
|
+
deleteImages: DeleteImages;
|
7
|
+
getImage: GetImage;
|
8
|
+
getImages: GetImages;
|
9
|
+
init: Init;
|
10
|
+
uploadImage: UploadImage;
|
11
|
+
uploadImages: UploadImages;
|
12
|
+
}
|
13
|
+
export type DeleteImage = (personId: string, imageName: string, fileName: string) => Promise<void | {
|
14
|
+
customError: CustomError;
|
15
|
+
}>;
|
16
|
+
export type DeleteImages = (personId: string, personImages: PersonImage[]) => Promise<void | {
|
17
|
+
customError: CustomError;
|
18
|
+
}>;
|
19
|
+
export type GetImage = (personId: string, imageName: string, fileName: string, extension: string) => Promise<{
|
20
|
+
customError: CustomError;
|
21
|
+
} | {
|
22
|
+
base64Image: string;
|
23
|
+
}>;
|
24
|
+
export type GetImages = (personId: string, personImages: PersonImage[], personImageFileName: PersonImageFileName) => Promise<{
|
25
|
+
base64Images: string[];
|
26
|
+
} | {
|
27
|
+
customError: CustomError;
|
28
|
+
}>;
|
29
|
+
export type Init = (bucketName: string) => void;
|
30
|
+
export type UploadImage = (fileBuffer: Buffer, personId: string, imageName: string, fileName: string, extension: string) => Promise<void | {
|
31
|
+
customError: CustomError;
|
32
|
+
}>;
|
33
|
+
export type UploadImages = (personId: string, images: Image[]) => Promise<void | {
|
34
|
+
customError: CustomError;
|
35
|
+
}>;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { S3Client } from '@aws-sdk/client-s3';
|
2
|
+
import { DeleteFile, GetFile, GetImage, UploadFile, UploadImage } from './types.js';
|
3
|
+
export declare class S3Worker {
|
4
|
+
bucketName: string;
|
5
|
+
client: S3Client;
|
6
|
+
startDate: Date;
|
7
|
+
constructor(bucketName: string);
|
8
|
+
deleteFile: DeleteFile;
|
9
|
+
getFile: GetFile;
|
10
|
+
getImage: GetImage;
|
11
|
+
uploadFile: UploadFile;
|
12
|
+
uploadImage: UploadImage;
|
13
|
+
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
2
|
+
import { HTTP_CACHE_CONTROL_MAX_AGE } from '../../http/index.js';
|
3
|
+
import { DEFAULT_AWS_REGION } from '../../region/index.js';
|
4
|
+
import { composeCustomError } from '../../../error/index.js';
|
5
|
+
export class S3Worker {
|
6
|
+
bucketName;
|
7
|
+
client;
|
8
|
+
startDate = new Date();
|
9
|
+
constructor(bucketName) {
|
10
|
+
this.bucketName = bucketName;
|
11
|
+
this.client = new S3Client({ region: DEFAULT_AWS_REGION });
|
12
|
+
}
|
13
|
+
deleteFile = async (key) => {
|
14
|
+
try {
|
15
|
+
await this.client.send(new DeleteObjectCommand({
|
16
|
+
Bucket: this.bucketName,
|
17
|
+
Key: key,
|
18
|
+
}));
|
19
|
+
}
|
20
|
+
catch (err) {
|
21
|
+
return {
|
22
|
+
customError: composeCustomError('Cannot delete file in S3', 'backend', { err, bucketName: this.bucketName, key }),
|
23
|
+
};
|
24
|
+
}
|
25
|
+
return;
|
26
|
+
};
|
27
|
+
getFile = async (key) => {
|
28
|
+
let stream;
|
29
|
+
try {
|
30
|
+
const response = await this.client.send(new GetObjectCommand({
|
31
|
+
Bucket: this.bucketName,
|
32
|
+
Key: key,
|
33
|
+
}));
|
34
|
+
if (!response) {
|
35
|
+
return {
|
36
|
+
customError: composeCustomError('Error during get image from S3', 'backend', { key }),
|
37
|
+
};
|
38
|
+
}
|
39
|
+
stream = response.Body;
|
40
|
+
}
|
41
|
+
catch (err) {
|
42
|
+
return {
|
43
|
+
customError: composeCustomError('Cannot get file from S3', 'backend', { err, key }),
|
44
|
+
};
|
45
|
+
}
|
46
|
+
return {
|
47
|
+
stream,
|
48
|
+
};
|
49
|
+
};
|
50
|
+
getImage = async (key, extension) => {
|
51
|
+
let base64Image;
|
52
|
+
const resp = await this.getFile(key);
|
53
|
+
if ('customError' in resp) {
|
54
|
+
return resp;
|
55
|
+
}
|
56
|
+
const { stream } = resp;
|
57
|
+
try {
|
58
|
+
const buffer = Buffer.concat(await stream.toArray());
|
59
|
+
base64Image = `data:image/${extension};base64,${btoa(new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), ''))}`;
|
60
|
+
}
|
61
|
+
catch (err) {
|
62
|
+
return {
|
63
|
+
customError: composeCustomError('Cannot get file from S3', 'backend', { err, key }),
|
64
|
+
};
|
65
|
+
}
|
66
|
+
return { base64Image };
|
67
|
+
};
|
68
|
+
uploadFile = async (key, fileBuffer, options) => {
|
69
|
+
try {
|
70
|
+
await this.client.send(new PutObjectCommand({
|
71
|
+
Body: fileBuffer,
|
72
|
+
Bucket: this.bucketName,
|
73
|
+
Key: key,
|
74
|
+
...options,
|
75
|
+
CacheControl: `max-age=${HTTP_CACHE_CONTROL_MAX_AGE}`,
|
76
|
+
}));
|
77
|
+
}
|
78
|
+
catch (err) {
|
79
|
+
return {
|
80
|
+
customError: composeCustomError('Cannot upload file to S3', 'backend', { err, file: fileBuffer, key, options }),
|
81
|
+
};
|
82
|
+
}
|
83
|
+
return;
|
84
|
+
};
|
85
|
+
uploadImage = async (key, fileBuffer, extension) => this.uploadFile(key, fileBuffer, {
|
86
|
+
ContentEncoding: 'base64',
|
87
|
+
ContentType: `image/${extension}`,
|
88
|
+
});
|
89
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { CustomError } from '../../../error/index.js';
|
2
|
+
export type DeleteFile = (key: string) => Promise<void | {
|
3
|
+
customError: CustomError;
|
4
|
+
}>;
|
5
|
+
export type GetFile = (key: string) => Promise<{
|
6
|
+
stream: any;
|
7
|
+
} | {
|
8
|
+
customError: CustomError;
|
9
|
+
}>;
|
10
|
+
export type GetImage = (key: string, extension: string) => Promise<{
|
11
|
+
customError: CustomError;
|
12
|
+
} | {
|
13
|
+
base64Image: string;
|
14
|
+
}>;
|
15
|
+
export type UploadFile = (key: string, fileBuffer: Buffer, options?: {
|
16
|
+
ContentEncoding?: string;
|
17
|
+
ContentType?: string;
|
18
|
+
}) => Promise<void | {
|
19
|
+
customError: CustomError;
|
20
|
+
}>;
|
21
|
+
export type UploadImage = (key: string, fileBuffer: Buffer, extension: string) => Promise<void | {
|
22
|
+
customError: CustomError;
|
23
|
+
}>;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './type.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './type.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './type.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './type.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/src/index.d.ts
CHANGED
@@ -3,6 +3,7 @@ export * from './environment/index.js';
|
|
3
3
|
export * from './error/index.js';
|
4
4
|
export * from './helper/index.js';
|
5
5
|
export * from './page/index.js';
|
6
|
+
export * from './person/index.js';
|
6
7
|
export * from './project/index.js';
|
7
8
|
export * from './type/index.js';
|
8
9
|
export * from './validator/index.js';
|
package/src/index.js
CHANGED
@@ -3,6 +3,7 @@ export * from './environment/index.js';
|
|
3
3
|
export * from './error/index.js';
|
4
4
|
export * from './helper/index.js';
|
5
5
|
export * from './page/index.js';
|
6
|
+
export * from './person/index.js';
|
6
7
|
export * from './project/index.js';
|
7
8
|
export * from './type/index.js';
|
8
9
|
export * from './validator/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './person-image/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './person-image/index.js';
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const PERSON_IMAGE_FILE_NAMES: readonly ["original", 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { ImageDimension } from '../../image/index.js';
|
2
|
+
import { PersonImageWidth } from './width/index.js';
|
3
|
+
export interface PersonImage {
|
4
|
+
dimensions: {
|
5
|
+
original: ImageDimension<number>;
|
6
|
+
resized: ImageDimension<PersonImageWidth>[];
|
7
|
+
};
|
8
|
+
extension: string;
|
9
|
+
name: string;
|
10
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const PERSON_IMAGE_WIDTHS: readonly [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288];
|
@@ -0,0 +1 @@
|
|
1
|
+
export const PERSON_IMAGE_WIDTHS = [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|