webdevkaleem
webdevkaleem
TTCTheo's Typesafe Cult
Created by webdevkaleem on 2/12/2025 in #questions
Renaming a file but on download it shows the file's key instead of it's name
Main tech stack: Nextjs: 15v, Drizzle orm: 0.39v, Clerk: 6v, Uploadthing: 7v. Github: https://github.com/webdevkaleem/zip4you Description: So when i upload a file, i generate a random name using cuid2. After upload is completed, a UI pops up where you can rename the media. This works flawlessly as the new name is updated inside Uploadthing and Postgres. The issue is that when i download the media from the client UI, it shows the key instead of the name for the media. But There is one special case where something else happens. I have a tRPC procedure (/api/trpc/media.gmail) which gets a request from zapier and does it's own thing. Here's the catch. When this is procedure runs, it takes the subject from the header and set that as the file name. Now when i download the file from the client UI it shows the name correctly. However In both cases the updated name isn't reflected when i start a download on the client.
37 replies
TTCTheo's Typesafe Cult
Created by webdevkaleem on 1/23/2025 in #questions
Twitch Re-sub confusion
No description
8 replies
TTCTheo's Typesafe Cult
Created by webdevkaleem on 1/10/2025 in #questions
Uploadthing: Type-error when sending custom field data to the client
So i want to send some data down to the client upon image upload. api/uploadthing.core.ts
.onUploadComplete(async ({ metadata, file }) => {
const commonFileName = file.name.split(".")[0];
const commonFileType = file.name.split(".")[1];

// 1. Fetch the original image which is uploaded
const responseImage = await fetch(file.url);

// 2. Error check
if (!responseImage.ok) new UploadThingError("Failed to fetch image");

// 3. Create a buffer of the original image
const bufferImage = await responseImage.arrayBuffer();

// 4. Make mobile & tablet resized buffers using sharp
const mobileBuffer = await sharp(bufferImage).resize(400, 400).toBuffer();
const tabletBuffer = await sharp(bufferImage).resize(600, 600).toBuffer();

// 5. Create uploadthing files using the buffers
const mobileImage = new UTFile(
[mobileBuffer],
`${commonFileName}/mobile.${commonFileType}`,
);
const tabletImage = new UTFile(
[tabletBuffer],
`${commonFileName}/tablet.${commonFileType}`,
);

// 6. Upload the files
const savedImages = await utapi.uploadFiles([mobileImage, tabletImage]);

// 7. ::Check:: If the images were uploaded successfully
if (!savedImages[0]?.data) {
new UploadThingError("Failed to fetch image");
}

// 8. Create an array of the images with the fields that are to be used in the frontend
const imagesArr: {
key: string;
url: string;
}[] = savedImages
.map((obj) => {
if (obj.data) {
return {
key: obj.data.key,
url: obj.data.url,
};
}
})
.filter((obj) => obj !== undefined);

// 9. Return data to the frontend
return {
metadata: { uploadedBy: metadata.userId, images: [...imagesArr] },
};
}),
.onUploadComplete(async ({ metadata, file }) => {
const commonFileName = file.name.split(".")[0];
const commonFileType = file.name.split(".")[1];

// 1. Fetch the original image which is uploaded
const responseImage = await fetch(file.url);

// 2. Error check
if (!responseImage.ok) new UploadThingError("Failed to fetch image");

// 3. Create a buffer of the original image
const bufferImage = await responseImage.arrayBuffer();

// 4. Make mobile & tablet resized buffers using sharp
const mobileBuffer = await sharp(bufferImage).resize(400, 400).toBuffer();
const tabletBuffer = await sharp(bufferImage).resize(600, 600).toBuffer();

// 5. Create uploadthing files using the buffers
const mobileImage = new UTFile(
[mobileBuffer],
`${commonFileName}/mobile.${commonFileType}`,
);
const tabletImage = new UTFile(
[tabletBuffer],
`${commonFileName}/tablet.${commonFileType}`,
);

// 6. Upload the files
const savedImages = await utapi.uploadFiles([mobileImage, tabletImage]);

// 7. ::Check:: If the images were uploaded successfully
if (!savedImages[0]?.data) {
new UploadThingError("Failed to fetch image");
}

// 8. Create an array of the images with the fields that are to be used in the frontend
const imagesArr: {
key: string;
url: string;
}[] = savedImages
.map((obj) => {
if (obj.data) {
return {
key: obj.data.key,
url: obj.data.url,
};
}
})
.filter((obj) => obj !== undefined);

// 9. Return data to the frontend
return {
metadata: { uploadedBy: metadata.userId, images: [...imagesArr] },
};
}),
type-error
Argument of type '({ metadata, file }: AdapterArgs & { metadata: { userId: string; images: { key: string; url: string; }[]; }; file: UploadedFileData; }) => Promise<{ metadata: { uploadedBy: string; images: { ...; }[]; }; }>' is not assignable to parameter of type 'UploadCompleteFn<{ userId: string; images: { key: string; url: string; }[]; }, void | JsonObject, AdapterArgs>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'MaybePromise<void | JsonObject>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'Promise<void | JsonObject>'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'void | JsonObject'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'JsonObject'.
Property 'metadata' is incompatible with index signature.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonObject'.
Property 'images' is incompatible with index signature.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonArray'.
Type '{ key: string; url: string; }' is not assignable to type 'JsonValue'.ts(2345)
Argument of type '({ metadata, file }: AdapterArgs & { metadata: { userId: string; images: { key: string; url: string; }[]; }; file: UploadedFileData; }) => Promise<{ metadata: { uploadedBy: string; images: { ...; }[]; }; }>' is not assignable to parameter of type 'UploadCompleteFn<{ userId: string; images: { key: string; url: string; }[]; }, void | JsonObject, AdapterArgs>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'MaybePromise<void | JsonObject>'.
Type 'Promise<{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }>' is not assignable to type 'Promise<void | JsonObject>'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'void | JsonObject'.
Type '{ metadata: { uploadedBy: string; images: { key: string; url: string; }[]; }; }' is not assignable to type 'JsonObject'.
Property 'metadata' is incompatible with index signature.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ uploadedBy: string; images: { key: string; url: string; }[]; }' is not assignable to type 'JsonObject'.
Property 'images' is incompatible with index signature.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonValue | JsonObject | JsonArray'.
Type '{ key: string; url: string; }[]' is not assignable to type 'JsonArray'.
Type '{ key: string; url: string; }' is not assignable to type 'JsonValue'.ts(2345)
The imagesArr is what i want on the client as I loop over imagesArr to render all the images. [Important Point]: In the backend all the images are uploaded successfully and in the right size as well -------------
Nextjs 15
App router
tRPC
Nextjs 15
App router
tRPC
12 replies
TTCTheo's Typesafe Cult
Created by webdevkaleem on 1/10/2025 in #questions
Uploadthing muti image generation from a single image
I want to upload a single image and have 2 copies generated which are smaller than the original image (for mobile 400x400 and tablet 600x600). I want this process to be automatic, when the original image (1000x1000) has been done uploadthing. Any help on how should i complete this task (T3 stack: App router, tRPC, uploadthing) Thanks
2 replies