includio-cms 0.0.37 → 0.0.38

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.
@@ -1,7 +1,7 @@
1
1
  import { PUBLIC_URL } from '$env/static/public';
2
2
  import { getCMS } from '../../cms.js';
3
3
  import z from 'zod';
4
- import { getImageStyle } from '../media/styles/operations/getImageStyle.js';
4
+ import { getImageStyles } from './utils/imageStyles.js';
5
5
  export async function resolveMediaFields(data, fields) {
6
6
  const mediaIds = [];
7
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -74,34 +74,26 @@ export async function resolveMediaFields(data, fields) {
74
74
  switch (field.type) {
75
75
  case 'image': {
76
76
  if (field.multiple && Array.isArray(val)) {
77
- result[field.slug] = val.map((id) => ({
78
- data: mediaMap[id] ?? null,
79
- styles: {}
77
+ result[field.slug] = await Promise.all(val.map(async (id) => {
78
+ const mediaFile = mediaMap[id];
79
+ if (!mediaFile) {
80
+ return { data: null, styles: {} };
81
+ }
82
+ return {
83
+ data: mediaFile,
84
+ styles: await getImageStyles(field, mediaFile)
85
+ };
80
86
  }));
81
87
  }
82
88
  else {
83
- if (field.styles) {
84
- const styles = await Promise.all(field.styles.map(async (style) => {
85
- const styleDbData = await getImageStyle(val, style);
86
- return [
87
- style.name,
88
- {
89
- url: styleDbData.url,
90
- media: style.media,
91
- mimeType: style.format
92
- }
93
- ];
94
- }));
95
- const finalVal = {
96
- data: mediaMap[val] ?? null,
97
- styles: Object.fromEntries(styles)
98
- };
99
- result[field.slug] = finalVal;
89
+ const mediaFile = mediaMap[val];
90
+ if (!mediaFile) {
91
+ result[field.slug] = { data: null, styles: {} };
100
92
  break;
101
93
  }
102
94
  const finalVal = {
103
- data: mediaMap[val] ?? null,
104
- styles: {}
95
+ data: mediaFile,
96
+ styles: await getImageStyles(field, mediaFile)
105
97
  };
106
98
  result[field.slug] = finalVal;
107
99
  break;
@@ -0,0 +1,3 @@
1
+ import type { ImageField } from '../../../../types/fields.js';
2
+ import type { ImageStyle, MediaFile } from '../../../../types/media.js';
3
+ export declare function getImageStyles(field: ImageField, val: MediaFile): Promise<Record<string, ImageStyle>>;
@@ -0,0 +1,26 @@
1
+ import { getImageStyle } from '../../media/styles/operations/getImageStyle.js';
2
+ const defaultStyles = [
3
+ {
4
+ name: 'defaultWebp',
5
+ format: 'webp'
6
+ },
7
+ {
8
+ name: 'defaultAvif',
9
+ format: 'avif'
10
+ }
11
+ ];
12
+ export async function getImageStyles(field, val) {
13
+ const stylesArr = [...(!val.url.endsWith('.svg') ? defaultStyles : []), ...(field.styles || [])];
14
+ const styles = await Promise.all(stylesArr.map(async (style) => {
15
+ const styleDbData = await getImageStyle(val.id, style);
16
+ return [
17
+ style.name,
18
+ {
19
+ url: styleDbData.url,
20
+ media: styleDbData.media,
21
+ mimeType: styleDbData.mimeType
22
+ }
23
+ ];
24
+ }));
25
+ return Object.fromEntries(styles);
26
+ }
@@ -14,10 +14,14 @@ export async function generateImageStyle(mediaFileId, style) {
14
14
  throw new Error('Media file not found');
15
15
  }
16
16
  const imageBuffer = await file.arrayBuffer();
17
- const outputBuffer = await sharp(Buffer.from(imageBuffer))
18
- .resize(style.width, style.height)
19
- .toFormat(style.format)
20
- .toBuffer();
17
+ let sharpInstance = sharp(Buffer.from(imageBuffer));
18
+ if (style.width || style.height) {
19
+ sharpInstance = sharpInstance.resize(style.width, style.height);
20
+ }
21
+ if (style.format) {
22
+ sharpInstance = sharpInstance.toFormat(style.format);
23
+ }
24
+ const outputBuffer = await sharpInstance.toBuffer();
21
25
  return getCMS().filesAdapter.uploadFile(new File([new Uint8Array(outputBuffer)], `${mediaFileId}_${style.name}.${style.format}`, {
22
26
  type: `image/${style.format}`
23
27
  }));
@@ -201,7 +201,7 @@ export function pg(config) {
201
201
  const [imageStyle] = await db
202
202
  .select()
203
203
  .from(schema.imageStylesTable)
204
- .where(and(eq(schema.imageStylesTable.mediaFileId, mediaFileId), eq(schema.imageStylesTable.name, style.name), eq(schema.imageStylesTable.width, style.width), eq(schema.imageStylesTable.height, style.height)))
204
+ .where(and(eq(schema.imageStylesTable.mediaFileId, mediaFileId), eq(schema.imageStylesTable.name, style.name), style.width ? eq(schema.imageStylesTable.width, style.width) : undefined, style.height ? eq(schema.imageStylesTable.height, style.height) : undefined))
205
205
  .limit(1);
206
206
  if (!imageStyle)
207
207
  return null;
@@ -77,7 +77,7 @@ export declare const imageStylesTable: import("drizzle-orm/pg-core/table", { wit
77
77
  columnType: "PgInteger";
78
78
  data: number;
79
79
  driverParam: string | number;
80
- notNull: true;
80
+ notNull: false;
81
81
  hasDefault: false;
82
82
  isPrimaryKey: false;
83
83
  isAutoincrement: false;
@@ -94,7 +94,7 @@ export declare const imageStylesTable: import("drizzle-orm/pg-core/table", { wit
94
94
  columnType: "PgInteger";
95
95
  data: number;
96
96
  driverParam: string | number;
97
- notNull: true;
97
+ notNull: false;
98
98
  hasDefault: false;
99
99
  isPrimaryKey: false;
100
100
  isAutoincrement: false;
@@ -4,8 +4,8 @@ export const imageStylesTable = pgTable('image_styles', {
4
4
  mediaFileId: uuid('media_file_id').notNull(),
5
5
  name: text('name').notNull(),
6
6
  url: text('url').notNull(),
7
- width: integer('width').notNull(),
8
- height: integer('height').notNull(),
7
+ width: integer('width'),
8
+ height: integer('height'),
9
9
  crop: boolean('crop').notNull().default(false),
10
10
  media: text('media'),
11
11
  mimeType: text('mime_type').notNull()
@@ -1,3 +1,4 @@
1
+ import type { FormatEnum } from 'sharp';
1
2
  import type { ImageStyle, MediaFile } from './media.js';
2
3
  export type FieldType = 'text' | 'richtext' | 'number' | 'boolean' | 'date' | 'datetime' | 'file' | 'image' | 'select' | 'radio' | 'checkboxes' | 'relation' | 'object' | 'array' | 'slug' | 'seo' | 'url';
3
4
  export interface BaseField {
@@ -67,9 +68,9 @@ export interface ImageField extends BaseField {
67
68
  }
68
69
  export interface ImageFieldStyle {
69
70
  name: string;
70
- width: number;
71
- height: number;
72
- format?: 'jpeg' | 'png' | 'webp' | 'avif';
71
+ width?: number;
72
+ height?: number;
73
+ format?: keyof FormatEnum;
73
74
  media?: string;
74
75
  crop?: boolean;
75
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "includio-cms",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",