@depthbomb/common 2.0.0 → 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/dist/url.d.cts CHANGED
@@ -1,6 +1,15 @@
1
1
  //#region src/url.d.ts
2
+ /**
3
+ * Values accepted by {@link URLPath} constructors and helpers.
4
+ */
2
5
  type URLLike = string | URL | URLPath;
6
+ /**
7
+ * A single query parameter value (including nested and array values).
8
+ */
3
9
  type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
10
+ /**
11
+ * Query-object shape used by URL query mutation helpers.
12
+ */
4
13
  type QueryObject = Record<string, QueryValue | QueryValue[]>;
5
14
  /**
6
15
  * Tagged-template helper for encoded URL path segments.
@@ -9,44 +18,186 @@ type QueryObject = Record<string, QueryValue | QueryValue[]>;
9
18
  * const path = url`/users/${userId}/posts/${postId}`;
10
19
  */
11
20
  declare function url(strings: TemplateStringsArray, ...values: unknown[]): string;
21
+ /**
22
+ * Immutable URL utility wrapper with convenience path/query operations.
23
+ */
12
24
  declare class URLPath {
13
25
  #private;
26
+ /**
27
+ * Creates a `URLPath` from a URL-like input and optional base URL.
28
+ *
29
+ * @param input URL value to parse.
30
+ * @param base Optional base URL for relative inputs.
31
+ */
14
32
  constructor(input: URLLike, base?: URLLike);
33
+ /**
34
+ * URL protocol including trailing `:`.
35
+ */
15
36
  get protocol(): string;
37
+ /**
38
+ * Host including port when present.
39
+ */
16
40
  get host(): string;
41
+ /**
42
+ * Hostname without port.
43
+ */
17
44
  get hostname(): string;
45
+ /**
46
+ * Port component, or an empty string when absent.
47
+ */
18
48
  get port(): string;
49
+ /**
50
+ * URL origin (`protocol + // + host`).
51
+ */
19
52
  get origin(): string;
53
+ /**
54
+ * Username component.
55
+ */
20
56
  get username(): string;
57
+ /**
58
+ * Password component.
59
+ */
21
60
  get password(): string;
61
+ /**
62
+ * Hash fragment including leading `#` when present.
63
+ */
22
64
  get hash(): string;
65
+ /**
66
+ * Search component including leading `?` when present.
67
+ */
23
68
  get search(): string;
69
+ /**
70
+ * Returns a copy of query parameters.
71
+ */
24
72
  get searchParams(): URLSearchParams;
73
+ /**
74
+ * URL pathname component.
75
+ */
25
76
  get pathname(): string;
77
+ /**
78
+ * Decoded pathname segments without empty parts.
79
+ */
26
80
  get parts(): string[];
81
+ /**
82
+ * Final path segment (decoded).
83
+ */
27
84
  get name(): string;
85
+ /**
86
+ * File suffix from {@link name}, including the leading dot.
87
+ */
28
88
  get suffix(): string;
89
+ /**
90
+ * File name without suffix from {@link name}.
91
+ */
29
92
  get stem(): string;
93
+ /**
94
+ * Parent path with the last path segment removed.
95
+ */
30
96
  get parent(): URLPath;
97
+ /**
98
+ * Appends path segments and returns a new URL.
99
+ *
100
+ * @param segments Segments to append.
101
+ */
31
102
  joinpath(...segments: string[]): URLPath;
103
+ /**
104
+ * Alias of {@link joinpath}.
105
+ *
106
+ * @param segments Segments to append.
107
+ */
32
108
  div(...segments: string[]): URLPath;
109
+ /**
110
+ * Creates a copy with replaced pathname parts.
111
+ *
112
+ * @param parts Decoded path parts.
113
+ */
33
114
  private withPath;
115
+ /**
116
+ * Replaces query parameter values for the provided keys.
117
+ *
118
+ * @param params Query values to set.
119
+ */
34
120
  withQuery(params: QueryObject): URLPath;
121
+ /**
122
+ * Alias of {@link withQuery}.
123
+ *
124
+ * @param params Query values to set.
125
+ */
35
126
  withQueryPatch(params: QueryObject): URLPath;
127
+ /**
128
+ * Appends query parameter values without deleting existing values.
129
+ *
130
+ * @param params Query values to append.
131
+ */
36
132
  appendQuery(params: QueryObject): URLPath;
133
+ /**
134
+ * Removes query keys whose values are entirely empty strings.
135
+ */
37
136
  withoutEmptyQuery(): URLPath;
137
+ /**
138
+ * Removes selected query keys.
139
+ *
140
+ * @param keys Query keys to remove.
141
+ */
38
142
  withoutQuery(...keys: string[]): URLPath;
143
+ /**
144
+ * Sets the hash fragment and returns a new URL.
145
+ *
146
+ * @param hash Hash value with or without leading `#`.
147
+ */
39
148
  withHash(hash: string): URLPath;
149
+ /**
150
+ * Removes the hash fragment.
151
+ */
40
152
  withoutHash(): URLPath;
153
+ /**
154
+ * Calls global `fetch` with this URL as input.
155
+ *
156
+ * @param init Optional fetch options.
157
+ */
41
158
  fetch(init?: RequestInit): Promise<Response>;
159
+ /**
160
+ * Resolves a relative URL against this URL.
161
+ *
162
+ * @param relative Relative URL/path.
163
+ */
42
164
  resolve(relative: string): URLPath;
165
+ /**
166
+ * Compares URLs by normalized string value.
167
+ *
168
+ * @param other URL to compare.
169
+ */
43
170
  equals(other: URLLike): boolean;
171
+ /**
172
+ * Returns a new native `URL` instance.
173
+ */
44
174
  toURL(): URL;
175
+ /**
176
+ * Returns the URL as a string.
177
+ */
45
178
  toString(): string;
179
+ /**
180
+ * Primitive value representation.
181
+ */
46
182
  valueOf(): string;
183
+ /**
184
+ * Primitive coercion hook.
185
+ */
47
186
  [Symbol.toPrimitive](): string;
187
+ /**
188
+ * Creates a `URLPath` from URL-like input.
189
+ *
190
+ * @param input URL value to parse.
191
+ * @param base Optional base URL for relative inputs.
192
+ */
48
193
  static from(input: URLLike, base?: URLLike): URLPath;
194
+ /**
195
+ * Parses an absolute URL string.
196
+ *
197
+ * @param input URL string to parse.
198
+ */
49
199
  static parse(input: string): URLPath;
200
+ private appendQueryValue;
50
201
  }
