@stackframe/stack-shared 2.7.20 → 2.7.22
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/CHANGELOG.md +12 -0
- package/dist/crud.js +76 -0
- package/dist/hooks/use-strict-memo.js +75 -0
- package/dist/interface/serverInterface.d.ts +1 -1
- package/dist/interface/serverInterface.js +1 -1
- package/dist/known-errors.js +1 -1
- package/dist/utils/arrays.js +75 -1
- package/dist/utils/caches.js +33 -0
- package/dist/utils/compile-time.js +3 -0
- package/dist/utils/dates.js +4 -4
- package/dist/utils/functions.js +15 -0
- package/dist/utils/html.js +28 -0
- package/dist/utils/http.js +29 -0
- package/dist/utils/ips.js +29 -0
- package/dist/utils/json.js +135 -0
- package/dist/utils/maps.js +145 -0
- package/dist/utils/objects.js +69 -0
- package/dist/utils/promises.js +205 -3
- package/dist/utils/proxies.js +72 -0
- package/dist/utils/react.js +82 -0
- package/dist/utils/results.d.ts +5 -3
- package/dist/utils/results.js +220 -6
- package/dist/utils/strings.js +223 -2
- package/dist/utils/unicode.js +13 -0
- package/dist/utils/urls.js +115 -0
- package/dist/utils/uuids.js +30 -0
- package/package.json +1 -1
package/dist/utils/urls.js
CHANGED
|
@@ -8,15 +8,47 @@ export function createUrlIfValid(...args) {
|
|
|
8
8
|
return null;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
import.meta.vitest?.test("createUrlIfValid", ({ expect }) => {
|
|
12
|
+
// Test with valid URLs
|
|
13
|
+
expect(createUrlIfValid("https://example.com")).toBeInstanceOf(URL);
|
|
14
|
+
expect(createUrlIfValid("https://example.com/path?query=value#hash")).toBeInstanceOf(URL);
|
|
15
|
+
expect(createUrlIfValid("/path", "https://example.com")).toBeInstanceOf(URL);
|
|
16
|
+
// Test with invalid URLs
|
|
17
|
+
expect(createUrlIfValid("")).toBeNull();
|
|
18
|
+
expect(createUrlIfValid("not a url")).toBeNull();
|
|
19
|
+
expect(createUrlIfValid("http://")).toBeNull();
|
|
20
|
+
});
|
|
11
21
|
export function isValidUrl(url) {
|
|
12
22
|
return !!createUrlIfValid(url);
|
|
13
23
|
}
|
|
24
|
+
import.meta.vitest?.test("isValidUrl", ({ expect }) => {
|
|
25
|
+
// Test with valid URLs
|
|
26
|
+
expect(isValidUrl("https://example.com")).toBe(true);
|
|
27
|
+
expect(isValidUrl("http://localhost:3000")).toBe(true);
|
|
28
|
+
expect(isValidUrl("ftp://example.com")).toBe(true);
|
|
29
|
+
// Test with invalid URLs
|
|
30
|
+
expect(isValidUrl("")).toBe(false);
|
|
31
|
+
expect(isValidUrl("not a url")).toBe(false);
|
|
32
|
+
expect(isValidUrl("http://")).toBe(false);
|
|
33
|
+
});
|
|
14
34
|
export function isValidHostname(hostname) {
|
|
15
35
|
const url = createUrlIfValid(`https://${hostname}`);
|
|
16
36
|
if (!url)
|
|
17
37
|
return false;
|
|
18
38
|
return url.hostname === hostname;
|
|
19
39
|
}
|
|
40
|
+
import.meta.vitest?.test("isValidHostname", ({ expect }) => {
|
|
41
|
+
// Test with valid hostnames
|
|
42
|
+
expect(isValidHostname("example.com")).toBe(true);
|
|
43
|
+
expect(isValidHostname("localhost")).toBe(true);
|
|
44
|
+
expect(isValidHostname("sub.domain.example.com")).toBe(true);
|
|
45
|
+
expect(isValidHostname("127.0.0.1")).toBe(true);
|
|
46
|
+
// Test with invalid hostnames
|
|
47
|
+
expect(isValidHostname("")).toBe(false);
|
|
48
|
+
expect(isValidHostname("example.com/path")).toBe(false);
|
|
49
|
+
expect(isValidHostname("https://example.com")).toBe(false);
|
|
50
|
+
expect(isValidHostname("example com")).toBe(false);
|
|
51
|
+
});
|
|
20
52
|
export function isLocalhost(urlOrString) {
|
|
21
53
|
const url = createUrlIfValid(urlOrString);
|
|
22
54
|
if (!url)
|
|
@@ -27,6 +59,24 @@ export function isLocalhost(urlOrString) {
|
|
|
27
59
|
return true;
|
|
28
60
|
return false;
|
|
29
61
|
}
|
|
62
|
+
import.meta.vitest?.test("isLocalhost", ({ expect }) => {
|
|
63
|
+
// Test with localhost URLs
|
|
64
|
+
expect(isLocalhost("http://localhost")).toBe(true);
|
|
65
|
+
expect(isLocalhost("https://localhost:8080")).toBe(true);
|
|
66
|
+
expect(isLocalhost("http://sub.localhost")).toBe(true);
|
|
67
|
+
expect(isLocalhost("http://127.0.0.1")).toBe(true);
|
|
68
|
+
expect(isLocalhost("http://127.1.2.3")).toBe(true);
|
|
69
|
+
// Test with non-localhost URLs
|
|
70
|
+
expect(isLocalhost("https://example.com")).toBe(false);
|
|
71
|
+
expect(isLocalhost("http://192.168.1.1")).toBe(false);
|
|
72
|
+
expect(isLocalhost("http://10.0.0.1")).toBe(false);
|
|
73
|
+
// Test with URL objects
|
|
74
|
+
expect(isLocalhost(new URL("http://localhost"))).toBe(true);
|
|
75
|
+
expect(isLocalhost(new URL("https://example.com"))).toBe(false);
|
|
76
|
+
// Test with invalid URLs
|
|
77
|
+
expect(isLocalhost("not a url")).toBe(false);
|
|
78
|
+
expect(isLocalhost("")).toBe(false);
|
|
79
|
+
});
|
|
30
80
|
export function isRelative(url) {
|
|
31
81
|
const randomDomain = `${generateSecureRandomString()}.stack-auth.example.com`;
|
|
32
82
|
const u = createUrlIfValid(url, `https://${randomDomain}`);
|
|
@@ -38,9 +88,37 @@ export function isRelative(url) {
|
|
|
38
88
|
return false;
|
|
39
89
|
return true;
|
|
40
90
|
}
|
|
91
|
+
import.meta.vitest?.test("isRelative", ({ expect }) => {
|
|
92
|
+
// We can't easily mock generateSecureRandomString in this context
|
|
93
|
+
// but we can still test the function's behavior
|
|
94
|
+
// Test with relative URLs
|
|
95
|
+
expect(isRelative("/")).toBe(true);
|
|
96
|
+
expect(isRelative("/path")).toBe(true);
|
|
97
|
+
expect(isRelative("/path?query=value#hash")).toBe(true);
|
|
98
|
+
// Test with absolute URLs
|
|
99
|
+
expect(isRelative("https://example.com")).toBe(false);
|
|
100
|
+
expect(isRelative("http://example.com")).toBe(false);
|
|
101
|
+
expect(isRelative("//example.com")).toBe(false);
|
|
102
|
+
// Note: The implementation treats empty strings and invalid URLs as relative
|
|
103
|
+
// This is because they can be resolved against a base URL
|
|
104
|
+
expect(isRelative("")).toBe(true);
|
|
105
|
+
expect(isRelative("not a url")).toBe(true);
|
|
106
|
+
});
|
|
41
107
|
export function getRelativePart(url) {
|
|
42
108
|
return url.pathname + url.search + url.hash;
|
|
43
109
|
}
|
|
110
|
+
import.meta.vitest?.test("getRelativePart", ({ expect }) => {
|
|
111
|
+
// Test with various URLs
|
|
112
|
+
expect(getRelativePart(new URL("https://example.com"))).toBe("/");
|
|
113
|
+
expect(getRelativePart(new URL("https://example.com/path"))).toBe("/path");
|
|
114
|
+
expect(getRelativePart(new URL("https://example.com/path?query=value"))).toBe("/path?query=value");
|
|
115
|
+
expect(getRelativePart(new URL("https://example.com/path#hash"))).toBe("/path#hash");
|
|
116
|
+
expect(getRelativePart(new URL("https://example.com/path?query=value#hash"))).toBe("/path?query=value#hash");
|
|
117
|
+
// Test with different domains but same paths
|
|
118
|
+
const url1 = new URL("https://example.com/path?query=value#hash");
|
|
119
|
+
const url2 = new URL("https://different.com/path?query=value#hash");
|
|
120
|
+
expect(getRelativePart(url1)).toBe(getRelativePart(url2));
|
|
121
|
+
});
|
|
44
122
|
/**
|
|
45
123
|
* A template literal tag that returns a URL.
|
|
46
124
|
*
|
|
@@ -49,6 +127,27 @@ export function getRelativePart(url) {
|
|
|
49
127
|
export function url(strings, ...values) {
|
|
50
128
|
return new URL(urlString(strings, ...values));
|
|
51
129
|
}
|
|
130
|
+
import.meta.vitest?.test("url", ({ expect }) => {
|
|
131
|
+
// Test with no interpolation
|
|
132
|
+
expect(url `https://example.com`).toBeInstanceOf(URL);
|
|
133
|
+
expect(url `https://example.com`.href).toBe("https://example.com/");
|
|
134
|
+
// Test with string interpolation
|
|
135
|
+
expect(url `https://example.com/${"path"}`).toBeInstanceOf(URL);
|
|
136
|
+
expect(url `https://example.com/${"path"}`.pathname).toBe("/path");
|
|
137
|
+
// Test with number interpolation
|
|
138
|
+
expect(url `https://example.com/${42}`).toBeInstanceOf(URL);
|
|
139
|
+
expect(url `https://example.com/${42}`.pathname).toBe("/42");
|
|
140
|
+
// Test with boolean interpolation
|
|
141
|
+
expect(url `https://example.com/${true}`).toBeInstanceOf(URL);
|
|
142
|
+
expect(url `https://example.com/${true}`.pathname).toBe("/true");
|
|
143
|
+
// Test with special characters in interpolation
|
|
144
|
+
expect(url `https://example.com/${"path with spaces"}`).toBeInstanceOf(URL);
|
|
145
|
+
expect(url `https://example.com/${"path with spaces"}`.pathname).toBe("/path%20with%20spaces");
|
|
146
|
+
// Test with multiple interpolations
|
|
147
|
+
expect(url `https://example.com/${"path"}?query=${"value"}`).toBeInstanceOf(URL);
|
|
148
|
+
expect(url `https://example.com/${"path"}?query=${"value"}`.pathname).toBe("/path");
|
|
149
|
+
expect(url `https://example.com/${"path"}?query=${"value"}`.search).toBe("?query=value");
|
|
150
|
+
});
|
|
52
151
|
/**
|
|
53
152
|
* A template literal tag that returns a URL string.
|
|
54
153
|
*
|
|
@@ -57,3 +156,19 @@ export function url(strings, ...values) {
|
|
|
57
156
|
export function urlString(strings, ...values) {
|
|
58
157
|
return templateIdentity(strings, ...values.map(encodeURIComponent));
|
|
59
158
|
}
|
|
159
|
+
import.meta.vitest?.test("urlString", ({ expect }) => {
|
|
160
|
+
// Test with no interpolation
|
|
161
|
+
expect(urlString `https://example.com`).toBe("https://example.com");
|
|
162
|
+
// Test with string interpolation
|
|
163
|
+
expect(urlString `https://example.com/${"path"}`).toBe("https://example.com/path");
|
|
164
|
+
// Test with number interpolation
|
|
165
|
+
expect(urlString `https://example.com/${42}`).toBe("https://example.com/42");
|
|
166
|
+
// Test with boolean interpolation
|
|
167
|
+
expect(urlString `https://example.com/${true}`).toBe("https://example.com/true");
|
|
168
|
+
// Test with special characters in interpolation
|
|
169
|
+
expect(urlString `https://example.com/${"path with spaces"}`).toBe("https://example.com/path%20with%20spaces");
|
|
170
|
+
expect(urlString `https://example.com/${"?&="}`).toBe("https://example.com/%3F%26%3D");
|
|
171
|
+
// Test with multiple interpolations
|
|
172
|
+
expect(urlString `https://example.com/${"path"}?query=${"value"}`).toBe("https://example.com/path?query=value");
|
|
173
|
+
expect(urlString `https://example.com/${"path"}?query=${"value with spaces"}`).toBe("https://example.com/path?query=value%20with%20spaces");
|
|
174
|
+
});
|
package/dist/utils/uuids.js
CHANGED
|
@@ -3,6 +3,36 @@ export function generateUuid() {
|
|
|
3
3
|
// crypto.randomUuid is not supported in all browsers, so this is a polyfill
|
|
4
4
|
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => (+c ^ generateRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16));
|
|
5
5
|
}
|
|
6
|
+
import.meta.vitest?.test("generateUuid", ({ expect }) => {
|
|
7
|
+
// Test that the function returns a valid UUID
|
|
8
|
+
const uuid = generateUuid();
|
|
9
|
+
expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
|
|
10
|
+
// Test that multiple calls generate different UUIDs
|
|
11
|
+
const uuid2 = generateUuid();
|
|
12
|
+
expect(uuid).not.toBe(uuid2);
|
|
13
|
+
// Test that the UUID is version 4 (random)
|
|
14
|
+
expect(uuid.charAt(14)).toBe('4');
|
|
15
|
+
// Test that the UUID has the correct variant (8, 9, a, or b in position 19)
|
|
16
|
+
expect('89ab').toContain(uuid.charAt(19));
|
|
17
|
+
});
|
|
6
18
|
export function isUuid(str) {
|
|
7
19
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(str);
|
|
8
20
|
}
|
|
21
|
+
import.meta.vitest?.test("isUuid", ({ expect }) => {
|
|
22
|
+
// Test with valid UUIDs
|
|
23
|
+
expect(isUuid("123e4567-e89b-42d3-a456-426614174000")).toBe(true);
|
|
24
|
+
expect(isUuid("123e4567-e89b-42d3-8456-426614174000")).toBe(true);
|
|
25
|
+
expect(isUuid("123e4567-e89b-42d3-9456-426614174000")).toBe(true);
|
|
26
|
+
expect(isUuid("123e4567-e89b-42d3-a456-426614174000")).toBe(true);
|
|
27
|
+
expect(isUuid("123e4567-e89b-42d3-b456-426614174000")).toBe(true);
|
|
28
|
+
// Test with invalid UUIDs
|
|
29
|
+
expect(isUuid("")).toBe(false);
|
|
30
|
+
expect(isUuid("not-a-uuid")).toBe(false);
|
|
31
|
+
expect(isUuid("123e4567-e89b-12d3-a456-426614174000")).toBe(false); // Wrong version (not 4)
|
|
32
|
+
expect(isUuid("123e4567-e89b-42d3-c456-426614174000")).toBe(false); // Wrong variant (not 8, 9, a, or b)
|
|
33
|
+
expect(isUuid("123e4567-e89b-42d3-a456-42661417400")).toBe(false); // Too short
|
|
34
|
+
expect(isUuid("123e4567-e89b-42d3-a456-4266141740000")).toBe(false); // Too long
|
|
35
|
+
expect(isUuid("123e4567-e89b-42d3-a456_426614174000")).toBe(false); // Wrong format (underscore instead of dash)
|
|
36
|
+
// Test with uppercase letters (should fail as UUID should be lowercase)
|
|
37
|
+
expect(isUuid("123E4567-E89B-42D3-A456-426614174000")).toBe(false);
|
|
38
|
+
});
|