Files
userbase/app/src/media/MediaField.ts
T
dswbx 55082e9d0e feat: improve media handling
added local range requests, fix mime type detection, improve uploading using FormData, correctly use mime type allow list, added previews for audio, pdf and text
2025-09-29 14:55:19 +02:00

76 lines
1.8 KiB
TypeScript

import { Field, baseFieldConfigSchema } from "data/fields";
import { s } from "bknd/utils";
export const mediaFieldConfigSchema = s
.strictObject({
entity: s.string(), // @todo: is this really required?
min_items: s.number(),
max_items: s.number(),
mime_types: s.array(s.string()),
...baseFieldConfigSchema.properties,
})
.partial();
export type MediaFieldConfig = s.Static<typeof mediaFieldConfigSchema>;
export type MediaItem = {
id: number;
path: string;
mime_type: string;
size: number;
scope: number;
etag: string;
modified_at: Date;
folder: boolean;
};
export class MediaField<
Required extends true | false = false,
TypeOverride = MediaItem[],
> extends Field<MediaFieldConfig, TypeOverride, Required> {
override readonly type = "media";
constructor(name: string, config: Partial<MediaFieldConfig>) {
// field must be virtual, as it doesn't store a reference to the entity
super(name, { ...config, fillable: ["update"], virtual: true });
}
protected getSchema() {
return mediaFieldConfigSchema;
}
getMaxItems(): number | undefined {
return this.config.max_items;
}
getAllowedMimeTypes(): string[] | undefined {
return this.config.mime_types;
}
getMinItems(): number | undefined {
return this.config.min_items;
}
override schema() {
return undefined;
}
override toJsonSchema() {
// @todo: should be a variable, since media could be a diff entity
const $ref = "../schema.json#/properties/media";
const minItems = this.config?.min_items;
const maxItems = this.config?.max_items;
if (maxItems === 1) {
return { $ref } as any;
} else {
return {
type: "array",
items: { $ref },
minItems,
maxItems,
};
}
}
}