@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.
Files changed (59) hide show
  1. package/package.json +3 -2
  2. package/src/aws/http/configs/cache-control/index.d.ts +1 -0
  3. package/src/aws/http/configs/cache-control/index.js +1 -0
  4. package/src/aws/http/configs/cache-control/max-age/index.d.ts +1 -0
  5. package/src/aws/http/configs/cache-control/max-age/index.js +1 -0
  6. package/src/aws/http/configs/index.d.ts +1 -0
  7. package/src/aws/http/configs/index.js +1 -0
  8. package/src/aws/http/index.d.ts +1 -0
  9. package/src/aws/http/index.js +1 -0
  10. package/src/aws/image/convert-base-64-image/index.d.ts +1 -0
  11. package/src/aws/image/convert-base-64-image/index.js +1 -0
  12. package/src/aws/image/convert-base-64-image/type.d.ts +1 -0
  13. package/src/aws/image/convert-base-64-image/type.js +1 -0
  14. package/src/aws/image/convert-base-64-image/util.d.ts +2 -0
  15. package/src/aws/image/convert-base-64-image/util.js +1 -0
  16. package/src/aws/image/index.d.ts +1 -0
  17. package/src/aws/image/index.js +1 -0
  18. package/src/aws/index.d.ts +1 -0
  19. package/src/aws/index.js +1 -0
  20. package/src/aws/s3/index.d.ts +2 -0
  21. package/src/aws/s3/index.js +2 -0
  22. package/src/aws/s3/person-image-worker/index.d.ts +2 -0
  23. package/src/aws/s3/person-image-worker/index.js +106 -0
  24. package/src/aws/s3/person-image-worker/types.d.ts +35 -0
  25. package/src/aws/s3/person-image-worker/types.js +1 -0
  26. package/src/aws/s3/worker/index.d.ts +13 -0
  27. package/src/aws/s3/worker/index.js +89 -0
  28. package/src/aws/s3/worker/types.d.ts +23 -0
  29. package/src/aws/s3/worker/types.js +1 -0
  30. package/src/image/image/index.d.ts +1 -0
  31. package/src/image/image/index.js +1 -0
  32. package/src/image/image/type.d.ts +5 -0
  33. package/src/image/image/type.js +1 -0
  34. package/src/image/image-dimension/index.d.ts +1 -0
  35. package/src/image/image-dimension/index.js +1 -0
  36. package/src/image/image-dimension/type.d.ts +5 -0
  37. package/src/image/image-dimension/type.js +1 -0
  38. package/src/image/index.d.ts +2 -0
  39. package/src/image/index.js +2 -0
  40. package/src/index.d.ts +1 -0
  41. package/src/index.js +1 -0
  42. package/src/person/index.d.ts +1 -0
  43. package/src/person/index.js +1 -0
  44. package/src/person/person-image/file-name/config.d.ts +1 -0
  45. package/src/person/person-image/file-name/config.js +2 -0
  46. package/src/person/person-image/file-name/index.d.ts +2 -0
  47. package/src/person/person-image/file-name/index.js +2 -0
  48. package/src/person/person-image/file-name/type.d.ts +2 -0
  49. package/src/person/person-image/file-name/type.js +1 -0
  50. package/src/person/person-image/index.d.ts +3 -0
  51. package/src/person/person-image/index.js +3 -0
  52. package/src/person/person-image/type.d.ts +10 -0
  53. package/src/person/person-image/type.js +1 -0
  54. package/src/person/person-image/width/config.d.ts +1 -0
  55. package/src/person/person-image/width/config.js +1 -0
  56. package/src/person/person-image/width/index.d.ts +2 -0
  57. package/src/person/person-image/width/index.js +2 -0
  58. package/src/person/person-image/width/type.d.ts +2 -0
  59. 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.133",
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,2 @@
1
+ import { ConvertBase64ToImage } from './type.js';
2
+ export declare const convertBase64ToImage: ConvertBase64ToImage;
@@ -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';
@@ -1,6 +1,7 @@
1
1
  export * from './account-id/index.js';
2
2
  export * from './app-config/index.js';
3
3
  export * from './cdk/index.js';
4
+ export * from './image/index.js';
4
5
  export * from './lambda/index.js';
5
6
  export * from './region/index.js';
6
7
  export * from './s3/index.js';
package/src/aws/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './account-id/index.js';
2
2
  export * from './app-config/index.js';
3
3
  export * from './cdk/index.js';
4
+ export * from './image/index.js';
4
5
  export * from './lambda/index.js';
5
6
  export * from './region/index.js';
6
7
  export * from './s3/index.js';
@@ -1 +1,3 @@
1
+ export * from './person-image-worker/index.js';
1
2
  export * from './s3-arn/index.js';
3
+ export * from './worker/index.js';
@@ -1 +1,3 @@
1
+ export * from './person-image-worker/index.js';
1
2
  export * from './s3-arn/index.js';
3
+ export * from './worker/index.js';
@@ -0,0 +1,2 @@
1
+ import { IPersonImageWorker } from './types.js';
2
+ export declare const PersonImageWorker: IPersonImageWorker;
@@ -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,5 @@
1
+ import { PersonImage } from '../../person/index.js';
2
+ export interface Image {
3
+ personImage: PersonImage;
4
+ base64Image: string;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from './type.js';
@@ -0,0 +1 @@
1
+ export * from './type.js';
@@ -0,0 +1,5 @@
1
+ import { PersonImageWidth } from '../../person/index.js';
2
+ export interface ImageDimension<T extends PersonImageWidth | number> {
3
+ height: number;
4
+ width: T;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './image/index.js';
2
+ export * from './image-dimension/index.js';
@@ -0,0 +1,2 @@
1
+ export * from './image/index.js';
2
+ export * from './image-dimension/index.js';
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,2 @@
1
+ import { PERSON_IMAGE_WIDTHS } from '../width/config.js';
2
+ export const PERSON_IMAGE_FILE_NAMES = ['original', ...PERSON_IMAGE_WIDTHS];
@@ -0,0 +1,2 @@
1
+ export * from './config.js';
2
+ export * from './type.js';
@@ -0,0 +1,2 @@
1
+ export * from './config.js';
2
+ export * from './type.js';
@@ -0,0 +1,2 @@
1
+ import { PERSON_IMAGE_FILE_NAMES } from './config.js';
2
+ export type PersonImageFileName = (typeof PERSON_IMAGE_FILE_NAMES)[number];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './file-name/index.js';
2
+ export * from './width/index.js';
3
+ export * from './type.js';
@@ -0,0 +1,3 @@
1
+ export * from './file-name/index.js';
2
+ export * from './width/index.js';
3
+ export * from './type.js';
@@ -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,2 @@
1
+ export * from './config.js';
2
+ export * from './type.js';
@@ -0,0 +1,2 @@
1
+ export * from './config.js';
2
+ export * from './type.js';
@@ -0,0 +1,2 @@
1
+ import { PERSON_IMAGE_WIDTHS } from './config.js';
2
+ export type PersonImageWidth = (typeof PERSON_IMAGE_WIDTHS)[number];
@@ -0,0 +1 @@
1
+ export {};