Skip to content

Commit

Permalink
refactor: migrate asset uploader to postgrest
Browse files Browse the repository at this point in the history
Got some experience with using postgrest api.
  • Loading branch information
TrySound committed Jul 27, 2024
1 parent 34ae041 commit cc7401c
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 142 deletions.
11 changes: 9 additions & 2 deletions apps/builder/app/routes/rest.assets.$name.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { z } from "zod";
import type { ActionFunctionArgs } from "@remix-run/server-runtime";
import type { Asset } from "@webstudio-is/sdk";
import { uploadFile } from "@webstudio-is/asset-uploader/index.server";
import type { ActionData } from "~/builder/shared/assets";
import { createAssetClient } from "~/shared/asset-client";
import { z } from "zod";
import { createContext } from "~/shared/context.server";

const UrlBody = z.object({
url: z.string(),
Expand Down Expand Up @@ -50,7 +51,13 @@ export const action = async (
body = imageRequest.body;
}

const asset = await uploadFile(params.name, body, createAssetClient());
const context = await createContext(request);
const asset = await uploadFile(
params.name,
body,
createAssetClient(),
context
);
return {
uploadedAssets: [asset],
};
Expand Down
1 change: 0 additions & 1 deletion packages/asset-uploader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"@aws-crypto/sha256-js": "^5.2.0",
"@smithy/signature-v4": "^2.3.0",
"@webstudio-is/fonts": "workspace:*",
"@webstudio-is/prisma-client": "workspace:*",
"@webstudio-is/sdk": "workspace:*",
"@webstudio-is/trpc-interface": "workspace:*",
"fontkit": "^2.0.2",
Expand Down
46 changes: 23 additions & 23 deletions packages/asset-uploader/src/db/load.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { prisma, type Project } from "@webstudio-is/prisma-client";
import {
authorizeProject,
type AppContext,
Expand All @@ -8,7 +7,7 @@ import type { Asset } from "@webstudio-is/sdk";
import { formatAsset } from "../utils/format-asset";

export const loadAssetsByProject = async (
projectId: Project["id"],
projectId: string,
context: AppContext,
{ skipPermissionsCheck = false }: { skipPermissionsCheck?: boolean } = {}
): Promise<Asset[]> => {
Expand All @@ -25,26 +24,27 @@ export const loadAssetsByProject = async (
);
}

const assets = await prisma.asset.findMany({
select: {
file: true,
id: true,
projectId: true,
},
where: {
projectId,
file: { status: "UPLOADED" },
},
orderBy: {
file: { createdAt: "desc" },
},
});
const assets = await context.postgrest.client
.from("Asset")
.select(
`
assetId:id,
projectId,
file:File!inner (*)
`
)
.eq("projectId", projectId)
.eq("file.status", "UPLOADED");

return assets.map((asset) =>
formatAsset({
assetId: asset.id,
projectId: asset.projectId,
file: asset.file,
})
);
const result: Asset[] = [];
for (const { assetId, projectId, file } of assets.data ?? []) {
if (file) {
result.push(formatAsset({ assetId, projectId, file }));
}
}

// order by createdAt desc
result.sort((left, right) => right.createdAt.localeCompare(left.createdAt));

return result;
};
71 changes: 34 additions & 37 deletions packages/asset-uploader/src/delete.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { prisma, type Project } from "@webstudio-is/prisma-client";
import {
authorizeProject,
type AppContext,
Expand All @@ -9,7 +8,7 @@ import type { Asset } from "@webstudio-is/sdk";
export const deleteAssets = async (
props: {
ids: Array<Asset["id"]>;
projectId: Project["id"];
projectId: string;
},
context: AppContext
) => {
Expand All @@ -24,50 +23,48 @@ export const deleteAssets = async (
);
}

const assets = await prisma.asset.findMany({
select: {
file: true,
id: true,
projectId: true,
name: true,
},
where: { id: { in: props.ids }, projectId: props.projectId },
});
const assets = await context.postgrest.client
.from("Asset")
.select(
`
id,
projectId,
name,
file:File!inner (*)
`
)
.in("id", props.ids)
.eq("projectId", props.projectId);

if (assets.length === 0) {
if ((assets.data ?? []).length === 0) {
throw new Error("Assets not found");
}

await prisma.project.updateMany({
where: {
id: props.projectId,
previewImageAssetId: {
in: props.ids,
},
},
data: {
previewImageAssetId: null,
},
});
await context.postgrest.client
.from("Project")
.update({ previewImageAssetId: null })
.eq("id", props.projectId)
.in("previewImageAssetId", props.ids);

await prisma.asset.deleteMany({
where: { id: { in: props.ids }, projectId: props.projectId },
});
await context.postgrest.client
.from("Asset")
.delete()
.in("id", props.ids)
.eq("projectId", props.projectId);

// find unused files
const unusedFileNames = new Set(assets.map((asset) => asset.name));
const assetsByStillUsedFileName = await prisma.asset.findMany({
where: { name: { in: Array.from(unusedFileNames) } },
});
for (const asset of assetsByStillUsedFileName) {
const unusedFileNames = new Set(assets.data?.map((asset) => asset.name));
const assetsByStillUsedFileName = await context.postgrest.client
.from("Asset")
.select("name")
.in("name", Array.from(unusedFileNames));
for (const asset of assetsByStillUsedFileName.data ?? []) {
unusedFileNames.delete(asset.name);
}

// delete unused files
await prisma.file.updateMany({
where: { name: { in: Array.from(unusedFileNames) } },
data: {
isDeleted: true,
},
});
await context.postgrest.client
.from("File")
.update({ isDeleted: true })
.in("name", Array.from(unusedFileNames));
};
33 changes: 17 additions & 16 deletions packages/asset-uploader/src/patch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type Patch, applyPatches } from "immer";
import { type Project, prisma } from "@webstudio-is/prisma-client";
import {
type AppContext,
authorizeProject,
Expand All @@ -13,7 +12,7 @@ import { loadAssetsByProject } from "./db/load";
* update patches are ignored
*/
export const patchAssets = async (
{ projectId }: { projectId: Project["id"] },
{ projectId }: { projectId: string },
patches: Array<Patch>,
context: AppContext
) => {
Expand Down Expand Up @@ -51,29 +50,31 @@ export const patchAssets = async (
}
}
if (addedAssets.length !== 0) {
const files = await prisma.file.findMany({
where: { name: { in: addedAssets.map((asset) => asset.name) } },
});
const files = await context.postgrest.client
.from("File")
.select()
.in(
"name",
addedAssets.map((asset) => asset.name)
);

const fileNames = new Set(files.map((file) => file.name));
const fileNames = new Set(files.data?.map((file) => file.name));

// restore file when undo is triggered
await prisma.file.updateMany({
where: { name: { in: Array.from(fileNames) } },
data: {
isDeleted: false,
},
});
await context.postgrest.client
.from("File")
.update({ isDeleted: false })
.in("name", Array.from(fileNames));

await prisma.asset.createMany({
data: addedAssets
await context.postgrest.client.from("Asset").insert(
addedAssets
// making sure corresponding file exist before creating an asset that references it
.filter((asset) => fileNames.has(asset.name))
.map((asset) => ({
id: asset.id,
projectId,
name: asset.name,
})),
});
}))
);
}
};
Loading

0 comments on commit cc7401c

Please sign in to comment.