Skip to content

Commit 5399983

Browse files
committed
chore: release version 5.2.0 with minor updates
- Added `copyToClipboard()` helper function to README.md and exports. - Included `extractEmailDomain` in the helpers index. - Updated CHANGELOG.md to reflect the new version and changes.
1 parent 4a9d910 commit 5399983

8 files changed

Lines changed: 76 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# deverything
22

3+
## 5.2.0
4+
5+
### Minor Changes
6+
7+
- email domain
8+
39
## 5.1.0
410

511
### Minor Changes

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Contributions always welcome!
108108
- `chunkedDynamic()` process with dynamic chunk sizes
109109
- `clamp()` clamp number in a range
110110
- `cleanSpaces()` trims and turns double spaces into single space
111+
- `copyToClipboard()` copy a string to the system clipboard (browser only)
111112
- `cyclicalItem()` get item from array with cyclical indexing
112113
- `dir()` get directory listing
113114
- `enumKeys()` enum FRUIT { APPLE, PEAR } => ["APPLE", "PEAR"]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "deverything",
3-
"version": "5.1.0",
3+
"version": "5.2.0",
44
"description": "Everything you need for Dev",
55
"main": "./dist/index.js",
66
"module": "./dist/index.mjs",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { afterEach, expect, test, vi } from "vitest";
2+
import { copyToClipboard } from "./copyToClipboard";
3+
4+
afterEach(() => {
5+
vi.unstubAllGlobals();
6+
});
7+
8+
test("copyToClipboard writes the value to the clipboard", async () => {
9+
const writeText = vi.fn().mockResolvedValue(undefined);
10+
vi.stubGlobal("navigator", { clipboard: { writeText } });
11+
12+
await copyToClipboard("hello");
13+
14+
expect(writeText).toHaveBeenCalledWith("hello");
15+
});
16+
17+
test("copyToClipboard throws when the Clipboard API is unavailable", async () => {
18+
vi.stubGlobal("navigator", {});
19+
20+
await expect(copyToClipboard("hello")).rejects.toThrow(
21+
"Clipboard API is not available in this environment"
22+
);
23+
});

src/helpers/copyToClipboard.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copy a string to the system clipboard, works only in the browser
3+
* @param value - the string to copy
4+
* @returns a promise that resolves once the write is complete, or rejects if the Clipboard API is unavailable or the write fails
5+
*/
6+
export const copyToClipboard = async (value: string): Promise<void> => {
7+
if (typeof navigator === "undefined" || !navigator.clipboard) {
8+
throw new Error("Clipboard API is not available in this environment");
9+
}
10+
11+
await navigator.clipboard.writeText(value);
12+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { describe, expect, test } from "vitest";
2+
import { extractEmailDomain } from "./extractEmailDomain";
3+
4+
describe("extractEmailDomain", () => {
5+
test("extracts domain from a standard email", () => {
6+
expect(extractEmailDomain("user@example.com")).toBe("example.com");
7+
});
8+
9+
test("extracts domain with subdomain", () => {
10+
expect(extractEmailDomain("user@mail.example.com")).toBe(
11+
"mail.example.com"
12+
);
13+
});
14+
15+
test("returns undefined when there is no @", () => {
16+
expect(extractEmailDomain("notanemail")).toBeUndefined();
17+
});
18+
19+
test("returns undefined when @ is the last character", () => {
20+
expect(extractEmailDomain("user@")).toBeUndefined();
21+
});
22+
23+
test("handles multiple @ signs (uses first)", () => {
24+
expect(extractEmailDomain("a@b@example.com")).toBe("b@example.com");
25+
});
26+
});

src/helpers/extractEmailDomain.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const extractEmailDomain = (email: string): string | undefined => {
2+
const atIndex = email.indexOf("@");
3+
if (atIndex === -1 || atIndex === email.length - 1) return undefined;
4+
return email.slice(atIndex + 1);
5+
};

src/helpers/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ export * from "./chunkedAsync";
99
export * from "./chunkedDynamic";
1010
export * from "./clamp";
1111
export * from "./cleanSpaces";
12+
export * from "./copyToClipboard";
1213
export * from "./cyclicalItem";
1314
export * from "./dir";
1415
export * from "./enumKeys";
1516
export * from "./enumValues";
17+
export * from "./extractEmailDomain";
1618
export * from "./filterAlphanumeric";
1719
export * from "./first";
1820
export * from "./firstKey";

0 commit comments

Comments
 (0)