@ryuu-reinzz/haruka-lib 2.1.1 โ†’ 2.2.1

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,189 +0,0 @@
1
- import sharp, { Color } from 'sharp'
2
- import { StickerTypes } from './internal/Metadata/StickerTypes'
3
-
4
- /** Sticker metadata config */
5
- export interface IStickerConfig {
6
- /** Sticker Pack title*/
7
- pack?: string
8
- /** Sticker Pack Author*/
9
- author?: string
10
- /** Sticker Pack ID*/
11
- id?: string
12
- /** Sticker Category*/
13
- categories?: Categories[]
14
- }
15
-
16
- export interface IStickerOptions extends IStickerConfig {
17
- /** How you want your sticker to look like
18
- * Can be crop or full. Defaults to 'default' (no changes)
19
- */
20
- type?: StickerTypes | string
21
-
22
- /**
23
- * Quality of the output webp image. Must be an integer from 0 to 100 (defaults to 100
24
- */
25
- quality?: sharp.WebpOptions['quality']
26
- /**
27
- * Background Color of the sticker (only for type full)
28
- */
29
- background?: Color
30
- }
31
-
32
- export interface IRawMetadata {
33
- emojis: string[]
34
- 'sticker-pack-id': string
35
- 'sticker-pack-name': string
36
- 'sticker-pack-publisher': string
37
- }
38
-
39
- export type Metadata = IStickerConfig | IStickerOptions
40
-
41
- type Love =
42
- | 'โค'
43
- | '๐Ÿ˜'
44
- | '๐Ÿ˜˜'
45
- | '๐Ÿ’•'
46
- | '๐Ÿ˜ป'
47
- | '๐Ÿ’‘'
48
- | '๐Ÿ‘ฉโ€โคโ€๐Ÿ‘ฉ'
49
- | '๐Ÿ‘จโ€โคโ€๐Ÿ‘จ'
50
- | '๐Ÿ’'
51
- | '๐Ÿ‘ฉโ€โคโ€๐Ÿ’‹โ€๐Ÿ‘ฉ'
52
- | '๐Ÿ‘จโ€โคโ€๐Ÿ’‹โ€๐Ÿ‘จ'
53
- | '๐Ÿงก'
54
- | '๐Ÿ’›'
55
- | '๐Ÿ’š'
56
- | '๐Ÿ’™'
57
- | '๐Ÿ’œ'
58
- | '๐Ÿ–ค'
59
- | '๐Ÿ’”'
60
- | 'โฃ'
61
- | '๐Ÿ’ž'
62
- | '๐Ÿ’“'
63
- | '๐Ÿ’—'
64
- | '๐Ÿ’–'
65
- | '๐Ÿ’˜'
66
- | '๐Ÿ’'
67
- | '๐Ÿ’Ÿ'
68
- | 'โ™ฅ'
69
- | '๐Ÿ’Œ'
70
- | '๐Ÿ’‹'
71
- | '๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ'
72
- | '๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ'
73
- | '๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ'
74
- | '๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ'
75
- | '๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ'
76
- | '๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ'
77
- | '๐Ÿ‘ฌ'
78
- | '๐Ÿ‘ญ'
79
- | '๐Ÿ‘ซ'
80
- | '๐Ÿฅฐ'
81
- | '๐Ÿ˜š'
82
- | '๐Ÿ˜™'
83
- | '๐Ÿ‘„'
84
- | '๐ŸŒน'
85
- | '๐Ÿ˜ฝ'
86
- | 'โฃ๏ธ'
87
- | 'โค๏ธ'
88
- type Happy =
89
- | '๐Ÿ˜€'
90
- | '๐Ÿ˜ƒ'
91
- | '๐Ÿ˜„'
92
- | '๐Ÿ˜'
93
- | '๐Ÿ˜†'
94
- | '๐Ÿ˜…'
95
- | '๐Ÿ˜‚'
96
- | '๐Ÿคฃ'
97
- | '๐Ÿ™‚'
98
- | '๐Ÿ˜›'
99
- | '๐Ÿ˜'
100
- | '๐Ÿ˜œ'
101
- | '๐Ÿคช'
102
- | '๐Ÿค—'
103
- | '๐Ÿ˜บ'
104
- | '๐Ÿ˜ธ'
105
- | '๐Ÿ˜น'
106
- | 'โ˜บ'
107
- | '๐Ÿ˜Œ'
108
- | '๐Ÿ˜‰'
109
- | '๐Ÿค—'
110
- | '๐Ÿ˜Š'
111
- type Sad =
112
- | 'โ˜น'
113
- | '๐Ÿ˜ฃ'
114
- | '๐Ÿ˜–'
115
- | '๐Ÿ˜ซ'
116
- | '๐Ÿ˜ฉ'
117
- | '๐Ÿ˜ข'
118
- | '๐Ÿ˜ญ'
119
- | '๐Ÿ˜ž'
120
- | '๐Ÿ˜”'
121
- | '๐Ÿ˜Ÿ'
122
- | '๐Ÿ˜•'
123
- | '๐Ÿ˜ค'
124
- | '๐Ÿ˜ '
125
- | '๐Ÿ˜ฅ'
126
- | '๐Ÿ˜ฐ'
127
- | '๐Ÿ˜จ'
128
- | '๐Ÿ˜ฟ'
129
- | '๐Ÿ˜พ'
130
- | '๐Ÿ˜“'
131
- | '๐Ÿ™โ€โ™‚'
132
- | '๐Ÿ™โ€โ™€'
133
- | '๐Ÿ’”'
134
- | '๐Ÿ™'
135
- | '๐Ÿฅบ'
136
- | '๐Ÿค•'
137
- | 'โ˜”๏ธ'
138
- | 'โ›ˆ'
139
- | '๐ŸŒฉ'
140
- | '๐ŸŒง'
141
- type Angry =
142
- | '๐Ÿ˜ฏ'
143
- | '๐Ÿ˜ฆ'
144
- | '๐Ÿ˜ง'
145
- | '๐Ÿ˜ฎ'
146
- | '๐Ÿ˜ฒ'
147
- | '๐Ÿ™€'
148
- | '๐Ÿ˜ฑ'
149
- | '๐Ÿคฏ'
150
- | '๐Ÿ˜ณ'
151
- | 'โ—'
152
- | 'โ•'
153
- | '๐Ÿคฌ'
154
- | '๐Ÿ˜ก'
155
- | '๐Ÿ˜ '
156
- | '๐Ÿ™„'
157
- | '๐Ÿ‘ฟ'
158
- | '๐Ÿ˜พ'
159
- | '๐Ÿ˜ค'
160
- | '๐Ÿ’ข'
161
- | '๐Ÿ‘บ'
162
- | '๐Ÿ—ฏ๏ธ'
163
- | '๐Ÿ˜’'
164
- | '๐Ÿฅต'
165
- type Greet = '๐Ÿ‘‹'
166
- type Celebrate =
167
- | '๐ŸŽŠ'
168
- | '๐ŸŽ‰'
169
- | '๐ŸŽ'
170
- | '๐ŸŽˆ'
171
- | '๐Ÿ‘ฏโ€โ™‚๏ธ'
172
- | '๐Ÿ‘ฏ'
173
- | '๐Ÿ‘ฏโ€โ™€๏ธ'
174
- | '๐Ÿ’ƒ'
175
- | '๐Ÿ•บ'
176
- | '๐Ÿ”ฅ'
177
- | 'โญ๏ธ'
178
- | 'โœจ'
179
- | '๐Ÿ’ซ'
180
- | '๐ŸŽ‡'
181
- | '๐ŸŽ†'
182
- | '๐Ÿป'
183
- | '๐Ÿฅ‚'
184
- | '๐Ÿพ'
185
- | '๐ŸŽ‚'
186
- | '๐Ÿฐ'
187
-
188
- /** Sticker Category. Learn More: https://github.com/WhatsApp/stickers/wiki/Tag-your-stickers-with-Emojis*/
189
- export type Categories = Love | Happy | Sad | Angry | Greet | Celebrate
@@ -1,12 +0,0 @@
1
- import { randomBytes } from 'crypto'
2
-
3
- export default abstract class Utils {
4
- static generateStickerID = (): string => randomBytes(32).toString('hex')
5
- }
6
-
7
- export const defaultBg = {
8
- r: 0,
9
- g: 0,
10
- b: 0,
11
- alpha: 0
12
- }
@@ -1,13 +0,0 @@
1
- import { Image } from 'node-webpmux'
2
- import { IRawMetadata } from '.'
3
-
4
- /**
5
- * Extracts metadata from a WebP image.
6
- * @param {Buffer}image - The image buffer to extract metadata from
7
- */
8
- export const extractMetadata = async (image: Buffer): Promise<Partial<IRawMetadata>> => {
9
- const img = new Image()
10
- await img.load(image)
11
- const exif = img.exif?.toString('utf-8') ?? '{}'
12
- return JSON.parse(exif.substring(exif.indexOf('{'), exif.lastIndexOf('}') + 1) ?? '{}') as IRawMetadata
13
- }
@@ -1,9 +0,0 @@
1
- import { Sticker } from './Sticker'
2
-
3
- export * from './Sticker'
4
- export * from './extractMetadata'
5
- export * from './Types'
6
- export { default as StickerMetadata } from './internal/Metadata/StickerMetadata'
7
- export { default as Exif } from './internal/Metadata/Exif'
8
- export * from './internal/Metadata/StickerTypes'
9
- export default Sticker
@@ -1,39 +0,0 @@
1
- import { Image } from 'node-webpmux'
2
- import { TextEncoder } from 'util'
3
- import { Metadata } from '../../Types'
4
- import RawMetadata from './RawMetadata'
5
-
6
- export default class Exif {
7
- private data: RawMetadata
8
- private exif: Buffer | null = null
9
- constructor(options: Metadata) {
10
- this.data = new RawMetadata(options)
11
- }
12
-
13
- build = (): Buffer => {
14
- const data = JSON.stringify(this.data)
15
- const exif = Buffer.concat([
16
- Buffer.from([
17
- 0x49, 0x49, 0x2a, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00,
18
- 0x00, 0x16, 0x00, 0x00, 0x00
19
- ]),
20
- Buffer.from(data, 'utf-8')
21
- ])
22
- exif.writeUIntLE(new TextEncoder().encode(data).length, 14, 4)
23
- return exif
24
- }
25
-
26
- add = async (image: string | Buffer | Image): Promise<Buffer> => {
27
- const exif = this.exif || this.build()
28
- image =
29
- image instanceof Image
30
- ? image
31
- : await (async () => {
32
- const img = new Image()
33
- await img.load(image)
34
- return img
35
- })()
36
- image.exif = exif
37
- return await image.save(null)
38
- }
39
- }
@@ -1,15 +0,0 @@
1
- import { IRawMetadata, Metadata } from '../../Types'
2
- import Utils from '../../Utils'
3
-
4
- export default class RawMetadata implements IRawMetadata {
5
- emojis: string[]
6
- 'sticker-pack-id': string
7
- 'sticker-pack-name': string
8
- 'sticker-pack-publisher': string
9
- constructor(options: Metadata) {
10
- this['sticker-pack-id'] = options.id || Utils.generateStickerID()
11
- this['sticker-pack-name'] = options.pack || ''
12
- this['sticker-pack-publisher'] = options.author || ''
13
- this.emojis = options.categories || []
14
- }
15
- }
@@ -1,60 +0,0 @@
1
- import { Categories, IStickerConfig, IStickerOptions } from '../../Types'
2
- import Utils from '../../Utils'
3
-
4
- export default class StickerMetadata implements IStickerOptions {
5
- public crop = false
6
- public full = false
7
- constructor(
8
- public pack = '',
9
- public author = '',
10
- public categories: Categories[] = [],
11
- public id = Utils.generateStickerID()
12
- ) {}
13
-
14
- static from = (object: Partial<StickerMetadata>): StickerMetadata => {
15
- return new StickerMetadata(object.pack, object.author, object.categories, object.id)
16
- }
17
-
18
- public setPack = (title: string): this => {
19
- this.pack = title
20
- return this
21
- }
22
-
23
- public setAuthor = (author: string): this => {
24
- this.author = author
25
- return this
26
- }
27
-
28
- public setId = (id: string): this => {
29
- this.id = id
30
- return this
31
- }
32
-
33
- public setCrop = (value: boolean): this => {
34
- this.crop = value
35
- this.full = !value
36
- return this
37
- }
38
-
39
- public setFull = (value: boolean): this => {
40
- this.crop = !value
41
- this.full = value
42
- return this
43
- }
44
-
45
- public setCategories = (categories: string | string[]): this => {
46
- this.categories = (
47
- typeof categories === 'string' ? categories.split(',').map((emoji) => emoji.trim()) : categories
48
- ) as Categories[]
49
- return this
50
- }
51
-
52
- public toJSON = (): IStickerConfig => {
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- const obj: any = {}
55
- Object.keys(this)
56
- .filter((key) => typeof this[key as keyof this] !== 'function')
57
- .forEach((key) => (obj[key] = this[key as keyof IStickerConfig] as IStickerConfig[keyof IStickerConfig]))
58
- return obj as IStickerConfig
59
- }
60
- }
@@ -1,7 +0,0 @@
1
- export enum StickerTypes {
2
- DEFAULT = 'default',
3
- CROPPED = 'crop',
4
- FULL = 'full',
5
- CIRCLE = 'circle',
6
- ROUNDED = 'rounded'
7
- }
@@ -1,87 +0,0 @@
1
- import sharp, { fit } from 'sharp'
2
- import videoToGif from './videoToGif'
3
- import { writeFile } from 'fs-extra'
4
- import { tmpdir } from 'os'
5
- import crop from './crop'
6
- import { StickerTypes } from './Metadata/StickerTypes'
7
- import { defaultBg } from '../Utils'
8
- import { IStickerOptions } from '..'
9
-
10
- const convert = async (
11
- data: Buffer,
12
- mime: string,
13
- { quality = 100, background = defaultBg, type = StickerTypes.DEFAULT }: IStickerOptions
14
- ): Promise<Buffer> => {
15
- const isVideo = mime.startsWith('video')
16
- let image = isVideo ? await videoToGif(data) : data
17
- const isAnimated = isVideo || mime.includes('gif') || mime.includes('webp')
18
-
19
- if (isAnimated && ['crop', 'circle', 'rouded'].includes(type)) {
20
- const filename = `${tmpdir()}/${Math.random().toString(36)}.webp`
21
- await writeFile(filename, image)
22
- ;[image, type] = [
23
- await crop(filename),
24
- type === StickerTypes.CIRCLE
25
- ? StickerTypes.CIRCLE
26
- : type === StickerTypes.ROUNDED
27
- ? StickerTypes.ROUNDED
28
- : StickerTypes.DEFAULT
29
- ]
30
- }
31
-
32
- const img = sharp(image, { animated: isAnimated }).toFormat('webp')
33
-
34
- switch (type) {
35
- case StickerTypes.CROPPED:
36
- img.resize(512, 512, {
37
- fit: fit.cover
38
- })
39
- break
40
-
41
- case StickerTypes.FULL:
42
- img.resize(512, 512, {
43
- fit: fit.contain,
44
- background
45
- })
46
- break
47
-
48
- case StickerTypes.CIRCLE:
49
- img.resize(512, 512, {
50
- fit: fit.cover
51
- }).composite([
52
- {
53
- input: Buffer.from(
54
- `<svg width="512" height="512"><circle cx="256" cy="256" r="256" fill="${background}"/></svg>`
55
- ),
56
- blend: 'dest-in',
57
- gravity: 'northeast',
58
- tile: true
59
- }
60
- ])
61
- break
62
-
63
- case StickerTypes.ROUNDED:
64
- img.resize(512, 512, {
65
- fit: fit.cover
66
- }).composite([
67
- {
68
- input: Buffer.from(
69
- `<svg width="512" height="512"><rect rx="50" ry="50" width="512" height="512" fill="${background}"/></svg>`
70
- ),
71
- blend: 'dest-in',
72
- gravity: 'northeast',
73
- tile: true
74
- }
75
- ])
76
- break
77
- }
78
-
79
- return await img
80
- .webp({
81
- quality,
82
- lossless: false
83
- })
84
- .toBuffer()
85
- }
86
-
87
- export default convert
@@ -1,32 +0,0 @@
1
- import Ffmpeg from 'fluent-ffmpeg'
2
- import { readFile } from 'fs-extra'
3
- import { tmpdir } from 'os'
4
-
5
- const crop = async (filename: string): Promise<Buffer> => {
6
- const file = await new Promise<string>((resolve) => {
7
- const name = `${tmpdir()}/${Math.random().toString(36)}.webp`
8
- Ffmpeg(filename)
9
- // eslint-disable-next-line no-useless-escape
10
- .outputOptions([
11
- '-vcodec',
12
- 'libwebp',
13
- '-vf',
14
- // eslint-disable-next-line no-useless-escape
15
- `crop=w='min(min(iw\,ih)\,500)':h='min(min(iw\,ih)\,500)',scale=500:500,setsar=1,fps=15`,
16
- '-loop',
17
- '0',
18
- '-preset',
19
- 'default',
20
- '-an',
21
- '-vsync',
22
- '0',
23
- '-s',
24
- '512:512'
25
- ])
26
- .save(name)
27
- .on('end', () => resolve(name))
28
- })
29
- return await readFile(file)
30
- }
31
-
32
- export default crop
@@ -1,19 +0,0 @@
1
- import Ffmpeg from 'fluent-ffmpeg'
2
- import { readFile } from 'fs-extra'
3
- import { tmpdir } from 'os'
4
-
5
- const imagesToWebp = async (filename: string): Promise<Buffer> => {
6
- const file = await new Promise<string>((resolve) => {
7
- const name = `${tmpdir()}/${Math.random().toString(36)}.webp`
8
- Ffmpeg(filename)
9
- .outputOption('-lavfi split[v],palettegen,[v]paletteuse')
10
- .outputOption('-vcodec libwebp')
11
- .outputFPS(10)
12
- .loop(0)
13
- .save(name)
14
- .on('end', () => resolve(name))
15
- })
16
- return await readFile(file)
17
- }
18
-
19
- export default imagesToWebp
@@ -1,8 +0,0 @@
1
- declare module 'node-webpmux' {
2
- export class Image {
3
- constructor()
4
- exif: Buffer
5
- load(buffer: Buffer | string): Promise<void>
6
- save(...args: unknown[]): Promise<Buffer>
7
- }
8
- }
@@ -1,18 +0,0 @@
1
- import ffmpeg from 'fluent-ffmpeg'
2
- import { writeFile, readFile, unlink } from 'fs-extra'
3
- import { tmpdir } from 'os'
4
-
5
- /** https://stackoverflow.com/questions/52156713/fluent-ffmpeg-h264-to-gif-throwing-error-1 */
6
- const videoToGif = async (data: Buffer): Promise<Buffer> => {
7
- const filename = `${tmpdir()}/${Math.random().toString(36)}`
8
- const [video, gif] = ['video', 'gif'].map((ext) => `${filename}.${ext}`)
9
- await writeFile(video, data)
10
- await new Promise((resolve) => {
11
- ffmpeg(video).save(gif).on('end', resolve)
12
- })
13
- const buffer = await readFile(gif)
14
- ;[video, gif].forEach((file) => unlink(file))
15
- return buffer
16
- }
17
-
18
- export default videoToGif
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "ESNext",
5
- "rootDir": "main/sticker-engine/type-script",
6
- "outDir": "main/sticker-engine/java-script",
7
- "allowJs": true,
8
- "esModuleInterop": true,
9
- "declaration": true,
10
- "moduleResolution": "node"
11
- },
12
- "include": ["main/sticker-engine/type-script/**/*"]
13
- }