GithubHelp home page GithubHelp logo

ufo's People

Contributors

airmoi avatar aryraditya avatar atinux avatar aurelienbottazini avatar autofix-ci[bot] avatar bokub avatar brandonlinu avatar daniacu avatar danielroe avatar divine avatar ea-agital avatar felixonmars avatar hecktarzuli avatar hexrw avatar ignisda avatar madebyfabian avatar mannil avatar natanfeitosa avatar nozomuikuta avatar oleghalin avatar pi0 avatar podlebar avatar rajkadhi10 avatar renovate[bot] avatar smeng9 avatar thijsw avatar trurlmcbyte avatar yshrsmz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ufo's Issues

Encoded slash in URL

Hello,

I have a case where we have an encoded slash in an URL (comes from an external api).

For example this one:
http://localhost/abc/deg%2f

Please note it is using the lowercase version of the encoding %2f and not %2F.
The library transforms this url into http://localhost/abc/deg/ and thus it breaks our routing.

decodeURIComponent('%2f') does transform %2f into /
I could not find anything forbidding people to use lowercase versions when encoding.

When typing directly the URL, Chrome does not transform http://localhost/abc/deg%2f into http://localhost/abc/deg/.

So I think the library should support those lowercase encoded versions.

Double `?` stringifyParsedURL

Double ? added when using stringifyParsedURL

let path = '/?query=value#test';

let parsedPath = ufo.parsePath(path)

// {pathname: "/", search: "?query=value", hash: "#test"}

ufo.stringifyParsedURL(parsedPath );

// Returns
// "/??query=value#test"

// Should be
// "/?query=value#test"

Thanks!

destructive decode of pathname

Currently used decodeURIComponent after parse pathname.
So path like /a/b%2Fc will be after "normalization" /a/b/c.
By IMHO it's not a clear and destructive

windows paths aren't handled when parsing

parseURL('D:/a/framework/framework/test/fixtures/basic/pages/[...slug].vue?macro=true')
// {
//   protocol: '',
//   auth: '',
//   host: '',
//   pathname: '',
//   search: '',
//   hash: ''
// }

withQuery can't remove a query param from the path

Currently, we can't remove a query param from the original path using the query object given in withQuery without rebuild the entire URL.

Proposed solution

Based on the Vue Router behaviour, if you send a undefined value to a query parameter, it removes from the path; if you want to keep the param, but send it without value, then you can use a null value. This represent a breaking change, but it has the most sense for this scenario, because the undefined value should represent a value that does not exists, not "an empty value": for a empty value, we have the null value.

Current behaviour:

For param = undefined

const path = withQuery('https://example.com?page=2', { page: undefined });
console.log(path); // Return "https://example.com?page"

For param = null

const path = withQuery('https://example.com?page=2', { page: null });
console.log(path); // Return "https://example.com?page"

Proposed behaviour:

For param = undefined

const path = withQuery('https://example.com?page=2', { page: undefined });
console.log(path); // Return "https://example.com"

For param = null

const path = withQuery('https://example.com?page=2', { page: null });
console.log(path); // Return "https://example.com?page"

Wrong parseQuery return value in case of query with array containing empty element

Function parseQuery returns this object for query 'param=3&param=':

{
    param: [
        "3",
        ""
    ]
}

But return value for query 'param=&param=3' is different:

{
    param: "3"
}

As i figured out, it happens because of using if (obj[key]) condition, instead of checking if (obj[key] !== undefined)

    if (obj[key]) { <-- here is a problem 
      if (Array.isArray(obj[key])) {
        obj[key].push(value);
      } else {
        obj[key] = [obj[key], value];
      }
    } else {
      obj[key] = value;
    }

Double `?` when using with Query

Reprodution:

require('ufo').withQuery('http://a.com?v=1', { foo: 'bar', bar: 'baz' })

Returns:

http://a.com?v=1?foo=bar

Expected:

http://a.com?v=1&foo=bar

Improperly parsed hash in URLs with port

Hey,

Parsing an URL with a port and a hash without a slash in-between results in an improperly parsed URL, where hash is empty and host contains the hash.

Also, shouldn't there be an entry fort port?

Reproduction

Input: parseURL('https://domain.test:3000#owo')
Current output:

{
  protocol: 'https:',
  auth: '',
  host: 'domain.test:3000#owo',
  pathname: '',
  search: '',
  hash: ''
}

Expected output:

{
  protocol: 'https:',
  auth: '',
  host: 'domain.test:3000',
  pathname: '',
  search: '',
  hash: '#owo'
}

url constructed with 'withQuery' does not give same result with 'parseQuery'

