Bekacru / better-fetch

Advanced fetch wrapper for typescript
https://better-fetch.vercel.app/
210 stars 7 forks source link

$fetch not picking up baseUrl #7

Closed OwenVey closed 4 months ago

OwenVey commented 4 months ago

Edit: I think it maybe have to do with using baseUrl in createFetch but baseURL in $fetch. (Note the capital URL) I'm getting the following error:

343 |   try {
344 |     _url = url.startsWith("http") ? url : new URL(url, options == null ? void 0 : options.baseURL);
345 |   } catch (e) {
346 |     if (e instanceof TypeError) {
347 |       if (!(options == null ? void 0 : options.baseURL)) {
348 |         throw TypeError(
                    ^
TypeError: Invalid URL /players/:playerTag/battlelog. Are you passing in a relative url but not setting the baseURL?
      at getURL (/Users/owenvey/Developer/elysia-app/node_modules/@better-fetch/fetch/dist/index.js:348:15)
      at /Users/owenvey/Developer/elysia-app/node_modules/@better-fetch/fetch/dist/index.js:440:16

When doing:

export const $fetch = createFetch({
  baseUrl: 'https://api.brawlstars.com/v1',
  retry: 1,
  auth: {
    type: 'Bearer',
    token: '...',
  },
  schema: createSchema({
    '/players/:playerTag/battlelog': {
      query: z.object({
        limit: z.number().min(1).max(200).optional(),
      }),
      output: BattleList,
    },
  }),
});

await $fetch('/players/:playerTag/battlelog', {
  params: {
    playerTag: encodeURIComponent('#QC88QVP'),
  },
  query: {
    limit: 200,
  },
});

If i manually add baseUrl to the $fetch() call, I no longer get the error.

Bekacru commented 4 months ago

It should be baseURL, not baseUrl. The current type workaround doesn't allow us to capture excess properties when defining a schema, which is why it's not showing any type errors.

OwenVey commented 4 months ago

Ahh I see, looks like the docs still have baseUrl used in a few places.

Regarding baseURL, it seems like its ignoring the /v1 at the end of my URL. Is this intended? I can get around it by adding prefix: 'v1' to the schema but then I'd have to specific v1/... in the $fetch calls

Bekacru commented 4 months ago

Ahh I see, looks like the docs still have baseUrl used in a few places.

Regarding baseURL, it seems like its ignoring the /v1 at the end of my URL. Is this intended? I can get around it by adding prefix: 'v1' to the schema but then I'd have to specific v1/... in the $fetch calls

Oh I'll check the docs.

On the url, if you end the base url with extra forward slash ("/") and remove the initial "/" from the path it should merge properly.

Like "https://test/com/v1/" as base url and paths will have format of "path/more-path/"

But we should add a check for that and format the url

Bekacru commented 4 months ago

@OwenVey a patch has been released that should fix this issue

OwenVey commented 4 months ago

⚡⚡ Speedy!! Works great!

One more question, for this /players/:playerTag/battlelog route, playerTag is a string like #QC88QVP where it starts with a #. I noticed that if I don't encode the param myself, it breaks the parsing and ends up with a URL like https://api.brawlstars.com/v1/players/?limit=200#QC88QVP/battlelog instead of https://api.brawlstars.com/v1/players/%23QC88QVP/battlelog?limit=200.

Doing

 params: {
        playerTag: encodeURIComponent('#QC88QVP'),
      },

is not a problem, just wondering if it would be a good idea for URI encoding to happen automatically or maybe a way to configure it through the better fetch API. What are your thoughts?

Bekacru commented 4 months ago

Oh great recommendation. Yeah I think we should normalize url. It'll be released on 1.1.4.