@effect/platform 0.72.2 → 0.73.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.
Files changed (65) hide show
  1. package/README.md +637 -0
  2. package/Url/package.json +6 -0
  3. package/dist/cjs/HttpApi.js.map +1 -1
  4. package/dist/cjs/HttpApiEndpoint.js.map +1 -1
  5. package/dist/cjs/HttpApiGroup.js.map +1 -1
  6. package/dist/cjs/HttpClient.js +8 -1
  7. package/dist/cjs/HttpClient.js.map +1 -1
  8. package/dist/cjs/HttpMethod.js +24 -1
  9. package/dist/cjs/HttpMethod.js.map +1 -1
  10. package/dist/cjs/OpenApi.js +82 -42
  11. package/dist/cjs/OpenApi.js.map +1 -1
  12. package/dist/cjs/Runtime.js.map +1 -1
  13. package/dist/cjs/Url.js +259 -0
  14. package/dist/cjs/Url.js.map +1 -0
  15. package/dist/cjs/index.js +3 -1
  16. package/dist/cjs/internal/httpClient.js +3 -1
  17. package/dist/cjs/internal/httpClient.js.map +1 -1
  18. package/dist/dts/HttpApi.d.ts +1 -2
  19. package/dist/dts/HttpApi.d.ts.map +1 -1
  20. package/dist/dts/HttpApiBuilder.d.ts +1 -1
  21. package/dist/dts/HttpApiBuilder.d.ts.map +1 -1
  22. package/dist/dts/HttpApiEndpoint.d.ts +16 -8
  23. package/dist/dts/HttpApiEndpoint.d.ts.map +1 -1
  24. package/dist/dts/HttpApiGroup.d.ts +1 -2
  25. package/dist/dts/HttpApiGroup.d.ts.map +1 -1
  26. package/dist/dts/HttpClient.d.ts +22 -0
  27. package/dist/dts/HttpClient.d.ts.map +1 -1
  28. package/dist/dts/HttpMethod.d.ts +22 -0
  29. package/dist/dts/HttpMethod.d.ts.map +1 -1
  30. package/dist/dts/OpenApi.d.ts +100 -110
  31. package/dist/dts/OpenApi.d.ts.map +1 -1
  32. package/dist/dts/Runtime.d.ts +48 -0
  33. package/dist/dts/Runtime.d.ts.map +1 -1
  34. package/dist/dts/Url.d.ts +591 -0
  35. package/dist/dts/Url.d.ts.map +1 -0
  36. package/dist/dts/index.d.ts +4 -0
  37. package/dist/dts/index.d.ts.map +1 -1
  38. package/dist/esm/HttpApi.js.map +1 -1
  39. package/dist/esm/HttpApiEndpoint.js.map +1 -1
  40. package/dist/esm/HttpApiGroup.js.map +1 -1
  41. package/dist/esm/HttpClient.js +7 -0
  42. package/dist/esm/HttpClient.js.map +1 -1
  43. package/dist/esm/HttpMethod.js +22 -0
  44. package/dist/esm/HttpMethod.js.map +1 -1
  45. package/dist/esm/OpenApi.js +82 -41
  46. package/dist/esm/OpenApi.js.map +1 -1
  47. package/dist/esm/Runtime.js.map +1 -1
  48. package/dist/esm/Url.js +248 -0
  49. package/dist/esm/Url.js.map +1 -0
  50. package/dist/esm/index.js +4 -0
  51. package/dist/esm/index.js.map +1 -1
  52. package/dist/esm/internal/httpClient.js +2 -0
  53. package/dist/esm/internal/httpClient.js.map +1 -1
  54. package/package.json +10 -2
  55. package/src/HttpApi.ts +2 -3
  56. package/src/HttpApiBuilder.ts +1 -1
  57. package/src/HttpApiEndpoint.ts +22 -13
  58. package/src/HttpApiGroup.ts +2 -3
  59. package/src/HttpClient.ts +28 -0
  60. package/src/HttpMethod.ts +24 -0
  61. package/src/OpenApi.ts +174 -181
  62. package/src/Runtime.ts +48 -0
  63. package/src/Url.ts +632 -0
  64. package/src/index.ts +5 -0
  65. package/src/internal/httpClient.ts +11 -0
