A social knowledge tool for researchers built on ATProto
1import { URL } from '../../../domain/value-objects/URL';
2import { IMetadataService } from '../../../domain/services/IMetadataService';
3import { ICardRepository } from '../../../domain/ICardRepository';
4import { UseCase } from 'src/shared/core/UseCase';
5import { err, ok, Result } from 'src/shared/core/Result';
6
7export interface GetUrlMetadataQuery {
8 url: string;
9}
10
11export interface GetUrlMetadataResult {
12 metadata: {
13 url: string;
14 title?: string;
15 description?: string;
16 author?: string;
17 siteName?: string;
18 imageUrl?: string;
19 type?: string;
20 };
21}
22
23export class ValidationError extends Error {
24 constructor(message: string) {
25 super(message);
26 this.name = 'ValidationError';
27 }
28}
29
30export class GetUrlMetadataUseCase
31 implements UseCase<GetUrlMetadataQuery, Result<GetUrlMetadataResult>>
32{
33 constructor(
34 private metadataService: IMetadataService,
35 private cardRepository: ICardRepository,
36 ) {}
37
38 async execute(
39 query: GetUrlMetadataQuery,
40 ): Promise<Result<GetUrlMetadataResult>> {
41 // Validate and create URL value object
42 const urlResult = URL.create(query.url);
43 if (urlResult.isErr()) {
44 return err(
45 new ValidationError(`Invalid URL: ${urlResult.error.message}`),
46 );
47 }
48 const url = urlResult.value;
49
50 try {
51 // Fetch metadata from external service
52 const metadataResult = await this.metadataService.fetchMetadata(url);
53 if (metadataResult.isErr()) {
54 return err(
55 new Error(
56 `Failed to fetch metadata: ${metadataResult.error instanceof Error ? metadataResult.error.message : 'Unknown error'}`,
57 ),
58 );
59 }
60
61 const metadata = metadataResult.value;
62
63 return ok({
64 metadata: {
65 url: metadata.url,
66 title: metadata.title,
67 description: metadata.description,
68 author: metadata.author,
69 siteName: metadata.siteName,
70 imageUrl: metadata.imageUrl,
71 type: metadata.type,
72 },
73 });
74 } catch (error) {
75 return err(
76 new Error(
77 `Failed to get URL metadata: ${error instanceof Error ? error.message : 'Unknown error'}`,
78 ),
79 );
80 }
81 }
82}