const myurl = withQuery('https://example.com', {'abc':'123'})
// https://example.com?abc=123 

const urlObject = parseQuery(myurl)
// current => {https://example.com?abc: "123"} โŒ
// expected => {abc: "123"}


console.log(myurl);
console.log(urlObject);

While the url with extra & parses the query params correctly.
But, chromium browsers remove this extra & and thus it cannot be used.

const urlObject = parseQuery(`https://example.com?&abc=123 `)
// {https://example.com?: "", abc: "123 "}
console.log(urlObject);

Package no longer transpiled by Nuxt

After f0241d4 Nuxt no longer transpiles this package when it's used on the client-side.

It's supposed to do that as it has ufo in transpile array by default: https://github.com/nuxt/nuxt.js/blob/777a4b7f5033c86c37cbd93008f3ca792e4af8bc/packages/webpack/src/config/base.js#L78-L78

It works with 0.7.9 version of the package but not 0.7.11.

I have verified that it's due to changing the browser export from index.js to index.cjs but not sure why as I'm not that familiar with babel/webpack. Manually renaming the file and reverting the export name in package.json to index.js makes it work again.

parseURL without proto

Currerrently, parseURL('avatars0.githubusercontent.com') results into { pathname: 'avatars0.githubusercontent.com', search: '', hash: '' } whis is wrong! We might either add a fallback protocol or throw an error for this.

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]

Hi, I have a problem when nuxt run development mode

FATAL Package subpath './package.json' is not defined by "exports" in /Users/hienanh/client-barber/node_modules/@nuxt/ufo/package.json

at throwExportsNotFound (internal/modules/esm/resolve.js:290:9)
at packageExportsResolve (internal/modules/esm/resolve.js:513:3)
at resolveExports (internal/modules/cjs/loader.js:432:36)
at Function.Module._findPath (internal/modules/cjs/loader.js:472:31)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:867:27)
at Function.Module._load (internal/modules/cjs/loader.js:725:27)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Resolver.requireModule (node_modules/@nuxt/core/dist/core.js:618:26)
at Builder.validateTemplate (node_modules/@nuxt/builder/dist/builder.js:5674:38)
at Builder.build (node_modules/@nuxt/builder/dist/builder.js:5602:12)
at Object.run (node_modules/@nuxt/cli/dist/cli-build.js:109:7)
at NuxtCommand.run (node_modules/@nuxt/cli/dist/cli-index.js:2803:7)

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ โ”‚
โ”‚ โœ– Nuxt Fatal Error โ”‚
โ”‚ โ”‚
โ”‚ Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath โ”‚
โ”‚ './package.json' is not defined by "exports" in โ”‚
โ”‚ /Users/hienanh/client-barber/node_modules/@nuxt/ufo/package.json โ”‚
โ”‚ โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
Help me

How can I get a "%7C" params using withQuery

Environment

Node18

Reproduction

expect(withQuery("/test", { paths: "path1%7Cpath2" })).toBe(
    "/test?paths=path1%7Cpath2"
);

Describe the bug

This is an issue from Nuxt: nuxt/nuxt#22186
I'm trying to use useFetch function with params containing "%7C", but ufo will encode % to %25, how can I get "%7C"?

Additional context

Also, why is %7C converted to | again?
image

Logs

No response

decouple `resolveURL` from `$URL`

ufo/resolveURL was originally based on native URL but then due to platform differences and need for polyfill, we switched to lighter utils.

Using createURL/$URL for resolveURL does unnecessary encoding/decoding and adds more to the bundle. We can internally use parseURL now.

Also, we can still keep $URL it as a ponyfill but docs need to be improved it is not exactly the same as whatwg URL.

invalid handling of `withBase` on different origins

for example,

withBase('//user:[email protected]/', 'https://anotherdomain.com/')
// https://anotherdomain.com/user:[email protected]/

Expected: https://user:[email protected]/

Tested with urijs and new URL(), both are working correctly. But failed in ufo

new URL('//user:[email protected]/', 'https://anotherdomain.com/').toString()
// 'https://user:[email protected]/'
new URI('//user:[email protected]/').absoluteTo('https://anotherdomain.com/').toString()
// 'https://user:[email protected]/'

Splice filename from URL

Describe the feature

It whould be a great help if parseURL also strip filenames like http://foo.com/foo/bar.png?test=123#token into { protocol: 'http:', auth: '', host: 'foo.com', pathname: '/foo', search: '?test=123', hash: '#token', filename: 'bar.png' }.

I think its a great feature because files are also a part of url.

Additional information

  • Would you be willing to help implement this feature?

