@lucidcms/core
Version:
The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.
1 lines • 9.34 kB
Source Map (JSON)
{"version":3,"file":"upsert-crop.mjs","names":["mediaServices.checks.checkMediaKeyAccess","mediaServices.checks.checkAwaitingSync","processedImageServices.clearSingle","mediaServices.strategies.update","mediaServices.strategies.syncMedia","mediaServices.strategies.deleteObject"],"sources":["../../../../src/services/media/helpers/upsert-crop.ts"],"sourcesContent":["import type { BooleanInt } from \"../../../libs/db/types.js\";\nimport { copy } from \"../../../libs/i18n/index.js\";\nimport {\n\tMediaAwaitingSyncRepository,\n\tMediaRepository,\n} from \"../../../libs/repositories/index.js\";\nimport type { MediaCropInput, MediaOrigin } from \"../../../types/response.js\";\nimport type { ServiceFn } from \"../../../utils/services/types.js\";\nimport { mediaServices, processedImageServices } from \"../../index.js\";\n\ntype CropParent = {\n\tid: number;\n\tkey: string;\n\ttype: string;\n\torigin: MediaOrigin;\n\tpublic: BooleanInt;\n\ttenant_key: string | null;\n\trelation_type?: \"crop\" | \"poster\" | null;\n};\n\n/** Creates, restores, or overwrites the stable crop derivative for a source. */\nconst upsertCrop: ServiceFn<\n\t[\n\t\t{\n\t\t\tparent: CropParent;\n\t\t\tcrop: MediaCropInput;\n\t\t\tuserId: number;\n\t\t},\n\t],\n\t{ id: number; key: string }\n> = async (context, data) => {\n\tif (data.parent.type !== \"image\" || data.parent.relation_type === \"crop\") {\n\t\treturn {\n\t\t\terror: {\n\t\t\t\ttype: \"basic\",\n\t\t\t\tstatus: 400,\n\t\t\t\tmessage: copy(\"server:core.media.errors.image.only\"),\n\t\t\t},\n\t\t\tdata: undefined,\n\t\t};\n\t}\n\n\tconst Media = new MediaRepository(context.db.client, context.config.db);\n\tconst MediaAwaitingSync = new MediaAwaitingSyncRepository(\n\t\tcontext.db.client,\n\t\tcontext.config.db,\n\t);\n\n\tconst [keyAccessRes, awaitingSyncRes, existingCropRes] = await Promise.all([\n\t\tmediaServices.checks.checkMediaKeyAccess(context, { key: data.crop.key }),\n\t\tmediaServices.checks.checkAwaitingSync(context, { key: data.crop.key }),\n\t\tMedia.selectSingle({\n\t\t\tselect: [\"id\", \"key\", \"e_tag\", \"file_size\", \"type\", \"tenant_key\"],\n\t\t\twhere: [\n\t\t\t\t{ key: \"parent_media_id\", operator: \"=\", value: data.parent.id },\n\t\t\t\t{ key: \"relation_type\", operator: \"=\", value: \"crop\" },\n\t\t\t],\n\t\t}),\n\t]);\n\tif (keyAccessRes.error) return keyAccessRes;\n\tif (awaitingSyncRes.error) return awaitingSyncRes;\n\tif (existingCropRes.error) return existingCropRes;\n\n\tlet file: {\n\t\tkey: string;\n\t\tetag: string | null;\n\t\ttype: \"image\";\n\t\tmimeType: string;\n\t\textension: string;\n\t\tsize: number;\n\t};\n\n\tif (existingCropRes.data) {\n\t\tconst clearProcessedRes = await processedImageServices.clearSingle(\n\t\t\tcontext,\n\t\t\t{\n\t\t\t\tkey: existingCropRes.data.key,\n\t\t\t},\n\t\t);\n\t\tif (clearProcessedRes.error) return clearProcessedRes;\n\n\t\tconst updateRes = await mediaServices.strategies.update(context, {\n\t\t\tpreviousSize: existingCropRes.data.file_size,\n\t\t\tpreviousKey: existingCropRes.data.key,\n\t\t\tpreviousType: \"image\",\n\t\t\tpreviousEtag: existingCropRes.data.e_tag,\n\t\t\ttenantKey: existingCropRes.data.tenant_key,\n\t\t\tupdatedKey: data.crop.key,\n\t\t\ttargetKey: existingCropRes.data.key,\n\t\t\tallowedType: \"image\",\n\t\t\tfileName: data.crop.fileName,\n\t\t});\n\t\tif (updateRes.error) return updateRes;\n\t\tfile = { ...updateRes.data, type: \"image\" };\n\t} else {\n\t\tconst syncRes = await mediaServices.strategies.syncMedia(context, {\n\t\t\tkey: data.crop.key,\n\t\t\tfileName: data.crop.fileName,\n\t\t\tallowedType: \"image\",\n\t\t});\n\t\tif (syncRes.error) return syncRes;\n\t\tfile = {\n\t\t\tkey: syncRes.data.key,\n\t\t\tetag: syncRes.data.etag,\n\t\t\ttype: \"image\",\n\t\t\tmimeType: syncRes.data.mimeType,\n\t\t\textension: syncRes.data.extension,\n\t\t\tsize: syncRes.data.size,\n\t\t};\n\t}\n\n\tconst now = new Date().toISOString();\n\tconst cropData = {\n\t\tkey: file.key,\n\t\te_tag: file.etag,\n\t\torigin: data.parent.origin,\n\t\tpublic: data.parent.public,\n\t\ttype: file.type,\n\t\tmime_type: file.mimeType,\n\t\tfile_extension: file.extension,\n\t\tfile_name: data.crop.fileName,\n\t\tfile_size: file.size,\n\t\twidth: data.crop.width,\n\t\theight: data.crop.height,\n\t\tfocal_x: data.crop.focalPoint\n\t\t\t? Math.round(data.crop.focalPoint.x * 10000)\n\t\t\t: null,\n\t\tfocal_y: data.crop.focalPoint\n\t\t\t? Math.round(data.crop.focalPoint.y * 10000)\n\t\t\t: null,\n\t\tcrop_x: data.crop.state.x,\n\t\tcrop_y: data.crop.state.y,\n\t\tcrop_width: data.crop.state.width,\n\t\tcrop_height: data.crop.state.height,\n\t\tcrop_rotation: data.crop.state.rotation,\n\t\tcrop_skew_x: data.crop.state.skewX,\n\t\tcrop_skew_y: data.crop.state.skewY,\n\t\tblur_hash: data.crop.blurHash ?? null,\n\t\taverage_color: data.crop.averageColor ?? null,\n\t\tbase64: data.crop.base64 ?? null,\n\t\tis_dark: data.crop.isDark ?? null,\n\t\tis_light: data.crop.isLight ?? null,\n\t\tis_hidden: true,\n\t\tis_deleted: false,\n\t\tis_deleted_at: null,\n\t\tdeleted_by: null,\n\t\tfolder_id: null,\n\t\tparent_media_id: data.parent.id,\n\t\trelation_type: \"crop\" as const,\n\t\ttenant_key: data.parent.tenant_key,\n\t\tupdated_at: now,\n\t\tupdated_by: data.userId,\n\t};\n\n\tconst cropRes = existingCropRes.data\n\t\t? await Media.updateSingle({\n\t\t\t\twhere: [{ key: \"id\", operator: \"=\", value: existingCropRes.data.id }],\n\t\t\t\tdata: cropData,\n\t\t\t\treturning: [\"id\", \"key\"],\n\t\t\t\tvalidation: { enabled: true },\n\t\t\t})\n\t\t: await Media.createSingle({\n\t\t\t\tdata: {\n\t\t\t\t\t...cropData,\n\t\t\t\t\tis_deleted_at: undefined,\n\t\t\t\t\tdeleted_by: undefined,\n\t\t\t\t\tcreated_at: now,\n\t\t\t\t\tcreated_by: data.userId,\n\t\t\t\t},\n\t\t\t\treturning: [\"id\", \"key\"],\n\t\t\t\tvalidation: { enabled: true },\n\t\t\t});\n\tif (cropRes.error) {\n\t\tif (!existingCropRes.data) {\n\t\t\tawait mediaServices.strategies.deleteObject(context, {\n\t\t\t\tkey: file.key,\n\t\t\t\tsize: file.size,\n\t\t\t\tprocessedSize: 0,\n\t\t\t\ttenantKey: data.parent.tenant_key,\n\t\t\t});\n\t\t}\n\t\treturn cropRes;\n\t}\n\n\tconst deleteAwaitingRes = await MediaAwaitingSync.deleteSingle({\n\t\twhere: [{ key: \"key\", operator: \"=\", value: data.crop.key }],\n\t\treturning: [\"key\"],\n\t});\n\tif (deleteAwaitingRes.error) return deleteAwaitingRes;\n\n\treturn { error: undefined, data: cropRes.data };\n};\n\nexport default upsertCrop;\n"],"mappings":"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"}