@stryke/http 0.5.3 → 0.7.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/cookie.cjs CHANGED
@@ -9,7 +9,7 @@ exports.serializeCookie = serializeCookie;
9
9
  exports.splitSetCookieString = splitSetCookieString;
10
10
  var _typeChecks = require("@stryke/type-checks");
11
11
  function parseCookie(r, c) {
12
- if (!(0, _typeChecks.isString)(r)) throw new TypeError("argument str must be a string");
12
+ if (!(0, _typeChecks.isString)(r)) throw new Error("argument str must be a string");
13
13
  const i = {},
14
14
  e = c ?? {},
15
15
  o = e.decode ?? (t => t.includes("%") ? decodeURIComponent(t) : t);
@@ -94,10 +94,10 @@ const u = /^[\t\u0020-\u007E\u0080-\u00FF]+$/;
94
94
  function serializeCookie(r, c, i) {
95
95
  const e = i ?? {},
96
96
  o = e.encode ?? encodeURIComponent;
97
- if (!(0, _typeChecks.isFunction)(o)) throw new TypeError("option encode is invalid");
98
- if (!u.test(r)) throw new TypeError("argument name is invalid");
97
+ if (!(0, _typeChecks.isFunction)(o)) throw new Error("option encode is invalid");
98
+ if (!u.test(r)) throw new Error("argument name is invalid");
99
99
  const a = o(c);
100
- if (a && !u.test(a)) throw new TypeError("argument val is invalid");
100
+ if (a && !u.test(a)) throw new Error("argument val is invalid");
101
101
  let t = `${r}=${a}`;
102
102
  if (!(0, _typeChecks.isSet)(e.maxAge)) {
103
103
  const n = Number(e.maxAge);
@@ -105,15 +105,15 @@ function serializeCookie(r, c, i) {
105
105
  t += `; Max-Age=${Math.floor(n)}`;
106
106
  }
107
107
  if (e.domain) {
108
- if (!u.test(e.domain)) throw new TypeError("option domain is invalid");
108
+ if (!u.test(e.domain)) throw new Error("option domain is invalid");
109
109
  t += `; Domain=${e.domain}`;
110
110
  }
111
111
  if (e.path) {
112
- if (!u.test(e.path)) throw new TypeError("option path is invalid");
112
+ if (!u.test(e.path)) throw new Error("option path is invalid");
113
113
  t += `; Path=${e.path}`;
114
114
  }
115
115
  if (e.expires) {
116
- if (!(0, _typeChecks.isDate)(e.expires) || Number.isNaN(e.expires.valueOf())) throw new TypeError("option expires is invalid");
116
+ if (!(0, _typeChecks.isDate)(e.expires) || Number.isNaN(e.expires.valueOf())) throw new Error("option expires is invalid");
117
117
  t += `; Expires=${e.expires.toUTCString()}`;
118
118
  }
119
119
  if (e.httpOnly && (t += "; HttpOnly"), e.secure && (t += "; Secure"), e.priority) switch ((0, _typeChecks.isString)(e.priority) ? e.priority.toLowerCase() : e.priority) {
@@ -133,7 +133,7 @@ function serializeCookie(r, c, i) {
133
133
  break;
134
134
  }
135
135
  default:
136
- throw new TypeError("option priority is invalid");
136
+ throw new Error("option priority is invalid");
137
137
  }
138
138
  if (e.sameSite) switch ((0, _typeChecks.isString)(e.sameSite) ? e.sameSite.toLowerCase() : e.sameSite) {
139
139
  case !0:
@@ -157,7 +157,7 @@ function serializeCookie(r, c, i) {
157
157
  break;
158
158
  }
159
159
  default:
160
- throw new TypeError("option sameSite is invalid");
160
+ throw new Error("option sameSite is invalid");
161
161
  }
162
162
  return e.partitioned && (t += "; Partitioned"), t;
163
163
  }
package/dist/cookie.d.ts CHANGED
@@ -23,8 +23,6 @@ export declare function parseSetCookie(setCookieValue: string, options?: SetCook
23
23
  * @param value - value to set the cookie to
24
24
  * @param options - object containing serialization options
25
25
  * @returns a `Set-Cookie` header string
26
- *
27
- * @throws TypeError when `maxAge` options is invalid
28
26
  */
29
27
  export declare function serializeCookie(name: string, value: string, options?: CookieSerializeOptions): string;
30
28
  /**
package/dist/cookie.mjs CHANGED
@@ -1 +1 @@
1
- import{isDate as h,isFunction as d,isSet as g,isString as p}from"@stryke/type-checks";export function parseCookie(r,c){if(!p(r))throw new TypeError("argument str must be a string");const i={},e=c??{},o=e.decode??(t=>t.includes("%")?decodeURIComponent(t):t);let a=0;for(;a<r.length;){const t=r.indexOf("=",a);if(t===-1)break;let n=r.indexOf(";",a);if(n===-1)n=r.length;else if(n<t){a=r.lastIndexOf(";",t-1)+1;continue}const s=r.slice(a,t).trim();if(e?.filter&&!e?.filter(s)){a=n+1;continue}if(i[s]===void 0){let l=r.slice(t+1,n).trim();l.codePointAt(0)===34&&(l=l.slice(1,-1));try{i[s]=o(l)}catch{i[s]=l}}a=n+1}return i}export function parseSetCookie(r,c){const i=(r||"").split(";").filter(s=>p(s)&&!!s.trim()),e=i.shift()||"";let o="",a="";const t=e.split("=");t.length>1?(o=t.shift(),a=t.join("=")):a=e;try{a=c?.decode===!1?a:(c?.decode??decodeURIComponent)(a)}catch{}const n={name:o,value:a};for(const s of i){const l=s.split("="),f=(l.shift()||"").trimStart().toLowerCase(),m=l.join("=");switch(f){case"expires":{n.expires=new Date(m);break}case"max-age":{n.maxAge=Number.parseInt(m,10);break}case"secure":{n.secure=!0;break}case"httponly":{n.httpOnly=!0;break}case"samesite":{n.sameSite=m;break}default:n[f]=m}}return n}const u=/^[\t\u0020-\u007E\u0080-\u00FF]+$/;export function serializeCookie(r,c,i){const e=i??{},o=e.encode??encodeURIComponent;if(!d(o))throw new TypeError("option encode is invalid");if(!u.test(r))throw new TypeError("argument name is invalid");const a=o(c);if(a&&!u.test(a))throw new TypeError("argument val is invalid");let t=`${r}=${a}`;if(!g(e.maxAge)){const n=Number(e.maxAge);if(Number.isNaN(n)||!Number.isFinite(n))throw new TypeError("option maxAge is invalid");t+=`; Max-Age=${Math.floor(n)}`}if(e.domain){if(!u.test(e.domain))throw new TypeError("option domain is invalid");t+=`; Domain=${e.domain}`}if(e.path){if(!u.test(e.path))throw new TypeError("option path is invalid");t+=`; Path=${e.path}`}if(e.expires){if(!h(e.expires)||Number.isNaN(e.expires.valueOf()))throw new TypeError("option expires is invalid");t+=`; Expires=${e.expires.toUTCString()}`}if(e.httpOnly&&(t+="; HttpOnly"),e.secure&&(t+="; Secure"),e.priority)switch(p(e.priority)?e.priority.toLowerCase():e.priority){case"low":{t+="; Priority=Low";break}case"medium":{t+="; Priority=Medium";break}case"high":{t+="; Priority=High";break}default:throw new TypeError("option priority is invalid")}if(e.sameSite)switch(p(e.sameSite)?e.sameSite.toLowerCase():e.sameSite){case!0:{t+="; SameSite=Strict";break}case"lax":{t+="; SameSite=Lax";break}case"strict":{t+="; SameSite=Strict";break}case"none":{t+="; SameSite=None";break}default:throw new TypeError("option sameSite is invalid")}return e.partitioned&&(t+="; Partitioned"),t}export function splitSetCookieString(r){if(Array.isArray(r))return r.flatMap(f=>splitSetCookieString(f));if(!p(r))return[];const c=[];let i=0,e,o,a,t,n;const s=()=>{for(;i<r.length&&/\s/.test(r.charAt(i));)i+=1;return i<r.length},l=()=>(o=r.charAt(i),o!=="="&&o!==";"&&o!==",");for(;i<r.length;){for(e=i,n=!1;s();)if(o=r.charAt(i),o===","){for(a=i,i+=1,s(),t=i;i<r.length&&l();)i+=1;i<r.length&&r.charAt(i)==="="?(n=!0,i=t,c.push(r.slice(e,a)),e=i):i=a+1}else i+=1;(!n||i>=r.length)&&c.push(r.slice(e))}return c}
1
+ import{isDate as h,isFunction as d,isSet as g,isString as p}from"@stryke/type-checks";export function parseCookie(r,c){if(!p(r))throw new Error("argument str must be a string");const i={},e=c??{},o=e.decode??(t=>t.includes("%")?decodeURIComponent(t):t);let a=0;for(;a<r.length;){const t=r.indexOf("=",a);if(t===-1)break;let n=r.indexOf(";",a);if(n===-1)n=r.length;else if(n<t){a=r.lastIndexOf(";",t-1)+1;continue}const s=r.slice(a,t).trim();if(e?.filter&&!e?.filter(s)){a=n+1;continue}if(i[s]===void 0){let l=r.slice(t+1,n).trim();l.codePointAt(0)===34&&(l=l.slice(1,-1));try{i[s]=o(l)}catch{i[s]=l}}a=n+1}return i}export function parseSetCookie(r,c){const i=(r||"").split(";").filter(s=>p(s)&&!!s.trim()),e=i.shift()||"";let o="",a="";const t=e.split("=");t.length>1?(o=t.shift(),a=t.join("=")):a=e;try{a=c?.decode===!1?a:(c?.decode??decodeURIComponent)(a)}catch{}const n={name:o,value:a};for(const s of i){const l=s.split("="),f=(l.shift()||"").trimStart().toLowerCase(),m=l.join("=");switch(f){case"expires":{n.expires=new Date(m);break}case"max-age":{n.maxAge=Number.parseInt(m,10);break}case"secure":{n.secure=!0;break}case"httponly":{n.httpOnly=!0;break}case"samesite":{n.sameSite=m;break}default:n[f]=m}}return n}const u=/^[\t\u0020-\u007E\u0080-\u00FF]+$/;export function serializeCookie(r,c,i){const e=i??{},o=e.encode??encodeURIComponent;if(!d(o))throw new Error("option encode is invalid");if(!u.test(r))throw new Error("argument name is invalid");const a=o(c);if(a&&!u.test(a))throw new Error("argument val is invalid");let t=`${r}=${a}`;if(!g(e.maxAge)){const n=Number(e.maxAge);if(Number.isNaN(n)||!Number.isFinite(n))throw new TypeError("option maxAge is invalid");t+=`; Max-Age=${Math.floor(n)}`}if(e.domain){if(!u.test(e.domain))throw new Error("option domain is invalid");t+=`; Domain=${e.domain}`}if(e.path){if(!u.test(e.path))throw new Error("option path is invalid");t+=`; Path=${e.path}`}if(e.expires){if(!h(e.expires)||Number.isNaN(e.expires.valueOf()))throw new Error("option expires is invalid");t+=`; Expires=${e.expires.toUTCString()}`}if(e.httpOnly&&(t+="; HttpOnly"),e.secure&&(t+="; Secure"),e.priority)switch(p(e.priority)?e.priority.toLowerCase():e.priority){case"low":{t+="; Priority=Low";break}case"medium":{t+="; Priority=Medium";break}case"high":{t+="; Priority=High";break}default:throw new Error("option priority is invalid")}if(e.sameSite)switch(p(e.sameSite)?e.sameSite.toLowerCase():e.sameSite){case!0:{t+="; SameSite=Strict";break}case"lax":{t+="; SameSite=Lax";break}case"strict":{t+="; SameSite=Strict";break}case"none":{t+="; SameSite=None";break}default:throw new Error("option sameSite is invalid")}return e.partitioned&&(t+="; Partitioned"),t}export function splitSetCookieString(r){if(Array.isArray(r))return r.flatMap(f=>splitSetCookieString(f));if(!p(r))return[];const c=[];let i=0,e,o,a,t,n;const s=()=>{for(;i<r.length&&/\s/.test(r.charAt(i));)i+=1;return i<r.length},l=()=>(o=r.charAt(i),o!=="="&&o!==";"&&o!==",");for(;i<r.length;){for(e=i,n=!1;s();)if(o=r.charAt(i),o===","){for(a=i,i+=1,s(),t=i;i<r.length&&l();)i+=1;i<r.length&&r.charAt(i)==="="?(n=!0,i=t,c.push(r.slice(e,a)),e=i):i=a+1}else i+=1;(!n||i>=r.length)&&c.push(r.slice(e))}return c}
package/dist/index.cjs CHANGED
@@ -36,14 +36,14 @@ Object.keys(_types).forEach(function (key) {
36
36
  }
37
37
  });
38
38
  });
39
- var _urlBuilder = require("./url-builder.cjs");
40
- Object.keys(_urlBuilder).forEach(function (key) {
39
+ var _url = require("./url.cjs");
40
+ Object.keys(_url).forEach(function (key) {
41
41
  if (key === "default" || key === "__esModule") return;
42
- if (key in exports && exports[key] === _urlBuilder[key]) return;
42
+ if (key in exports && exports[key] === _url[key]) return;
43
43
  Object.defineProperty(exports, key, {
44
44
  enumerable: true,
45
45
  get: function () {
46
- return _urlBuilder[key];
46
+ return _url[key];
47
47
  }
48
48
  });
49
49
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from "./cookie";
2
2
  export * from "./format-data-uri";
3
3
  export * from "./types";
4
- export * from "./url-builder";
4
+ export * from "./url";
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export*from"./cookie";export*from"./format-data-uri";export*from"./types";export*from"./url-builder";
1
+ export*from"./cookie";export*from"./format-data-uri";export*from"./types";export*from"./url";
package/dist/types.cjs CHANGED
@@ -1 +1,7 @@
1
- "use strict";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PROTOCOL_RELATIVE_SYMBOL = void 0;
7
+ const PROTOCOL_RELATIVE_SYMBOL = exports.PROTOCOL_RELATIVE_SYMBOL = Symbol("protocol-relative");
package/dist/types.d.ts CHANGED
@@ -1,13 +1,93 @@
1
- import type { ParsedURL } from "ufo";
2
- export type StormURL = ParsedURL & {
3
- __typename: "StormURL";
4
- queryParams: Record<string, any>;
5
- paths: string[];
1
+ export interface StormURLBuilderOptions {
2
+ /**
3
+ * Should the URL be decoded
4
+ *
5
+ * @defaultValue `true`
6
+ */
7
+ decode?: boolean;
8
+ /**
9
+ * Should the URL include a locale path segment
10
+ */
11
+ locale?: string | true;
12
+ /**
13
+ * The default protocol to use
14
+ *
15
+ * @defaultValue "https"
16
+ */
17
+ defaultProtocol?: string;
18
+ }
19
+ export declare const PROTOCOL_RELATIVE_SYMBOL: unique symbol;
20
+ export interface IStormURL {
21
+ /**
22
+ * A string containing the username and password specified before the domain name.
23
+ */
24
+ auth: string;
25
+ /**
26
+ * A string containing the username specified before the domain name.
27
+ */
6
28
  username?: string;
29
+ /**
30
+ * A string containing the password specified before the domain name.
31
+ */
7
32
  password?: string;
33
+ /**
34
+ * A string containing the domain (that is the hostname) followed by (if a port was specified) a `:` and the port of the URL.
35
+ */
36
+ host: string;
37
+ /**
38
+ * A string containing the domain of the URL.
39
+ */
8
40
  hostname?: string;
41
+ /**
42
+ * A string containing the port number of the URL.
43
+ */
9
44
  port?: string;
10
- };
45
+ /**
46
+ * A string containing the protocol scheme of the URL, including the final `:`.
47
+ */
48
+ protocol?: string;
49
+ /**
50
+ * A stringified value that returns the whole URL.
51
+ */
52
+ href: string;
53
+ /**
54
+ * A string containing an initial `/` followed by the path of the URL, not including the query string or fragment.
55
+ */
56
+ pathname: string;
57
+ /**
58
+ * The paths of the URL
59
+ */
60
+ paths: any[];
61
+ /**
62
+ * A string containing a `#` followed by the fragment identifier of the URL.
63
+ */
64
+ hash: string;
65
+ /**
66
+ * A string indicating the URL's parameter string; if any parameters are provided, this string includes all of them, beginning with the leading `?` character.
67
+ */
68
+ search: string;
69
+ /**
70
+ * The search parameters of the URL
71
+ *
72
+ * @remarks
73
+ * This is a `URLSearchParams` object that contains the search parameters of the URL.
74
+ */
75
+ searchParams: URLSearchParams;
76
+ /**
77
+ * The search parameters of the URL
78
+ *
79
+ * @remarks
80
+ * This is a Record\<string, any\> object that contains the search parameters of the URL.
81
+ */
82
+ params: Record<string, any>;
83
+ /**
84
+ * An optional symbol to indicate that the URL is protocol-relative
85
+ *
86
+ * @remarks
87
+ * This is used when the URL is protocol-relative (e.g. //example.com)
88
+ */
89
+ [PROTOCOL_RELATIVE_SYMBOL]?: boolean;
90
+ }
11
91
  /**
12
92
  * Additional serialization options
13
93
  */
package/dist/types.mjs CHANGED
@@ -0,0 +1 @@
1
+ export const PROTOCOL_RELATIVE_SYMBOL=Symbol("protocol-relative");
package/dist/url.cjs ADDED
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StormURL = void 0;
7
+ var _stormJson = require("@stryke/json/storm-json");
8
+ var _joinPaths = require("@stryke/path/join-paths");
9
+ var _isInteger = require("@stryke/type-checks/is-integer");
10
+ var _isUndefined = require("@stryke/type-checks/is-undefined");
11
+ var _ufo = require("ufo");
12
+ class StormURL {
13
+ #h;
14
+ #i;
15
+ #r;
16
+ #t;
17
+ #s;
18
+ #a;
19
+ #o = [];
20
+ #e;
21
+ #n;
22
+ constructor(t, s = {
23
+ decode: !0
24
+ }) {
25
+ this.#h = s;
26
+ const i = (0, _ufo.parseURL)(this.#h.decode ? (0, _ufo.decode)(t) : t),
27
+ h = (0, _ufo.parseAuth)(i.auth);
28
+ this.#i = h.username, this.#r = h.password;
29
+ const a = (0, _ufo.parseHost)(i.host);
30
+ this.#t = a.hostname, this.#s = a.port, this.#a = i.protocol, this.#e = i.hash || "", this.#n = (0, _ufo.parseQuery)(i.search), this.#o = i.pathname ? i.pathname.split("/").filter(Boolean) : [];
31
+ }
32
+ set params(t) {
33
+ this.#n = t;
34
+ }
35
+ get params() {
36
+ return this.#n;
37
+ }
38
+ get searchParams() {
39
+ const t = new URLSearchParams();
40
+ for (const [s, i] of Object.entries(this.params)) t.append(s, i);
41
+ return t;
42
+ }
43
+ set searchParams(t) {
44
+ this.params = Object.fromEntries(t.entries());
45
+ }
46
+ set search(t) {
47
+ this.params = (0, _ufo.parseQuery)(t);
48
+ }
49
+ get search() {
50
+ const t = (0, _ufo.stringifyQuery)(this.params);
51
+ return t ? t.startsWith("?") ? t : `?${t}` : "";
52
+ }
53
+ set hash(t) {
54
+ this.#e = t.startsWith("#") ? t : `#${t}`;
55
+ }
56
+ get hash() {
57
+ return this.#e;
58
+ }
59
+ set port(t) {
60
+ this.#s = !(0, _isUndefined.isUndefined)(t) && (0, _isInteger.isInteger)(t) ? `${t}` : void 0;
61
+ }
62
+ get port() {
63
+ return this.#s;
64
+ }
65
+ set auth(t) {
66
+ const s = (0, _ufo.parseAuth)(t);
67
+ this.#i = s.username, this.#r = s.password;
68
+ }
69
+ get auth() {
70
+ return this.#i && this.#r ? `${this.#i}:${this.#r}` : this.#i ? this.#i : this.#r ? this.#r : "";
71
+ }
72
+ set protocol(t) {
73
+ this.#a = t.endsWith(":") ? t : t.endsWith("://") ? t.slice(0, -2) : `${t}:`;
74
+ }
75
+ get protocol() {
76
+ return this.#a || this.#h.defaultProtocol || "https:";
77
+ }
78
+ set hostname(t) {
79
+ this.#t = t;
80
+ }
81
+ get hostname() {
82
+ return this.#t;
83
+ }
84
+ set host(t) {
85
+ const s = (0, _ufo.parseHost)(t);
86
+ this.#t = s.hostname, this.#s = s.port;
87
+ }
88
+ get host() {
89
+ return this.#t && this.#s ? `${this.#t}:${this.#s}` : this.#t ? this.#t : this.#s ? this.#s : "";
90
+ }
91
+ set paths(t) {
92
+ this.#o = t.filter(Boolean);
93
+ }
94
+ get paths() {
95
+ return this.#o;
96
+ }
97
+ set pathname(t) {
98
+ this.paths = (0, _ufo.cleanDoubleSlashes)(t).split("/");
99
+ }
100
+ get pathname() {
101
+ return `/${this.paths ? (0, _joinPaths.joinPaths)(...this.paths.map(t => _stormJson.StormJSON.stringify(t))) : ""}`;
102
+ }
103
+ set path(t) {
104
+ const s = (0, _ufo.parsePath)(t);
105
+ this.pathname = s.pathname, this.search = s.search, this.#e = s.hash;
106
+ }
107
+ get path() {
108
+ return (0, _ufo.stringifyParsedURL)({
109
+ pathname: this.pathname,
110
+ search: this.search,
111
+ hash: this.hash
112
+ });
113
+ }
114
+ get href() {
115
+ return this.toString();
116
+ }
117
+ set href(t) {
118
+ const s = (0, _ufo.parseURL)(t);
119
+ this.protocol = s.protocol || this.protocol, this.auth = s.auth || this.auth, this.host = s.host || this.host, this.pathname = s.pathname || this.pathname, this.search = s.search || this.search, this.hash = s.hash || this.hash;
120
+ }
121
+ get origin() {
122
+ return `${this.protocol}//${this.host}`;
123
+ }
124
+ get isScriptProtocol() {
125
+ return (0, _ufo.isScriptProtocol)(this.protocol);
126
+ }
127
+ get isRelative() {
128
+ return (0, _ufo.isRelative)(this.toString());
129
+ }
130
+ get isNonEmptyURL() {
131
+ return (0, _ufo.isNonEmptyURL)(this.toString());
132
+ }
133
+ get __typename() {
134
+ return "StormURL";
135
+ }
136
+ isSamePath(t) {
137
+ return (0, _ufo.isSamePath)(this.path, t);
138
+ }
139
+ isEqual(t) {
140
+ return (0, _ufo.isEqual)(this.toString(), typeof t == "string" ? t : t instanceof StormURL ? t.toString() : (0, _ufo.stringifyParsedURL)(t));
141
+ }
142
+ toParsed() {
143
+ return {
144
+ protocol: this.protocol,
145
+ auth: this.auth,
146
+ host: this.host,
147
+ pathname: this.pathname,
148
+ search: this.search,
149
+ hash: this.hash
150
+ };
151
+ }
152
+ toString() {
153
+ return (0, _ufo.stringifyParsedURL)(this.toParsed());
154
+ }
155
+ toEncoded() {
156
+ return (0, _ufo.normalizeURL)(this.toString());
157
+ }
158
+ }
159
+ exports.StormURL = StormURL;
160
+ _stormJson.StormJSON.instance.registerCustom({
161
+ isApplicable: r => r.__typename === "StormURL",
162
+ serialize: r => r.toEncoded(),
163
+ deserialize: r => new StormURL(r, {
164
+ decode: !0
165
+ })
166
+ }, "StormURL");
package/dist/url.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import type { ParsedURL } from "ufo";
2
+ import type { IStormURL, StormURLBuilderOptions } from "./types";
3
+ /**
4
+ * A class used to build URLs
5
+ *
6
+ * @remarks
7
+ * This class is used to build URLs with a fluent API.
8
+ *
9
+ * The [UFO](https://github.com/unjs/ufo) library is used under the hood to parse and stringify URLs.
10
+ */
11
+ export declare class StormURL implements IStormURL, Partial<URL> {
12
+ #private;
13
+ constructor(initialURL: string, options?: StormURLBuilderOptions);
14
+ set params(value: Record<string, any>);
15
+ get params(): Record<string, any>;
16
+ get searchParams(): URLSearchParams;
17
+ set searchParams(value: URLSearchParams);
18
+ set search(value: string);
19
+ get search(): string;
20
+ set hash(value: string);
21
+ get hash(): string;
22
+ set port(value: string | number | undefined);
23
+ get port(): string | undefined;
24
+ set auth(value: string | undefined);
25
+ get auth(): string;
26
+ set protocol(value: string);
27
+ get protocol(): string;
28
+ set hostname(value: string);
29
+ get hostname(): string;
30
+ set host(value: string | undefined);
31
+ get host(): string;
32
+ set paths(value: any[]);
33
+ get paths(): any[];
34
+ set pathname(value: string);
35
+ get pathname(): string;
36
+ set path(value: string);
37
+ get path(): string;
38
+ get href(): string;
39
+ set href(value: string);
40
+ get origin(): string;
41
+ get isScriptProtocol(): boolean;
42
+ get isRelative(): boolean;
43
+ get isNonEmptyURL(): boolean;
44
+ get __typename(): string;
45
+ isSamePath(path: string): boolean;
46
+ isEqual(url: string | ParsedURL | StormURL): boolean;
47
+ toParsed(): ParsedURL;
48
+ toString(): string;
49
+ toEncoded(): string;
50
+ }
package/dist/url.mjs ADDED
@@ -0,0 +1 @@
1
+ import{StormJSON as o}from"@stryke/json/storm-json";import{joinPaths as m}from"@stryke/path/join-paths";import{isInteger as g}from"@stryke/type-checks/is-integer";import{isUndefined as l}from"@stryke/type-checks/is-undefined";import{cleanDoubleSlashes as d,decode as b,isEqual as R,isNonEmptyURL as S,isRelative as f,isSamePath as U,isScriptProtocol as L,normalizeURL as P,parseAuth as n,parseHost as p,parsePath as y,parseQuery as c,parseURL as u,stringifyParsedURL as e,stringifyQuery as $}from"ufo";export class StormURL{#h;#i;#r;#t;#s;#a;#o=[];#e;#n;constructor(t,s={decode:!0}){this.#h=s;const i=u(this.#h.decode?b(t):t),h=n(i.auth);this.#i=h.username,this.#r=h.password;const a=p(i.host);this.#t=a.hostname,this.#s=a.port,this.#a=i.protocol,this.#e=i.hash||"",this.#n=c(i.search),this.#o=i.pathname?i.pathname.split("/").filter(Boolean):[]}set params(t){this.#n=t}get params(){return this.#n}get searchParams(){const t=new URLSearchParams;for(const[s,i]of Object.entries(this.params))t.append(s,i);return t}set searchParams(t){this.params=Object.fromEntries(t.entries())}set search(t){this.params=c(t)}get search(){const t=$(this.params);return t?t.startsWith("?")?t:`?${t}`:""}set hash(t){this.#e=t.startsWith("#")?t:`#${t}`}get hash(){return this.#e}set port(t){this.#s=!l(t)&&g(t)?`${t}`:void 0}get port(){return this.#s}set auth(t){const s=n(t);this.#i=s.username,this.#r=s.password}get auth(){return this.#i&&this.#r?`${this.#i}:${this.#r}`:this.#i?this.#i:this.#r?this.#r:""}set protocol(t){this.#a=t.endsWith(":")?t:t.endsWith("://")?t.slice(0,-2):`${t}:`}get protocol(){return this.#a||this.#h.defaultProtocol||"https:"}set hostname(t){this.#t=t}get hostname(){return this.#t}set host(t){const s=p(t);this.#t=s.hostname,this.#s=s.port}get host(){return this.#t&&this.#s?`${this.#t}:${this.#s}`:this.#t?this.#t:this.#s?this.#s:""}set paths(t){this.#o=t.filter(Boolean)}get paths(){return this.#o}set pathname(t){this.paths=d(t).split("/")}get pathname(){return`/${this.paths?m(...this.paths.map(t=>o.stringify(t))):""}`}set path(t){const s=y(t);this.pathname=s.pathname,this.search=s.search,this.#e=s.hash}get path(){return e({pathname:this.pathname,search:this.search,hash:this.hash})}get href(){return this.toString()}set href(t){const s=u(t);this.protocol=s.protocol||this.protocol,this.auth=s.auth||this.auth,this.host=s.host||this.host,this.pathname=s.pathname||this.pathname,this.search=s.search||this.search,this.hash=s.hash||this.hash}get origin(){return`${this.protocol}//${this.host}`}get isScriptProtocol(){return L(this.protocol)}get isRelative(){return f(this.toString())}get isNonEmptyURL(){return S(this.toString())}get __typename(){return"StormURL"}isSamePath(t){return U(this.path,t)}isEqual(t){return R(this.toString(),typeof t=="string"?t:t instanceof StormURL?t.toString():e(t))}toParsed(){return{protocol:this.protocol,auth:this.auth,host:this.host,pathname:this.pathname,search:this.search,hash:this.hash}}toString(){return e(this.toParsed())}toEncoded(){return P(this.toString())}}o.instance.registerCustom({isApplicable:r=>r.__typename==="StormURL",serialize:r=>r.toEncoded(),deserialize:r=>new StormURL(r,{decode:!0})},"StormURL");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stryke/http",
3
- "version": "0.5.3",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "A package containing HTTP communication utilities used by Storm Software.",
6
6
  "repository": {
@@ -11,8 +11,9 @@
11
11
  "private": false,
12
12
  "dependencies": {
13
13
  "ufo": "1.5.4",
14
- "@stryke/json": ">=0.5.4",
15
- "@stryke/type-checks": ">=0.1.4"
14
+ "@stryke/json": "^0.7.0",
15
+ "@stryke/path": "^0.4.7",
16
+ "@stryke/type-checks": "^0.2.0"
16
17
  },
17
18
  "devDependencies": { "@types/node": "^22.13.1" },
18
19
  "publishConfig": { "access": "public" },
@@ -59,19 +60,10 @@
59
60
  }
60
61
  ],
61
62
  "exports": {
62
- "./url-builder": {
63
- "import": {
64
- "types": "./dist/url-builder.d.ts",
65
- "default": "./dist/url-builder.mjs"
66
- },
67
- "require": {
68
- "types": "./dist/url-builder.d.ts",
69
- "default": "./dist/url-builder.cjs"
70
- },
71
- "default": {
72
- "types": "./dist/url-builder.d.ts",
73
- "default": "./dist/url-builder.mjs"
74
- }
63
+ "./url": {
64
+ "import": { "types": "./dist/url.d.ts", "default": "./dist/url.mjs" },
65
+ "require": { "types": "./dist/url.d.ts", "default": "./dist/url.cjs" },
66
+ "default": { "types": "./dist/url.d.ts", "default": "./dist/url.mjs" }
75
67
  },
76
68
  "./types": {
77
69
  "import": { "types": "./dist/types.d.ts", "default": "./dist/types.mjs" },
@@ -1,98 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.StormURLBuilder = void 0;
7
- var _stormJson = require("@stryke/json/storm-json");
8
- var _isString = require("@stryke/type-checks/is-string");
9
- var _ufo = require("ufo");
10
- class StormURLBuilder {
11
- #t;
12
- static create(t, r) {
13
- return new StormURLBuilder(t, r);
14
- }
15
- constructor(t, r) {
16
- const s = r?.decode ?? !0,
17
- i = (0, _isString.isString)(t) ? s ? (0, _ufo.parseURL)((0, _ufo.decode)(t)) : (0, _ufo.parseURL)(t) : t;
18
- this.#t = {
19
- __typename: "StormURL",
20
- queryParams: {},
21
- ...i,
22
- paths: i.pathname ? i.pathname.split("/").filter(Boolean) : []
23
- }, this.#t.host && this.withHost(this.#t.host), this.#t.auth && this.withAuth(this.#t.auth);
24
- }
25
- get _url() {
26
- return this.#t;
27
- }
28
- withProtocol(t) {
29
- return this.#t.protocol = t, this;
30
- }
31
- withHostname(t) {
32
- return this.#t.hostname = t, this;
33
- }
34
- withPort(t) {
35
- return this.#t.port = String(t), this;
36
- }
37
- withUsername(t) {
38
- return this.#t.username = t, this;
39
- }
40
- withPassword(t) {
41
- return this.#t.password = t, this;
42
- }
43
- withHost(t) {
44
- if ((0, _isString.isString)(t)) {
45
- this.#t.host = t;
46
- const r = (0, _ufo.parseAuth)(t);
47
- this.#t.username = r.username, this.#t.password = r.password;
48
- } else this.#t.hostname = t.hostname, this.#t.port = t.port, this.#t.auth = `${t.hostname}${t.port ? `:${t.port}` : ""}`;
49
- return this;
50
- }
51
- withPath(t) {
52
- const r = (0, _ufo.parsePath)(t.startsWith("/") ? t : `/${t}`);
53
- return this.#t = {
54
- ...this.#t,
55
- ...r,
56
- paths: r.pathname.split("/").filter(Boolean)
57
- }, this;
58
- }
59
- withHash(t) {
60
- return this.#t.hash = t, this;
61
- }
62
- withAuth(t) {
63
- if ((0, _isString.isString)(t)) {
64
- this.#t.auth = t;
65
- const r = (0, _ufo.parseAuth)(t);
66
- this.#t.username = r.username, this.#t.password = r.password;
67
- } else this.#t.username = t.username, this.#t.password = t.password, this.#t.auth = `${t.username}:${t.password}`;
68
- return this;
69
- }
70
- withQuery(t) {
71
- return this.#t.queryParams = {}, this.addQueryParam(t), this;
72
- }
73
- addQueryParam(t) {
74
- if ((0, _isString.isString)(t)) {
75
- const r = (0, _ufo.parseQuery)(t);
76
- for (const s of Object.entries(r)) s[0] && (this.#t.queryParams[s[0]] = this.parseQueryParamValue(s[1]));
77
- } else if (Array.isArray(t) && t.length === 2) this.#t.queryParams[t[0]] = this.parseQueryParamValue(t[1]);else for (const r of Object.entries(t)) r[0] && (this.#t.queryParams[r[0]] = this.parseQueryParamValue(r[1]));
78
- return this;
79
- }
80
- build() {
81
- return this.#t;
82
- }
83
- toString() {
84
- return (0, _ufo.cleanDoubleSlashes)((0, _ufo.stringifyParsedURL)(this.#t));
85
- }
86
- toEncoded() {
87
- return (0, _ufo.encode)(this.toString());
88
- }
89
- parseQueryParamValue(t) {
90
- if (Array.isArray(t)) {
91
- const r = [];
92
- for (const s of t) r.push(this.parseQueryParamValue(s));
93
- return r;
94
- }
95
- return _stormJson.StormJSON.parse(t);
96
- }
97
- }
98
- exports.StormURLBuilder = StormURLBuilder;
@@ -1,138 +0,0 @@
1
- import type { ParsedAuth, ParsedHost } from "ufo";
2
- import type { StormURL } from "./types";
3
- export interface StormURLBuilderOptions {
4
- /**
5
- * Should the URL be decoded
6
- *
7
- * @defaultValue `true`
8
- */
9
- decode: boolean;
10
- }
11
- /**
12
- * A class used to build URLs
13
- *
14
- * @remarks
15
- * This class is used to build URLs with a fluent API.
16
- *
17
- * The [UFO](https://github.com/unjs/ufo) library is used under the hood to parse and stringify URLs.
18
- *
19
- * @class StormURLBuilder
20
- */
21
- export declare class StormURLBuilder {
22
- #private;
23
- /**
24
- * Create a new URL builder
25
- *
26
- * @param url - The URL to build
27
- * @param options - The options for the URL builder
28
- * @returns The URL builder
29
- */
30
- static create(url: string | StormURL, options?: StormURLBuilderOptions): StormURLBuilder;
31
- /**
32
- * Create a new URL builder
33
- */
34
- protected constructor(url: string | StormURL, options?: StormURLBuilderOptions);
35
- get _url(): StormURL;
36
- /**
37
- * Set the protocol of the URL
38
- *
39
- * @param protocol - The protocol to set
40
- * @returns The URL builder
41
- */
42
- withProtocol(protocol: string): StormURLBuilder;
43
- /**
44
- * Set the hostname of the URL
45
- *
46
- * @param hostname - The hostname to set
47
- * @returns The URL builder
48
- */
49
- withHostname(hostname: string): StormURLBuilder;
50
- /**
51
- * Set the port of the URL
52
- *
53
- * @param port - The port to set
54
- * @returns The URL builder
55
- */
56
- withPort(port: number): StormURLBuilder;
57
- /**
58
- * Set the username of the URL
59
- *
60
- * @param username - The username to set
61
- * @returns The URL builder
62
- */
63
- withUsername(username: string): StormURLBuilder;
64
- /**
65
- * Set the password of the URL
66
- *
67
- * @param password - The password to set
68
- * @returns The URL builder
69
- */
70
- withPassword(password: string): StormURLBuilder;
71
- /**
72
- * Set the pathname of the URL
73
- *
74
- * @param pathname - The pathname to set
75
- * @returns The URL builder
76
- */
77
- withHost(host: string | ParsedHost): StormURLBuilder;
78
- /**
79
- * Set the path of the URL
80
- *
81
- * @param path - The path to set
82
- * @returns The URL builder
83
- */
84
- withPath(path: string): StormURLBuilder;
85
- /**
86
- * Set the hash of the URL
87
- *
88
- * @param hash - The hash to set
89
- * @returns The URL builder
90
- */
91
- withHash(hash: string): StormURLBuilder;
92
- /**
93
- * Set the auth of the URL
94
- *
95
- * @param auth - The auth to set
96
- * @returns The URL builder
97
- */
98
- withAuth(auth: string | ParsedAuth): StormURLBuilder;
99
- /**
100
- * Set the query of the URL
101
- *
102
- * @param query - The query to set
103
- * @returns The URL builder
104
- */
105
- withQuery(query: string | [string, any] | Record<string, any>): StormURLBuilder;
106
- /**
107
- * Add a query parameter to the URL
108
- *
109
- * @param queryParam - The query parameter to add
110
- * @returns The URL builder
111
- */
112
- addQueryParam(queryParam: string | [string, any] | Record<string, any>): StormURLBuilder;
113
- /**
114
- * Returns the built URL
115
- *
116
- * @returns The built URL
117
- */
118
- build(): StormURL;
119
- /**
120
- * Returns the string representation of the URL
121
- *
122
- * @returns The string representation of the URL
123
- */
124
- toString(): string;
125
- /**
126
- * Returns the encoded string representation of the URL
127
- *
128
- * @returns The encoded string representation of the URL
129
- */
130
- toEncoded(): string;
131
- /**
132
- * Parse a query parameter value
133
- *
134
- * @param value - The value to parse
135
- * @returns The parsed value
136
- */
137
- private parseQueryParamValue;
138
- }
@@ -1 +0,0 @@
1
- import{StormJSON as a}from"@stryke/json/storm-json";import{isString as e}from"@stryke/type-checks/is-string";import{cleanDoubleSlashes as h,decode as u,encode as p,parseAuth as o,parsePath as m,parseQuery as d,parseURL as n,stringifyParsedURL as l}from"ufo";export class StormURLBuilder{#t;static create(t,r){return new StormURLBuilder(t,r)}constructor(t,r){const s=r?.decode??!0,i=e(t)?s?n(u(t)):n(t):t;this.#t={__typename:"StormURL",queryParams:{},...i,paths:i.pathname?i.pathname.split("/").filter(Boolean):[]},this.#t.host&&this.withHost(this.#t.host),this.#t.auth&&this.withAuth(this.#t.auth)}get _url(){return this.#t}withProtocol(t){return this.#t.protocol=t,this}withHostname(t){return this.#t.hostname=t,this}withPort(t){return this.#t.port=String(t),this}withUsername(t){return this.#t.username=t,this}withPassword(t){return this.#t.password=t,this}withHost(t){if(e(t)){this.#t.host=t;const r=o(t);this.#t.username=r.username,this.#t.password=r.password}else this.#t.hostname=t.hostname,this.#t.port=t.port,this.#t.auth=`${t.hostname}${t.port?`:${t.port}`:""}`;return this}withPath(t){const r=m(t.startsWith("/")?t:`/${t}`);return this.#t={...this.#t,...r,paths:r.pathname.split("/").filter(Boolean)},this}withHash(t){return this.#t.hash=t,this}withAuth(t){if(e(t)){this.#t.auth=t;const r=o(t);this.#t.username=r.username,this.#t.password=r.password}else this.#t.username=t.username,this.#t.password=t.password,this.#t.auth=`${t.username}:${t.password}`;return this}withQuery(t){return this.#t.queryParams={},this.addQueryParam(t),this}addQueryParam(t){if(e(t)){const r=d(t);for(const s of Object.entries(r))s[0]&&(this.#t.queryParams[s[0]]=this.parseQueryParamValue(s[1]))}else if(Array.isArray(t)&&t.length===2)this.#t.queryParams[t[0]]=this.parseQueryParamValue(t[1]);else for(const r of Object.entries(t))r[0]&&(this.#t.queryParams[r[0]]=this.parseQueryParamValue(r[1]));return this}build(){return this.#t}toString(){return h(l(this.#t))}toEncoded(){return p(this.toString())}parseQueryParamValue(t){if(Array.isArray(t)){const r=[];for(const s of t)r.push(this.parseQueryParamValue(s));return r}return a.parse(t)}}