Skip to content

Commit

Permalink
fix: type inference
Browse files Browse the repository at this point in the history
  • Loading branch information
RaphaelEscrig committed Jan 2, 2025
1 parent b8aaa96 commit 7ebafc5
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
16 changes: 8 additions & 8 deletions src/__tests__/linkup-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('LinkupClient', () => {
query: 'foo',
depth: 'deep',
outputType: 'sourcedAnswer',
} as SearchParams);
});

expect(maxios.post).toHaveBeenCalledWith(
'/search',
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('LinkupClient', () => {
// Non Axios error
maxios.post.mockRejectedValueOnce(new Error('unknown'));
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupUnknownError));

// 400 invalid
Expand All @@ -155,7 +155,7 @@ describe('LinkupClient', () => {
response: { status: 400, data: { message: '' } },
});
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupInvalidRequestError));

// 400 empty result
Expand All @@ -167,7 +167,7 @@ describe('LinkupClient', () => {
},
});
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupNoResultError));

// 403
Expand All @@ -179,7 +179,7 @@ describe('LinkupClient', () => {
},
});
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupAuthenticationError));

// 429
Expand All @@ -191,7 +191,7 @@ describe('LinkupClient', () => {
},
});
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupInsufficientCreditError));

// 500
Expand All @@ -203,7 +203,7 @@ describe('LinkupClient', () => {
},
});
await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupUnknownError));
});

Expand All @@ -217,7 +217,7 @@ describe('LinkupClient', () => {
});

await underTest
.search({} as SearchParams)
.search({} as SearchParams<'sourcedAnswer'>)
.catch((e) => expect(e).toBeInstanceOf(LinkupInvalidRequestError));
});
});
23 changes: 16 additions & 7 deletions src/linkup-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {
} from './errors';
import {
ApiConfig,
LinkupSearchResponse,
SearchOutputType,
SearchParams,
SearchResults,
SourcedAnswer,
StructuredOutputSchema,
LinkupSearchResponse,
} from './types';
import { getVersionFromPackage } from './utils/version.utils';
import zodToJsonSchema from 'zod-to-json-schema';
Expand All @@ -30,9 +31,17 @@ export class LinkupClient {
this.baseUrl = config.baseUrl || 'https://api.linkup.so/v1';
}

async search<T extends SearchOutputType>(
async search<T extends 'sourcedAnswer' | 'searchResults' | 'structured'>(
params: SearchParams<T>,
): Promise<LinkupSearchResponse<T>> {
): Promise<
T extends 'sourcedAnswer'
? SourcedAnswer
: T extends 'searchResults'
? SearchResults
: T extends 'structured'
? StructuredOutputSchema
: never
> {
return axios
.post('/search', this.sanitizeParams(params), {
baseURL: this.baseUrl,
Expand All @@ -49,13 +58,13 @@ export class LinkupClient {
});
}

private sanitizeParams({
private sanitizeParams<T extends SearchOutputType>({
query,
depth,
outputType,
includeImages = false,
structuredOutputSchema,
}: SearchParams): Record<string, string | boolean> {
}: SearchParams<T>): Record<string, string | boolean> {
const searchParams: Record<string, string | boolean> = {
q: query,
depth,
Expand All @@ -74,9 +83,9 @@ export class LinkupClient {
return searchParams;
}

private formatResponse<T extends SearchOutputType>(
private formatResponse<T>(
searchResponse: unknown,
outputType: T,
outputType: SearchOutputType,
): LinkupSearchResponse<T> {
switch (outputType) {
case 'sourcedAnswer':
Expand Down
14 changes: 8 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ export type StructuredOutputSchema =
| Record<string, unknown>
| ZodObject<ZodRawShape>;

export interface SearchParams<T extends SearchOutputType = SearchOutputType> {
export interface SearchParams<T extends SearchOutputType> {
query: string;
depth: SearchDepth;
outputType: T;
includeImages?: boolean;
structuredOutputSchema?: StructuredOutputSchema;
}

export type LinkupSearchResponse<T extends SearchOutputType> = {
sourcedAnswer: SourcedAnswer;
searchResults: SearchResults;
structured: unknown;
}[T];
export type LinkupSearchResponse<T> = T extends 'sourcedAnswer'
? SourcedAnswer
: T extends 'searchResults'
? SearchResults
: T extends 'structured'
? StructuredOutputSchema
: never;

export interface SourcedAnswer {
answer: string;
Expand Down

0 comments on commit 7ebafc5

Please sign in to comment.