@jrmc/adonis-attachment 3.3.0-beta.1 → 3.3.0-beta.2
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.
- package/build/src/attachments/variant_attachment.d.ts +1 -0
- package/build/src/attachments/variant_attachment.js +3 -0
- package/build/src/converter_manager.js +5 -0
- package/build/src/services/record_with_attachment.js +1 -1
- package/build/src/types/attachment.d.ts +2 -0
- package/build/src/types/converter.d.ts +6 -0
- package/build/src/utils/helpers.d.ts +3 -0
- package/build/src/utils/helpers.js +20 -0
- package/package.json +3 -1
|
@@ -11,6 +11,7 @@ import { AttachmentBase } from './attachment_base.js';
|
|
|
11
11
|
export declare class Variant extends AttachmentBase implements VariantInterface {
|
|
12
12
|
#private;
|
|
13
13
|
key: string;
|
|
14
|
+
blurhash?: string;
|
|
14
15
|
constructor(drive: DriveService, attributes: VariantAttributes, input?: Input);
|
|
15
16
|
/**
|
|
16
17
|
* Getters
|
|
@@ -8,10 +8,12 @@ import { AttachmentBase } from './attachment_base.js';
|
|
|
8
8
|
export class Variant extends AttachmentBase {
|
|
9
9
|
key;
|
|
10
10
|
#folder;
|
|
11
|
+
blurhash;
|
|
11
12
|
constructor(drive, attributes, input) {
|
|
12
13
|
super(drive, attributes, input);
|
|
13
14
|
this.key = attributes.key;
|
|
14
15
|
this.#folder = attributes.folder;
|
|
16
|
+
this.blurhash = attributes.blurhash;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Getters
|
|
@@ -27,6 +29,7 @@ export class Variant extends AttachmentBase {
|
|
|
27
29
|
key: this.key,
|
|
28
30
|
folder: this.folder,
|
|
29
31
|
name: this.name,
|
|
32
|
+
blurhash: this.blurhash,
|
|
30
33
|
...super.toObject(),
|
|
31
34
|
};
|
|
32
35
|
}
|
|
@@ -2,6 +2,7 @@ import string from '@adonisjs/core/helpers/string';
|
|
|
2
2
|
import db from '@adonisjs/lucid/services/db';
|
|
3
3
|
import attachmentManager from '../services/main.js';
|
|
4
4
|
import * as errors from './errors.js';
|
|
5
|
+
import { encodeImageToBlurhash } from './utils/helpers.js';
|
|
5
6
|
export class ConverterManager {
|
|
6
7
|
#record;
|
|
7
8
|
#attributeName;
|
|
@@ -32,6 +33,10 @@ export class ConverterManager {
|
|
|
32
33
|
throw new errors.E_CANNOT_PATH_BY_CONVERTER();
|
|
33
34
|
}
|
|
34
35
|
const variant = await attachments[i].createVariant(option, output);
|
|
36
|
+
if (converter.options.blurhash) {
|
|
37
|
+
const options = typeof converter.options.blurhash !== 'boolean' ? converter.options.blurhash : undefined;
|
|
38
|
+
variant.blurhash = await encodeImageToBlurhash(variant.input, options);
|
|
39
|
+
}
|
|
35
40
|
await attachmentManager.save(variant);
|
|
36
41
|
}
|
|
37
42
|
}
|
|
@@ -214,7 +214,7 @@ export default class Record {
|
|
|
214
214
|
const dirtyValue = this.#model.$dirty[name];
|
|
215
215
|
const originalValue = this.#model.$original[name]; // if dirtyValue is null, check original type
|
|
216
216
|
const isDirtyAttachment = dirtyValue instanceof Attachment ||
|
|
217
|
-
(Array.isArray(dirtyValue) && dirtyValue.every((item) => item instanceof Attachment));
|
|
217
|
+
(Array.isArray(dirtyValue) && dirtyValue.every((item) => item instanceof Attachment) && dirtyValue.length);
|
|
218
218
|
const isOriginalAttachment = originalValue instanceof Attachment ||
|
|
219
219
|
(Array.isArray(originalValue) && originalValue.every((item) => item instanceof Attachment));
|
|
220
220
|
return isDirtyAttachment || isOriginalAttachment;
|
|
@@ -41,6 +41,7 @@ export type Attachment = AttachmentBase & {
|
|
|
41
41
|
export type Variant = AttachmentBase & {
|
|
42
42
|
key: string;
|
|
43
43
|
folder: string;
|
|
44
|
+
blurhash?: string;
|
|
44
45
|
toObject(): VariantAttributes;
|
|
45
46
|
};
|
|
46
47
|
export type LucidOptions = {
|
|
@@ -67,4 +68,5 @@ export type AttachmentAttributes = AttachmentBaseAttributes & {
|
|
|
67
68
|
export type VariantAttributes = AttachmentBaseAttributes & {
|
|
68
69
|
key: string;
|
|
69
70
|
folder: string;
|
|
71
|
+
blurhash?: string;
|
|
70
72
|
};
|
|
@@ -22,6 +22,11 @@ export type ConverterAttributes = {
|
|
|
22
22
|
input: Input;
|
|
23
23
|
options: ConverterOptions;
|
|
24
24
|
};
|
|
25
|
+
export type BlurhashOptions = {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
componentX: number;
|
|
28
|
+
componentY: number;
|
|
29
|
+
};
|
|
25
30
|
type jpeg = {
|
|
26
31
|
format: 'jpeg';
|
|
27
32
|
options: {
|
|
@@ -127,5 +132,6 @@ export type ConverterOptions = {
|
|
|
127
132
|
fastShrinkOnLoad?: Boolean;
|
|
128
133
|
};
|
|
129
134
|
format?: 'jpeg' | 'jpg' | 'png' | 'gif' | 'webp' | 'avif' | 'heif' | 'tiff' | 'raw' | jpeg | png | gif | webp | avif | heif;
|
|
135
|
+
blurhash?: boolean | BlurhashOptions;
|
|
130
136
|
};
|
|
131
137
|
export {};
|
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
6
|
*/
|
|
7
|
+
import type { Input } from '../types/input.js';
|
|
8
|
+
import type { BlurhashOptions } from '../types/converter.js';
|
|
7
9
|
export declare function cleanObject(obj: any): any;
|
|
8
10
|
export declare function use(module: string): Promise<any>;
|
|
9
11
|
export declare function bufferToTempFile(input: Buffer): Promise<string>;
|
|
10
12
|
export declare function streamToTempFile(input: NodeJS.ReadableStream): Promise<string>;
|
|
11
13
|
export declare function downloadToTempFile(input: URL): Promise<string>;
|
|
12
14
|
export declare function isBase64(str: string): boolean;
|
|
15
|
+
export declare function encodeImageToBlurhash(input: Input, options?: BlurhashOptions): Promise<string>;
|
|
@@ -11,6 +11,7 @@ import fs from 'node:fs/promises';
|
|
|
11
11
|
import { pipeline } from 'node:stream';
|
|
12
12
|
import { promisify } from 'node:util';
|
|
13
13
|
import { createWriteStream } from 'node:fs';
|
|
14
|
+
import { encode } from 'blurhash';
|
|
14
15
|
import * as errors from '../errors.js';
|
|
15
16
|
const streamPipeline = promisify(pipeline);
|
|
16
17
|
export function cleanObject(obj) {
|
|
@@ -91,3 +92,22 @@ export function isBase64(str) {
|
|
|
91
92
|
return false;
|
|
92
93
|
}
|
|
93
94
|
}
|
|
95
|
+
export function encodeImageToBlurhash(input, options) {
|
|
96
|
+
const { componentX, componentY } = options || { componentX: 4, componentY: 4 };
|
|
97
|
+
return new Promise(async (resolve, reject) => {
|
|
98
|
+
try {
|
|
99
|
+
const sharp = await use('sharp');
|
|
100
|
+
// Convert input to pixels
|
|
101
|
+
const { data: pixels, info: metadata } = await sharp(input)
|
|
102
|
+
.raw()
|
|
103
|
+
.ensureAlpha()
|
|
104
|
+
.toBuffer({ resolveWithObject: true });
|
|
105
|
+
return resolve(encode(new Uint8ClampedArray(pixels), metadata.width, metadata.height, componentX, componentY));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.log('--------------');
|
|
109
|
+
console.log(error);
|
|
110
|
+
return reject(error);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jrmc/adonis-attachment",
|
|
3
|
-
"version": "3.3.0-beta.
|
|
3
|
+
"version": "3.3.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Turn any field on your Lucid model to an attachment data type",
|
|
6
6
|
"engines": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@poppinss/defer": "^1.1.1",
|
|
68
|
+
"blurhash": "^2.0.5",
|
|
68
69
|
"exifreader": "^4.26.0",
|
|
69
70
|
"file-type": "^19.6.0",
|
|
70
71
|
"mime-types": "^2.1.35"
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
"flydrive": "^1.1.0",
|
|
95
96
|
"luxon": "^3.5.0",
|
|
96
97
|
"prettier": "^3.4.2",
|
|
98
|
+
"sharp": "^0.33.5",
|
|
97
99
|
"ts-node": "^10.9.2",
|
|
98
100
|
"typescript": "^5.7.3",
|
|
99
101
|
"vitepress": "^1.5.0"
|