aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/web/components/settings/ImportExport.tsx29
-rw-r--r--packages/open-api/hoarder-openapi-spec.json188
-rw-r--r--packages/shared/types/bookmarks.ts27
-rw-r--r--packages/trpc/routers/bookmarks.ts9
4 files changed, 120 insertions, 133 deletions
diff --git a/apps/web/components/settings/ImportExport.tsx b/apps/web/components/settings/ImportExport.tsx
index 5cb35def..34e069da 100644
--- a/apps/web/components/settings/ImportExport.tsx
+++ b/apps/web/components/settings/ImportExport.tsx
@@ -22,7 +22,6 @@ import { Download, Upload } from "lucide-react";
import {
useCreateBookmarkWithPostHook,
- useUpdateBookmark,
useUpdateBookmarkTags,
} from "@hoarder/shared-react/hooks/bookmarks";
import {
@@ -57,7 +56,6 @@ export function ImportExportRow() {
} | null>(null);
const { mutateAsync: createBookmark } = useCreateBookmarkWithPostHook();
- const { mutateAsync: updateBookmark } = useUpdateBookmark();
const { mutateAsync: createList } = useCreateBookmarkList();
const { mutateAsync: addToList } = useAddBookmarkToList();
const { mutateAsync: updateTags } = useUpdateBookmarkTags();
@@ -71,8 +69,13 @@ export function ImportExportRow() {
if (bookmark.content === undefined) {
throw new Error("Content is undefined");
}
- const created = await createBookmark(
- bookmark.content.type === BookmarkTypes.LINK
+ const created = await createBookmark({
+ title: bookmark.title,
+ createdAt: bookmark.addDate
+ ? new Date(bookmark.addDate * 1000)
+ : undefined,
+ note: bookmark.notes,
+ ...(bookmark.content.type === BookmarkTypes.LINK
? {
type: BookmarkTypes.LINK,
url: bookmark.content.url,
@@ -80,24 +83,10 @@ export function ImportExportRow() {
: {
type: BookmarkTypes.TEXT,
text: bookmark.content.text,
- },
- );
+ }),
+ });
await Promise.all([
- // Update title and createdAt if they're set
- bookmark.title.length > 0 || bookmark.addDate
- ? updateBookmark({
- bookmarkId: created.id,
- title: bookmark.title,
- createdAt: bookmark.addDate
- ? new Date(bookmark.addDate * 1000)
- : undefined,
- note: bookmark.notes,
- }).catch(() => {
- /* empty */
- })
- : undefined,
-
// Add to import list
addToList({
bookmarkId: created.id,
diff --git a/packages/open-api/hoarder-openapi-spec.json b/packages/open-api/hoarder-openapi-spec.json
index eac98326..7a490d36 100644
--- a/packages/open-api/hoarder-openapi-spec.json
+++ b/packages/open-api/hoarder-openapi-spec.json
@@ -454,136 +454,106 @@
"content": {
"application/json": {
"schema": {
- "oneOf": [
+ "allOf": [
{
"type": "object",
"properties": {
- "type": {
- "type": "string",
- "enum": [
- "link"
- ]
- },
- "url": {
- "type": "string",
- "format": "uri"
- },
"title": {
"type": "string",
- "nullable": true
- },
- "description": {
- "type": "string",
- "nullable": true
- },
- "imageUrl": {
- "type": "string",
"nullable": true,
- "format": "uri"
- },
- "imageAssetId": {
- "type": "string",
- "nullable": true
- },
- "screenshotAssetId": {
- "type": "string",
- "nullable": true
- },
- "fullPageArchiveAssetId": {
- "type": "string",
- "nullable": true
+ "maxLength": 250
},
- "videoAssetId": {
- "type": "string",
- "nullable": true
- },
- "favicon": {
- "type": "string",
- "nullable": true,
- "format": "uri"
+ "archived": {
+ "type": "boolean"
},
- "htmlContent": {
- "type": "string",
- "nullable": true
+ "favourited": {
+ "type": "boolean"
},
- "crawledAt": {
- "type": "string",
- "nullable": true
- }
- },
- "required": [
- "type",
- "url"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "text"
- ]
+ "note": {
+ "type": "string"
},
- "text": {
+ "summary": {
"type": "string"
},
- "sourceUrl": {
- "type": "string",
- "nullable": true
+ "createdAt": {
+ "type": "string"
}
- },
- "required": [
- "type",
- "text"
- ]
+ }
},
{
- "type": "object",
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "asset"
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "link"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": [
+ "type",
+ "url"
]
},
- "assetType": {
- "type": "string",
- "enum": [
- "image",
- "pdf"
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "text"
+ ]
+ },
+ "text": {
+ "type": "string"
+ },
+ "sourceUrl": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "text"
]
},
- "assetId": {
- "type": "string"
- },
- "fileName": {
- "type": "string",
- "nullable": true
- },
- "sourceUrl": {
- "type": "string",
- "nullable": true
- }
- },
- "required": [
- "type",
- "assetType",
- "assetId"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "type": "string",
- "enum": [
- "unknown"
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "asset"
+ ]
+ },
+ "assetType": {
+ "type": "string",
+ "enum": [
+ "image",
+ "pdf"
+ ]
+ },
+ "assetId": {
+ "type": "string"
+ },
+ "fileName": {
+ "type": "string"
+ },
+ "sourceUrl": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "assetType",
+ "assetId"
]
}
- },
- "required": [
- "type"
]
}
]
diff --git a/packages/shared/types/bookmarks.ts b/packages/shared/types/bookmarks.ts
index 1d8052f4..a02a4b29 100644
--- a/packages/shared/types/bookmarks.ts
+++ b/packages/shared/types/bookmarks.ts
@@ -114,7 +114,32 @@ const zBookmarkTypeAssetSchema = zBareBookmarkSchema.merge(
export type ZBookmarkTypeAsset = z.infer<typeof zBookmarkTypeAssetSchema>;
// POST /v1/bookmarks
-export const zNewBookmarkRequestSchema = zBookmarkContentSchema;
+export const zNewBookmarkRequestSchema = z
+ .object({
+ title: z.string().max(MAX_TITLE_LENGTH).nullish(),
+ archived: z.boolean().optional(),
+ favourited: z.boolean().optional(),
+ note: z.string().optional(),
+ summary: z.string().optional(),
+ createdAt: z.date().optional(),
+ })
+ .and(
+ z.discriminatedUnion("type", [
+ z.object({ type: z.literal(BookmarkTypes.LINK), url: z.string().url() }),
+ z.object({
+ type: z.literal(BookmarkTypes.TEXT),
+ text: z.string(),
+ sourceUrl: z.string().optional(),
+ }),
+ z.object({
+ type: z.literal(BookmarkTypes.ASSET),
+ assetType: z.enum(["image", "pdf"]),
+ assetId: z.string(),
+ fileName: z.string().optional(),
+ sourceUrl: z.string().optional(),
+ }),
+ ]),
+ );
export type ZNewBookmarkRequest = z.infer<typeof zNewBookmarkRequestSchema>;
// GET /v1/bookmarks
diff --git a/packages/trpc/routers/bookmarks.ts b/packages/trpc/routers/bookmarks.ts
index 4e58bcdc..c7fdcc17 100644
--- a/packages/trpc/routers/bookmarks.ts
+++ b/packages/trpc/routers/bookmarks.ts
@@ -271,9 +271,6 @@ export const bookmarksAppRouter = router({
return { ...alreadyExists, alreadyExists: true };
}
}
- if (input.type == BookmarkTypes.UNKNOWN) {
- throw new TRPCError({ code: "BAD_REQUEST" });
- }
const bookmark = await ctx.db.transaction(async (tx) => {
const bookmark = (
await tx
@@ -281,6 +278,12 @@ export const bookmarksAppRouter = router({
.values({
userId: ctx.user.id,
type: input.type,
+ title: input.title,
+ archived: input.archived,
+ favourited: input.favourited,
+ note: input.note,
+ summary: input.summary,
+ createdAt: input.createdAt,
})
.returning()
)[0];