bare-url 2.1.6 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/global.d.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import * as url from '.'
2
2
 
3
3
  type URLConstructor = typeof url.URL
4
+ type URLSearchParamsConstructor = typeof url.URLSearchParams
4
5
 
5
6
  declare global {
6
7
  type URL = url.URL
8
+ type URLSearchParams = url.URLSearchParams
7
9
 
8
10
  const URL: URLConstructor
11
+ const URLSearchParams: URLSearchParamsConstructor
9
12
  }
package/global.js CHANGED
@@ -1 +1,2 @@
1
1
  global.URL = require('.')
2
+ global.URLSearchParams = require('./lib/url-search-params')
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import URLError from './lib/errors'
2
+ import URLSearchParams from './lib/url-search-params'
2
3
 
3
4
  interface URL {
4
5
  href: string
@@ -10,6 +11,7 @@ interface URL {
10
11
  port: string
11
12
  pathname: string
12
13
  search: string
14
+ searchParams: URLSearchParams
13
15
  hash: string
14
16
 
15
17
  toString(): string
@@ -31,7 +33,7 @@ declare namespace URL {
31
33
 
32
34
  export function pathToFileURL(pathname: string): URL
33
35
 
34
- export { URL, type URLError, URLError as errors }
36
+ export { URL, type URLError, URLError as errors, URLSearchParams }
35
37
  }
36
38
 
37
39
  export = URL
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const path = require('bare-path')
2
2
  const binding = require('./binding')
3
3
  const errors = require('./lib/errors')
4
+ const URLSearchParams = require('./lib/url-search-params')
4
5
 
5
6
  const kind = Symbol.for('bare.url.kind')
6
7
 
@@ -14,13 +15,15 @@ module.exports = exports = class URL {
14
15
  constructor(input, base, opts = {}) {
15
16
  if (arguments.length === 0) throw errors.INVALID_URL()
16
17
 
17
- input = `${input}`
18
+ input = String(input)
18
19
 
19
- if (base !== undefined) base = `${base}`
20
+ if (base !== undefined) base = String(base)
20
21
 
21
22
  this._components = new Uint32Array(8)
22
23
 
23
24
  this._parse(input, base, opts.throw !== false)
25
+
26
+ if (this._href) this._params = new URLSearchParams(this.search, this)
24
27
  }
25
28
 
26
29
  get [kind]() {
@@ -35,6 +38,8 @@ module.exports = exports = class URL {
35
38
 
36
39
  set href(value) {
37
40
  this._update(value)
41
+
42
+ this._params._parse(this.search)
38
43
  }
39
44
 
40
45
  // https://url.spec.whatwg.org/#dom-url-protocol
@@ -195,6 +200,14 @@ module.exports = exports = class URL {
195
200
  this._components[7] - 1 /* # */
196
201
  )
197
202
  )
203
+
204
+ this._params._parse(this.search)
205
+ }
206
+
207
+ // https://url.spec.whatwg.org/#dom-url-searchparams
208
+
209
+ get searchParams() {
210
+ return this._params
198
211
  }
199
212
 
200
213
  // https://url.spec.whatwg.org/#dom-url-hash
@@ -230,6 +243,7 @@ module.exports = exports = class URL {
230
243
  port: this.port,
231
244
  pathname: this.pathname,
232
245
  search: this.search,
246
+ searchParams: this.searchParams,
233
247
  hash: this.hash
234
248
  }
235
249
  }
@@ -242,10 +256,10 @@ module.exports = exports = class URL {
242
256
  return this._slice(0, start) + replacement + this._slice(end)
243
257
  }
244
258
 
245
- _parse(href, base, shouldThrow) {
259
+ _parse(input, base, shouldThrow) {
246
260
  try {
247
261
  this._href = binding.parse(
248
- String(href),
262
+ String(input),
249
263
  base ? String(base) : null,
250
264
  this._components,
251
265
  shouldThrow
@@ -257,9 +271,9 @@ module.exports = exports = class URL {
257
271
  }
258
272
  }
259
273
 
260
- _update(href) {
274
+ _update(input) {
261
275
  try {
262
- this._parse(href, null, true)
276
+ this._parse(input, null, true)
263
277
  } catch (err) {
264
278
  if (err instanceof TypeError) throw err
265
279
  }
@@ -278,7 +292,8 @@ function cannotHaveCredentialsOrPort(url) {
278
292
 
279
293
  const URL = exports
280
294
 
281
- exports.URL = URL // For Node.js compatibility
295
+ exports.URL = URL
296
+ exports.URLSearchParams = URLSearchParams
282
297
 
283
298
  exports.errors = errors
284
299
 
@@ -290,11 +305,13 @@ exports.isURL = function isURL(value) {
290
305
  )
291
306
  }
292
307
 
308
+ // https://url.spec.whatwg.org/#dom-url-parse
293
309
  exports.parse = function parse(input, base) {
294
310
  const url = new URL(input, base, { throw: false })
295
- return url.href ? url : null
311
+ return url._href ? url : null
296
312
  }
297
313
 
314
+ // https://url.spec.whatwg.org/#dom-url-canparse
298
315
  exports.canParse = function canParse(input, base) {
299
316
  return binding.canParse(String(input), base ? String(base) : null)
300
317
  }
@@ -0,0 +1,21 @@
1
+ interface URLSearchParams extends Iterable<[name: string, value: string]> {
2
+ readonly size: number
3
+
4
+ append(name: string, value: string): void
5
+ delete(name: string, value?: string): void
6
+ get(name: string): string | undefined
7
+ getAll(name: string): string[]
8
+ has(name: string, value?: string): boolean
9
+ set(name: string, value: string): void
10
+
11
+ toString(): string
12
+ toJSON(): string
13
+ }
14
+
15
+ declare class URLSearchParams {
16
+ constructor(
17
+ init: string | Record<string, string> | Iterable<[string, string]>
18
+ )
19
+ }
20
+
21
+ export = URLSearchParams
@@ -0,0 +1,176 @@
1
+ module.exports = class URLSearchParams {
2
+ static _urls = new WeakMap()
3
+
4
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
5
+ constructor(init, url = null) {
6
+ this._params = new Map()
7
+
8
+ if (url) URLSearchParams._urls.set(this, url)
9
+
10
+ if (typeof init === 'string') {
11
+ this._parse(init)
12
+ } else if (init) {
13
+ for (const [name, value] of typeof init[Symbol.iterator] === 'function'
14
+ ? init
15
+ : Object.entries(init)) {
16
+ this.append(name, value)
17
+ }
18
+ }
19
+ }
20
+
21
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-size
22
+ get size() {
23
+ return this._params.length
24
+ }
25
+
26
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-append
27
+ append(name, value = null) {
28
+ if (value === null) return
29
+
30
+ let list = this._params.get(name)
31
+
32
+ if (list === undefined) {
33
+ list = []
34
+ this._params.set(name, list)
35
+ }
36
+
37
+ list.push(value)
38
+
39
+ this._update()
40
+ }
41
+
42
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-delete
43
+ delete(name, value = null) {
44
+ if (value === null) this._params.delete(name)
45
+ else {
46
+ let list = this._params.get(name)
47
+
48
+ if (list === undefined) return
49
+
50
+ list = list.filter((found) => found !== value)
51
+
52
+ if (list.length === 0) this._params.delete(name)
53
+ else this._params.set(name, list)
54
+ }
55
+
56
+ this._update()
57
+ }
58
+
59
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-get
60
+ get(name) {
61
+ const list = this._params.get(name)
62
+
63
+ if (list === undefined) return null
64
+
65
+ return list[0]
66
+ }
67
+
68
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-getall
69
+ getAll(name) {
70
+ const list = this._params.get(name)
71
+
72
+ if (list === undefined) return []
73
+
74
+ return Array.from(list)
75
+ }
76
+
77
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-has
78
+ has(name, value = null) {
79
+ const list = this._params.get(name)
80
+
81
+ if (list === undefined) return false
82
+
83
+ if (value === null) return true
84
+
85
+ return list.includes(value)
86
+ }
87
+
88
+ // https://url.spec.whatwg.org/#dom-urlsearchparams-set
89
+ set(name, value = null) {
90
+ if (value === null) this._params.delete(name)
91
+ else this._params.set(name, [value])
92
+
93
+ this._update()
94
+ }
95
+
96
+ toString() {
97
+ return this._serialize()
98
+ }
99
+
100
+ toJSON() {
101
+ return [...this]
102
+ }
103
+
104
+ *[Symbol.iterator]() {
105
+ for (const [name, values] of this._params) {
106
+ for (const value of values) yield [name, value]
107
+ }
108
+ }
109
+
110
+ [Symbol.for('bare.inspect')]() {
111
+ const object = {
112
+ __proto__: { constructor: URLSearchParams }
113
+ }
114
+
115
+ for (const [name, values] of this._params) {
116
+ if (values.length === 1) object[name] = values[0]
117
+ else object[name] = values
118
+ }
119
+
120
+ return object
121
+ }
122
+
123
+ // https://url.spec.whatwg.org/#concept-urlsearchparams-update
124
+ _update() {
125
+ const url = URLSearchParams._urls.get(this)
126
+
127
+ if (url === undefined) return
128
+
129
+ url.search = this._serialize()
130
+ }
131
+
132
+ // https://url.spec.whatwg.org/#concept-urlencoded-parser
133
+ _parse(input) {
134
+ if (input[0] === '?') input = input.substring(1)
135
+
136
+ this._params = new Map()
137
+
138
+ for (const sequence of input.split('&')) {
139
+ if (sequence.length === 0) continue
140
+
141
+ let i = sequence.indexOf('=')
142
+ if (i === -1) i = sequence.length
143
+
144
+ const name = decodeURIComponent(sequence.substring(0, i))
145
+ const value = decodeURIComponent(
146
+ sequence.substring(i + 1, sequence.length)
147
+ )
148
+
149
+ let list = this._params.get(name)
150
+
151
+ if (list === undefined) {
152
+ list = []
153
+ this._params.set(name, list)
154
+ }
155
+
156
+ list.push(value)
157
+ }
158
+ }
159
+
160
+ // https://url.spec.whatwg.org/#concept-urlencoded-serializer
161
+ _serialize() {
162
+ let output = ''
163
+
164
+ for (let [name, values] of this._params) {
165
+ name = encodeURIComponent(name)
166
+
167
+ for (const value of values) {
168
+ if (output) output += '&'
169
+
170
+ output += name + '=' + encodeURIComponent(value)
171
+ }
172
+ }
173
+
174
+ return output
175
+ }
176
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-url",
3
- "version": "2.1.6",
3
+ "version": "2.2.1",
4
4
  "description": "WHATWG URL implementation for JavaScript",
5
5
  "exports": {
6
6
  "./package": "./package.json",