package/src/Runtime.ts CHANGED
@@ -36,6 +36,30 @@ export const defaultTeardown: Teardown = <E, A>(
36
36
  * @since 1.0.0
37
37
  */
38
38
  export interface RunMain {
39
+ /**
40
+ * Helps you run a main effect with built-in error handling, logging, and signal management.
41
+ *
42
+ * **Details**
43
+ *
44
+ * This function launches an Effect as the main entry point, setting exit codes
45
+ * based on success or failure, handling interrupts (e.g., Ctrl+C), and optionally
46
+ * logging errors. By default, it logs errors and uses a "pretty" format, but both
47
+ * behaviors can be turned off. You can also provide custom teardown logic to
48
+ * finalize resources or produce different exit codes.
49
+ *
50
+ * **Options**
51
+ *
52
+ * An optional object that can include:
53
+ * - `disableErrorReporting`: Turn off automatic error logging.
54
+ * - `disablePrettyLogger`: Avoid adding the pretty logger.
55
+ * - `teardown`: Provide custom finalization logic.
56
+ *
57
+ * **When to Use**
58
+ *
59
+ * Use this function to run an Effect as your application’s main program, especially
60
+ * when you need structured error handling, log management, interrupt support,
61
+ * or advanced teardown capabilities.
62
+ */
39
63
  (
40
64
  options?: {
41
65
  readonly disableErrorReporting?: boolean | undefined
@@ -43,6 +67,30 @@ export interface RunMain {
43
67
  readonly teardown?: Teardown | undefined
44
68
  }
45
69
  ): <E, A>(effect: Effect.Effect<A, E>) => void
70
+ /**
71
+ * Helps you run a main effect with built-in error handling, logging, and signal management.
72
+ *
73
+ * **Details**
74
+ *
75
+ * This function launches an Effect as the main entry point, setting exit codes
76
+ * based on success or failure, handling interrupts (e.g., Ctrl+C), and optionally
77
+ * logging errors. By default, it logs errors and uses a "pretty" format, but both
78
+ * behaviors can be turned off. You can also provide custom teardown logic to
79
+ * finalize resources or produce different exit codes.
80
+ *
81
+ * **Options**
82
+ *
83
+ * An optional object that can include:
84
+ * - `disableErrorReporting`: Turn off automatic error logging.
85
+ * - `disablePrettyLogger`: Avoid adding the pretty logger.
86
+ * - `teardown`: Provide custom finalization logic.
87
+ *
88
+ * **When to Use**
89
+ *
90
+ * Use this function to run an Effect as your application’s main program, especially
91
+ * when you need structured error handling, log management, interrupt support,
92
+ * or advanced teardown capabilities.
93
+ */
46
94
  <E, A>(
47
95
  effect: Effect.Effect<A, E>,
48
96
  options?: {
package/src/Url.ts ADDED
@@ -0,0 +1,632 @@
1
+ /**
2
+ * @since 1.0.0
3
+ */
4
+ import * as Cause from "effect/Cause"
5
+ import * as Either from "effect/Either"
6
+ import { dual } from "effect/Function"
7
+ import * as UrlParams from "./UrlParams.js"
8
+
9
+ /**
10
+ * Parses a URL string into a `URL` object, returning an `Either` type for safe
11
+ * error handling.
12
+ *
13
+ * **Details**
14
+ *
15
+ * This function converts a string into a `URL` object, enabling safe URL
16
+ * parsing with built-in error handling. If the string is invalid or fails to
17
+ * parse, this function does not throw an error; instead, it wraps the error in
18
+ * a `IllegalArgumentException` and returns it as the `Left` value of an
19
+ * `Either`. The `Right` value contains the successfully parsed `URL`.
20
+ *
21
+ * An optional `base` parameter can be provided to resolve relative URLs. If
22
+ * specified, the function interprets the input `url` as relative to this
23
+ * `base`. This is especially useful when dealing with URLs that might not be
24
+ * fully qualified.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { Url } from "@effect/platform"
29
+ * import { Either } from "effect"
30
+ *
31
+ * // Parse an absolute URL
32
+ * //
33
+ * // ┌─── Either<URL, IllegalArgumentException>
34
+ * // ▼
35
+ * const parsed = Url.fromString("https://example.com/path")
36
+ *
37
+ * if (Either.isRight(parsed)) {
38
+ * console.log("Parsed URL:", parsed.right.toString())
39
+ * } else {
40
+ * console.log("Error:", parsed.left.message)
41
+ * }
42
+ * // Output: Parsed URL: https://example.com/path
43
+ *
44
+ * // Parse a relative URL with a base
45
+ * const relativeParsed = Url.fromString("/relative-path", "https://example.com")
46
+ *
47
+ * if (Either.isRight(relativeParsed)) {
48
+ * console.log("Parsed relative URL:", relativeParsed.right.toString())
49
+ * } else {
50
+ * console.log("Error:", relativeParsed.left.message)
51
+ * }
52
+ * // Output: Parsed relative URL: https://example.com/relative-path
53
+ * ```
54
+ *
55
+ * @since 1.0.0
56
+ * @category Constructors
57
+ */
58
+ export const fromString: {
59
+ /**
60
+ * Parses a URL string into a `URL` object, returning an `Either` type for safe
61
+ * error handling.
62
+ *
63
+ * **Details**
64
+ *
65
+ * This function converts a string into a `URL` object, enabling safe URL
66
+ * parsing with built-in error handling. If the string is invalid or fails to
67
+ * parse, this function does not throw an error; instead, it wraps the error in
68
+ * a `IllegalArgumentException` and returns it as the `Left` value of an
69
+ * `Either`. The `Right` value contains the successfully parsed `URL`.
70
+ *
71
+ * An optional `base` parameter can be provided to resolve relative URLs. If
72
+ * specified, the function interprets the input `url` as relative to this
73
+ * `base`. This is especially useful when dealing with URLs that might not be
74
+ * fully qualified.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * import { Url } from "@effect/platform"
79
+ * import { Either } from "effect"
80
+ *
81
+ * // Parse an absolute URL
82
+ * //
83
+ * // ┌─── Either<URL, IllegalArgumentException>
84
+ * // ▼
85
+ * const parsed = Url.fromString("https://example.com/path")
86
+ *
87
+ * if (Either.isRight(parsed)) {
88
+ * console.log("Parsed URL:", parsed.right.toString())
89
+ * } else {
90
+ * console.log("Error:", parsed.left.message)
91
+ * }
92
+ * // Output: Parsed URL: https://example.com/path
93
+ *
94
+ * // Parse a relative URL with a base
95
+ * const relativeParsed = Url.fromString("/relative-path", "https://example.com")
96
+ *
97
+ * if (Either.isRight(relativeParsed)) {
98
+ * console.log("Parsed relative URL:", relativeParsed.right.toString())
99
+ * } else {
100
+ * console.log("Error:", relativeParsed.left.message)
101
+ * }
102
+ * // Output: Parsed relative URL: https://example.com/relative-path
103
+ * ```
104
+ *
105
+ * @since 1.0.0
106
+ * @category Constructors
107
+ */
108
+ (url: string, base?: string | URL | undefined): Either.Either<URL, Cause.IllegalArgumentException>
109
+ } = (url, base) =>
110
+ Either.try({
111
+ try: () => new URL(url, base),
112
+ catch: (cause) =>
113
+ new Cause.IllegalArgumentException(cause instanceof globalThis.Error ? cause.message : "Invalid input")
114
+ })
115
+
116
+ /**
117
+ * This function clones the original `URL` object and applies a callback to the
118
+ * clone, allowing multiple updates at once.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * import { Url } from "@effect/platform"
123
+ *
124
+ * const myUrl = new URL("https://example.com")
125
+ *
126
+ * const mutatedUrl = Url.mutate(myUrl, (url) => {
127
+ * url.username = "user"
128
+ * url.password = "pass"
129
+ * })
130
+ *
131
+ * console.log("Mutated:", mutatedUrl.toString())
132
+ * // Output: Mutated: https://user:pass@example.com/
133
+ * ```
134
+ *
135
+ * @since 1.0.0
136
+ * @category Modifiers
137
+ */
138
+ export const mutate: {
139
+ /**
140
+ * This function clones the original `URL` object and applies a callback to the
141
+ * clone, allowing multiple updates at once.
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * import { Url } from "@effect/platform"
146
+ *
147
+ * const myUrl = new URL("https://example.com")
148
+ *
149
+ * const mutatedUrl = Url.mutate(myUrl, (url) => {
150
+ * url.username = "user"
151
+ * url.password = "pass"
152
+ * })
153
+ *
154
+ * console.log("Mutated:", mutatedUrl.toString())
155
+ * // Output: Mutated: https://user:pass@example.com/
156
+ * ```
157
+ *
158
+ * @since 1.0.0
159
+ * @category Modifiers
160
+ */
161
+ (f: (url: URL) => void): (self: URL) => URL
162
+ /**
163
+ * This function clones the original `URL` object and applies a callback to the
164
+ * clone, allowing multiple updates at once.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * import { Url } from "@effect/platform"
169
+ *
170
+ * const myUrl = new URL("https://example.com")
171
+ *
172
+ * const mutatedUrl = Url.mutate(myUrl, (url) => {
173
+ * url.username = "user"
174
+ * url.password = "pass"
175
+ * })
176
+ *
177
+ * console.log("Mutated:", mutatedUrl.toString())
178
+ * // Output: Mutated: https://user:pass@example.com/
179
+ * ```
180
+ *
181
+ * @since 1.0.0
182
+ * @category Modifiers
183
+ */
184
+ (self: URL, f: (url: URL) => void): URL
185
+ } = dual(2, (self: URL, f: (url: URL) => void) => {
186
+ const copy = new URL(self)
187
+ f(copy)
188
+ return copy
189
+ })
190
+
191
+ /** @internal */
192
+ const immutableURLSetter = <P extends keyof URL>(property: P): {
193
+ (value: URL[P]): (url: URL) => URL
194
+ (url: URL, value: URL[P]): URL
195
+ } =>
196
+ dual(2, (url: URL, value: URL[P]) =>
197
+ mutate(url, (url) => {
198
+ url[property] = value
199
+ }))
200
+
201
+ /**
202
+ * Updates the hash fragment of the URL.
203
+ *
204
+ * @since 1.0.0
205
+ * @category Setters
206
+ */
207
+ export const setHash: {
208
+ /**
209
+ * Updates the hash fragment of the URL.
210
+ *
211
+ * @since 1.0.0
212
+ * @category Setters
213
+ */
214
+ (hash: string): (url: URL) => URL
215
+ /**
216
+ * Updates the hash fragment of the URL.
217
+ *
218
+ * @since 1.0.0
219
+ * @category Setters
220
+ */
221
+ (url: URL, hash: string): URL
222
+ } = immutableURLSetter("hash")
223
+
224
+ /**
225
+ * Updates the host (domain and port) of the URL.
226
+ *
227
+ * @since 1.0.0
228
+ * @category Setters
229
+ */
230
+ export const setHost: {
231
+ /**
232
+ * Updates the host (domain and port) of the URL.
233
+ *
234
+ * @since 1.0.0
235
+ * @category Setters
236
+ */
237
+ (host: string): (url: URL) => URL
238
+ /**
239
+ * Updates the host (domain and port) of the URL.
240
+ *
241
+ * @since 1.0.0
242
+ * @category Setters
243
+ */
244
+ (url: URL, host: string): URL
245
+ } = immutableURLSetter("host")
246
+
247
+ /**
248
+ * Updates the domain of the URL without modifying the port.
249
+ *
250
+ * @since 1.0.0
251
+ * @category Setters
252
+ */
253
+ export const setHostname: {
254
+ /**
255
+ * Updates the domain of the URL without modifying the port.
256
+ *
257
+ * @since 1.0.0
258
+ * @category Setters
259
+ */
260
+ (hostname: string): (url: URL) => URL
261
+ /**
262
+ * Updates the domain of the URL without modifying the port.
263
+ *
264
+ * @since 1.0.0
265
+ * @category Setters
266
+ */
267
+ (url: URL, hostname: string): URL
268
+ } = immutableURLSetter("hostname")
269
+
270
+ /**
271
+ * Replaces the entire URL string.
272
+ *
273
+ * @since 1.0.0
274
+ * @category Setters
275
+ */
276
+ export const setHref: {
277
+ /**
278
+ * Replaces the entire URL string.
279
+ *
280
+ * @since 1.0.0
281
+ * @category Setters
282
+ */
283
+ (href: string): (url: URL) => URL
284
+ /**
285
+ * Replaces the entire URL string.
286
+ *
287
+ * @since 1.0.0
288
+ * @category Setters
289
+ */
290
+ (url: URL, href: string): URL
291
+ } = immutableURLSetter("href")
292
+
293
+ /**
294
+ * Updates the password used for authentication.
295
+ *
296
+ * @since 1.0.0
297
+ * @category Setters
298
+ */
299
+ export const setPassword: {
300
+ /**
301
+ * Updates the password used for authentication.
302
+ *
303
+ * @since 1.0.0
304
+ * @category Setters
305
+ */
306
+ (password: string): (url: URL) => URL
307
+ /**
308
+ * Updates the password used for authentication.
309
+ *
310
+ * @since 1.0.0
311
+ * @category Setters
312
+ */
313
+ (url: URL, password: string): URL
314
+ } = immutableURLSetter("password")
315
+
316
+ /**
317
+ * Updates the path of the URL.
318
+ *
319
+ * @since 1.0.0
320
+ * @category Setters
321
+ */
322
+ export const setPathname: {
323
+ /**
324
+ * Updates the path of the URL.
325
+ *
326
+ * @since 1.0.0
327
+ * @category Setters
328
+ */
329
+ (pathname: string): (url: URL) => URL
330
+ /**
331
+ * Updates the path of the URL.
332
+ *
333
+ * @since 1.0.0
334
+ * @category Setters
335
+ */
336
+ (url: URL, pathname: string): URL
337
+ } = immutableURLSetter("pathname")
338
+
339
+ /**
340
+ * Updates the port of the URL.
341
+ *
342
+ * @since 1.0.0
343
+ * @category Setters
344
+ */
345
+ export const setPort: {
346
+ /**
347
+ * Updates the port of the URL.
348
+ *
349
+ * @since 1.0.0
350
+ * @category Setters
351
+ */
352
+ (port: string): (url: URL) => URL
353
+ /**
354
+ * Updates the port of the URL.
355
+ *
356
+ * @since 1.0.0
357
+ * @category Setters
358
+ */
359
+ (url: URL, port: string): URL
360
+ } = immutableURLSetter("port")
361
+
362
+ /**
363
+ * Updates the protocol (e.g., `http`, `https`).
364
+ *
365
+ * @since 1.0.0
366
+ * @category Setters
367
+ */
368
+ export const setProtocol: {
369
+ /**
370
+ * Updates the protocol (e.g., `http`, `https`).
371
+ *
372
+ * @since 1.0.0
373
+ * @category Setters
374
+ */
375
+ (protocol: string): (url: URL) => URL
376
+ /**
377
+ * Updates the protocol (e.g., `http`, `https`).
378
+ *
379
+ * @since 1.0.0
380
+ * @category Setters
381
+ */
382
+ (url: URL, protocol: string): URL
383
+ } = immutableURLSetter("protocol")
384
+
385
+ /**
386
+ * Updates the query string of the URL.
387
+ *
388
+ * @since 1.0.0
389
+ * @category Setters
390
+ */
391
+ export const setSearch: {
392
+ /**
393
+ * Updates the query string of the URL.
394
+ *
395
+ * @since 1.0.0
396
+ * @category Setters
397
+ */
398
+ (search: string): (url: URL) => URL
399
+ /**
400
+ * Updates the query string of the URL.
401
+ *
402
+ * @since 1.0.0
403
+ * @category Setters
404
+ */
405
+ (url: URL, search: string): URL
406
+ } = immutableURLSetter("search")
407
+
408
+ /**
409
+ * Updates the username used for authentication.
410
+ *
411
+ * @since 1.0.0
412
+ * @category Setters
413
+ */
414
+ export const setUsername: {
415
+ /**
416
+ * Updates the username used for authentication.
417
+ *
418
+ * @since 1.0.0
419
+ * @category Setters
420
+ */
421
+ (username: string): (url: URL) => URL
422
+ /**
423
+ * Updates the username used for authentication.
424
+ *
425
+ * @since 1.0.0
426
+ * @category Setters
427
+ */
428
+ (url: URL, username: string): URL
429
+ } = immutableURLSetter("username")
430
+
431
+ /**
432
+ * Updates the query parameters of a URL.
433
+ *
434
+ * **Details**
435
+ *
436
+ * This function allows you to set or replace the query parameters of a `URL`
437
+ * object using the provided `UrlParams`. It creates a new `URL` object with the
438
+ * updated parameters, leaving the original object unchanged.
439
+ *
440
+ * @example
441
+ * ```ts
442
+ * import { Url, UrlParams } from "@effect/platform"
443
+ *
444
+ * const myUrl = new URL("https://example.com?foo=bar")
445
+ *
446
+ * // Write parameters
447
+ * const updatedUrl = Url.setUrlParams(
448
+ * myUrl,
449
+ * UrlParams.fromInput([["key", "value"]])
450
+ * )
451
+ *
452
+ * console.log(updatedUrl.toString())
453
+ * // Output: https://example.com/?key=value
454
+ * ```
455
+ *
456
+ * @since 1.0.0
457
+ * @category Setters
458
+ */
459
+ export const setUrlParams: {
460
+ /**
461
+ * Updates the query parameters of a URL.
462
+ *
463
+ * **Details**
464
+ *
465
+ * This function allows you to set or replace the query parameters of a `URL`
466
+ * object using the provided `UrlParams`. It creates a new `URL` object with the
467
+ * updated parameters, leaving the original object unchanged.
468
+ *
469
+ * @example
470
+ * ```ts
471
+ * import { Url, UrlParams } from "@effect/platform"
472
+ *
473
+ * const myUrl = new URL("https://example.com?foo=bar")
474
+ *
475
+ * // Write parameters
476
+ * const updatedUrl = Url.setUrlParams(
477
+ * myUrl,
478
+ * UrlParams.fromInput([["key", "value"]])
479
+ * )
480
+ *
481
+ * console.log(updatedUrl.toString())
482
+ * // Output: https://example.com/?key=value
483
+ * ```
484
+ *
485
+ * @since 1.0.0
486
+ * @category Setters
487
+ */
488
+ (urlParams: UrlParams.UrlParams): (url: URL) => URL
489
+ /**
490
+ * Updates the query parameters of a URL.
491
+ *
492
+ * **Details**
493
+ *
494
+ * This function allows you to set or replace the query parameters of a `URL`
495
+ * object using the provided `UrlParams`. It creates a new `URL` object with the
496
+ * updated parameters, leaving the original object unchanged.
497
+ *
498
+ * @example
499
+ * ```ts
500
+ * import { Url, UrlParams } from "@effect/platform"
501
+ *
502
+ * const myUrl = new URL("https://example.com?foo=bar")
503
+ *
504
+ * // Write parameters
505
+ * const updatedUrl = Url.setUrlParams(
506
+ * myUrl,
507
+ * UrlParams.fromInput([["key", "value"]])
508
+ * )
509
+ *
510
+ * console.log(updatedUrl.toString())
511
+ * // Output: https://example.com/?key=value
512
+ * ```
513
+ *
514
+ * @since 1.0.0
515
+ * @category Setters
516
+ */
517
+ (url: URL, urlParams: UrlParams.UrlParams): URL
518
+ } = dual(2, (url: URL, searchParams: UrlParams.UrlParams) =>
519
+ mutate(url, (url) => {
520
+ url.search = UrlParams.toString(searchParams)
521
+ }))
522
+
523
+ /**
524
+ * Retrieves the query parameters from a URL.
525
+ *
526
+ * **Details**
527
+ *
528
+ * This function extracts the query parameters from a `URL` object and returns
529
+ * them as `UrlParams`. The resulting structure can be easily manipulated or
530
+ * inspected.
531
+ *
532
+ * @example
533
+ * ```ts
534
+ * import { Url } from "@effect/platform"
535
+ *
536
+ * const myUrl = new URL("https://example.com?foo=bar")
537
+ *
538
+ * // Read parameters
539
+ * const params = Url.urlParams(myUrl)
540
+ *
541
+ * console.log(params)
542
+ * // Output: [ [ 'foo', 'bar' ] ]
543
+ * ```
544
+ *
545
+ * @since 1.0.0
546
+ * @category Getters
547
+ */
548
+ export const urlParams = (url: URL): UrlParams.UrlParams => UrlParams.fromInput(url.searchParams)
549
+
550
+ /**
551
+ * Reads, modifies, and updates the query parameters of a URL.
552
+ *
553
+ * **Details**
554
+ *
555
+ * This function provides a functional way to interact with query parameters by
556
+ * reading the current parameters, applying a transformation function, and then
557
+ * writing the updated parameters back to the URL. It returns a new `URL` object
558
+ * with the modified parameters, ensuring immutability.
559
+ *
560
+ * @example
561
+ * ```ts
562
+ * import { Url, UrlParams } from "@effect/platform"
563
+ *
564
+ * const myUrl = new URL("https://example.com?foo=bar")
565
+ *
566
+ * const changedUrl = Url.modifyUrlParams(myUrl, UrlParams.append("key", "value"))
567
+ *
568
+ * console.log(changedUrl.toString())
569
+ * // Output: https://example.com/?foo=bar&key=value
570
+ * ```
571
+ *
572
+ * @since 1.0.0
573
+ * @category Modifiers
574
+ */
575
+ export const modifyUrlParams: {
576
+ /**
577
+ * Reads, modifies, and updates the query parameters of a URL.
578
+ *
579
+ * **Details**
580
+ *
581
+ * This function provides a functional way to interact with query parameters by
582
+ * reading the current parameters, applying a transformation function, and then
583
+ * writing the updated parameters back to the URL. It returns a new `URL` object
584
+ * with the modified parameters, ensuring immutability.
585
+ *
586
+ * @example
587
+ * ```ts
588
+ * import { Url, UrlParams } from "@effect/platform"
589
+ *
590
+ * const myUrl = new URL("https://example.com?foo=bar")
591
+ *
592
+ * const changedUrl = Url.modifyUrlParams(myUrl, UrlParams.append("key", "value"))
593
+ *
594
+ * console.log(changedUrl.toString())
595
+ * // Output: https://example.com/?foo=bar&key=value
596
+ * ```
597
+ *
598
+ * @since 1.0.0
599
+ * @category Modifiers
600
+ */
601
+ (f: (urlParams: UrlParams.UrlParams) => UrlParams.UrlParams): (url: URL) => URL
602
+ /**
603
+ * Reads, modifies, and updates the query parameters of a URL.
604
+ *
605
+ * **Details**
606
+ *
607
+ * This function provides a functional way to interact with query parameters by
608
+ * reading the current parameters, applying a transformation function, and then
609
+ * writing the updated parameters back to the URL. It returns a new `URL` object
610
+ * with the modified parameters, ensuring immutability.
611
+ *
612
+ * @example
613
+ * ```ts
614
+ * import { Url, UrlParams } from "@effect/platform"
615
+ *
616
+ * const myUrl = new URL("https://example.com?foo=bar")
617
+ *
618
+ * const changedUrl = Url.modifyUrlParams(myUrl, UrlParams.append("key", "value"))
619
+ *
620
+ * console.log(changedUrl.toString())
621
+ * // Output: https://example.com/?foo=bar&key=value
622
+ * ```
623
+ *
624
+ * @since 1.0.0
625
+ * @category Modifiers
626
+ */
627
+ (url: URL, f: (urlParams: UrlParams.UrlParams) => UrlParams.UrlParams): URL
628
+ } = dual(2, (url: URL, f: (urlParams: UrlParams.UrlParams) => UrlParams.UrlParams) =>
629
+ mutate(url, (url) => {
630
+ const params = f(UrlParams.fromInput(url.searchParams))
631
+ url.search = UrlParams.toString(params)
632
+ }))
package/src/index.ts CHANGED
@@ -249,6 +249,11 @@ export * as Terminal from "./Terminal.js"
249
249
  */
250
250
  export * as Transferable from "./Transferable.js"
251
251
 
252
+ /**
253
+ * @since 1.0.0
254
+ */
255
+ export * as Url from "./Url.js"
256
+
252
257
  /**
253
258
  * @since 1.0.0
254
259
  */