mikro-orm-attachments 1.3.2 → 2.0.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.
- package/CHANGELOG.md +2 -0
- package/dist/converters/BaseConverter.js +1 -0
- package/dist/converters/ImgkitConverter.d.ts +877 -0
- package/dist/converters/ImgkitConverter.js +1 -0
- package/dist/converters/SharpConverter.d.ts +38 -0
- package/dist/converters/SharpConverter.js +1 -0
- package/dist/index.d.ts +67 -160
- package/dist/index.js +1 -1
- package/dist/metadata/BaseMetadata.d.ts +25 -0
- package/dist/metadata/BaseMetadata.js +1 -0
- package/dist/metadata/ImgkitMetadata.d.ts +28 -0
- package/dist/metadata/ImgkitMetadata.js +1 -0
- package/dist/metadata/SharpMetadata.js +1 -0
- package/dist/shared/chunk-4thj50nc.js +2 -0
- package/dist/shared/chunk-523ncfdc.js +2 -0
- package/dist/shared/chunk-cm81a68q.js +2 -0
- package/package.json +41 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as o}from"../shared/chunk-4thj50nc.js";import{b as i}from"../shared/chunk-cm81a68q.js";import{fileTypeFromBuffer as n}from"file-type";class m extends o{options;constructor(t){super();this.options=t}async supports(t){return t.mimeType.startsWith("image/")}async handle(t){let e=await(await i("imgkit")).transform(t.buffer,this.options??{}),r=await n(new Uint8Array(e.buffer));return{buffer:e,mimeType:r?.mime??t.mimeType,extname:r?.ext??t.extname}}}export{m as ImgkitConverter};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type VariantSpec = BaseConverter<ConvertInput, ConvertOutput>;
|
|
2
|
+
interface ConvertInput {
|
|
3
|
+
buffer: Buffer;
|
|
4
|
+
size: number;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
variantName?: string;
|
|
7
|
+
variant?: VariantSpec;
|
|
8
|
+
extname: string;
|
|
9
|
+
}
|
|
10
|
+
interface ConvertOutput {
|
|
11
|
+
buffer: Buffer;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
extname: string;
|
|
14
|
+
}
|
|
15
|
+
declare abstract class BaseConverter<
|
|
16
|
+
TInput extends ConvertInput,
|
|
17
|
+
TOutput extends ConvertOutput
|
|
18
|
+
> {
|
|
19
|
+
abstract supports(input: TInput): Promise<boolean>;
|
|
20
|
+
abstract handle(input: TInput): Promise<TOutput>;
|
|
21
|
+
}
|
|
22
|
+
import * as Sharp from "sharp";
|
|
23
|
+
type SharpFormat = "jpg" | "jpeg" | "png" | "webp" | "avif" | "gif" | "tiff" | "heic" | "heif";
|
|
24
|
+
interface SharpConverterOptions {
|
|
25
|
+
resize?: Sharp.ResizeOptions;
|
|
26
|
+
autoOrient?: boolean;
|
|
27
|
+
format?: SharpFormat | {
|
|
28
|
+
format: SharpFormat;
|
|
29
|
+
options: Sharp.PngOptions | Sharp.JpegOptions | Sharp.WebpOptions | Sharp.AvifOptions | Sharp.GifOptions | Sharp.TiffOptions | Sharp.HeifOptions;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
declare class SharpConverter extends BaseConverter<ConvertInput, ConvertOutput> {
|
|
33
|
+
private readonly options?;
|
|
34
|
+
constructor(options?: SharpConverterOptions | undefined);
|
|
35
|
+
supports(input: ConvertInput): Promise<boolean>;
|
|
36
|
+
handle(input: ConvertInput): Promise<ConvertOutput>;
|
|
37
|
+
}
|
|
38
|
+
export { SharpConverter };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as n}from"../shared/chunk-4thj50nc.js";import{b as a}from"../shared/chunk-cm81a68q.js";import{fileTypeFromBuffer as h}from"file-type";class u extends n{options;constructor(t){super();this.options=t}async supports(t){return t.mimeType.startsWith("image/")}async handle(t){let s=await a("sharp"),f=this.options?.resize||{},e=this.options?.format||"webp",m=this.options?.autoOrient||!0,r={};if(typeof e!=="string")r=e?.options,e=e.format;let o=s(t.buffer).withMetadata();if(m)o.autoOrient();let p=await o.resize(f).toFormat(e,r).toBuffer(),i=await h(p);return{buffer:p,mimeType:i?.mime??t.mimeType,extname:i?.ext??t.extname}}}export{u as SharpConverter};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,143 +1,32 @@
|
|
|
1
1
|
import { PropertyOptions } from "@mikro-orm/core";
|
|
2
|
-
import { DriverContract } from "flydrive/types";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
handle(input: ConvertInput, options: ConverterOptions): Promise<ConvertOutput>;
|
|
2
|
+
import { DriverContract as DriverContract2 } from "flydrive/types";
|
|
3
|
+
declare abstract class BaseMetadata<TMetadata> {
|
|
4
|
+
abstract metadata(input: ConvertInput): Promise<TMetadata>;
|
|
6
5
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
interface ConvertInput {
|
|
13
|
-
buffer: Buffer;
|
|
14
|
-
size: number;
|
|
15
|
-
mimeType: string;
|
|
16
|
-
variantName: string;
|
|
17
|
-
variant: VariantSpec;
|
|
18
|
-
extname: string;
|
|
6
|
+
import { DriverContract } from "flydrive/types";
|
|
7
|
+
interface EventSubscriber {
|
|
8
|
+
getSubscribedEvents(): string[];
|
|
9
|
+
onLoad(args: any): Promise<void>;
|
|
10
|
+
beforeFlush(args: any): Promise<void>;
|
|
19
11
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
declare class AttachmentSubscriber<
|
|
13
|
+
const TDrivers extends Record<string, DriverContract>,
|
|
14
|
+
const TVariants extends Record<string, VariantSpec>
|
|
15
|
+
> implements EventSubscriber {
|
|
16
|
+
private;
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly disks;
|
|
19
|
+
constructor(options: AttachmentOptions<TDrivers, TVariants>);
|
|
20
|
+
onLoad(args: any): Promise<void>;
|
|
21
|
+
beforeFlush(args: any): Promise<void>;
|
|
22
|
+
AttachmentDecorator(options?: AttachmentDecoratorProps<AttachmentSubscriber<TDrivers, TVariants>>): (target: any, propertyKey: string) => void;
|
|
24
23
|
}
|
|
25
|
-
type jpeg = {
|
|
26
|
-
format: "jpeg";
|
|
27
|
-
options?: {
|
|
28
|
-
quality?: number;
|
|
29
|
-
progressive?: boolean;
|
|
30
|
-
chromaSubsampling?: string;
|
|
31
|
-
optimiseCoding?: boolean;
|
|
32
|
-
optimizeCoding?: boolean;
|
|
33
|
-
mozjpeg?: boolean;
|
|
34
|
-
trellisQuantisation?: boolean;
|
|
35
|
-
overshootDeringing?: boolean;
|
|
36
|
-
optimiseScans?: boolean;
|
|
37
|
-
optimizeScans?: boolean;
|
|
38
|
-
quantisationTable?: number;
|
|
39
|
-
quantizationTable?: number;
|
|
40
|
-
force?: boolean;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
type png = {
|
|
44
|
-
format: "png";
|
|
45
|
-
options?: {
|
|
46
|
-
quality?: number;
|
|
47
|
-
progressive?: boolean;
|
|
48
|
-
compressionLevel?: number;
|
|
49
|
-
adaptiveFiltering?: boolean;
|
|
50
|
-
palette?: boolean;
|
|
51
|
-
effort?: number;
|
|
52
|
-
colours?: number;
|
|
53
|
-
colors?: number;
|
|
54
|
-
dither?: number;
|
|
55
|
-
force?: boolean;
|
|
56
|
-
};
|
|
57
|
-
};
|
|
58
|
-
type gif = {
|
|
59
|
-
format: "gif";
|
|
60
|
-
options?: {
|
|
61
|
-
reuse?: boolean;
|
|
62
|
-
progressive?: boolean;
|
|
63
|
-
colours?: number;
|
|
64
|
-
colors?: number;
|
|
65
|
-
effort?: number;
|
|
66
|
-
dither?: number;
|
|
67
|
-
interFrameMaxError?: number;
|
|
68
|
-
interPaletteMaxError?: number;
|
|
69
|
-
loop?: number;
|
|
70
|
-
delay?: number | number[];
|
|
71
|
-
force?: boolean;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
type webp = {
|
|
75
|
-
format: "webp";
|
|
76
|
-
options?: {
|
|
77
|
-
quality?: number;
|
|
78
|
-
alphaQuality?: number;
|
|
79
|
-
lossless?: boolean;
|
|
80
|
-
nearLossless?: boolean;
|
|
81
|
-
smartSubsample?: boolean;
|
|
82
|
-
preset?: string;
|
|
83
|
-
effort?: number;
|
|
84
|
-
loop?: number;
|
|
85
|
-
delay?: number | number[];
|
|
86
|
-
minSize?: boolean;
|
|
87
|
-
mixed?: boolean;
|
|
88
|
-
force?: boolean;
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
type avif = {
|
|
92
|
-
format: "avif";
|
|
93
|
-
options?: {
|
|
94
|
-
quality?: number;
|
|
95
|
-
lossless?: boolean;
|
|
96
|
-
effort?: number;
|
|
97
|
-
chromaSubsampling?: string;
|
|
98
|
-
bitdepth?: number;
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
type heif = {
|
|
102
|
-
format: "heif";
|
|
103
|
-
options?: {
|
|
104
|
-
compression?: string;
|
|
105
|
-
quality?: number;
|
|
106
|
-
lossless?: boolean;
|
|
107
|
-
effort?: number;
|
|
108
|
-
chromaSubsampling?: string;
|
|
109
|
-
bitdepth?: number;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
type ConverterOptions = {
|
|
113
|
-
resize?: number | {
|
|
114
|
-
width?: number;
|
|
115
|
-
height?: number;
|
|
116
|
-
fit?: "contain" | "cover" | "fill" | "inside" | "outside";
|
|
117
|
-
position?: string;
|
|
118
|
-
background?: string | {
|
|
119
|
-
r: number;
|
|
120
|
-
g: number;
|
|
121
|
-
b: number;
|
|
122
|
-
alpha: number;
|
|
123
|
-
};
|
|
124
|
-
kernel?: string;
|
|
125
|
-
withoutEnlargement?: boolean;
|
|
126
|
-
withoutReduction?: boolean;
|
|
127
|
-
fastShrinkOnLoad?: boolean;
|
|
128
|
-
};
|
|
129
|
-
format?: "jpeg" | "jpg" | "png" | "gif" | "webp" | "avif" | "heif" | "tiff" | "raw" | jpeg | png | gif | webp | avif | heif;
|
|
130
|
-
autoOrient?: boolean;
|
|
131
|
-
blurhash?: boolean | BlurhashOptions;
|
|
132
|
-
startTime?: number;
|
|
133
|
-
startPage?: number;
|
|
134
|
-
};
|
|
135
24
|
type StringKeyOf<T> = Extract<keyof T, string>;
|
|
136
25
|
type DriversOf<S> = S extends AttachmentSubscriber<infer TDrivers, any> ? TDrivers : never;
|
|
137
26
|
type VariantsOf<S> = S extends AttachmentSubscriber<any, infer TVariants> ? TVariants : never;
|
|
138
27
|
type VariantSelection<TVariants extends Record<string, VariantSpec>> = ReadonlyArray<StringKeyOf<TVariants> | Record<string, VariantSpec>> | Partial<TVariants> | Record<string, VariantSpec>;
|
|
139
28
|
interface AttachmentPropertyOptions<
|
|
140
|
-
TDrivers extends Record<string,
|
|
29
|
+
TDrivers extends Record<string, DriverContract2> = Record<string, DriverContract2>,
|
|
141
30
|
TVariants extends Record<string, VariantSpec> = Record<string, VariantSpec>
|
|
142
31
|
> {
|
|
143
32
|
folder?: string;
|
|
@@ -147,14 +36,15 @@ interface AttachmentPropertyOptions<
|
|
|
147
36
|
}
|
|
148
37
|
type AttachmentPropertyOptionsFor<S extends AttachmentSubscriber<any, any>> = AttachmentPropertyOptions<DriversOf<S>, VariantsOf<S>>;
|
|
149
38
|
interface AttachmentOptions<
|
|
150
|
-
TDrivers extends Record<string,
|
|
151
|
-
TVariants extends Record<string, VariantSpec> = Record<string, VariantSpec
|
|
39
|
+
TDrivers extends Record<string, DriverContract2> = Record<string, DriverContract2>,
|
|
40
|
+
TVariants extends Record<string, VariantSpec> = Record<string, VariantSpec>,
|
|
41
|
+
TMetadata extends BaseMetadata<any> = BaseMetadata<any>
|
|
152
42
|
> {
|
|
153
43
|
readonly drivers: TDrivers;
|
|
154
44
|
readonly defaultDriver: StringKeyOf<TDrivers>;
|
|
155
45
|
readonly rename?: boolean | ((file: File, columnName: string, entity: any) => string);
|
|
156
|
-
readonly converters?: Converter[];
|
|
157
46
|
readonly variants?: TVariants;
|
|
47
|
+
readonly metadata?: TMetadata;
|
|
158
48
|
}
|
|
159
49
|
declare const ALLOWED_PROPERTY_OPTIONS: readonly ["accessor", "comment", "customOrder", "getter", "getterName", "hidden", "index", "lazy", "name", "nullable", "serializedName", "serializedPrimaryKey", "serializer", "version"];
|
|
160
50
|
type AllowedPropertyOptions = (typeof ALLOWED_PROPERTY_OPTIONS)[number];
|
|
@@ -167,28 +57,42 @@ interface AttachmentBase {
|
|
|
167
57
|
mimeType: string;
|
|
168
58
|
path: string;
|
|
169
59
|
originalName: string;
|
|
60
|
+
meta?: ConvertMetadata;
|
|
170
61
|
variants: Omit<AttachmentBase, "variants" | "originalName" | "drive">[];
|
|
171
62
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
63
|
+
type VariantSpec = BaseConverter<ConvertInput, ConvertOutput>;
|
|
64
|
+
type BlurhashOptions = {
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
componentX: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
67
|
+
componentY: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
68
|
+
};
|
|
69
|
+
interface ConvertInput {
|
|
70
|
+
buffer: Buffer;
|
|
71
|
+
size: number;
|
|
72
|
+
mimeType: string;
|
|
73
|
+
variantName?: string;
|
|
74
|
+
variant?: VariantSpec;
|
|
75
|
+
extname: string;
|
|
178
76
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
77
|
+
interface ConvertOutput {
|
|
78
|
+
buffer: Buffer;
|
|
79
|
+
mimeType: string;
|
|
80
|
+
extname: string;
|
|
81
|
+
}
|
|
82
|
+
interface ConvertMetadata {
|
|
83
|
+
dimension: {
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
declare abstract class BaseConverter<
|
|
89
|
+
TInput extends ConvertInput,
|
|
90
|
+
TOutput extends ConvertOutput
|
|
91
|
+
> {
|
|
92
|
+
abstract supports(input: TInput): Promise<boolean>;
|
|
93
|
+
abstract handle(input: TInput): Promise<TOutput>;
|
|
191
94
|
}
|
|
95
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
192
96
|
import { Disk } from "flydrive";
|
|
193
97
|
import { SignedURLOptions } from "flydrive/types";
|
|
194
98
|
import { Readable as Readable_d9sohc } from "node:stream";
|
|
@@ -205,18 +109,21 @@ declare class Attachment<Variants extends string = string> {
|
|
|
205
109
|
* @throws An error if the file cannot be downloaded.
|
|
206
110
|
*/
|
|
207
111
|
static fromUrl(url: string): Promise<Attachment>;
|
|
208
|
-
url(variant?:
|
|
209
|
-
|
|
112
|
+
url(variant?: Variants): string | Promise<string> | undefined;
|
|
113
|
+
originalName(): string;
|
|
114
|
+
size(variant?: Variants): number | undefined;
|
|
115
|
+
meta(variant?: Variants): ConvertMetadata | undefined;
|
|
116
|
+
preSignedUrl(variantNameOrOptions?: string | SignedURLOptions, signedUrlOptions?: SignedURLOptions): Promise<string> | undefined;
|
|
210
117
|
blurhash(): string | undefined;
|
|
211
|
-
getDisk(): Disk;
|
|
118
|
+
getDisk(): Disk | undefined;
|
|
212
119
|
getDrive(): string;
|
|
213
|
-
getBytes(variantName?: Variants): Promise<Uint8Array<ArrayBufferLike
|
|
214
|
-
getBuffer(variantName?: Variants): Promise<
|
|
215
|
-
getStream(variantName?: Variants): Promise<Readable_d9sohc>;
|
|
120
|
+
getBytes(variantName?: Variants): Promise<Uint8Array<ArrayBufferLike> | undefined>;
|
|
121
|
+
getBuffer(variantName?: Variants): Promise<Buffer2<ArrayBuffer> | null>;
|
|
122
|
+
getStream(variantName?: Variants): Promise<Readable_d9sohc | undefined>;
|
|
216
123
|
getMimeType(variantName?: Variants): string;
|
|
217
124
|
toJSON(): {
|
|
218
|
-
url: string | Promise<string
|
|
125
|
+
url: string | Promise<string> | undefined;
|
|
219
126
|
blurhash: string | undefined;
|
|
220
127
|
};
|
|
221
128
|
}
|
|
222
|
-
export { AttachmentSubscriber, AttachmentPropertyOptions, AttachmentOptions, Attachment };
|
|
129
|
+
export { AttachmentSubscriber, AttachmentPropertyOptions, AttachmentOptions, AttachmentDecoratorProps, Attachment };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as C}from"./shared/chunk-4thj50nc.js";import{c as W,d as l}from"./shared/chunk-cm81a68q.js";import{Buffer as B}from"node:buffer";var x=Symbol("attachment:loaded"),D=Symbol("attachment:options"),y=Symbol("attachment:file"),i=Symbol("attachment:disk"),P=Symbol("attachment:fn:process"),V=Symbol("attachment:fn:load"),O=Symbol("attachment:fn:save");class p{[x]=!1;[y];[i];data;constructor(t){if(t instanceof File)this[y]=t;else this[x]=!0,this.data=t}#t(){if(!this[x])throw Error("Attachment is not processed, please flush the entity first.")}get#s(){return this.#t(),this[i]}[O](){return this.data??{}}static[V](t){return new p(t)}[P](t){if(this[x])return;this.data=t,this[x]=!0}static fromFile(t){return new p(t)}static async fromUrl(t){let r=await fetch(t),s=await r.arrayBuffer(),e,o=r.headers.get("content-disposition");if(o){let S=o.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/i);if(S)e=S[1].replace(/['"]/g,"")}if(!e)e=t.split("?")[0].split("/").pop()||"download";let c=B.from(s),n=new File([c],e,{type:r.headers.get("content-type")??""});return new p(n)}#r(t){this.#t();let r=this.data?.variants.find((s)=>s.name===t)??null;if(!r)throw Error(`Attachment: Variant '${t}' not found`);return r}url(t){if(this.#t(),t)return this.#s?.getUrl(this.#r(t).path);return this.data?.url}originalName(){return this.data?.originalName??""}size(t){if(t)return this.#r(t).size;return this.data?.size}meta(t){if(t)return this.#r(t).meta;return this.data?.meta}preSignedUrl(t,r){if(this.#t(),typeof t==="string")return this.#s?.getSignedUrl(this.#r(t).path,r);return this.#s?.getSignedUrl(this.data?.path??"",r)}blurhash(){return this.#t(),this.data?.blurhash}getDisk(){return this.#s}getDrive(){return this.data?.drive??""}async getBytes(t){this.#t();let r=t?this.#r(t).path:this.data?.path??"";return this.#s?.getBytes(r)}async getBuffer(t){this.#t();let r=await this.getBytes(t);if(!r)return null;return B.from(r)}async getStream(t){this.#t();let r=t?this.#r(t).path:this.data?.path??"";return this.#s?.getStream(r)}getMimeType(t){return this.#t(),(t?this.#r(t):this.data)?.mimeType??""}toJSON(){return{url:this.url(),blurhash:this.blurhash()}}}import{Disk as M}from"flydrive";import{join as I}from"node:path";import{fileTypeFromBuffer as Q}from"file-type";import{v7 as X}from"uuid";class b{att;file;disk;buffer;modelOptions;config;entity;columnName;diskName;fileInfo;constructor(t,r){this.att=t;let{disk:s,options:e,config:o,entity:c,columnName:n,diskName:h}=r;if(this.disk=s,this.modelOptions=e,this.config=o,this.entity=c,this.columnName=n,this.diskName=h,t[x])throw Error("Attachment already processed, please use the Attachment.fromFile method to create a new attachment");this.file=this.att[y]}done(t){this.att[P](t)}generateKey(t,...r){let s=this.modelOptions.folder??"";return s=s.replace(/:([A-Za-z0-9_]+)/g,(e,o)=>{let c=this.entity[o];if(c===void 0||c===null)throw Error(`Missing value for Attachment path "${o}" in entity ${this.entity.constructor.name}. Please ensure that the referenced property is computed before the attachment is processed. (Auto incrementing fields are not supported.)`);return this.normalizeFileName(String(c))}),I(s,t,...r)}normalizeFileName(t){return encodeURIComponent(t.replace(/[^a-zA-Z0-9.-]/g,"_")).toLowerCase()}async fileToBuffer(){if(this.buffer)return this.buffer;let t=await this.file.arrayBuffer(),r=Buffer.from(t);return this.buffer=r,r}getFileName(){if(!this.config.rename)return this.normalizeFileName(this.file.name);if(typeof this.config.rename==="function")return this.normalizeFileName(this.config.rename(this.file,this.columnName,this.entity));return this.normalizeFileName(X())}async getFileType(){return Q(await this.fileToBuffer())}async analyseFile(){let t=await this.getFileType();this.fileInfo={extname:t?.ext??this.file.name.split(".").pop()??"",mimeType:t?.mime??this.file.type,size:this.file.size}}async uploadFile(t,r){await this.disk.put(t,r)}async pickConverter(t,r){if(!this.fileInfo)throw Error("Attachment Converter: File info not found");if(this.config.variants?.[t])r=this.config.variants[t];if(r instanceof C){if(await r.supports({size:this.fileInfo.size,mimeType:this.fileInfo.mimeType,buffer:await this.fileToBuffer(),extname:this.fileInfo.extname}))return r}return null}async process(){await this.analyseFile();let t=await this.fileToBuffer(),r=this.getFileName(),s=this.fileInfo?.extname??"",e=this.generateKey(r,`${r}.${s}`);await this.uploadFile(e,t);let o={name:r,extname:s,size:this.file.size,drive:this.diskName,mimeType:this.file.type,path:e,url:await this.disk.getUrl(e),originalName:this.file.name,variants:[]},c=await this.config.metadata?.metadata({buffer:t,size:this.fileInfo?.size??0,mimeType:this.fileInfo?.mimeType??"",extname:this.fileInfo?.extname??""});if(o.meta=c,this.modelOptions.variants)for(let[n,h]of Object.entries(this.modelOptions.variants)){let S=await this.pickConverter(n,h);if(!S)throw Error(`Attachment Converter: No converter for the variant ${n} found`);let m=await S.handle({buffer:t,size:this.fileInfo?.size??0,mimeType:this.fileInfo?.mimeType??"",extname:this.fileInfo?.extname??"",variantName:n,variant:h}),g=this.generateKey(e.split("/").pop().split(".").shift(),`${n}.${m.extname}`);await this.uploadFile(g,m.buffer),o.variants.push({name:n,extname:m.extname,size:m.buffer.length,mimeType:m.mimeType,path:g})}if(this.fileInfo?.mimeType.startsWith("image/")){if(typeof this.modelOptions.blurhash==="boolean"?this.modelOptions.blurhash:this.modelOptions.blurhash?.enabled)o.blurhash=await l(t,typeof this.modelOptions.blurhash==="object"?this.modelOptions.blurhash:void 0)}this.done(o)}}import{Type as Z,ValidationError as $}from"@mikro-orm/core";class R extends Z{options={folder:"attachments",blurhash:!0};constructor(t){super();this.options={...this.options,...t}}convertToDatabaseValue(t){if(t===null)return null;if(t instanceof p)return t[O]();return t}convertToJSValue(t){try{return p[V](JSON.parse(t))}catch(r){try{return p[V](t)}catch(s){throw $.invalidType(R,t,"database")}}}getColumnType(){return"json"}}var J={blurhash:!0},T={rename:!0},F=["accessor","comment","customOrder","getter","getterName","hidden","index","lazy","name","nullable","serializedName","serializedPrimaryKey","serializer","version"];var{Property:w}=W(["@mikro-orm/decorators/legacy","@mikro-orm/core"]),d=Symbol("attachment:props");function A(t={}){return(r,s)=>{let{mikro:e,attachment:o}=G(t,F);o={...J,...o};let c=r.constructor;if(!c[d])c[d]={};return c[d][s]=o,w({...e,type:new R(o)})(r,s)}}function Y(t){return A(t)}function z(t){let s=t.constructor[d];return s?s:{}}function G(t,r){let s=new Set(r),e={},o={};for(let c in t)if(s.has(c))e[c]=t[c];else o[c]=t[c];return{mikro:e,attachment:o}}class q{options;disks;constructor(t){this.options=t;this.options={...T,...this.options},this.disks=new Map(Object.entries(this.options.drivers).map(([r,s])=>[r,new M(s)]))}async onLoad(t){let{entity:r}=t,s=z(r);for(let e of Object.keys(s)){let o=r[e],c=s[e];if(o instanceof p){let n=this.#t(c,o.getDrive(),!1);if(!n)continue;o[i]=n}}}#t(t,r,s){let e=this.disks.get(r??t.driver??this.options.defaultDriver);if(r&&!e)e=this.disks.get(t.driver??this.options.defaultDriver);if(!e){if(s)throw Error(`Unknown attachment driver "${String(r??t.driver??this.options.defaultDriver)}"`);return null}return e}async beforeFlush(t){let{uow:r}=t,s=new Set([...r.getChangeSets().map((e)=>e.entity),...r.getPersistStack()]);for(let e of s)await this.#s(e)}async#s(t){let r=z(t);for(let s of Object.keys(r)){let e=t[s],o=r[s];if(e instanceof p){if(e[x])continue;let c=this.#t(o);if(!c)continue;e[i]=c;let n=this.#r(o.variants),h=new b(e,{disk:c,options:{...o,variants:n},config:this.options,entity:t,columnName:s,diskName:o.driver??this.options.defaultDriver});try{await h.process()}catch(S){throw console.error(S),Error("Failed to process attachment")}}}}AttachmentDecorator(t){return Y(t)}#r(t){if(!t)return;if(Array.isArray(t)){let r={};for(let s of t)if(typeof s==="string"){let e=this.options.variants?.[s];if(!e)throw Error(`Unknown attachment variant "${s}"`);r[s]=e}else if(s&&typeof s==="object")Object.assign(r,s);return r}if(t&&typeof t==="object")return t;return}}export{q as AttachmentSubscriber,p as Attachment};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
declare abstract class BaseMetadata<TMetadata> {
|
|
2
|
+
abstract metadata(input: ConvertInput): Promise<TMetadata>;
|
|
3
|
+
}
|
|
4
|
+
type VariantSpec = BaseConverter<ConvertInput, ConvertOutput>;
|
|
5
|
+
interface ConvertInput {
|
|
6
|
+
buffer: Buffer;
|
|
7
|
+
size: number;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
variantName?: string;
|
|
10
|
+
variant?: VariantSpec;
|
|
11
|
+
extname: string;
|
|
12
|
+
}
|
|
13
|
+
interface ConvertOutput {
|
|
14
|
+
buffer: Buffer;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
extname: string;
|
|
17
|
+
}
|
|
18
|
+
declare abstract class BaseConverter<
|
|
19
|
+
TInput extends ConvertInput,
|
|
20
|
+
TOutput extends ConvertOutput
|
|
21
|
+
> {
|
|
22
|
+
abstract supports(input: TInput): Promise<boolean>;
|
|
23
|
+
abstract handle(input: TInput): Promise<TOutput>;
|
|
24
|
+
}
|
|
25
|
+
export { BaseMetadata };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as a}from"../shared/chunk-523ncfdc.js";export{a as BaseMetadata};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
declare abstract class BaseMetadata<TMetadata> {
|
|
2
|
+
abstract metadata(input: ConvertInput): Promise<TMetadata>;
|
|
3
|
+
}
|
|
4
|
+
type VariantSpec = BaseConverter<ConvertInput, ConvertOutput>;
|
|
5
|
+
interface ConvertInput {
|
|
6
|
+
buffer: Buffer;
|
|
7
|
+
size: number;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
variantName?: string;
|
|
10
|
+
variant?: VariantSpec;
|
|
11
|
+
extname: string;
|
|
12
|
+
}
|
|
13
|
+
interface ConvertOutput {
|
|
14
|
+
buffer: Buffer;
|
|
15
|
+
mimeType: string;
|
|
16
|
+
extname: string;
|
|
17
|
+
}
|
|
18
|
+
declare abstract class BaseConverter<
|
|
19
|
+
TInput extends ConvertInput,
|
|
20
|
+
TOutput extends ConvertOutput
|
|
21
|
+
> {
|
|
22
|
+
abstract supports(input: TInput): Promise<boolean>;
|
|
23
|
+
abstract handle(input: TInput): Promise<TOutput>;
|
|
24
|
+
}
|
|
25
|
+
declare class ImgkitMetadata<T extends exports_index_d.ImageMetadata> extends BaseMetadata<T> {
|
|
26
|
+
metadata(input: ConvertInput): Promise<T>;
|
|
27
|
+
}
|
|
28
|
+
export { ImgkitMetadata };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as t}from"../shared/chunk-cm81a68q.js";import{e as a}from"../shared/chunk-523ncfdc.js";class m extends a{async metadata(e){return await(await t("imgkit")).metadata(e.buffer)}}export{m as ImgkitMetadata};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../shared/chunk-cm81a68q.js";import"../shared/chunk-523ncfdc.js";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as l}from"module";import{encode as f}from"blurhash";var h=l(import.meta.url);async function p(t){try{let r=await import(t);if(r.default)return r.default;return r}catch(r){throw Error(`Module ${t} not found, please install it first.`)}}function w(t){for(let r of t)try{return h(r)}catch{continue}throw Error(`Could not resolve any of the following modules: ${t.join(", ")}`)}function y(t,r){let{componentX:n,componentY:a}=r??{enabled:!0,componentX:4,componentY:4};return new Promise(async(i,s)=>{try{let e=await p("sharp"),{data:u,info:o}=await e(t).raw().ensureAlpha().toBuffer({resolveWithObject:!0}),c=f(new Uint8ClampedArray(u),o.width,o.height,n,a);return i(c)}catch(e){return s(e)}})}
|
|
2
|
+
export{p as b,w as c,y as d};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mikro-orm-attachments",
|
|
3
3
|
"description": "Attachment handling for MikroORM with support for image processing, variants, and multiple storage drivers",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -17,6 +17,36 @@
|
|
|
17
17
|
"default": "./dist/index.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
+
"./converters/SharpConverter": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./dist/converters/SharpConverter.d.ts",
|
|
23
|
+
"default": "./dist/converters/SharpConverter.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"./converters/BaseConverter": {
|
|
27
|
+
"import": "./dist/converters/BaseConverter.js"
|
|
28
|
+
},
|
|
29
|
+
"./converters/ImgkitConverter": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/converters/ImgkitConverter.d.ts",
|
|
32
|
+
"default": "./dist/converters/ImgkitConverter.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"./metadata/ImgkitMetadata": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/metadata/ImgkitMetadata.d.ts",
|
|
38
|
+
"default": "./dist/metadata/ImgkitMetadata.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"./metadata/BaseMetadata": {
|
|
42
|
+
"import": {
|
|
43
|
+
"types": "./dist/metadata/BaseMetadata.d.ts",
|
|
44
|
+
"default": "./dist/metadata/BaseMetadata.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"./metadata/SharpMetadata": {
|
|
48
|
+
"import": "./dist/metadata/SharpMetadata.js"
|
|
49
|
+
},
|
|
20
50
|
"./package.json": "./package.json"
|
|
21
51
|
},
|
|
22
52
|
"scripts": {
|
|
@@ -43,24 +73,25 @@
|
|
|
43
73
|
"url": "https://github.com/reptoxx/mikro-orm-attachments"
|
|
44
74
|
},
|
|
45
75
|
"optionalDependencies": {
|
|
46
|
-
"@mikro-orm/decorators": "^7.0.
|
|
76
|
+
"@mikro-orm/decorators": "^7.0.9"
|
|
47
77
|
},
|
|
48
78
|
"peerDependencies": {
|
|
49
|
-
"@mikro-orm/core": "^
|
|
79
|
+
"@mikro-orm/core": "^7.0.9",
|
|
50
80
|
"sharp": "^0.34.5",
|
|
51
81
|
"blurhash": "^2.0.5",
|
|
52
|
-
"flydrive": "^1.
|
|
82
|
+
"flydrive": "^2.1.0"
|
|
53
83
|
},
|
|
54
84
|
"devDependencies": {
|
|
55
|
-
"@mikro-orm/core": "^
|
|
56
|
-
"@typescript/native-preview": "^7.0.0-dev.
|
|
57
|
-
"bun-types": "
|
|
58
|
-
"bunup": "^0.16.
|
|
85
|
+
"@mikro-orm/core": "^7.0.9",
|
|
86
|
+
"@typescript/native-preview": "^7.0.0-dev.20260407.1",
|
|
87
|
+
"bun-types": "1.3.11",
|
|
88
|
+
"bunup": "^0.16.31",
|
|
89
|
+
"imgkit": "^2.2.1",
|
|
59
90
|
"standard-version": "^9.5.0",
|
|
60
|
-
"typescript": "^
|
|
91
|
+
"typescript": "^6.0.2"
|
|
61
92
|
},
|
|
62
93
|
"dependencies": {
|
|
63
|
-
"file-type": "^21.3.
|
|
94
|
+
"file-type": "^21.3.4",
|
|
64
95
|
"uuid": "^13.0.0"
|
|
65
96
|
},
|
|
66
97
|
"engines": {
|