umsizi 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present Jack WebDev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ # Umsizi
2
+
3
+ > The missing TypeScript standard library.
4
+
5
+ **Umsizi** (pronounced *oom-see-zee*) is a modern, zero-dependency utility library built from the ground up for TypeScript applications. The name comes from the Zulu word for **"helper"** or **"assistant"**—which is exactly what this library is designed to be.
6
+
7
+ It provides small, focused utilities that preserve types, eliminate repetitive code, and replace the disorganized `utils/` folder every project eventually creates.
8
+
9
+ ```ts
10
+ import { identity } from "umsizi";
11
+
12
+ const user = {
13
+ id: "1",
14
+ name: "Jack",
15
+ };
16
+
17
+ const result = identity(user);
18
+ // inferred as:
19
+ // {
20
+ // id: string;
21
+ // name: string;
22
+ // }
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Why Umsizi
28
+
29
+ Most TypeScript projects slowly accumulate a standard set of custom helpers:
30
+
31
+ ```ts
32
+ src/
33
+ └─ utils/
34
+ ├─ arrays.ts
35
+ ├─ objects.ts
36
+ ├─ promises.ts
37
+ └─ guards.ts
38
+
39
+ ```
40
+
41
+ These copy-pasted snippets usually become undocumented, inconsistently typed, and completely untested. Umsizi replaces that folder with a single, production-ready, and highly optimized package.
42
+
43
+ ### Core Principles
44
+
45
+ - **TypeScript-First:** Built around strict type inference. Types flow naturally through every utility so you never have to manually cast with `as`.
46
+ - **Composition Over Configuration:** Every function does exactly one thing cleanly, favoring simple composition over complex, bloated configuration objects.
47
+ - **Zero Dependencies:** No runtime dependencies means smaller installs, fewer security vulnerabilities, and predictable behavior.
48
+ - **Tree-Shakable:** Only ship what you use. Unused utilities will never affect your production bundle size.
49
+ - **Immutable by Default:** Utilities avoid mutating your existing data structures.
50
+
51
+ ---
52
+
53
+ ## Installation
54
+
55
+ Install via your package manager of choice:
56
+
57
+ ```bash
58
+ # npm
59
+ npm install umsizi
60
+
61
+ # pnpm
62
+ pnpm add umsizi
63
+
64
+ # yarn
65
+ yarn add umsizi
66
+
67
+ # bun
68
+ bun add umsizi
69
+
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Package Structure
75
+
76
+ Umsizi is split into focused entry points:
77
+
78
+ ```ts
79
+ import { identity } from "umsizi";
80
+ import { isRenderFunction } from "umsizi/react";
81
+ import { normalizePathname } from "umsizi/next";
82
+ import { hasFileExtension } from "umsizi/node";
83
+ ```
84
+
85
+ Current structure:
86
+
87
+ ```txt
88
+ src/
89
+ core/
90
+ react/
91
+ next/
92
+ node/
93
+ ```
94
+
95
+ - `umsizi`: framework-agnostic core utilities
96
+ - `umsizi/react`: React-oriented helpers
97
+ - `umsizi/next`: Next.js-oriented helpers
98
+ - `umsizi/node`: Node-oriented helpers
99
+
100
+ ---
101
+
102
+ ## API Reference
103
+
104
+ ### Core Utilities
105
+
106
+ #### `identity`
107
+
108
+ ```ts
109
+ import { identity } from "umsizi";
110
+
111
+ const value = identity("umsizi");
112
+ // "umsizi"
113
+
114
+ ```
115
+
116
+ ### React Utilities (`umsizi/react`)
117
+
118
+ #### `isRenderFunction`
119
+
120
+ Small guard for values that should be callable in render-oriented code paths.
121
+
122
+ ```ts
123
+ import { isRenderFunction } from "umsizi/react";
124
+
125
+ const value: unknown = () => "ready";
126
+
127
+ if (isRenderFunction(value)) {
128
+ value();
129
+ }
130
+ ```
131
+
132
+ ### Next.js Utilities (`umsizi/next`)
133
+
134
+ #### `normalizePathname`
135
+
136
+ Normalizes path-like strings by ensuring a leading slash, collapsing duplicate slashes, and preserving root.
137
+
138
+ ```ts
139
+ import { normalizePathname } from "umsizi/next";
140
+
141
+ normalizePathname("dashboard");
142
+ // "/dashboard"
143
+
144
+ normalizePathname("//dashboard///settings");
145
+ // "/dashboard/settings"
146
+ ```
147
+
148
+ ### Node.js Utilities (`umsizi/node`)
149
+
150
+ #### `hasFileExtension`
151
+
152
+ Checks whether a file path ends with a specific extension.
153
+
154
+ ```ts
155
+ import { hasFileExtension } from "umsizi/node";
156
+
157
+ hasFileExtension("src/index.ts", ".ts");
158
+ // true
159
+
160
+ hasFileExtension("package.json", "json");
161
+ // true
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Current Status
167
+
168
+ Umsizi is still in early development. The package structure is in place, the initial utilities are implemented, and the public API is intentionally small.
169
+
170
+ New helpers should only be added when they meet the project standards for:
171
+
172
+ - type safety
173
+ - runtime correctness
174
+ - API clarity
175
+ - zero-dependency design
176
+
177
+ ---
178
+
179
+ ## How Umsizi Compares
180
+
181
+ - **vs Lodash:** Lodash was built for an era before modern JavaScript and TypeScript existed. Umsizi embraces modern JS features and prioritizes zero-overhead type inference.
182
+ - **vs Radash:** While Radash is excellent, Umsizi hones in purely on application development patterns and strict, seamless type inference.
183
+ - **vs Remeda:** Remeda heavily emphasizes functional programming paradigms like data-last currying. Umsizi targets straightforward, standard-library-style code for everyday projects.
184
+
185
+ ---
186
+
187
+ ## Contributing
188
+
189
+ See [CONTRIBUTING.md](./CONTRIBUTING.md).
190
+
191
+ If you want to introduce a helper, ensure it meets the baseline:
192
+
193
+ 1. It solves a highly recurring, real-world application problem.
194
+ 2. It features bulletproof TypeScript type safety.
195
+ 3. It includes comprehensive runtime and type-level tests.
196
+ 4. It remains entirely dependency-free.
197
+
198
+ ---
199
+
200
+ ## License
201
+
202
+ MIT
@@ -0,0 +1,5 @@
1
+ //#region src/node/has-file-extension.d.ts
2
+ declare function hasFileExtension(filePath: string, extension: string): boolean;
3
+ //#endregion
4
+ export { hasFileExtension as t };
5
+ //# sourceMappingURL=index-Bi-DJKKn.d.ts.map
@@ -0,0 +1,5 @@
1
+ //#region src/next/normalize-pathname.d.ts
2
+ declare function normalizePathname(pathname: string): string;
3
+ //#endregion
4
+ export { normalizePathname as t };
5
+ //# sourceMappingURL=index-Cfup-UnB.d.ts.map
@@ -0,0 +1,5 @@
1
+ //#region src/react/is-render-function.d.ts
2
+ declare function isRenderFunction(value: unknown): value is (...args: readonly unknown[]) => unknown;
3
+ //#endregion
4
+ export { isRenderFunction as t };
5
+ //# sourceMappingURL=index-uHJbGgdS.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { t as normalizePathname } from "./index-Cfup-UnB.js";
2
+ import { t as hasFileExtension } from "./index-Bi-DJKKn.js";
3
+ import { t as isRenderFunction } from "./index-uHJbGgdS.js";
4
+
5
+ //#region src/core/identity.d.ts
6
+ declare function identity<T>(value: T): T;
7
+ //#endregion
8
+ export { hasFileExtension, identity, isRenderFunction, normalizePathname };
9
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { t as normalizePathname } from "./next-B9pvCR1P.js";
2
+ import { t as hasFileExtension } from "./node-Di-uva1n.js";
3
+ import { t as isRenderFunction } from "./react-DPRQiKYh.js";
4
+
5
+ //#region src/core/identity.ts
6
+ function identity(value) {
7
+ return value;
8
+ }
9
+
10
+ //#endregion
11
+ export { hasFileExtension, identity, isRenderFunction, normalizePathname };
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/core/identity.ts"],"sourcesContent":["export function identity<T>(value: T): T {\n\treturn value;\n}\n"],"mappings":";;;;;AAAA,SAAgB,SAAY,OAAa;AACxC,QAAO"}
@@ -0,0 +1,11 @@
1
+ //#region src/next/normalize-pathname.ts
2
+ function normalizePathname(pathname) {
3
+ if (pathname === "") return "/";
4
+ const normalized = pathname.replace(/\/{2,}/g, "/").replace(/\/$/, "");
5
+ if (normalized === "") return "/";
6
+ return normalized.startsWith("/") ? normalized : `/${normalized}`;
7
+ }
8
+
9
+ //#endregion
10
+ export { normalizePathname as t };
11
+ //# sourceMappingURL=next-B9pvCR1P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-B9pvCR1P.js","names":[],"sources":["../src/next/normalize-pathname.ts"],"sourcesContent":["export function normalizePathname(pathname: string): string {\n\tif (pathname === \"\") {\n\t\treturn \"/\";\n\t}\n\n\tconst normalized = pathname.replace(/\\/{2,}/g, \"/\").replace(/\\/$/, \"\");\n\n\tif (normalized === \"\") {\n\t\treturn \"/\";\n\t}\n\n\treturn normalized.startsWith(\"/\") ? normalized : `/${normalized}`;\n}\n"],"mappings":";AAAA,SAAgB,kBAAkB,UAA0B;AAC3D,KAAI,aAAa,GAChB,QAAO;CAGR,MAAM,aAAa,SAAS,QAAQ,WAAW,IAAI,CAAC,QAAQ,OAAO,GAAG;AAEtE,KAAI,eAAe,GAClB,QAAO;AAGR,QAAO,WAAW,WAAW,IAAI,GAAG,aAAa,IAAI"}
package/dist/next.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { t as normalizePathname } from "./index-Cfup-UnB.js";
2
+ export { normalizePathname };
package/dist/next.js ADDED
@@ -0,0 +1,3 @@
1
+ import { t as normalizePathname } from "./next-B9pvCR1P.js";
2
+
3
+ export { normalizePathname };
@@ -0,0 +1,9 @@
1
+ //#region src/node/has-file-extension.ts
2
+ function hasFileExtension(filePath, extension) {
3
+ const normalizedExtension = extension.startsWith(".") ? extension : `.${extension}`;
4
+ return filePath.endsWith(normalizedExtension);
5
+ }
6
+
7
+ //#endregion
8
+ export { hasFileExtension as t };
9
+ //# sourceMappingURL=node-Di-uva1n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-Di-uva1n.js","names":[],"sources":["../src/node/has-file-extension.ts"],"sourcesContent":["export function hasFileExtension(filePath: string, extension: string): boolean {\n\tconst normalizedExtension = extension.startsWith(\".\")\n\t\t? extension\n\t\t: `.${extension}`;\n\n\treturn filePath.endsWith(normalizedExtension);\n}\n"],"mappings":";AAAA,SAAgB,iBAAiB,UAAkB,WAA4B;CAC9E,MAAM,sBAAsB,UAAU,WAAW,IAAI,GAClD,YACA,IAAI;AAEP,QAAO,SAAS,SAAS,oBAAoB"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { t as hasFileExtension } from "./index-Bi-DJKKn.js";
2
+ export { hasFileExtension };
package/dist/node.js ADDED
@@ -0,0 +1,3 @@
1
+ import { t as hasFileExtension } from "./node-Di-uva1n.js";
2
+
3
+ export { hasFileExtension };
@@ -0,0 +1,8 @@
1
+ //#region src/react/is-render-function.ts
2
+ function isRenderFunction(value) {
3
+ return typeof value === "function";
4
+ }
5
+
6
+ //#endregion
7
+ export { isRenderFunction as t };
8
+ //# sourceMappingURL=react-DPRQiKYh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-DPRQiKYh.js","names":[],"sources":["../src/react/is-render-function.ts"],"sourcesContent":["export function isRenderFunction(\n\tvalue: unknown,\n): value is (...args: readonly unknown[]) => unknown {\n\treturn typeof value === \"function\";\n}\n"],"mappings":";AAAA,SAAgB,iBACf,OACoD;AACpD,QAAO,OAAO,UAAU"}
@@ -0,0 +1,2 @@
1
+ import { t as isRenderFunction } from "./index-uHJbGgdS.js";
2
+ export { isRenderFunction };
package/dist/react.js ADDED
@@ -0,0 +1,3 @@
1
+ import { t as isRenderFunction } from "./react-DPRQiKYh.js";
2
+
3
+ export { isRenderFunction };
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "umsizi",
3
+ "version": "0.1.0",
4
+ "description": "A zero-dependency TypeScript utility library.",
5
+ "license": "MIT",
6
+ "author": "Jack-WebDev",
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/Jack-WebDev/umsizi.git"
11
+ },
12
+ "homepage": "https://github.com/Jack-WebDev/umsizi#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/Jack-WebDev/umsizi/issues"
15
+ },
16
+ "keywords": [
17
+ "typescript",
18
+ "utilities",
19
+ "helpers",
20
+ "toolkit",
21
+ "zero-dependency"
22
+ ],
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "sideEffects": false,
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./react": {
33
+ "types": "./dist/react.d.ts",
34
+ "import": "./dist/react.js"
35
+ },
36
+ "./next": {
37
+ "types": "./dist/next.d.ts",
38
+ "import": "./dist/next.js"
39
+ },
40
+ "./node": {
41
+ "types": "./dist/node.d.ts",
42
+ "import": "./dist/node.js"
43
+ }
44
+ },
45
+ "types": "./dist/index.d.ts",
46
+ "main": "./dist/index.js",
47
+ "module": "./dist/index.js",
48
+ "scripts": {
49
+ "build": "tsdown",
50
+ "ci": "pnpm run lint && pnpm run check-types && pnpm run test && pnpm run build && pnpm run check:package",
51
+ "check:package": "pnpm run check:package:npm && pnpm run check:package:jsr",
52
+ "check:package:jsr": "pnpm dlx jsr publish --dry-run --allow-dirty",
53
+ "check:package:npm": "HUSKY=0 npm_config_cache=/tmp/umsizi-npm-cache npm pack --dry-run --ignore-scripts",
54
+ "dev": "tsdown --watch",
55
+ "format": "biome format --write .",
56
+ "lint": "biome check .",
57
+ "lint:fix": "biome check --write .",
58
+ "check-types": "tsc --noEmit",
59
+ "release:publish": "pnpm run build && pnpm exec changeset publish && pnpm dlx jsr publish --allow-dirty",
60
+ "release:version": "pnpm exec changeset version && node ./scripts/sync-release-version.mjs",
61
+ "test": "vitest run",
62
+ "prepare": "husky"
63
+ },
64
+ "devDependencies": {
65
+ "@biomejs/biome": "2.5.1",
66
+ "husky": "^9.1.7",
67
+ "tsdown": "^0.16.8",
68
+ "typescript": "5.9.2",
69
+ "vitest": "4.1.9",
70
+ "lint-staged": "^16.1.2",
71
+ "@changesets/cli": "2.31.0"
72
+ },
73
+ "packageManager": "pnpm@10.32.1",
74
+ "publishConfig": {
75
+ "access": "public"
76
+ },
77
+ "lint-staged": {
78
+ "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}": [
79
+ "biome check --write ."
80
+ ]
81
+ },
82
+ "engines": {
83
+ "node": ">=20"
84
+ }
85
+ }