@ryuu-reinzz/haruka-lib 2.1.1 → 2.2.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.
Files changed (48) hide show
  1. package/main/index.js +1 -1
  2. package/main/socket.js +2 -5
  3. package/main/sticker-engine/image-to-webp.js +57 -0
  4. package/main/sticker-engine/index.js +6 -0
  5. package/main/sticker-engine/main-sticker.js +48 -0
  6. package/main/sticker-engine/video-to-webp.js +68 -0
  7. package/package.json +2 -5
  8. package/main/sticker-engine/java-script/Sticker.d.ts +0 -130
  9. package/main/sticker-engine/java-script/Sticker.js +0 -188
  10. package/main/sticker-engine/java-script/Types.d.ts +0 -43
  11. package/main/sticker-engine/java-script/Types.js +0 -1
  12. package/main/sticker-engine/java-script/Utils.d.ts +0 -9
  13. package/main/sticker-engine/java-script/Utils.js +0 -11
  14. package/main/sticker-engine/java-script/extractMetadata.d.ts +0 -6
  15. package/main/sticker-engine/java-script/extractMetadata.js +0 -12
  16. package/main/sticker-engine/java-script/index.d.ts +0 -8
  17. package/main/sticker-engine/java-script/index.js +0 -8
  18. package/main/sticker-engine/java-script/internal/Metadata/Exif.d.ts +0 -9
  19. package/main/sticker-engine/java-script/internal/Metadata/Exif.js +0 -35
  20. package/main/sticker-engine/java-script/internal/Metadata/RawMetadata.d.ts +0 -8
  21. package/main/sticker-engine/java-script/internal/Metadata/RawMetadata.js +0 -9
  22. package/main/sticker-engine/java-script/internal/Metadata/StickerMetadata.d.ts +0 -18
  23. package/main/sticker-engine/java-script/internal/Metadata/StickerMetadata.js +0 -49
  24. package/main/sticker-engine/java-script/internal/Metadata/StickerTypes.d.ts +0 -7
  25. package/main/sticker-engine/java-script/internal/Metadata/StickerTypes.js +0 -8
  26. package/main/sticker-engine/java-script/internal/convert.d.ts +0 -3
  27. package/main/sticker-engine/java-script/internal/convert.js +0 -69
  28. package/main/sticker-engine/java-script/internal/crop.d.ts +0 -2
  29. package/main/sticker-engine/java-script/internal/crop.js +0 -30
  30. package/main/sticker-engine/java-script/internal/imagesToWebp.d.ts +0 -2
  31. package/main/sticker-engine/java-script/internal/imagesToWebp.js +0 -17
  32. package/main/sticker-engine/java-script/internal/videoToGif.d.ts +0 -3
  33. package/main/sticker-engine/java-script/internal/videoToGif.js +0 -16
  34. package/main/sticker-engine/type-script/Sticker.ts +0 -206
  35. package/main/sticker-engine/type-script/Types.ts +0 -189
  36. package/main/sticker-engine/type-script/Utils.ts +0 -12
  37. package/main/sticker-engine/type-script/extractMetadata.ts +0 -13
  38. package/main/sticker-engine/type-script/index.ts +0 -9
  39. package/main/sticker-engine/type-script/internal/Metadata/Exif.ts +0 -39
  40. package/main/sticker-engine/type-script/internal/Metadata/RawMetadata.ts +0 -15
  41. package/main/sticker-engine/type-script/internal/Metadata/StickerMetadata.ts +0 -60
  42. package/main/sticker-engine/type-script/internal/Metadata/StickerTypes.ts +0 -7
  43. package/main/sticker-engine/type-script/internal/convert.ts +0 -87
  44. package/main/sticker-engine/type-script/internal/crop.ts +0 -32
  45. package/main/sticker-engine/type-script/internal/imagesToWebp.ts +0 -19
  46. package/main/sticker-engine/type-script/internal/node-webpmux.d.ts +0 -8
  47. package/main/sticker-engine/type-script/internal/videoToGif.ts +0 -18
  48. package/tsconfig.json +0 -13
