feat: fix issue with possibly sending undefined as searchparams to some providers

pull/659/head
Travis Fischer 2024-06-10 17:39:38 -05:00
rodzic 5671fc7026
commit 4538ade908
5 zmienionych plików z 35 dodań i 26 usunięć

Wyświetl plik

@ -556,7 +556,7 @@ export class ClearbitClient {
async companyEnrichment(options: clearbit.CompanyEnrichmentOptions) { async companyEnrichment(options: clearbit.CompanyEnrichmentOptions) {
return this.ky return this.ky
.get('https://company-stream.clearbit.com/v2/companies/find', { .get('https://company-stream.clearbit.com/v2/companies/find', {
searchParams: { ...options } searchParams: sanitizeSearchParams(options)
}) })
.json<clearbit.CompanyResponse>() .json<clearbit.CompanyResponse>()
} }
@ -564,7 +564,7 @@ export class ClearbitClient {
async companySearch(options: clearbit.CompanySearchOptions) { async companySearch(options: clearbit.CompanySearchOptions) {
return this.ky return this.ky
.get('https://discovery.clearbit.com/v1/companies/search', { .get('https://discovery.clearbit.com/v1/companies/search', {
searchParams: { ...options } searchParams: sanitizeSearchParams(options)
}) })
.json<clearbit.CompanySearchResponse>() .json<clearbit.CompanySearchResponse>()
} }

Wyświetl plik

@ -2,7 +2,7 @@ import defaultKy, { type KyInstance } from 'ky'
import pThrottle from 'p-throttle' import pThrottle from 'p-throttle'
import { AIFunctionsProvider } from '../fns.js' import { AIFunctionsProvider } from '../fns.js'
import { assert, getEnv, throttleKy } from '../utils.js' import { assert, getEnv, sanitizeSearchParams, throttleKy } from '../utils.js'
// TODO: need to add `aiFunction` wrappers for each method // TODO: need to add `aiFunction` wrappers for each method
@ -207,7 +207,7 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get('twitter/statuses/show', { .get('twitter/statuses/show', {
searchParams: options searchParams: sanitizeSearchParams(options)
}) })
.json<socialdata.TweetResponse>() .json<socialdata.TweetResponse>()
} }
@ -223,7 +223,7 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get(`twitter/tweets/${tweetId}/liking_users`, { .get(`twitter/tweets/${tweetId}/liking_users`, {
searchParams: params searchParams: sanitizeSearchParams(params)
}) })
.json<socialdata.UsersResponse>() .json<socialdata.UsersResponse>()
} }
@ -239,7 +239,7 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get(`twitter/tweets/${tweetId}/retweeted_by`, { .get(`twitter/tweets/${tweetId}/retweeted_by`, {
searchParams: params searchParams: sanitizeSearchParams(params)
}) })
.json<socialdata.UsersResponse>() .json<socialdata.UsersResponse>()
} }
@ -257,10 +257,10 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get('twitter/search', { .get('twitter/search', {
searchParams: { searchParams: sanitizeSearchParams({
type: 'top', type: 'top',
...options ...options
} })
}) })
.json<socialdata.TweetsResponse>() .json<socialdata.TweetsResponse>()
} }
@ -310,7 +310,7 @@ export class SocialDataClient extends AIFunctionsProvider {
.get( .get(
`twitter/user/${userId}/${replies ? 'tweets-and-replies' : 'tweets'}`, `twitter/user/${userId}/${replies ? 'tweets-and-replies' : 'tweets'}`,
{ {
searchParams: params searchParams: sanitizeSearchParams(params)
} }
) )
.json<socialdata.TweetsResponse>() .json<socialdata.TweetsResponse>()
@ -329,7 +329,7 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get(`twitter/user/${userId}/likes`, { .get(`twitter/user/${userId}/likes`, {
searchParams: params searchParams: sanitizeSearchParams(params)
}) })
.json<socialdata.TweetsResponse>() .json<socialdata.TweetsResponse>()
} }
@ -345,10 +345,10 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get('twitter/followers/list', { .get('twitter/followers/list', {
searchParams: { searchParams: sanitizeSearchParams({
user_id, user_id,
...params ...params
} })
}) })
.json<socialdata.UsersResponse>() .json<socialdata.UsersResponse>()
} }
@ -364,10 +364,10 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get('twitter/friends/list', { .get('twitter/friends/list', {
searchParams: { searchParams: sanitizeSearchParams({
user_id, user_id,
...params ...params
} })
}) })
.json<socialdata.UsersResponse>() .json<socialdata.UsersResponse>()
} }
@ -383,7 +383,7 @@ export class SocialDataClient extends AIFunctionsProvider {
return this.ky return this.ky
.get(`twitter/user/${sourceUserId}/following/${targetUserId}`, { .get(`twitter/user/${sourceUserId}/following/${targetUserId}`, {
searchParams: params searchParams: sanitizeSearchParams(params)
}) })
.json<socialdata.UserFollowingResponse>() .json<socialdata.UserFollowingResponse>()
} }
@ -391,10 +391,15 @@ export class SocialDataClient extends AIFunctionsProvider {
/** /**
* Returns a list of users with screenname or full name matching the search query. * Returns a list of users with screenname or full name matching the search query.
*/ */
async searchUsersByUsername(queryOrOpts: socialdata.SearchUsersOptions) { async searchUsersByUsername(
queryOrOpts: string | socialdata.SearchUsersOptions
) {
const params =
typeof queryOrOpts === 'string' ? { query: queryOrOpts } : queryOrOpts
return this.ky return this.ky
.get('twitter/search-users', { .get('twitter/search-users', {
searchParams: queryOrOpts searchParams: sanitizeSearchParams(params)
}) })
.json<socialdata.UsersResponse>() .json<socialdata.UsersResponse>()
} }

Wyświetl plik

@ -2,7 +2,7 @@ import defaultKy, { type KyInstance } from 'ky'
import { z } from 'zod' import { z } from 'zod'
import { aiFunction, AIFunctionsProvider } from '../fns.js' import { aiFunction, AIFunctionsProvider } from '../fns.js'
import { assert, getEnv } from '../utils.js' import { assert, getEnv, sanitizeSearchParams } from '../utils.js'
export namespace weatherapi { export namespace weatherapi {
export const BASE_URL = 'https://api.weatherapi.com/v1' export const BASE_URL = 'https://api.weatherapi.com/v1'
@ -124,10 +124,10 @@ export class WeatherClient extends AIFunctionsProvider {
return this.ky return this.ky
.get('current.json', { .get('current.json', {
searchParams: { searchParams: sanitizeSearchParams({
key: this.apiKey, key: this.apiKey,
...options ...options
} })
}) })
.json<weatherapi.CurrentWeatherResponse>() .json<weatherapi.CurrentWeatherResponse>()
} }

Wyświetl plik

@ -2,7 +2,7 @@ import defaultKy, { type KyInstance } from 'ky'
import { z } from 'zod' import { z } from 'zod'
import { aiFunction, AIFunctionsProvider } from '../fns.js' import { aiFunction, AIFunctionsProvider } from '../fns.js'
import { assert, getEnv } from '../utils.js' import { assert, getEnv, sanitizeSearchParams } from '../utils.js'
export namespace wolframalpha { export namespace wolframalpha {
export const API_BASE_URL = 'https://www.wolframalpha.com/api/' export const API_BASE_URL = 'https://www.wolframalpha.com/api/'
@ -85,6 +85,8 @@ export class WolframAlphaClient extends AIFunctionsProvider {
? { input: queryOrOptions } ? { input: queryOrOptions }
: queryOrOptions : queryOrOptions
return this.ky.get('v1/llm-api', { searchParams: { ...options } }).text() return this.ky
.get('v1/llm-api', { searchParams: sanitizeSearchParams(options) })
.text()
} }
} }

Wyświetl plik

@ -106,10 +106,12 @@ export function throttleKy(
* that correctly handles arrays of values as repeated keys. * that correctly handles arrays of values as repeated keys.
*/ */
export function sanitizeSearchParams( export function sanitizeSearchParams(
searchParams: Record< searchParams:
string, | Record<
string | number | boolean | string[] | number[] | boolean[] | undefined string,
> string | number | boolean | string[] | number[] | boolean[] | undefined
>
| object
): URLSearchParams { ): URLSearchParams {
return new URLSearchParams( return new URLSearchParams(
Object.entries(searchParams).flatMap(([key, value]) => { Object.entries(searchParams).flatMap(([key, value]) => {