51
202
  //#endregion
52
203
  export { QueryObject, QueryValue, URLLike, URLPath, url };
package/dist/url.d.mts CHANGED
@@ -1,6 +1,15 @@
1
1
  //#region src/url.d.ts
2
+ /**
3
+ * Values accepted by {@link URLPath} constructors and helpers.
4
+ */
2
5
  type URLLike = string | URL | URLPath;
6
+ /**
7
+ * A single query parameter value (including nested and array values).
8
+ */
3
9
  type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
10
+ /**
11
+ * Query-object shape used by URL query mutation helpers.
12
+ */
4
13
  type QueryObject = Record<string, QueryValue | QueryValue[]>;
5
14
  /**
6
15
  * Tagged-template helper for encoded URL path segments.
@@ -9,44 +18,186 @@ type QueryObject = Record<string, QueryValue | QueryValue[]>;
9
18
  * const path = url`/users/${userId}/posts/${postId}`;
10
19
  */
11
20
  declare function url(strings: TemplateStringsArray, ...values: unknown[]): string;
21
+ /**
22
+ * Immutable URL utility wrapper with convenience path/query operations.
23
+ */
12
24
  declare class URLPath {
13
25
  #private;
26
+ /**
27
+ * Creates a `URLPath` from a URL-like input and optional base URL.
28
+ *
29
+ * @param input URL value to parse.
30
+ * @param base Optional base URL for relative inputs.
31
+ */
14
32
  constructor(input: URLLike, base?: URLLike);
33
+ /**
34
+ * URL protocol including trailing `:`.
35
+ */
15
36
  get protocol(): string;
37
+ /**
38
+ * Host including port when present.
39
+ */
16
40
  get host(): string;
41
+ /**
42
+ * Hostname without port.
43
+ */
17
44
  get hostname(): string;
45
+ /**
46
+ * Port component, or an empty string when absent.
47
+ */
18
48
  get port(): string;
49
+ /**
50
+ * URL origin (`protocol + // + host`).
51
+ */
19
52
  get origin(): string;
53
+ /**
54
+ * Username component.
55
+ */
20
56
  get username(): string;
57
+ /**
58
+ * Password component.
59
+ */
21
60
  get password(): string;
61
+ /**
62
+ * Hash fragment including leading `#` when present.
63
+ */
22
64
  get hash(): string;
65
+ /**
66
+ * Search component including leading `?` when present.
67
+ */
23
68
  get search(): string;
69
+ /**
70
+ * Returns a copy of query parameters.
71
+ */
24
72
  get searchParams(): URLSearchParams;
73
+ /**
74
+ * URL pathname component.
75
+ */
25
76
  get pathname(): string;
77
+ /**
78
+ * Decoded pathname segments without empty parts.
79
+ */
26
80
  get parts(): string[];
81
+ /**
82
+ * Final path segment (decoded).
83
+ */
27
84
  get name(): string;
85
+ /**
86
+ * File suffix from {@link name}, including the leading dot.
87
+ */
28
88
  get suffix(): string;
89
+ /**
90
+ * File name without suffix from {@link name}.
91
+ */
29
92
  get stem(): string;
93
+ /**
94
+ * Parent path with the last path segment removed.
95
+ */
30
96
  get parent(): URLPath;
97
+ /**
98
+ * Appends path segments and returns a new URL.
99
+ *
100
+ * @param segments Segments to append.
101
+ */
31
102
  joinpath(...segments: string[]): URLPath;
103
+ /**
104
+ * Alias of {@link joinpath}.
105
+ *
106
+ * @param segments Segments to append.
107
+ */
32
108
  div(...segments: string[]): URLPath;
109
+ /**
110
+ * Creates a copy with replaced pathname parts.
111
+ *
112
+ * @param parts Decoded path parts.
113
+ */
33
114
  private withPath;
115
+ /**
116
+ * Replaces query parameter values for the provided keys.
117
+ *
118
+ * @param params Query values to set.
119
+ */
34
120
  withQuery(params: QueryObject): URLPath;
121
+ /**
122
+ * Alias of {@link withQuery}.
123
+ *
124
+ * @param params Query values to set.
125
+ */
35
126
  withQueryPatch(params: QueryObject): URLPath;
127
+ /**
128
+ * Appends query parameter values without deleting existing values.
129
+ *
130
+ * @param params Query values to append.
131
+ */
36
132
  appendQuery(params: QueryObject): URLPath;
133
+ /**
134
+ * Removes query keys whose values are entirely empty strings.
135
+ */
37
136
  withoutEmptyQuery(): URLPath;
137
+ /**
138
+ * Removes selected query keys.
139
+ *
140
+ * @param keys Query keys to remove.
141
+ */
38
142
  withoutQuery(...keys: string[]): URLPath;
143
+ /**
144
+ * Sets the hash fragment and returns a new URL.
145
+ *
146
+ * @param hash Hash value with or without leading `#`.
147
+ */
39
148
  withHash(hash: string): URLPath;
149
+ /**
150
+ * Removes the hash fragment.
151
+ */
40
152
  withoutHash(): URLPath;
153
+ /**
154
+ * Calls global `fetch` with this URL as input.
155
+ *
156
+ * @param init Optional fetch options.
157
+ */
41
158
  fetch(init?: RequestInit): Promise<Response>;
159
+ /**
160
+ * Resolves a relative URL against this URL.
161
+ *
162
+ * @param relative Relative URL/path.
163
+ */
42
164
  resolve(relative: string): URLPath;
165
+ /**
166
+ * Compares URLs by normalized string value.
167
+ *
168
+ * @param other URL to compare.
169
+ */
43
170
  equals(other: URLLike): boolean;
171
+ /**
172
+ * Returns a new native `URL` instance.
173
+ */
44
174
  toURL(): URL;
175
+ /**
176
+ * Returns the URL as a string.
177
+ */
45
178
  toString(): string;
179
+ /**
180
+ * Primitive value representation.
181
+ */
46
182
  valueOf(): string;
183
+ /**
184
+ * Primitive coercion hook.
185
+ */
47
186
  [Symbol.toPrimitive](): string;
187
+ /**
188
+ * Creates a `URLPath` from URL-like input.
189
+ *
190
+ * @param input URL value to parse.
191
+ * @param base Optional base URL for relative inputs.
192
+ */
48
193
  static from(input: URLLike, base?: URLLike): URLPath;
194
+ /**
195
+ * Parses an absolute URL string.
196
+ *
197
+ * @param input URL string to parse.
198
+ */
49
199
  static parse(input: string): URLPath;
200
+ private appendQueryValue;
50
201
  }