Query param array of object is not stringified

When using withQuery, arrays of objects are not serialized properly and becomes [object+Object].
I'd expect it to be at least stringify with JSON.stringify.

Current result:

withQuery('http://localhost:3000', { filters: [{ id: 1}, { name: 'ufo' }] })
// 'http://localhost:3000?filters=[object+Object]&filters=[object+Object]'

Expected results:

withQuery('http://localhost:3000', { filters: [{ id: 1}, { name: 'ufo' }] })
// 'http://localhost:3000?filters=%7B+id%3A+1%7D&filters=%7B+name%3A+%27ufo%27+%7D'

`normalizeURL` encodes url incorrectly

Environment

Node v16.20.0
Ufo v1.3.0

Reproduction

https://stackblitz.com/edit/stackblitz-starters-t7ehhr?file=index.mjs

Describe the bug

normalizeURL encodes urls incorrectly, different to encodeURI

Additional context

No response

Logs

No response

query compat with vue-routers `LocationObject`

Hey ๐Ÿ‘‹๐Ÿป

Right now, query methods, mainly withQuery, is not compatible with vue-routers LocationQuery.

vue-router:

type LocationQueryValue = string | null;
type LocationQuery = Record<string, LocationQueryValue | LocationQueryValue[]>;

ufo:

type QueryValue = string | string[] | undefined;
type QueryObject = Record<string, QueryValue>;

equal char in query value is not encoded

I have a usecase which requires me to pass a query-string-like string as a query value.

import { withQuery } from 'ufo'

const url = withQuery('https://example.com', { p: 'k1=v1&k2=v2' })

const url2 = new URL('https://example.com')
url2.searchParams.set('p', 'k1=v1&k2=v2')

console.log('withQuery', url)
console.log('URL', url2.href)

The above sample prints the following results.

withQuery https://example.com?p=k1=v1%26k2=v2
URL https://example.com/?p=k1%3Dv1%26k2%3Dv2

As you can see, ufo does not encode = char while URL does.

Is there any reason to not escape equal char in a query value?
Would be great if ufo can encode equal char as well.

stringifyParsedURL isn't documented

Describe the feature

I was looking for a function to take back in the same object type that came from parseURL. I found it looking through the source code (stringifyParsedURL). Please update the README if it's supposed to be public knowledge.

Additional information

  • Would you be willing to help implement this feature?

Allow defining type for getQuery() function via generic

Describe the feature

In server API When we use getQuery() function to parse params from query, it provides type as QueryValue | QueryValue[].
It would be great if we could provide types to this params.

check below code snippet.

