utills 0.1.2

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/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # utils
2
+
3
+ ![thumbmail](./public/assets/utills-web.jpg)
4
+
5
+ Lightweight, dependency-free utility functions for modern JavaScript and TypeScript projects.
6
+
7
+ This package is designed to be simple, secure, and developer-friendly.
8
+ It works in both **Node.js** and **browser environments** and follows modern **ESM standards**.
9
+
10
+ **Check out** 👉 [Docs](https://utills.vercel.app/)
11
+
12
+ ---
13
+
14
+ ## ✨ Features
15
+
16
+ - JavaScript & TypeScript compatible
17
+ - Modern ESM support
18
+ - Zero external dependencies
19
+ - Tree-shaking friendly
20
+ - Browser & Node.js support
21
+ - Secure (crypto-based utilities)
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
26
+
27
+ ```bash
28
+ npm install utils
29
+ ```
30
+
31
+ # Usage
32
+
33
+ ```bash
34
+
35
+ import {
36
+ randomId,
37
+ timeAgo,
38
+ } from "utils";
39
+
40
+ randomId();
41
+ timeAgo(Date.now() - 60000);
42
+ ```
43
+
44
+ ## Available Utilities
45
+
46
+ | Method | Parameters | Returns | Description |
47
+ | ------------------ | ----------------- | -------- | ------------------------------------------------------------ |
48
+ | **randomId** | `options?` | `string` | Generates a secure random ID with configurable options. |
49
+ | **generateSecret** | `length?` | `string` | Generates a cryptographically secure secret token. |
50
+ | **timeAgo** | `date`, `locale?` | `string` | Returns human-readable relative time (e.g. "2 minutes ago"). |
51
+
52
+ ## Contributing
53
+
54
+ Contributions are welcome and appreciated.
55
+
56
+ ## How to contribute
57
+
58
+ 1: Fork the repository
59
+ Clone your Fork
60
+
61
+ 2: Clone your fork
62
+
63
+ ```bash
64
+ git clone https://github.com/safayet35/utills
65
+ ```
66
+
67
+ 3: Create a new branch
68
+
69
+ ```bash
70
+ git checkout -b feature/new-utility
71
+ ```
72
+
73
+ 4: Add your utility function inside :
74
+
75
+ ```bash
76
+ src/core/
77
+ ```
78
+
79
+ 5: Export it from:
80
+
81
+ ```bash
82
+ src/core/index.ts
83
+ ```
84
+
85
+ 6: Build and test
86
+
87
+ ```bash
88
+ npm run build
89
+ ```
90
+
91
+ 7: Commit your changes with a clear message
92
+
93
+ 8: Open a Pull Request
94
+
95
+ ## Contribution Guideline
96
+
97
+ - One utility per file
98
+ - No external dependencies
99
+ - Use native APIs where possible
100
+ - Handle edge cases properly
101
+ - Keep code clean and readable
102
+
103
+ ## Roadmap
104
+
105
+ - More utility functions
106
+ - Logging utilities
107
+ - Optional advanced helpers
108
+ - Unit tests
109
+
110
+ ## License
111
+
112
+ MIT License © Safayet Rahman
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generate a cryptographically secure secret token
3
+ *
4
+ * @example
5
+ * generateSecret()
6
+ * generateSecret(32)
7
+ * generateSecret(64)
8
+ */
9
+ export declare function generateSecret(length?: number): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Generate a cryptographically secure secret token
3
+ *
4
+ * @example
5
+ * generateSecret()
6
+ * generateSecret(32)
7
+ * generateSecret(64)
8
+ */
9
+ export function generateSecret(length = 32) {
10
+ if (length <= 0) {
11
+ throw new Error("generateSecret: length must be greater than 0");
12
+ }
13
+ const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
14
+ const charsetLength = charset.length;
15
+ // Browser & Node compatible crypto
16
+ const cryptoObj = typeof crypto !== "undefined"
17
+ ? crypto
18
+ : // @ts-ignore
19
+ require("crypto").webcrypto;
20
+ const randomValues = new Uint32Array(length);
21
+ cryptoObj.getRandomValues(randomValues);
22
+ let secret = "";
23
+ for (let i = 0; i < length; i++) {
24
+ secret += charset[randomValues[i] % charsetLength];
25
+ }
26
+ return secret;
27
+ }
@@ -0,0 +1,3 @@
1
+ export { randomId } from "./randomId.js";
2
+ export { generateSecret } from "./generateSecret.js";
3
+ export { timeAgo } from "./timeAgo.js";
@@ -0,0 +1,3 @@
1
+ export { randomId } from "./randomId.js";
2
+ export { generateSecret } from "./generateSecret.js";
3
+ export { timeAgo } from "./timeAgo.js";
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Options for randomId generator
3
+ */
4
+ export interface RandomIdOptions {
5
+ /**
6
+ * Length of the generated ID
7
+ * @default 16
8
+ */
9
+ length?: number;
10
+ /**
11
+ * Custom characters to use
12
+ * @default alphanumeric (a-zA-Z0-9)
13
+ */
14
+ charset?: string;
15
+ /**
16
+ * If true, removes visually confusing characters (0, O, l, I)
17
+ * @default false
18
+ */
19
+ safe?: boolean;
20
+ }
21
+ /**
22
+ * Generate a secure random ID
23
+ *
24
+ * @example
25
+ * randomId()
26
+ * randomId({ length: 10 })
27
+ * randomId({ length: 12, safe: true })
28
+ */
29
+ export declare function randomId(options?: RandomIdOptions): string;
@@ -0,0 +1,29 @@
1
+ const DEFAULT_CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2
+ const SAFE_CHARSET = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
3
+ /**
4
+ * Generate a secure random ID
5
+ *
6
+ * @example
7
+ * randomId()
8
+ * randomId({ length: 10 })
9
+ * randomId({ length: 12, safe: true })
10
+ */
11
+ export function randomId(options = {}) {
12
+ const { length = 16, charset = options.safe ? SAFE_CHARSET : DEFAULT_CHARSET, } = options;
13
+ if (length <= 0) {
14
+ throw new Error("randomId: length must be greater than 0");
15
+ }
16
+ const charsLength = charset.length;
17
+ let result = "";
18
+ // Browser & Node compatible crypto
19
+ const cryptoObj = typeof crypto !== "undefined"
20
+ ? crypto
21
+ : // @ts-ignore
22
+ require("crypto").webcrypto;
23
+ const randomValues = new Uint32Array(length);
24
+ cryptoObj.getRandomValues(randomValues);
25
+ for (let i = 0; i < length; i++) {
26
+ result += charset[randomValues[i] % charsLength];
27
+ }
28
+ return result;
29
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns human readable relative time
3
+ *
4
+ * @example
5
+ * timeAgo(new Date())
6
+ * timeAgo("2025-01-01")
7
+ * timeAgo(1700000000000)
8
+ */
9
+ export declare function timeAgo(date: Date | string | number, locale?: string): string;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Returns human readable relative time
3
+ *
4
+ * @example
5
+ * timeAgo(new Date())
6
+ * timeAgo("2025-01-01")
7
+ * timeAgo(1700000000000)
8
+ */
9
+ export function timeAgo(date, locale = "en") {
10
+ const inputDate = new Date(date);
11
+ const now = new Date();
12
+ if (isNaN(inputDate.getTime())) {
13
+ throw new Error("timeAgo: invalid date");
14
+ }
15
+ const diff = now.getTime() - inputDate.getTime();
16
+ if (diff < 1000)
17
+ return "just now";
18
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
19
+ const units = [
20
+ ["year", 1000 * 60 * 60 * 24 * 365],
21
+ ["month", 1000 * 60 * 60 * 24 * 30],
22
+ ["day", 1000 * 60 * 60 * 24],
23
+ ["hour", 1000 * 60 * 60],
24
+ ["minute", 1000 * 60],
25
+ ["second", 1000],
26
+ ];
27
+ for (const [unit, ms] of units) {
28
+ const value = Math.floor(diff / ms);
29
+ if (value >= 1) {
30
+ return rtf.format(-value, unit);
31
+ }
32
+ }
33
+ return "just now";
34
+ }
@@ -0,0 +1 @@
1
+ export * from "./core/index.js";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./core/index.js";
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "utills",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc"
15
+ }
16
+ }