51
202
  //#endregion
52
203
  export { QueryObject, QueryValue, URLLike, URLPath, url };
package/dist/url.mjs CHANGED
@@ -1 +1 @@
1
- function e(e,...t){let n=``;for(let r=0;r<e.length;r++)n+=e[r],r<t.length&&(n+=encodeURIComponent(String(t[r])));return n}function t(e,n,r){if(r!=null){if(Array.isArray(r)){for(let i of r)t(e,n,i);return}if(typeof r==`object`){try{e.append(n,JSON.stringify(r))}catch{e.append(n,String(r))}return}e.append(n,String(r))}}var n=class e{#e;constructor(t,n){t instanceof e||t instanceof URL?this.#e=new URL(t.toString()):n?this.#e=new URL(t,n.toString()):this.#e=new URL(t)}get protocol(){return this.#e.protocol}get host(){return this.#e.host}get hostname(){return this.#e.hostname}get port(){return this.#e.port}get origin(){return this.#e.origin}get username(){return this.#e.username}get password(){return this.#e.password}get hash(){return this.#e.hash}get search(){return this.#e.search}get searchParams(){return new URLSearchParams(this.#e.search)}get pathname(){return this.#e.pathname}get parts(){return this.#e.pathname.split(`/`).filter(Boolean).map(decodeURIComponent)}get name(){return this.parts.at(-1)??``}get suffix(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(t):``}get stem(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(0,t):e}get parent(){let e=this.parts.slice(0,-1);return this.withPath(e)}joinpath(...e){let t=[...this.parts,...e.map(e=>e.replace(/^\/+|\/+$/g,``))];return this.withPath(t)}div(...e){return this.joinpath(...e)}withPath(t){let n=new URL(this.#e.toString());return n.pathname=`/`+t.map(encodeURIComponent).join(`/`),new e(n)}withQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))r.searchParams.delete(e),t(r.searchParams,e,i);return new e(r)}withQueryPatch(e){return this.withQuery(e)}appendQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))t(r.searchParams,e,i);return new e(r)}withoutEmptyQuery(){let t=new URL(this.#e.toString()),n=new Set;for(let e of t.searchParams.keys())n.has(e)||(n.add(e),t.searchParams.getAll(e).every(e=>e===``)&&t.searchParams.delete(e));return new e(t)}withoutQuery(...t){let n=new URL(this.#e.toString());for(let e of t)n.searchParams.delete(e);return new e(n)}withHash(t){let n=new URL(this.#e.toString());return n.hash=t.startsWith(`#`)?t:`#${t}`,new e(n)}withoutHash(){let t=new URL(this.#e.toString());return t.hash=``,new e(t)}async fetch(e){return fetch(this.#e,e)}resolve(t){return new e(t,this)}equals(t){return this.toString()===new e(t).toString()}toURL(){return new URL(this.#e.toString())}toString(){return this.#e.toString()}valueOf(){return this.toString()}[Symbol.toPrimitive](){return this.toString()}static from(t,n){return new e(t,n)}static parse(t){return new e(t)}};export{n as URLPath,e as url};
1
+ function e(e,...t){let n=``;for(let r=0;r<e.length;r++)n+=e[r],r<t.length&&(n+=encodeURIComponent(String(t[r])));return n}var t=class e{#e;constructor(t,n){t instanceof e||t instanceof URL?this.#e=new URL(t.toString()):n?this.#e=new URL(t,n.toString()):this.#e=new URL(t)}get protocol(){return this.#e.protocol}get host(){return this.#e.host}get hostname(){return this.#e.hostname}get port(){return this.#e.port}get origin(){return this.#e.origin}get username(){return this.#e.username}get password(){return this.#e.password}get hash(){return this.#e.hash}get search(){return this.#e.search}get searchParams(){return new URLSearchParams(this.#e.search)}get pathname(){return this.#e.pathname}get parts(){return this.#e.pathname.split(`/`).filter(Boolean).map(decodeURIComponent)}get name(){return this.parts.at(-1)??``}get suffix(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(t):``}get stem(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(0,t):e}get parent(){let e=this.parts.slice(0,-1);return this.withPath(e)}joinpath(...e){let t=[...this.parts,...e.map(e=>e.replace(/^\/+|\/+$/g,``))];return this.withPath(t)}div(...e){return this.joinpath(...e)}withPath(t){let n=new URL(this.#e.toString());return n.pathname=`/`+t.map(encodeURIComponent).join(`/`),new e(n)}withQuery(t){let n=new URL(this.#e.toString());for(let[e,r]of Object.entries(t))n.searchParams.delete(e),this.appendQueryValue(n.searchParams,e,r);return new e(n)}withQueryPatch(e){return this.withQuery(e)}appendQuery(t){let n=new URL(this.#e.toString());for(let[e,r]of Object.entries(t))this.appendQueryValue(n.searchParams,e,r);return new e(n)}withoutEmptyQuery(){let t=new URL(this.#e.toString()),n=new Set;for(let e of t.searchParams.keys())n.has(e)||(n.add(e),t.searchParams.getAll(e).every(e=>e===``)&&t.searchParams.delete(e));return new e(t)}withoutQuery(...t){let n=new URL(this.#e.toString());for(let e of t)n.searchParams.delete(e);return new e(n)}withHash(t){let n=new URL(this.#e.toString());return n.hash=t.startsWith(`#`)?t:`#${t}`,new e(n)}withoutHash(){let t=new URL(this.#e.toString());return t.hash=``,new e(t)}async fetch(e){return fetch(this.#e,e)}resolve(t){return new e(t,this)}equals(t){return this.toString()===new e(t).toString()}toURL(){return new URL(this.#e.toString())}toString(){return this.#e.toString()}valueOf(){return this.toString()}[Symbol.toPrimitive](){return this.toString()}static from(t,n){return new e(t,n)}static parse(t){return new e(t)}appendQueryValue(e,t,n){if(n!=null){if(Array.isArray(n)){for(let r of n)this.appendQueryValue(e,t,r);return}if(typeof n==`object`){try{e.append(t,JSON.stringify(n))}catch{e.append(t,String(n))}return}e.append(t,String(n))}}};export{t as URLPath,e as url};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depthbomb/common",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "A set of common utilities for TypeScript/JavaScript",
5
5
  "license": "MIT",
6
6
  "engines": {