export default defineEventHandler((event) => {
    const queries = getQuery(event)
	const searchQuery = queries.q
}

here the type of searchQuery is QueryValue | QueryValue[], but I want type to be string | undefined.It would be great If I could narrow down type to string | undefined.currently I am providing types using typeof for every param.

reference: nuxt/nuxt#22262

Additional information

  • Would you be willing to help implement this feature?

Empty array parameters generates invalid URL

Environment

node: v18.13.0
ufo: version 1.1.2

It might not depends on node version.

Reproduction

> const { stringifyQuery } = require('ufo')
> stringifyQuery({ 'a': 'X', 'b[]': [], c: "Y" })
'a=X&&c=Y'

Describe the bug

If the parameter has an empty array as value, a double ampersand is generated and generated URL is invalid.

Expected behavior:

> stringifyQuery({ 'a': 'X', 'b[]': [], c: "Y" })
'a=X&c=Y'

Especially, the "double ampersand" breaks my Nuxt/Rails hybrid application.

The behavior generates url like the following:

"https://localhost:3001/api/v1/users/search?page=1&perPage=25&sortBy=email-asc&&fullName=aaa;bbbb"

Ruby on Rails parses the query parameter as the following

{"page"=>"1",
 "per_page"=>"25",
 "sort_by"=>"email-asc",
 "full_name"=>"aaa",
 "bbbb"=>nil,
 "format"=>:json,
 "controller"=>"api/v1/users",
 "action"=>"search",
 "user"=>{}}

full_name=aaa;bbbb was separated to "full_name" => "aaa" and "bbbb" => '' and the value after semicolon is ignored in my search form.

Additional context

No response

Logs

No response

Unexpected behavior when passing a `data:` URL into parseURL()

Environment

Version: 1.2.0

Reproduction

https://stackblitz.com/edit/js-smsxy5?file=index.js

parseURL('data:image/png;base64,aaa//bbbbbb/ccc')
// { auth: "", hash: "", host: "bbbbbb", pathname: "/ccc", protocol: "", search: "" }

Describe the bug

When a data URL is passed into parseURL() it might detect a host and a pathname based on the base64 content of the data URL.

Additional context

Downstream issue: unjs/nitro#1431

Logs

No response

SyntaxError: "missing ( before catch"

Environment

chrome 75.0.3770 and firefox 67 and other

Reproduction

Run ufo code from browser like chrome 75.0.3770

Describe the bug

SyntaxError: "missing ( before catch"

Error from this fragment

ufo/src/encoding.ts

Lines 117 to 123 in ab3d4eb

export function decode (text: string | number = ""): string {
try {
return decodeURIComponent("" + text);
} catch {
return "" + text;
}
}

Additional context

Simple replace catch { -> catch (err) { fix it

Logs

No response

Feature Request: Setting trailing slash globally

Hi, first of all, thanks a lot for this, I've been struggling with slashes since I started working with nuxt. As I understand, how it works now you have to apply the desired method to each link. It would be awesome if this could be set globally in nuxt.config.js in order to enforce a consistent slash policy.

parseURL fails when parsing a relative URL containing other URLs.

Hi, I have a problem when nuxt hits the parseURL function with a relative URL containing other URLs.

On my case parseURL throws an Invalid URL error when parsing this relative URL:

/auth/callback#state=XXX&access_token=XXX&token_type=Bearer&expires_in=XXX&scope=email%20profile%20https://www.googleapis.com/auth/userinfo.email%20openid%20https://www.googleapis.com/auth/gmail.modify%20https://www.googleapis.com/auth/gmail.compose%20https://www.googleapis.com/auth/gmail.send%20https://mail.google.com/%20https://www.googleapis.com/auth/userinfo.profile&authuser=0&prompt=consent

It appears to be because hasProtocol matches https:/ on https://www.googleapis.com/auth/userinfo.email.

https://github.com/nuxt-contrib/ufo/blob/d15b6f067b4bf1e17e9ae0252dd17fb55f7ec148/src/index.ts#L23-L25

Use of booleans

Hello!

I want to replace qs with ufo as the latter is much more lighter and it's already included in nuxt, so I think it's a good and powerful replacement :).

I'm struggling to use withQuery as it expects a QueryType object, which only accepts strings or array of strings. I want to pass a boolean variable.

How I can accomplish it without using 'true'? Is the parsing of booleans out of the scope of ufo?

Thank you very much in advance!

Key with space in query params not working properly

Environment

Name: Ufo
Version: 1.1.2

Reproduction

Add any query params in which key is having space in it.

Describe the bug

Add any query params in which key is having space in it and check space is converted to '+' sign while encoding but while decoding '+' sign is not getting converted back to space.

Additional context

No response

Logs

No response

override urls with protocol with `withBase`

Reference: unjs/ofetch#113

Current behavior:

// http://base/http://domain
ufo.withBase('http://domain', 'http://base')

New behavior:

// http://domain
ufo.withBase('http://domain', 'http://base'})

URL behavior:

// http://domain/
new URL('http://domain', 'http://base').toString()

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Ignored or Blocked

These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

Detected dependencies

github-actions
.github/workflows/autofix.yml
  • actions/checkout v3
  • actions/setup-node v4
  • autofix-ci/action ff86a557419858bb967097bfc916833f5647fa8c
.github/workflows/ci.yml
  • actions/checkout v3
  • actions/setup-node v4
  • codecov/codecov-action v4
npm
package.json
  • @types/node ^20.16.1
  • @vitest/coverage-v8 ^2.0.5
  • automd ^0.3.8
  • changelogen ^0.5.5
  • eslint ^9.9.1
  • eslint-config-unjs ^0.3.2
  • jiti ^1.21.6
  • prettier ^3.3.3
  • typescript ^5.5.4
  • unbuild ^2.0.0
  • untyped ^1.4.2
  • vitest ^2.0.5
  • pnpm 9.8.0

  • Check this box to trigger a request for Renovate to run again on this repository

`withQuery` handles inline JSON wrongly.

When using e.g. {json: '{"test":["content"]}'} as query object, the result differs a lot from URLSearchParams and some systems do not accept the input.

Reproduction (StackBlitz):

import { withQuery } from 'ufo'

const content = {json: '{"test":["content"]}'}

//  json=%7B%22test%22%3A%5B%22content%22%5D%7D
const urlSearchParams = new URLSearchParams(content).toString() 

// json={%22test%22:[%22content%22]} 
const ufoResult = withQuery('', content) 

While the colon : does not need to be encoded necessarily, the square and curly brackets should be. Some APIs won't accept input then.

Example calls:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.