umsizi 0.2.2 → 0.3.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/README.md +108 -0
- package/dist/index.d.ts +183 -2
- package/dist/index.js +175 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -117,6 +117,114 @@ const value = identity("umsizi");
|
|
|
117
117
|
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
#### `typedKeys`
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import { typedKeys } from "umsizi";
|
|
124
|
+
|
|
125
|
+
const user = { id: "1", name: "Jack" } as const;
|
|
126
|
+
|
|
127
|
+
typedKeys(user);
|
|
128
|
+
// ["id", "name"]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### `typedEntries`
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { typedEntries } from "umsizi";
|
|
135
|
+
|
|
136
|
+
const user = { id: "1", active: true } as const;
|
|
137
|
+
|
|
138
|
+
typedEntries(user);
|
|
139
|
+
// [["id", "1"], ["active", true]]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### `typedFromEntries`
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { typedFromEntries } from "umsizi";
|
|
146
|
+
|
|
147
|
+
const user = typedFromEntries([
|
|
148
|
+
["id", "1"],
|
|
149
|
+
["active", true],
|
|
150
|
+
] as const);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### `pick`
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { pick } from "umsizi";
|
|
157
|
+
|
|
158
|
+
pick({ id: "1", name: "Jack", role: "admin" }, "id", "role");
|
|
159
|
+
// { id: "1", role: "admin" }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### `omit`
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { omit } from "umsizi";
|
|
166
|
+
|
|
167
|
+
omit({ id: "1", name: "Jack", role: "admin" }, "role");
|
|
168
|
+
// { id: "1", name: "Jack" }
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
For the best autocomplete, prefer the rest-key form for `pick()` and `omit()`.
|
|
172
|
+
If you pass an array literal and want exact key inference, use `as const`:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
pick(user, ["id", "role"] as const);
|
|
176
|
+
omit(user, ["createdAt"] as const);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### `isEmpty`
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
import { isEmpty } from "umsizi";
|
|
183
|
+
|
|
184
|
+
isEmpty({});
|
|
185
|
+
// true
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### `hasOwn`
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import { hasOwn } from "umsizi";
|
|
192
|
+
|
|
193
|
+
const user = { id: "1" };
|
|
194
|
+
const key: string = "id";
|
|
195
|
+
|
|
196
|
+
if (hasOwn(user, key)) {
|
|
197
|
+
user[key];
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### `mapValues`
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { mapValues } from "umsizi";
|
|
205
|
+
|
|
206
|
+
mapValues({ draft: 1, published: 2 }, (value) => value * 2);
|
|
207
|
+
// { draft: 2, published: 4 }
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### `filterValues`
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import { filterValues } from "umsizi";
|
|
214
|
+
|
|
215
|
+
filterValues({ a: 1, b: 0, c: null }, (value) => value !== null);
|
|
216
|
+
// { a: 1, b: 0 }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### `compactObject`
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { compactObject } from "umsizi";
|
|
223
|
+
|
|
224
|
+
compactObject({ id: "1", nickname: null, active: false });
|
|
225
|
+
// { id: "1", active: false }
|
|
226
|
+
```
|
|
227
|
+
|
|
120
228
|
### React Utilities (`umsizi/react`)
|
|
121
229
|
|
|
122
230
|
#### `isRenderFunction`
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,73 @@ import { t as normalizePathname } from "./index-rZiv1o95.js";
|
|
|
2
2
|
import { t as hasFileExtension } from "./index-DtjbEW43.js";
|
|
3
3
|
import { t as isRenderFunction } from "./index-dktuz4mv.js";
|
|
4
4
|
|
|
5
|
+
//#region src/core/types.d.ts
|
|
6
|
+
type StringKeyOf<T extends object> = Extract<keyof T, string>;
|
|
7
|
+
type ObjectEntry<T extends object> = { [K in StringKeyOf<T>]: readonly [K, T[K]] }[StringKeyOf<T>];
|
|
8
|
+
type ObjectEntries<T extends object> = Array<ObjectEntry<T>>;
|
|
9
|
+
type EntryTuple = readonly [PropertyKey, unknown];
|
|
10
|
+
type EntryTuples = ReadonlyArray<EntryTuple>;
|
|
11
|
+
type ObjectFromEntries<T extends EntryTuples> = { [K in T[number] as K[0]]: K[1] };
|
|
12
|
+
type ValueMapper<T extends object, R> = (value: T[StringKeyOf<T>], key: StringKeyOf<T>, object: T) => R;
|
|
13
|
+
type ValuePredicate<T extends object> = (value: T[StringKeyOf<T>], key: StringKeyOf<T>, object: T) => boolean;
|
|
14
|
+
type ValueGuard<T extends object, S extends T[StringKeyOf<T>]> = (value: T[StringKeyOf<T>], key: StringKeyOf<T>, object: T) => value is S;
|
|
15
|
+
type MappedValues<T extends object, R> = { [K in StringKeyOf<T>]: R };
|
|
16
|
+
type FilteredValues<T extends object, S extends T[StringKeyOf<T>]> = Partial<{ [K in StringKeyOf<T>]: Extract<T[K], S> }>;
|
|
17
|
+
type CompactedObject<T extends object> = Partial<{ [K in StringKeyOf<T>]: Exclude<T[K], null | undefined> }>;
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/core/compact-object.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new object with all `null` and `undefined` values removed.
|
|
22
|
+
*
|
|
23
|
+
* Other falsy values such as `0`, `false`, `""`, and `NaN` are preserved.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const user = { id: "1", nickname: null, active: false } as const;
|
|
28
|
+
*
|
|
29
|
+
* compactObject(user); // { id: "1", active: false }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare function compactObject<T extends object>(object: T): CompactedObject<T>;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/core/filter-values.d.ts
|
|
35
|
+
/**
|
|
36
|
+
* Filters an object's own enumerable string-keyed properties by value.
|
|
37
|
+
*
|
|
38
|
+
* Supports both boolean predicates and type-guard predicates. The result type
|
|
39
|
+
* remains partial because any property may be removed at runtime.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const settings = { retries: 3, label: "", timeout: null } as const;
|
|
44
|
+
*
|
|
45
|
+
* filterValues(settings, (value) => value !== null);
|
|
46
|
+
* // { retries: 3, label: "" }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
declare function filterValues<T extends object, S extends T[Extract<keyof T, string>]>(object: T, predicate: ValueGuard<T, S>): FilteredValues<T, S>;
|
|
50
|
+
declare function filterValues<T extends object>(object: T, predicate: ValuePredicate<T>): FilteredValues<T, T[Extract<keyof T, string>]>;
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/core/has-own.d.ts
|
|
53
|
+
/**
|
|
54
|
+
* Checks whether an object has the given property as its own key.
|
|
55
|
+
*
|
|
56
|
+
* This is a typed wrapper around `Object.hasOwn` that narrows the provided key
|
|
57
|
+
* when the check succeeds.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const user = { id: "1" };
|
|
62
|
+
* const key: string = "id";
|
|
63
|
+
*
|
|
64
|
+
* if (hasOwn(user, key)) {
|
|
65
|
+
* user[key]; // key is narrowed to "id"
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare function hasOwn<T extends object, K$1 extends PropertyKey>(object: T, key: K$1): key is Extract<K$1, keyof T>;
|
|
70
|
+
//#endregion
|
|
5
71
|
//#region src/core/identity.d.ts
|
|
6
|
-
|
|
7
72
|
/**
|
|
8
73
|
* Returns the given value unchanged.
|
|
9
74
|
*
|
|
@@ -17,5 +82,121 @@ import { t as isRenderFunction } from "./index-dktuz4mv.js";
|
|
|
17
82
|
*/
|
|
18
83
|
declare function identity<T>(value: T): T;
|
|
19
84
|
//#endregion
|
|
20
|
-
|
|
85
|
+
//#region src/core/is-empty.d.ts
|
|
86
|
+
/**
|
|
87
|
+
* Returns `true` when an object has no own enumerable properties.
|
|
88
|
+
*
|
|
89
|
+
* Both string keys and symbol keys are considered. Non-enumerable properties
|
|
90
|
+
* are ignored.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* isEmpty({}); // true
|
|
95
|
+
* isEmpty({ id: "1" }); // false
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
declare function isEmpty(object: object): boolean;
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/core/map-values.d.ts
|
|
101
|
+
/**
|
|
102
|
+
* Maps the values of an object's own enumerable string-keyed properties while
|
|
103
|
+
* preserving the original enumerable string-key set.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* const counts = { draft: 1, published: 2 };
|
|
108
|
+
*
|
|
109
|
+
* mapValues(counts, (value) => value * 2);
|
|
110
|
+
* // { draft: 2, published: 4 }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
declare function mapValues<T extends object, R>(object: T, mapper: ValueMapper<T, R>): MappedValues<T, R>;
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/core/omit.d.ts
|
|
116
|
+
/**
|
|
117
|
+
* Creates a new object excluding the selected own enumerable properties.
|
|
118
|
+
*
|
|
119
|
+
* Prefer the rest-key form for the strongest autocomplete and inference.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const user = { id: "1", name: "Umsizi", role: "admin" } as const;
|
|
124
|
+
*
|
|
125
|
+
* omit(user, "id", "name"); // { role: "admin" }
|
|
126
|
+
* omit(user, ["role"] as const); // { id: "1", name: "Umsizi" }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
declare function omit<T extends object, const Keys extends readonly (keyof T)[]>(object: T, ...keys: Keys): Omit<T, Keys[number]>;
|
|
130
|
+
declare function omit<T extends object, const FirstKey extends keyof T, const RestKeys extends readonly (keyof T)[]>(object: T, keys: readonly [FirstKey, ...RestKeys]): Omit<T, FirstKey | RestKeys[number]>;
|
|
131
|
+
declare function omit<T extends object>(object: T, keys: readonly (keyof T)[]): Partial<T>;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/core/pick.d.ts
|
|
134
|
+
/**
|
|
135
|
+
* Creates a new object containing only the selected own properties.
|
|
136
|
+
*
|
|
137
|
+
* Prefer the rest-key form for the strongest autocomplete and inference.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* const user = { id: "1", name: "Umsizi", role: "admin" } as const;
|
|
142
|
+
*
|
|
143
|
+
* pick(user, "name"); // { name: "Umsizi" }
|
|
144
|
+
* pick(user, ["id", "role"] as const); // { id: "1", role: "admin" }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
declare function pick<T extends object, const Keys extends readonly (keyof T)[]>(object: T, ...keys: Keys): Pick<T, Keys[number]>;
|
|
148
|
+
declare function pick<T extends object, const FirstKey extends keyof T, const RestKeys extends readonly (keyof T)[]>(object: T, keys: readonly [FirstKey, ...RestKeys]): Pick<T, FirstKey | RestKeys[number]>;
|
|
149
|
+
declare function pick<T extends object>(object: T, keys: readonly (keyof T)[]): Partial<T>;
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/core/typed-entries.d.ts
|
|
152
|
+
/**
|
|
153
|
+
* Returns the own enumerable string-keyed entries of an object with preserved
|
|
154
|
+
* key/value pairing.
|
|
155
|
+
*
|
|
156
|
+
* This is a typed wrapper around `Object.entries`.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const user = { id: "1", active: true } as const;
|
|
161
|
+
*
|
|
162
|
+
* typedEntries(user); // [["id", "1"], ["active", true]]
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
declare function typedEntries<T extends object>(object: T): ObjectEntries<T>;
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/core/typed-from-entries.d.ts
|
|
168
|
+
/**
|
|
169
|
+
* Creates an object from entries while preserving the key and value types from
|
|
170
|
+
* the input tuple array.
|
|
171
|
+
*
|
|
172
|
+
* This is a typed wrapper around `Object.fromEntries`.
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* const status = typedFromEntries([
|
|
177
|
+
* ["id", "1"],
|
|
178
|
+
* ["active", true],
|
|
179
|
+
* ] as const);
|
|
180
|
+
*
|
|
181
|
+
* // inferred as: { id: "1"; active: true }
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
declare function typedFromEntries<const T extends EntryTuples>(entries: T): ObjectFromEntries<T>;
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region src/core/typed-keys.d.ts
|
|
187
|
+
/**
|
|
188
|
+
* Returns the own enumerable string keys of an object with preserved key types.
|
|
189
|
+
*
|
|
190
|
+
* This is a typed wrapper around `Object.keys`.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* const user = { id: "1", name: "Umsizi" } as const;
|
|
195
|
+
*
|
|
196
|
+
* typedKeys(user); // ["id", "name"]
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
declare function typedKeys<T extends object>(object: T): Array<StringKeyOf<T>>;
|
|
200
|
+
//#endregion
|
|
201
|
+
export { compactObject, filterValues, hasFileExtension, hasOwn, identity, isEmpty, isRenderFunction, mapValues, normalizePathname, omit, pick, typedEntries, typedFromEntries, typedKeys };
|
|
21
202
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,80 @@ import { t as normalizePathname } from "./next-C3wp7UoQ.js";
|
|
|
2
2
|
import { t as hasFileExtension } from "./node-D-nlzpmG.js";
|
|
3
3
|
import { t as isRenderFunction } from "./react-BCidSnzT.js";
|
|
4
4
|
|
|
5
|
+
//#region src/core/typed-keys.ts
|
|
6
|
+
/**
|
|
7
|
+
* Returns the own enumerable string keys of an object with preserved key types.
|
|
8
|
+
*
|
|
9
|
+
* This is a typed wrapper around `Object.keys`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const user = { id: "1", name: "Umsizi" } as const;
|
|
14
|
+
*
|
|
15
|
+
* typedKeys(user); // ["id", "name"]
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
function typedKeys(object) {
|
|
19
|
+
return Object.keys(object);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/core/compact-object.ts
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new object with all `null` and `undefined` values removed.
|
|
26
|
+
*
|
|
27
|
+
* Other falsy values such as `0`, `false`, `""`, and `NaN` are preserved.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const user = { id: "1", nickname: null, active: false } as const;
|
|
32
|
+
*
|
|
33
|
+
* compactObject(user); // { id: "1", active: false }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function compactObject(object) {
|
|
37
|
+
const result = {};
|
|
38
|
+
for (const key of typedKeys(object)) {
|
|
39
|
+
const value = object[key];
|
|
40
|
+
if (value != null) result[key] = value;
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/core/filter-values.ts
|
|
47
|
+
function filterValues(object, predicate) {
|
|
48
|
+
const result = {};
|
|
49
|
+
for (const key of typedKeys(object)) {
|
|
50
|
+
const value = object[key];
|
|
51
|
+
if (predicate(value, key, object)) result[key] = value;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/core/has-own.ts
|
|
58
|
+
/**
|
|
59
|
+
* Checks whether an object has the given property as its own key.
|
|
60
|
+
*
|
|
61
|
+
* This is a typed wrapper around `Object.hasOwn` that narrows the provided key
|
|
62
|
+
* when the check succeeds.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const user = { id: "1" };
|
|
67
|
+
* const key: string = "id";
|
|
68
|
+
*
|
|
69
|
+
* if (hasOwn(user, key)) {
|
|
70
|
+
* user[key]; // key is narrowed to "id"
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
function hasOwn(object, key) {
|
|
75
|
+
return Object.hasOwn(object, key);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
5
79
|
//#region src/core/identity.ts
|
|
6
80
|
/**
|
|
7
81
|
* Returns the given value unchanged.
|
|
@@ -19,5 +93,105 @@ function identity(value) {
|
|
|
19
93
|
}
|
|
20
94
|
|
|
21
95
|
//#endregion
|
|
22
|
-
|
|
96
|
+
//#region src/core/is-empty.ts
|
|
97
|
+
/**
|
|
98
|
+
* Returns `true` when an object has no own enumerable properties.
|
|
99
|
+
*
|
|
100
|
+
* Both string keys and symbol keys are considered. Non-enumerable properties
|
|
101
|
+
* are ignored.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* isEmpty({}); // true
|
|
106
|
+
* isEmpty({ id: "1" }); // false
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
function isEmpty(object) {
|
|
110
|
+
if (Object.keys(object).length > 0) return false;
|
|
111
|
+
for (const key of Object.getOwnPropertySymbols(object)) if (Object.prototype.propertyIsEnumerable.call(object, key)) return false;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/core/map-values.ts
|
|
117
|
+
/**
|
|
118
|
+
* Maps the values of an object's own enumerable string-keyed properties while
|
|
119
|
+
* preserving the original enumerable string-key set.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* const counts = { draft: 1, published: 2 };
|
|
124
|
+
*
|
|
125
|
+
* mapValues(counts, (value) => value * 2);
|
|
126
|
+
* // { draft: 2, published: 4 }
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
function mapValues(object, mapper) {
|
|
130
|
+
const result = {};
|
|
131
|
+
for (const key of typedKeys(object)) result[key] = mapper(object[key], key, object);
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/core/omit.ts
|
|
137
|
+
function omit(object, firstKeyOrKeys, ...restKeys) {
|
|
138
|
+
const keys = Array.isArray(firstKeyOrKeys) ? firstKeyOrKeys : [firstKeyOrKeys, ...restKeys];
|
|
139
|
+
const omittedKeys = new Set(keys);
|
|
140
|
+
const result = {};
|
|
141
|
+
for (const key of Reflect.ownKeys(object)) if (Object.prototype.propertyIsEnumerable.call(object, key) && !omittedKeys.has(key)) result[key] = object[key];
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/core/pick.ts
|
|
147
|
+
function pick(object, firstKeyOrKeys, ...restKeys) {
|
|
148
|
+
const keys = Array.isArray(firstKeyOrKeys) ? firstKeyOrKeys : [firstKeyOrKeys, ...restKeys];
|
|
149
|
+
const result = {};
|
|
150
|
+
for (const key of keys) if (hasOwn(object, key)) result[key] = object[key];
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/core/typed-entries.ts
|
|
156
|
+
/**
|
|
157
|
+
* Returns the own enumerable string-keyed entries of an object with preserved
|
|
158
|
+
* key/value pairing.
|
|
159
|
+
*
|
|
160
|
+
* This is a typed wrapper around `Object.entries`.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* const user = { id: "1", active: true } as const;
|
|
165
|
+
*
|
|
166
|
+
* typedEntries(user); // [["id", "1"], ["active", true]]
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
function typedEntries(object) {
|
|
170
|
+
return Object.entries(object);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/core/typed-from-entries.ts
|
|
175
|
+
/**
|
|
176
|
+
* Creates an object from entries while preserving the key and value types from
|
|
177
|
+
* the input tuple array.
|
|
178
|
+
*
|
|
179
|
+
* This is a typed wrapper around `Object.fromEntries`.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* const status = typedFromEntries([
|
|
184
|
+
* ["id", "1"],
|
|
185
|
+
* ["active", true],
|
|
186
|
+
* ] as const);
|
|
187
|
+
*
|
|
188
|
+
* // inferred as: { id: "1"; active: true }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
function typedFromEntries(entries) {
|
|
192
|
+
return Object.fromEntries(entries);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//#endregion
|
|
196
|
+
export { compactObject, filterValues, hasFileExtension, hasOwn, identity, isEmpty, isRenderFunction, mapValues, normalizePathname, omit, pick, typedEntries, typedFromEntries, typedKeys };
|
|
23
197
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/core/identity.ts"],"sourcesContent":["/**\n * Returns the given value unchanged.\n *\n * Useful as a default callback, a type-inference anchor, or a no-op\n * placeholder where a transform function is expected.\n *\n * @example\n * ```ts\n * identity(\"umsizi\"); // \"umsizi\"\n * ```\n */\nexport function identity<T>(value: T): T {\n\treturn value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAWA,SAAgB,SAAY,OAAa;AACxC,QAAO"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["result: Partial<T>","result: Partial<T>"],"sources":["../src/core/typed-keys.ts","../src/core/compact-object.ts","../src/core/filter-values.ts","../src/core/has-own.ts","../src/core/identity.ts","../src/core/is-empty.ts","../src/core/map-values.ts","../src/core/omit.ts","../src/core/pick.ts","../src/core/typed-entries.ts","../src/core/typed-from-entries.ts"],"sourcesContent":["import type { StringKeyOf } from \"./types\";\n\n/**\n * Returns the own enumerable string keys of an object with preserved key types.\n *\n * This is a typed wrapper around `Object.keys`.\n *\n * @example\n * ```ts\n * const user = { id: \"1\", name: \"Umsizi\" } as const;\n *\n * typedKeys(user); // [\"id\", \"name\"]\n * ```\n */\nexport function typedKeys<T extends object>(object: T): Array<StringKeyOf<T>> {\n\treturn Object.keys(object) as Array<StringKeyOf<T>>;\n}\n","import { typedKeys } from \"./typed-keys\";\nimport type { CompactedObject } from \"./types\";\n\n/**\n * Creates a new object with all `null` and `undefined` values removed.\n *\n * Other falsy values such as `0`, `false`, `\"\"`, and `NaN` are preserved.\n *\n * @example\n * ```ts\n * const user = { id: \"1\", nickname: null, active: false } as const;\n *\n * compactObject(user); // { id: \"1\", active: false }\n * ```\n */\nexport function compactObject<T extends object>(object: T): CompactedObject<T> {\n\tconst result = {} as CompactedObject<T>;\n\n\tfor (const key of typedKeys(object)) {\n\t\tconst value = object[key];\n\n\t\tif (value != null) {\n\t\t\tresult[key] = value as Exclude<T[typeof key], null | undefined>;\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { typedKeys } from \"./typed-keys\";\nimport type { FilteredValues, ValueGuard, ValuePredicate } from \"./types\";\n\n/**\n * Filters an object's own enumerable string-keyed properties by value.\n *\n * Supports both boolean predicates and type-guard predicates. The result type\n * remains partial because any property may be removed at runtime.\n *\n * @example\n * ```ts\n * const settings = { retries: 3, label: \"\", timeout: null } as const;\n *\n * filterValues(settings, (value) => value !== null);\n * // { retries: 3, label: \"\" }\n * ```\n */\nexport function filterValues<\n\tT extends object,\n\tS extends T[Extract<keyof T, string>],\n>(object: T, predicate: ValueGuard<T, S>): FilteredValues<T, S>;\nexport function filterValues<T extends object>(\n\tobject: T,\n\tpredicate: ValuePredicate<T>,\n): FilteredValues<T, T[Extract<keyof T, string>]>;\nexport function filterValues<T extends object>(\n\tobject: T,\n\tpredicate: ValuePredicate<T>,\n): FilteredValues<T, T[Extract<keyof T, string>]> {\n\tconst result = {} as FilteredValues<T, T[Extract<keyof T, string>]>;\n\n\tfor (const key of typedKeys(object)) {\n\t\tconst value = object[key];\n\n\t\tif (predicate(value, key, object)) {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Checks whether an object has the given property as its own key.\n *\n * This is a typed wrapper around `Object.hasOwn` that narrows the provided key\n * when the check succeeds.\n *\n * @example\n * ```ts\n * const user = { id: \"1\" };\n * const key: string = \"id\";\n *\n * if (hasOwn(user, key)) {\n * user[key]; // key is narrowed to \"id\"\n * }\n * ```\n */\nexport function hasOwn<T extends object, K extends PropertyKey>(\n\tobject: T,\n\tkey: K,\n): key is Extract<K, keyof T> {\n\treturn Object.hasOwn(object, key);\n}\n","/**\n * Returns the given value unchanged.\n *\n * Useful as a default callback, a type-inference anchor, or a no-op\n * placeholder where a transform function is expected.\n *\n * @example\n * ```ts\n * identity(\"umsizi\"); // \"umsizi\"\n * ```\n */\nexport function identity<T>(value: T): T {\n\treturn value;\n}\n","/**\n * Returns `true` when an object has no own enumerable properties.\n *\n * Both string keys and symbol keys are considered. Non-enumerable properties\n * are ignored.\n *\n * @example\n * ```ts\n * isEmpty({}); // true\n * isEmpty({ id: \"1\" }); // false\n * ```\n */\nexport function isEmpty(object: object): boolean {\n\tif (Object.keys(object).length > 0) {\n\t\treturn false;\n\t}\n\n\tfor (const key of Object.getOwnPropertySymbols(object)) {\n\t\tif (Object.prototype.propertyIsEnumerable.call(object, key)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n","import { typedKeys } from \"./typed-keys\";\nimport type { MappedValues, ValueMapper } from \"./types\";\n\n/**\n * Maps the values of an object's own enumerable string-keyed properties while\n * preserving the original enumerable string-key set.\n *\n * @example\n * ```ts\n * const counts = { draft: 1, published: 2 };\n *\n * mapValues(counts, (value) => value * 2);\n * // { draft: 2, published: 4 }\n * ```\n */\nexport function mapValues<T extends object, R>(\n\tobject: T,\n\tmapper: ValueMapper<T, R>,\n): MappedValues<T, R> {\n\tconst result = {} as MappedValues<T, R>;\n\n\tfor (const key of typedKeys(object)) {\n\t\tresult[key] = mapper(object[key], key, object);\n\t}\n\n\treturn result;\n}\n","/**\n * Creates a new object excluding the selected own enumerable properties.\n *\n * Prefer the rest-key form for the strongest autocomplete and inference.\n *\n * @example\n * ```ts\n * const user = { id: \"1\", name: \"Umsizi\", role: \"admin\" } as const;\n *\n * omit(user, \"id\", \"name\"); // { role: \"admin\" }\n * omit(user, [\"role\"] as const); // { id: \"1\", name: \"Umsizi\" }\n * ```\n */\nexport function omit<T extends object, const Keys extends readonly (keyof T)[]>(\n\tobject: T,\n\t...keys: Keys\n): Omit<T, Keys[number]>;\nexport function omit<\n\tT extends object,\n\tconst FirstKey extends keyof T,\n\tconst RestKeys extends readonly (keyof T)[],\n>(\n\tobject: T,\n\tkeys: readonly [FirstKey, ...RestKeys],\n): Omit<T, FirstKey | RestKeys[number]>;\nexport function omit<T extends object>(\n\tobject: T,\n\tkeys: readonly (keyof T)[],\n): Partial<T>;\nexport function omit<T extends object>(\n\tobject: T,\n\tfirstKeyOrKeys: keyof T | readonly (keyof T)[],\n\t...restKeys: readonly (keyof T)[]\n): Partial<T> {\n\tconst keys = (\n\t\tArray.isArray(firstKeyOrKeys)\n\t\t\t? firstKeyOrKeys\n\t\t\t: [firstKeyOrKeys, ...restKeys]\n\t) as readonly (keyof T)[];\n\tconst omittedKeys = new Set<PropertyKey>(keys as readonly PropertyKey[]);\n\tconst result: Partial<T> = {};\n\n\tfor (const key of Reflect.ownKeys(object) as (keyof T)[]) {\n\t\tif (\n\t\t\tObject.prototype.propertyIsEnumerable.call(object, key) &&\n\t\t\t!omittedKeys.has(key)\n\t\t) {\n\t\t\t(result as T)[key] = object[key];\n\t\t}\n\t}\n\n\treturn result;\n}\n","import { hasOwn } from \"./has-own\";\n\n/**\n * Creates a new object containing only the selected own properties.\n *\n * Prefer the rest-key form for the strongest autocomplete and inference.\n *\n * @example\n * ```ts\n * const user = { id: \"1\", name: \"Umsizi\", role: \"admin\" } as const;\n *\n * pick(user, \"name\"); // { name: \"Umsizi\" }\n * pick(user, [\"id\", \"role\"] as const); // { id: \"1\", role: \"admin\" }\n * ```\n */\nexport function pick<T extends object, const Keys extends readonly (keyof T)[]>(\n\tobject: T,\n\t...keys: Keys\n): Pick<T, Keys[number]>;\nexport function pick<\n\tT extends object,\n\tconst FirstKey extends keyof T,\n\tconst RestKeys extends readonly (keyof T)[],\n>(\n\tobject: T,\n\tkeys: readonly [FirstKey, ...RestKeys],\n): Pick<T, FirstKey | RestKeys[number]>;\nexport function pick<T extends object>(\n\tobject: T,\n\tkeys: readonly (keyof T)[],\n): Partial<T>;\nexport function pick<T extends object>(\n\tobject: T,\n\tfirstKeyOrKeys: keyof T | readonly (keyof T)[],\n\t...restKeys: readonly (keyof T)[]\n): Partial<T> {\n\tconst keys = (\n\t\tArray.isArray(firstKeyOrKeys)\n\t\t\t? firstKeyOrKeys\n\t\t\t: [firstKeyOrKeys, ...restKeys]\n\t) as readonly (keyof T)[];\n\tconst result: Partial<T> = {};\n\n\tfor (const key of keys) {\n\t\tif (hasOwn(object, key)) {\n\t\t\tresult[key] = object[key];\n\t\t}\n\t}\n\n\treturn result;\n}\n","import type { ObjectEntries } from \"./types\";\n\n/**\n * Returns the own enumerable string-keyed entries of an object with preserved\n * key/value pairing.\n *\n * This is a typed wrapper around `Object.entries`.\n *\n * @example\n * ```ts\n * const user = { id: \"1\", active: true } as const;\n *\n * typedEntries(user); // [[\"id\", \"1\"], [\"active\", true]]\n * ```\n */\nexport function typedEntries<T extends object>(object: T): ObjectEntries<T> {\n\treturn Object.entries(object) as unknown as ObjectEntries<T>;\n}\n","import type { EntryTuples, ObjectFromEntries } from \"./types\";\n\n/**\n * Creates an object from entries while preserving the key and value types from\n * the input tuple array.\n *\n * This is a typed wrapper around `Object.fromEntries`.\n *\n * @example\n * ```ts\n * const status = typedFromEntries([\n * [\"id\", \"1\"],\n * [\"active\", true],\n * ] as const);\n *\n * // inferred as: { id: \"1\"; active: true }\n * ```\n */\nexport function typedFromEntries<const T extends EntryTuples>(\n\tentries: T,\n): ObjectFromEntries<T> {\n\treturn Object.fromEntries(entries) as ObjectFromEntries<T>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAcA,SAAgB,UAA4B,QAAkC;AAC7E,QAAO,OAAO,KAAK,OAAO;;;;;;;;;;;;;;;;;ACA3B,SAAgB,cAAgC,QAA+B;CAC9E,MAAM,SAAS,EAAE;AAEjB,MAAK,MAAM,OAAO,UAAU,OAAO,EAAE;EACpC,MAAM,QAAQ,OAAO;AAErB,MAAI,SAAS,KACZ,QAAO,OAAO;;AAIhB,QAAO;;;;;ACDR,SAAgB,aACf,QACA,WACiD;CACjD,MAAM,SAAS,EAAE;AAEjB,MAAK,MAAM,OAAO,UAAU,OAAO,EAAE;EACpC,MAAM,QAAQ,OAAO;AAErB,MAAI,UAAU,OAAO,KAAK,OAAO,CAChC,QAAO,OAAO;;AAIhB,QAAO;;;;;;;;;;;;;;;;;;;;;ACvBR,SAAgB,OACf,QACA,KAC6B;AAC7B,QAAO,OAAO,OAAO,QAAQ,IAAI;;;;;;;;;;;;;;;;ACTlC,SAAgB,SAAY,OAAa;AACxC,QAAO;;;;;;;;;;;;;;;;;ACAR,SAAgB,QAAQ,QAAyB;AAChD,KAAI,OAAO,KAAK,OAAO,CAAC,SAAS,EAChC,QAAO;AAGR,MAAK,MAAM,OAAO,OAAO,sBAAsB,OAAO,CACrD,KAAI,OAAO,UAAU,qBAAqB,KAAK,QAAQ,IAAI,CAC1D,QAAO;AAIT,QAAO;;;;;;;;;;;;;;;;;ACRR,SAAgB,UACf,QACA,QACqB;CACrB,MAAM,SAAS,EAAE;AAEjB,MAAK,MAAM,OAAO,UAAU,OAAO,CAClC,QAAO,OAAO,OAAO,OAAO,MAAM,KAAK,OAAO;AAG/C,QAAO;;;;;ACIR,SAAgB,KACf,QACA,gBACA,GAAG,UACU;CACb,MAAM,OACL,MAAM,QAAQ,eAAe,GAC1B,iBACA,CAAC,gBAAgB,GAAG,SAAS;CAEjC,MAAM,cAAc,IAAI,IAAiB,KAA+B;CACxE,MAAMA,SAAqB,EAAE;AAE7B,MAAK,MAAM,OAAO,QAAQ,QAAQ,OAAO,CACxC,KACC,OAAO,UAAU,qBAAqB,KAAK,QAAQ,IAAI,IACvD,CAAC,YAAY,IAAI,IAAI,CAErB,CAAC,OAAa,OAAO,OAAO;AAI9B,QAAO;;;;;ACpBR,SAAgB,KACf,QACA,gBACA,GAAG,UACU;CACb,MAAM,OACL,MAAM,QAAQ,eAAe,GAC1B,iBACA,CAAC,gBAAgB,GAAG,SAAS;CAEjC,MAAMC,SAAqB,EAAE;AAE7B,MAAK,MAAM,OAAO,KACjB,KAAI,OAAO,QAAQ,IAAI,CACtB,QAAO,OAAO,OAAO;AAIvB,QAAO;;;;;;;;;;;;;;;;;;AClCR,SAAgB,aAA+B,QAA6B;AAC3E,QAAO,OAAO,QAAQ,OAAO;;;;;;;;;;;;;;;;;;;;;ACE9B,SAAgB,iBACf,SACuB;AACvB,QAAO,OAAO,YAAY,QAAQ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umsizi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A zero-dependency TypeScript utility library.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Jack-WebDev",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
],
|
|
93
93
|
"scripts": {
|
|
94
94
|
"build": "tsdown",
|
|
95
|
-
"ci": "pnpm run lint && pnpm run check-types && pnpm run test:coverage && pnpm run build && pnpm exec size-limit && pnpm run check:package",
|
|
95
|
+
"ci": "pnpm run lint && pnpm run check-types && pnpm run check-types:examples && pnpm run test:coverage && pnpm run build && pnpm exec size-limit && pnpm run check:package",
|
|
96
96
|
"check:package": "pnpm run check:package:npm && pnpm run check:package:jsr",
|
|
97
97
|
"check:package:jsr": "pnpm dlx jsr publish --dry-run --allow-dirty",
|
|
98
98
|
"check:package:npm": "HUSKY=0 npm_config_cache=/tmp/umsizi-npm-cache npm pack --dry-run --ignore-scripts",
|
|
@@ -101,6 +101,7 @@
|
|
|
101
101
|
"lint": "biome check .",
|
|
102
102
|
"lint:fix": "biome check --write .",
|
|
103
103
|
"check-types": "tsc --noEmit",
|
|
104
|
+
"check-types:examples": "tsc --noEmit --project tsconfig.json --pretty false",
|
|
104
105
|
"release:publish": "pnpm run build && pnpm exec changeset publish && pnpm dlx jsr publish --allow-dirty",
|
|
105
106
|
"release:version": "pnpm exec changeset version && node ./scripts/sync-release-version.mjs",
|
|
106
107
|
"test": "vitest run",
|