@hobenakicoffee/libraries 1.3.0 → 1.5.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/package.json +1 -1
- package/src/types/supabase.ts +6 -0
- package/src/utils/format-number.test.ts +29 -0
- package/src/utils/format-number.ts +5 -0
- package/src/utils/get-social-link.test.ts +63 -0
- package/src/utils/get-social-link.ts +29 -0
- package/src/utils/get-user-name-initials.test.ts +34 -0
- package/src/utils/get-user-name-initials.ts +8 -0
- package/src/utils/index.ts +3 -0
package/package.json
CHANGED
package/src/types/supabase.ts
CHANGED
|
@@ -284,9 +284,11 @@ export type Database = {
|
|
|
284
284
|
display_name: string | null
|
|
285
285
|
full_name: string | null
|
|
286
286
|
id: string
|
|
287
|
+
is_page_active: boolean | null
|
|
287
288
|
layout: Json | null
|
|
288
289
|
page_slug: string
|
|
289
290
|
role: Database["public"]["Enums"]["user_role"]
|
|
291
|
+
social_links: Json | null
|
|
290
292
|
theme: Json | null
|
|
291
293
|
updated_at: string | null
|
|
292
294
|
username: string
|
|
@@ -301,9 +303,11 @@ export type Database = {
|
|
|
301
303
|
display_name?: string | null
|
|
302
304
|
full_name?: string | null
|
|
303
305
|
id: string
|
|
306
|
+
is_page_active?: boolean | null
|
|
304
307
|
layout?: Json | null
|
|
305
308
|
page_slug: string
|
|
306
309
|
role?: Database["public"]["Enums"]["user_role"]
|
|
310
|
+
social_links?: Json | null
|
|
307
311
|
theme?: Json | null
|
|
308
312
|
updated_at?: string | null
|
|
309
313
|
username: string
|
|
@@ -318,9 +322,11 @@ export type Database = {
|
|
|
318
322
|
display_name?: string | null
|
|
319
323
|
full_name?: string | null
|
|
320
324
|
id?: string
|
|
325
|
+
is_page_active?: boolean | null
|
|
321
326
|
layout?: Json | null
|
|
322
327
|
page_slug?: string
|
|
323
328
|
role?: Database["public"]["Enums"]["user_role"]
|
|
329
|
+
social_links?: Json | null
|
|
324
330
|
theme?: Json | null
|
|
325
331
|
updated_at?: string | null
|
|
326
332
|
username?: string
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { formatNumber } from "./format-number";
|
|
3
|
+
|
|
4
|
+
function digitsFromFormatted(formatted: string) {
|
|
5
|
+
const digits = formatted.replace(/\D/g, "");
|
|
6
|
+
return Number(digits);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
describe("formatNumber", () => {
|
|
10
|
+
test("formats positive numbers and rounds correctly", () => {
|
|
11
|
+
expect(digitsFromFormatted(formatNumber(1234.56))).toBe(1235);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("formats negative numbers using absolute value", () => {
|
|
15
|
+
expect(digitsFromFormatted(formatNumber(-9876.5))).toBe(9877);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("formats zero", () => {
|
|
19
|
+
expect(digitsFromFormatted(formatNumber(0))).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("rounds small fractional numbers to 0", () => {
|
|
23
|
+
expect(digitsFromFormatted(formatNumber(-0.4))).toBe(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("formats large numbers", () => {
|
|
27
|
+
expect(digitsFromFormatted(formatNumber(1000000))).toBe(1000000);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { getSocialLink } from "./get-social-link";
|
|
3
|
+
import { SupporterPlatforms } from "../constants";
|
|
4
|
+
|
|
5
|
+
describe("getSocialLink", () => {
|
|
6
|
+
test("returns null when username or platform is missing", () => {
|
|
7
|
+
expect(getSocialLink(undefined, SupporterPlatforms.FACEBOOK)).toBeNull();
|
|
8
|
+
expect(getSocialLink("alice", undefined)).toBeNull();
|
|
9
|
+
expect(getSocialLink()).toBeNull();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("returns correct Facebook URL", () => {
|
|
13
|
+
expect(getSocialLink("alice", SupporterPlatforms.FACEBOOK)).toBe(
|
|
14
|
+
"https://facebook.com/alice",
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("returns correct Instagram URL with spaces", () => {
|
|
19
|
+
expect(getSocialLink(" john doe ", SupporterPlatforms.INSTAGRAM)).toBe(
|
|
20
|
+
"https://instagram.com/johndoe",
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("returns correct TikTok URL", () => {
|
|
25
|
+
expect(getSocialLink("user123", SupporterPlatforms.TIKTOK)).toBe(
|
|
26
|
+
"https://tiktok.com/@user123",
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("returns correct YouTube URL", () => {
|
|
31
|
+
expect(getSocialLink("Jane", SupporterPlatforms.YOUTUBE)).toBe(
|
|
32
|
+
"https://youtube.com/Jane",
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("returns correct X (Twitter) URL", () => {
|
|
37
|
+
expect(getSocialLink("bob", SupporterPlatforms.X)).toBe(
|
|
38
|
+
"https://x.com/bob",
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("returns correct LinkedIn URL", () => {
|
|
43
|
+
expect(getSocialLink("johnsmith", SupporterPlatforms.LINKEDIN)).toBe(
|
|
44
|
+
"https://linkedin.com/in/johnsmith",
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("returns correct GitHub URL", () => {
|
|
49
|
+
expect(getSocialLink("octocat", SupporterPlatforms.GITHUB)).toBe(
|
|
50
|
+
"https://github.com/octocat",
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("returns null for unsupported platform", () => {
|
|
55
|
+
expect(getSocialLink("alice", "MYSPACE" as any)).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("sanitizes username with special characters", () => {
|
|
59
|
+
expect(getSocialLink("user name!@#", SupporterPlatforms.FACEBOOK)).toBe(
|
|
60
|
+
"https://facebook.com/username!%40%23",
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SupporterPlatforms, type SupporterPlatform } from "../constants";
|
|
2
|
+
|
|
3
|
+
export function getSocialLink(username?: string, platform?: SupporterPlatform) {
|
|
4
|
+
console.log("getSocialLink called with:", { username, platform });
|
|
5
|
+
if (!username || !platform) return null;
|
|
6
|
+
|
|
7
|
+
const sanitizedUsername = encodeURIComponent(
|
|
8
|
+
username.trim().replace(/\s+/g, ""),
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
switch (platform) {
|
|
12
|
+
case SupporterPlatforms.FACEBOOK:
|
|
13
|
+
return `https://facebook.com/${sanitizedUsername}`;
|
|
14
|
+
case SupporterPlatforms.INSTAGRAM:
|
|
15
|
+
return `https://instagram.com/${sanitizedUsername}`;
|
|
16
|
+
case SupporterPlatforms.TIKTOK:
|
|
17
|
+
return `https://tiktok.com/@${sanitizedUsername}`;
|
|
18
|
+
case SupporterPlatforms.YOUTUBE:
|
|
19
|
+
return `https://youtube.com/${sanitizedUsername}`;
|
|
20
|
+
case SupporterPlatforms.X:
|
|
21
|
+
return `https://x.com/${sanitizedUsername}`;
|
|
22
|
+
case SupporterPlatforms.LINKEDIN:
|
|
23
|
+
return `https://linkedin.com/in/${sanitizedUsername}`;
|
|
24
|
+
case SupporterPlatforms.GITHUB:
|
|
25
|
+
return `https://github.com/${sanitizedUsername}`;
|
|
26
|
+
default:
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getInitials } from "./get-user-name-initials";
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
|
|
4
|
+
describe("getInitials", () => {
|
|
5
|
+
test("returns initials for a full name", () => {
|
|
6
|
+
expect(getInitials("John Doe")).toBe("JD");
|
|
7
|
+
expect(getInitials("Jane Ann Smith")).toBe("JS");
|
|
8
|
+
expect(getInitials("Alice Bob Carol")).toBe("AC");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("returns single initial for single name", () => {
|
|
12
|
+
expect(getInitials("John")).toBe("J");
|
|
13
|
+
expect(getInitials("A")).toBe("A");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("handles extra spaces", () => {
|
|
17
|
+
expect(getInitials(" John Doe ")).toBe("JD");
|
|
18
|
+
expect(getInitials(" Alice ")).toBe("A");
|
|
19
|
+
expect(getInitials(" Alice Bob Carol ")).toBe("AC");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("returns ? for empty or undefined", () => {
|
|
23
|
+
expect(getInitials("")).toBe("?");
|
|
24
|
+
expect(getInitials(" ")).toBe("?");
|
|
25
|
+
expect(getInitials(undefined)).toBe("?");
|
|
26
|
+
expect(getInitials(null)).toBe("?");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("handles non-ASCII and special characters", () => {
|
|
30
|
+
expect(getInitials("Élodie Durand")).toBe("ÉD");
|
|
31
|
+
expect(getInitials("李 小龙")).toBe("李小");
|
|
32
|
+
expect(getInitials("O’Connor")).toBe("O");
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const regexPattern = /\s+/;
|
|
2
|
+
|
|
3
|
+
export function getInitials(name?: string | null) {
|
|
4
|
+
const parts = name?.trim().split(regexPattern).filter(Boolean) ?? [];
|
|
5
|
+
const first = parts[0]?.[0] ?? "?";
|
|
6
|
+
const last = parts.length > 1 ? (parts.at(-1)?.[0] ?? "") : "";
|
|
7
|
+
return `${first}${last}`.toUpperCase();
|
|
8
|
+
}
|
package/src/utils/index.ts
CHANGED