bare-url 2.1.5 → 2.2.0

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/binding.c CHANGED
@@ -165,47 +165,6 @@ bare_url_can_parse (js_env_t *env, js_callback_info_t *info) {
165
165
  return result;
166
166
  }
167
167
 
168
- static js_value_t *
169
- bare_url_tag (js_env_t *env, js_callback_info_t *info) {
170
- int err;
171
-
172
- size_t argc = 1;
173
- js_value_t *argv[1];
174
-
175
- err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
176
- assert(err == 0);
177
-
178
- assert(argc == 1);
179
-
180
- err = js_add_type_tag(env, argv[0], &bare_url__tag);
181
- assert(err == 0);
182
-
183
- return NULL;
184
- }
185
-
186
- static js_value_t *
187
- bare_url_is_tagged (js_env_t *env, js_callback_info_t *info) {
188
- int err;
189
-
190
- size_t argc = 1;
191
- js_value_t *argv[1];
192
-
193
- err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
194
- assert(err == 0);
195
-
196
- assert(argc == 1);
197
-
198
- bool is_url;
199
- err = js_check_type_tag(env, argv[0], &bare_url__tag, &is_url);
200
- assert(err == 0);
201
-
202
- js_value_t *result;
203
- err = js_get_boolean(env, is_url, &result);
204
- assert(err == 0);
205
-
206
- return result;
207
- }
208
-
209
168
  static js_value_t *
210
169
  bare_url_exports (js_env_t *env, js_value_t *exports) {
211
170
  int err;
@@ -221,8 +180,6 @@ bare_url_exports (js_env_t *env, js_value_t *exports) {
221
180
 
222
181
  V("parse", bare_url_parse)
223
182
  V("canParse", bare_url_can_parse)
224
- V("tag", bare_url_tag)
225
- V("isTagged", bare_url_is_tagged)
226
183
  #undef V
227
184
 
228
185
  return exports;
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,24 +1,33 @@
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')
5
+
6
+ const kind = Symbol.for('bare.url.kind')
4
7
 
5
8
  const isWindows = Bare.platform === 'win32'
6
9
 
7
10
  module.exports = exports = class URL {
8
- static {
9
- binding.tag(this)
11
+ static get [kind]() {
12
+ return 0 // Compatibility version
10
13
  }
11
14
 
12
15
  constructor(input, base, opts = {}) {
13
16
  if (arguments.length === 0) throw errors.INVALID_URL()
14
17
 
15
- input = `${input}`
18
+ input = String(input)
16
19
 
17
- if (base !== undefined) base = `${base}`
20
+ if (base !== undefined) base = String(base)
18
21
 
19
22
  this._components = new Uint32Array(8)
20
23
 
21
24
  this._parse(input, base, opts.throw !== false)
25
+
26
+ if (this._href) this._params = new URLSearchParams(this.search, this)
27
+ }
28
+
29
+ get [kind]() {
30
+ return URL[kind]
22
31
  }
23
32
 
24
33
  // https://url.spec.whatwg.org/#dom-url-href
@@ -29,6 +38,8 @@ module.exports = exports = class URL {
29
38
 
30
39
  set href(value) {
31
40
  this._update(value)
41
+
42
+ this._params._parse(this.search)
32
43
  }
33
44
 
34
45
  // https://url.spec.whatwg.org/#dom-url-protocol
@@ -189,6 +200,14 @@ module.exports = exports = class URL {
189
200
  this._components[7] - 1 /* # */
190
201
  )
191
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
192
211
  }
193
212
 
194
213
  // https://url.spec.whatwg.org/#dom-url-hash
@@ -224,6 +243,7 @@ module.exports = exports = class URL {
224
243
  port: this.port,
225
244
  pathname: this.pathname,
226
245
  search: this.search,
246
+ searchParams: this.searchParams,
227
247
  hash: this.hash
228
248
  }
229
249
  }
@@ -236,10 +256,10 @@ module.exports = exports = class URL {
236
256
  return this._slice(0, start) + replacement + this._slice(end)
237
257
  }
238
258
 
239
- _parse(href, base, shouldThrow) {
259
+ _parse(input, base, shouldThrow) {
240
260
  try {
241
261
  this._href = binding.parse(
242
- String(href),
262
+ String(input),
243
263
  base ? String(base) : null,
244
264
  this._components,
245
265
  shouldThrow
@@ -251,9 +271,9 @@ module.exports = exports = class URL {
251
271
  }
252
272
  }
253
273
 
254
- _update(href) {
274
+ _update(input) {
255
275
  try {
256
- this._parse(href, null, true)
276
+ this._parse(input, null, true)
257
277
  } catch (err) {
258
278
  if (err instanceof TypeError) throw err
259
279
  }
@@ -272,29 +292,26 @@ function cannotHaveCredentialsOrPort(url) {
272
292
 
273
293
  const URL = exports
274
294
 
275
- exports.URL = URL // For Node.js compatibility
295
+ exports.URL = URL
296
+ exports.URLSearchParams = URLSearchParams
276
297
 
277
298
  exports.errors = errors
278
299
 
279
300
  exports.isURL = function isURL(value) {
280
- if (typeof value !== 'object' || value === null) return false
281
-
282
- let constructor = value.constructor
283
-
284
- while (typeof constructor === 'function') {
285
- if (binding.isTagged(constructor)) return true
286
-
287
- constructor = Reflect.getPrototypeOf(constructor)
288
- }
301
+ if (value instanceof URL) return true
289
302
 
290
- return false
303
+ return (
304
+ typeof value === 'object' && value !== null && value[kind] === URL[kind]
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,174 @@
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 = sequence.substring(0, i)
145
+ const value = sequence.substring(i + 1, sequence.length)
146
+
147
+ let list = this._params.get(name)
148
+
149
+ if (list === undefined) {
150
+ list = []
151
+ this._params.set(name, list)
152
+ }
153
+
154
+ list.push(value)
155
+ }
156
+ }
157
+
158
+ // https://url.spec.whatwg.org/#concept-urlencoded-serializer
159
+ _serialize() {
160
+ let output = ''
161
+
162
+ for (let [name, values] of this._params) {
163
+ name = encodeURIComponent(name)
164
+
165
+ for (const value of values) {
166
+ if (output) output += '&'
167
+
168
+ output += name + '=' + encodeURIComponent(value)
169
+ }
170
+ }
171
+
172
+ return output
173
+ }
174
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-url",
3
- "version": "2.1.5",
3
+ "version": "2.2.0",
4
4
  "description": "WHATWG URL implementation for JavaScript",
5
5
  "exports": {
6
6
  "./package": "./package.json",
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file