@@ -1,35 +0,0 @@
1
- import { TextEncoder } from 'util';
2
- import RawMetadata from './RawMetadata.js';
3
- import WebPMux from 'node-webpmux';
4
- const { Image } = WebPMux;
5
- export default class Exif {
6
- constructor(options) {
7
- this.exif = null;
8
- this.build = () => {
9
- const data = JSON.stringify(this.data);
10
- const exif = Buffer.concat([
11
- Buffer.from([
12
- 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00,
13
- 0x00, 0x16, 0x00, 0x00, 0x00
14
- ]),
15
- Buffer.from(data, 'utf-8')
16
- ]);
17
- exif.writeUIntLE(new TextEncoder().encode(data).length, 14, 4);
18
- return exif;
19
- };
20
- this.add = async (image) => {
21
- const exif = this.exif || this.build();
22
- image =
23
- image instanceof Image
24
- ? image
25
- : await (async () => {
26
- const img = new Image();
27
- await img.load(image);
28
- return img;
29
- })();
30
- image.exif = exif;
31
- return await image.save(null);
32
- };
33
- this.data = new RawMetadata(options);
34
- }
35
- }
@@ -1,8 +0,0 @@
1
- import { IRawMetadata, Metadata } from '../../Types';
2
- export default class RawMetadata implements IRawMetadata {
3
- emojis: string[];
4
- 'sticker-pack-id': string;
5
- 'sticker-pack-name': string;
6
- 'sticker-pack-publisher': string;
7
- constructor(options: Metadata);
8
- }
@@ -1,9 +0,0 @@
1
- import Utils from '../../Utils.js';
2
- export default class RawMetadata {
3
- constructor(options) {
4
- this['sticker-pack-id'] = options.id || Utils.generateStickerID();
5
- this['sticker-pack-name'] = options.pack || '';
6
- this['sticker-pack-publisher'] = options.author || '';
7
- this.emojis = options.categories || [];
8
- }
9
- }
@@ -1,18 +0,0 @@
1
- import { Categories, IStickerConfig, IStickerOptions } from '../../Types';
2
- export default class StickerMetadata implements IStickerOptions {
3
- pack: string;
4
- author: string;
5
- categories: Categories[];
6
- id: string;
7
- crop: boolean;
8
- full: boolean;
9
- constructor(pack?: string, author?: string, categories?: Categories[], id?: string);
10
- static from: (object: Partial<StickerMetadata>) => StickerMetadata;
11
- setPack: (title: string) => this;
12
- setAuthor: (author: string) => this;
13
- setId: (id: string) => this;
14
- setCrop: (value: boolean) => this;
15
- setFull: (value: boolean) => this;
16
- setCategories: (categories: string | string[]) => this;
17
- toJSON: () => IStickerConfig;
18
- }
@@ -1,49 +0,0 @@
1
- import Utils from '../../Utils.js';
2
- class StickerMetadata {
3
- constructor(pack = '', author = '', categories = [], id = Utils.generateStickerID()) {
4
- this.pack = pack;
5
- this.author = author;
6
- this.categories = categories;
7
- this.id = id;
8
- this.crop = false;
9
- this.full = false;
10
- this.setPack = (title) => {
11
- this.pack = title;
12
- return this;
13
- };
14
- this.setAuthor = (author) => {
15
- this.author = author;
16
- return this;
17
- };
18
- this.setId = (id) => {
19
- this.id = id;
20
- return this;
21
- };
22
- this.setCrop = (value) => {
23
- this.crop = value;
24
- this.full = !value;
25
- return this;
26
- };
27
- this.setFull = (value) => {
28
- this.crop = !value;
29
- this.full = value;
30
- return this;
31
- };
32
- this.setCategories = (categories) => {
33
- this.categories = (typeof categories === 'string' ? categories.split(',').map((emoji) => emoji.trim()) : categories);
34
- return this;
35
- };
36
- this.toJSON = () => {
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- const obj = {};
39
- Object.keys(this)
40
- .filter((key) => typeof this[key] !== 'function')
41
- .forEach((key) => (obj[key] = this[key]));
42
- return obj;
43
- };
44
- }
45
- }
46
- StickerMetadata.from = (object) => {
47
- return new StickerMetadata(object.pack, object.author, object.categories, object.id);
48
- };
49
- export default StickerMetadata;
@@ -1,7 +0,0 @@
1
- export declare enum StickerTypes {
2
- DEFAULT = "default",
3
- CROPPED = "crop",
4
- FULL = "full",
5
- CIRCLE = "circle",
6
- ROUNDED = "rounded"
7
- }
@@ -1,8 +0,0 @@
1
- export var StickerTypes;
2
- (function (StickerTypes) {
3
- StickerTypes["DEFAULT"] = "default";
4
- StickerTypes["CROPPED"] = "crop";
5
- StickerTypes["FULL"] = "full";
6
- StickerTypes["CIRCLE"] = "circle";
7
- StickerTypes["ROUNDED"] = "rounded";
8
- })(StickerTypes || (StickerTypes = {}));
@@ -1,3 +0,0 @@
1
- import { IStickerOptions } from '..';
2
- declare const convert: (data: Buffer, mime: string, { quality, background, type }: IStickerOptions) => Promise<Buffer>;
3
- export default convert;
@@ -1,69 +0,0 @@
1
- import sharp from 'sharp';
2
- import videoToGif from './videoToGif.js';
3
- import fs from 'fs-extra';
4
- import { tmpdir } from 'os';
5
- import crop from './crop.js';
6
- import { StickerTypes } from './Metadata/StickerTypes.js';
7
- import { defaultBg } from '../Utils.js';
8
- const convert = async (data, mime, { quality = 100, background = defaultBg, type = StickerTypes.DEFAULT }) => {
9
- const isVideo = mime.startsWith('video');
10
- let image = isVideo ? await videoToGif(data) : data;
11
- const isAnimated = isVideo || mime.includes('gif') || mime.includes('webp');
12
- if (isAnimated && ['crop', 'circle', 'rouded'].includes(type)) {
13
- const filename = `${tmpdir()}/${Math.random().toString(36)}.webp`;
14
- await fs.writeFile(filename, image);
15
- [image, type] = [
16
- await crop(filename),
17
- type === StickerTypes.CIRCLE
18
- ? StickerTypes.CIRCLE
19
- : type === StickerTypes.ROUNDED
20
- ? StickerTypes.ROUNDED
21
- : StickerTypes.DEFAULT
22
- ];
23
- }
24
- const img = sharp(image, { animated: isAnimated }).toFormat('webp');
25
- switch (type) {
26
- case StickerTypes.CROPPED:
27
- img.resize(512, 512, {
28
- fit: sharp.fit.cover
29
- });
30
- break;
31
- case StickerTypes.FULL:
32
- img.resize(512, 512, {
33
- fit: sharp.fit.contain,
34
- background
35
- });
36
- break;
37
- case StickerTypes.CIRCLE:
38
- img.resize(512, 512, {
39
- fit: sharp.fit.cover
40
- }).composite([
41
- {
42
- input: Buffer.from(`<svg width="512" height="512"><circle cx="256" cy="256" r="256" fill="${background}"/></svg>`),
43
- blend: 'dest-in',
44
- gravity: 'northeast',
45
- tile: true
46
- }
47
- ]);
48
- break;
49
- case StickerTypes.ROUNDED:
50
- img.resize(512, 512, {
51
- fit: sharp.fit.cover
52
- }).composite([
53
- {
54
- input: Buffer.from(`<svg width="512" height="512"><rect rx="50" ry="50" width="512" height="512" fill="${background}"/></svg>`),
55
- blend: 'dest-in',
56
- gravity: 'northeast',
57
- tile: true
58
- }
59
- ]);
60
- break;
61
- }
62
- return await img
63
- .webp({
64
- quality,
65
- lossless: false
66
- })
67
- .toBuffer();
68
- };
69
- export default convert;
@@ -1,2 +0,0 @@
1
- declare const crop: (filename: string) => Promise<Buffer>;
2
- export default crop;
@@ -1,30 +0,0 @@
1
- import Ffmpeg from 'fluent-ffmpeg';
2
- import fs from 'fs-extra';
3
- import { tmpdir } from 'os';
4
- const crop = async (filename) => {
5
- const file = await new Promise((resolve) => {
6
- const name = `${tmpdir()}/${Math.random().toString(36)}.webp`;
7
- Ffmpeg(filename)
8
- // eslint-disable-next-line no-useless-escape
9
- .outputOptions([
10
- '-vcodec',
11
- 'libwebp',
12
- '-vf',
13
- // eslint-disable-next-line no-useless-escape
14
- `crop=w='min(min(iw\,ih)\,500)':h='min(min(iw\,ih)\,500)',scale=500:500,setsar=1,fps=15`,
15
- '-loop',
16
- '0',
17
- '-preset',
18
- 'default',
19
- '-an',
20
- '-vsync',
21
- '0',
22
- '-s',
23
- '512:512'
24
- ])
25
- .save(name)
26
- .on('end', () => resolve(name));
27
- });
28
- return await fs.readFile(file);
29
- };
30
- export default crop;
@@ -1,2 +0,0 @@
1
- declare const imagesToWebp: (filename: string) => Promise<Buffer>;
2
- export default imagesToWebp;
@@ -1,17 +0,0 @@
1
- import Ffmpeg from 'fluent-ffmpeg';
2
- import fs from 'fs-extra';
3
- import { tmpdir } from 'os';
4
- const imagesToWebp = async (filename) => {
5
- const file = await new Promise((resolve) => {
6
- const name = `${tmpdir()}/${Math.random().toString(36)}.webp`;
7
- Ffmpeg(filename)
8
- .outputOption('-lavfi split[v],palettegen,[v]paletteuse')
9
- .outputOption('-vcodec libwebp')
10
- .outputFPS(10)
11
- .loop(0)
12
- .save(name)
13
- .on('end', () => resolve(name));
14
- });
15
- return await fs.readFile(file);
16
- };
17
- export default imagesToWebp;
@@ -1,3 +0,0 @@
1
- /** https://stackoverflow.com/questions/52156713/fluent-ffmpeg-h264-to-gif-throwing-error-1 */
2
- declare const videoToGif: (data: Buffer) => Promise<Buffer>;
3
- export default videoToGif;
@@ -1,16 +0,0 @@
1
- import ffmpeg from 'fluent-ffmpeg';
2
- import fs from 'fs-extra';
3
- import { tmpdir } from 'os';
4
- /** https://stackoverflow.com/questions/52156713/fluent-ffmpeg-h264-to-gif-throwing-error-1 */
5
- const videoToGif = async (data) => {
6
- const filename = `${tmpdir()}/${Math.random().toString(36)}`;
7
- const [video, gif] = ['video', 'gif'].map((ext) => `${filename}.${ext}`);
8
- await fs.writeFile(video, data);
9
- await new Promise((resolve) => {
10
- ffmpeg(video).save(gif).on('end', resolve);
11
- });
12
- const buffer = await fs.readFile(gif);
13
- [video, gif].forEach((file) => fs.unlink(file));
14
- return buffer;
15
- };
16
- export default videoToGif;
@@ -1,206 +0,0 @@
1
- import { existsSync, readFile, writeFile } from 'fs-extra'
2
- import { IStickerConfig, IStickerOptions } from './Types'
3
- import axios from 'axios'
4
- import Utils, { defaultBg } from './Utils'
5
- import { fromBuffer } from 'file-type'
6
- import convert from './internal/convert'
7
- import Exif from './internal/Metadata/Exif'
8
- import { StickerTypes } from './internal/Metadata/StickerTypes'
9
- import { Categories, extractMetadata } from '.'
10
- import { Color } from 'sharp'
11
-
12
- /**
13
- * Sticker class
14
- */
15
- export class Sticker {
16
- /**
17
- * Sticker Constructor
18
- * @param {string|Buffer} [data] - File path, url or Buffer of the image/video to be converted
19
- * @param {IStickerOptions} [options] - Sticker options
20
- */
21
- constructor(private data: string | Buffer, public metadata: Partial<IStickerOptions> = {}) {
22
- this.metadata.author = this.metadata.author ?? ''
23
- this.metadata.pack = this.metadata.pack ?? ''
24
- this.metadata.id = this.metadata.id ?? Utils.generateStickerID()
25
- this.metadata.quality = this.metadata.quality ?? 100
26
- this.metadata.type = Object.values(StickerTypes).includes(this.metadata.type as StickerTypes)
27
- ? this.metadata.type
28
- : StickerTypes.DEFAULT
29
- this.metadata.background = this.metadata.background ?? defaultBg
30
- }
31
-
32
- private _parse = async (): Promise<Buffer> =>
33
- Buffer.isBuffer(this.data)
34
- ? this.data
35
- : this.data.trim().startsWith('<svg')
36
- ? Buffer.from(this.data)
37
- : (async () =>
38
- existsSync(this.data)
39
- ? readFile(this.data)
40
- : axios.get(this.data as string, { responseType: 'arraybuffer' }).then(({ data }) => data))()
41
-
42
- private _getMimeType = async (data: Buffer): Promise<string> => {
43
- const type = await fromBuffer(data)
44
- if (!type) {
45
- if (typeof this.data === 'string') return 'image/svg+xml'
46
- throw new Error('Invalid file type')
47
- }
48
- return type.mime
49
- }
50
-
51
- /**
52
- * Builds the sticker
53
- * @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
54
- * @example
55
- * const sticker = new Sticker('./image.png')
56
- * const buffer = sticker.build()
57
- */
58
- public build = async (): Promise<Buffer> => {
59
- const data = await this._parse()
60
- const mime = await this._getMimeType(data)
61
- return new Exif(this.metadata as IStickerConfig).add(await convert(data, mime, this.metadata))
62
- }
63
-
64
- /**
65
- * Alias for `.build()`
66
- * @param {string} [type] - How you want your sticker to look like
67
- * @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
68
- * @example
69
- * const sticker = new Sticker('./image.png')
70
- * const buffer = sticker.build()
71
- */
72
- public toBuffer = this.build
73
-
74
- public get defaultFilename(): string {
75
- return `./${this.metadata.pack}-${this.metadata.author}.webp`
76
- }
77
-
78
- /**
79
- * Saves the sticker to a file
80
- * @param [filename] - Filename to save the sticker to
81
- * @returns filename
82
- * @example
83
- * const sticker = new Sticker('./image.png')
84
- * sticker.toFile('./image.webp')
85
- */
86
- public toFile = async (filename = this.defaultFilename): Promise<string> => {
87
- await writeFile(filename, await this.build())
88
- return filename
89
- }
90
-
91
- /**
92
- * Set the sticker pack title
93
- * @param pack - Sticker Pack Title
94
- * @returns {this}
95
- * @example
96
- * const sticker = new Sticker('./image.png')
97
- * sticker.setPack('My Sticker Pack')
98
- * sticker.build()
99
- */
100
- public setPack = (pack: string): this => {
101
- this.metadata.pack = pack
102
- return this
103
- }
104
-
105
- /**
106
- * Set the sticker pack author
107
- * @param author - Sticker Pack Author
108
- * @returns
109
- */
110
- public setAuthor = (author: string): this => {
111
- this.metadata.author = author
112
- return this
113
- }
114
-
115
- /**
116
- * Set the sticker pack ID
117
- * @param id - Sticker Pack ID
118
- * @returns {this}
119
- * @example
120
- * const sticker = new Sticker('./image.png')
121
- * sticker.setID('my-sticker-pack')
122
- * sticker.build()
123
- */
124
- public setID = (id: string): this => {
125
- this.metadata.id = id
126
- return this
127
- }
128
-
129
- /**
130
- * Set the sticker category
131
- * @param categories - Sticker Category
132
- * @returns {this}
133
- * @example
134
- * const sticker = new Sticker('./image.png')
135
- * sticker.setCategories(['🌹'])
136
- */
137
- public setCategories = (categories: Categories[]): this => {
138
- this.metadata.categories = categories
139
- return this
140
- }
141
-
142
- /**
143
- * Set the sticker type
144
- * @param {StickerTypes|string}[type] - Sticker Type
145
- * @returns {this}
146
- */
147
- public setType = (type: StickerTypes | string): this => {
148
- this.metadata.type = type
149
- return this
150
- }
151
-
152
- /**
153
- * Set the sticker quality
154
- * @param {number}[quality] - Sticker Quality
155
- * @returns {this}
156
- */
157
- public setQuality = (quality: number): this => {
158
- this.metadata.quality = quality
159
- return this
160
- }
161
-
162
- /**
163
- * Set the background color for `full` images
164
- * @param {Color}[background] - Background color
165
- * @returns {this}
166
- */
167
- public setBackground = (background: Color): this => {
168
- this.metadata.background = background
169
- return this
170
- }
171
-
172
- /**
173
- * @deprecated
174
- * Use the `Sticker.build()` method instead
175
- */
176
- public get = this.build
177
-
178
- /**
179
- * Get BaileysMD-compatible message object
180
- * @returns {{ sticker: Buffer }}
181
- * @example
182
- * import { create } from '@adiwajshing/baileys-md'
183
- * const conn = create()
184
- * ...
185
- * const sticker = new Sticker('./image.png', { pack: 'My Sticker Pack', author: 'Me' })
186
- * const message = await sticker.toMessage()
187
- * conn.sendMessage(jid, message)
188
- */
189
- public toMessage = async (): Promise<{ sticker: Buffer }> => ({ sticker: await this.build() })
190
-
191
- /**
192
- * Extracts metadata from a WebP image.
193
- * @param {Buffer}image - The image buffer to extract metadata from
194
- */
195
- public static extractMetadata = extractMetadata
196
- }
197
-
198
- /**
199
- *
200
- * @param {string|Buffer} data - File path, url or Buffer of the image/video to be converted
201
- * @param {IStickerOptions} [options] - Sticker options
202
- * @returns {Promise<Buffer>} A promise that resolves to the sticker buffer
203
- */
204
- export const createSticker = async (...args: ConstructorParameters<typeof Sticker>): Promise<Buffer> => {
205
- return new Sticker(...args).build()
206
- }