@duplojs/utils 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/README.md +2 -0
- package/dist/addThis.d.ts +2 -0
- package/dist/clone.d.ts +2 -0
- package/dist/entryUseMapper.d.ts +6 -0
- package/dist/escapeRegExp.d.ts +1 -0
- package/dist/expectType.d.ts +5 -0
- package/dist/getLastOfUnion.d.ts +2 -0
- package/dist/getPropsWithTrueValue.d.ts +3 -0
- package/dist/getTypedEntries.d.ts +6 -0
- package/dist/getTypedKeys.d.ts +1 -0
- package/dist/hasKey.d.ts +2 -0
- package/dist/incremente.d.ts +33 -0
- package/dist/index.cjs +131 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.mjs +118 -0
- package/dist/isAny.d.ts +1 -0
- package/dist/overrideInterface.d.ts +1 -0
- package/dist/partialKeys.d.ts +2 -0
- package/dist/requiredKeys.d.ts +2 -0
- package/dist/simpleClone.d.ts +1 -0
- package/dist/simplifyType.d.ts +6 -0
- package/dist/sleep.d.ts +1 -0
- package/dist/stringToBytes.d.ts +15 -0
- package/dist/types.d.ts +4 -0
- package/dist/unPartial.d.ts +10 -0
- package/dist/unionToIntersection.d.ts +1 -0
- package/dist/unionToTuple.d.ts +4 -0
- package/dist/uniqueGeneric.d.ts +5 -0
- package/package.json +60 -0
package/README.md
ADDED
package/dist/clone.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AnyFunction, ObjectEntry, ObjectKey } from "./types";
|
|
2
|
+
import type { UnionToIntersection } from "./unionToIntersection";
|
|
3
|
+
export type EntriesToMapper<E extends ObjectEntry> = UnionToIntersection<E extends [infer K, infer V] ? {
|
|
4
|
+
[_P in K extends ObjectKey ? K : never]: (_value: V, _key: K) => any;
|
|
5
|
+
} : never>;
|
|
6
|
+
export declare function entryUseMapper<E extends ObjectEntry, M extends EntriesToMapper<E>, R = ReturnType<M[keyof M] extends AnyFunction ? M[keyof M] : never>>([key, value]: E, mapper: M): R;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function escapeRegExp(text: string): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export interface ExpectType<GenericOne extends unknown, GenericTwo extends unknown, GenericRule extends ((<V>() => V extends GenericOne ? 1 : 2) extends (<V>() => V extends GenericTwo ? 1 : 2) ? "strict" : (GenericOne extends GenericTwo ? true : 1) extends (GenericTwo extends GenericOne ? true : 2) ? "flexible" : GenericOne extends GenericTwo ? "one-extends-two" : GenericTwo extends GenericOne ? "two-extends-one" : never)> {
|
|
2
|
+
one: GenericOne;
|
|
3
|
+
two: GenericTwo;
|
|
4
|
+
rule: GenericRule;
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getTypedKeys<O extends object>(object: O): (keyof O)[];
|
package/dist/hasKey.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface NumberTail {
|
|
2
|
+
0: 1;
|
|
3
|
+
1: 2;
|
|
4
|
+
2: 3;
|
|
5
|
+
3: 4;
|
|
6
|
+
4: 5;
|
|
7
|
+
5: 6;
|
|
8
|
+
6: 7;
|
|
9
|
+
7: 8;
|
|
10
|
+
8: 9;
|
|
11
|
+
9: 10;
|
|
12
|
+
10: 11;
|
|
13
|
+
11: 12;
|
|
14
|
+
12: 13;
|
|
15
|
+
13: 14;
|
|
16
|
+
14: 15;
|
|
17
|
+
15: 16;
|
|
18
|
+
16: 17;
|
|
19
|
+
17: 18;
|
|
20
|
+
18: 19;
|
|
21
|
+
19: 20;
|
|
22
|
+
20: 21;
|
|
23
|
+
21: 22;
|
|
24
|
+
22: 23;
|
|
25
|
+
23: 24;
|
|
26
|
+
24: 25;
|
|
27
|
+
25: 26;
|
|
28
|
+
26: 27;
|
|
29
|
+
27: 28;
|
|
30
|
+
28: 29;
|
|
31
|
+
29: 30;
|
|
32
|
+
}
|
|
33
|
+
export type AddOne<T extends number> = T extends keyof NumberTail ? NumberTail[T] : never;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function getTypedEntries(object) {
|
|
4
|
+
return Object.entries(object);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function clone(unknownValue) {
|
|
8
|
+
if (!unknownValue) {
|
|
9
|
+
return unknownValue;
|
|
10
|
+
}
|
|
11
|
+
else if (typeof unknownValue !== "object") {
|
|
12
|
+
return unknownValue;
|
|
13
|
+
}
|
|
14
|
+
else if (unknownValue instanceof Array) {
|
|
15
|
+
return unknownValue.map(clone);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return getTypedEntries(unknownValue).reduce((pv, [key, value]) => {
|
|
19
|
+
pv[key] = clone(value);
|
|
20
|
+
return pv;
|
|
21
|
+
}, {});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function entryUseMapper([key, value], mapper) {
|
|
26
|
+
const ReTypedMapper = mapper;
|
|
27
|
+
return ReTypedMapper[key](value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function escapeRegExp(text) {
|
|
31
|
+
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getTypedKeys(object) {
|
|
35
|
+
return Object.keys(object);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function hasKey(obj, key) {
|
|
39
|
+
return key in obj;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function simpleClone(unknownValue) {
|
|
43
|
+
if (!unknownValue) {
|
|
44
|
+
return unknownValue;
|
|
45
|
+
}
|
|
46
|
+
else if (typeof unknownValue !== "object") {
|
|
47
|
+
return unknownValue;
|
|
48
|
+
}
|
|
49
|
+
else if (unknownValue.constructor?.name === "Object"
|
|
50
|
+
|| unknownValue.constructor === undefined) {
|
|
51
|
+
return getTypedEntries(unknownValue).reduce((pv, [key, value]) => {
|
|
52
|
+
pv[key] = simpleClone(value);
|
|
53
|
+
return pv;
|
|
54
|
+
}, {});
|
|
55
|
+
}
|
|
56
|
+
else if (unknownValue instanceof Array && unknownValue.constructor.name === "Array") {
|
|
57
|
+
return unknownValue.map(simpleClone);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
return unknownValue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function sleep(milliseconde) {
|
|
65
|
+
return new Promise((resolve) => void setTimeout(resolve, milliseconde));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* eslint-disable id-length */
|
|
69
|
+
class InvalidBytesInStringError extends Error {
|
|
70
|
+
input;
|
|
71
|
+
constructor(input) {
|
|
72
|
+
super("Invalid Input");
|
|
73
|
+
this.input = input;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
|
|
77
|
+
const unitMapper = {
|
|
78
|
+
b: 1,
|
|
79
|
+
kb: 1 << 10,
|
|
80
|
+
mb: 1 << 20,
|
|
81
|
+
gb: 1 << 30,
|
|
82
|
+
tb: Math.pow(1024, 4),
|
|
83
|
+
pb: Math.pow(1024, 5),
|
|
84
|
+
};
|
|
85
|
+
function stringToBytes(bytesInString) {
|
|
86
|
+
if (typeof bytesInString === "number") {
|
|
87
|
+
return bytesInString;
|
|
88
|
+
}
|
|
89
|
+
const regExpResults = parseRegExp.exec(bytesInString);
|
|
90
|
+
const floatValue = regExpResults
|
|
91
|
+
? parseFloat(regExpResults[1])
|
|
92
|
+
: parseInt(bytesInString, 10);
|
|
93
|
+
const unit = regExpResults
|
|
94
|
+
? regExpResults[4].toLowerCase()
|
|
95
|
+
: "b";
|
|
96
|
+
if (!hasKey(unitMapper, unit) || isNaN(floatValue)) {
|
|
97
|
+
throw new InvalidBytesInStringError(bytesInString);
|
|
98
|
+
}
|
|
99
|
+
return Math.floor(unitMapper[unit] * floatValue);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
class UnPartialError extends Error {
|
|
103
|
+
key;
|
|
104
|
+
partialObject;
|
|
105
|
+
constructor(key, partialObject) {
|
|
106
|
+
super(`The key "${key.toString()}" is missing in partial object.`);
|
|
107
|
+
this.key = key;
|
|
108
|
+
this.partialObject = partialObject;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function unPartial(partialObject, keys) {
|
|
112
|
+
keys.forEach((key) => {
|
|
113
|
+
if (partialObject[key] === undefined) {
|
|
114
|
+
throw new UnPartialError(key, partialObject);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return partialObject;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
exports.InvalidBytesInStringError = InvalidBytesInStringError;
|
|
121
|
+
exports.UnPartialError = UnPartialError;
|
|
122
|
+
exports.clone = clone;
|
|
123
|
+
exports.entryUseMapper = entryUseMapper;
|
|
124
|
+
exports.escapeRegExp = escapeRegExp;
|
|
125
|
+
exports.getTypedEntries = getTypedEntries;
|
|
126
|
+
exports.getTypedKeys = getTypedKeys;
|
|
127
|
+
exports.hasKey = hasKey;
|
|
128
|
+
exports.simpleClone = simpleClone;
|
|
129
|
+
exports.sleep = sleep;
|
|
130
|
+
exports.stringToBytes = stringToBytes;
|
|
131
|
+
exports.unPartial = unPartial;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from "./addThis";
|
|
2
|
+
export * from "./clone";
|
|
3
|
+
export * from "./entryUseMapper";
|
|
4
|
+
export * from "./escapeRegExp";
|
|
5
|
+
export * from "./expectType";
|
|
6
|
+
export * from "./getLastOfUnion";
|
|
7
|
+
export * from "./getPropsWithTrueValue";
|
|
8
|
+
export * from "./getTypedEntries";
|
|
9
|
+
export * from "./getTypedKeys";
|
|
10
|
+
export * from "./hasKey";
|
|
11
|
+
export * from "./incremente";
|
|
12
|
+
export * from "./isAny";
|
|
13
|
+
export * from "./overrideInterface";
|
|
14
|
+
export * from "./partialKeys";
|
|
15
|
+
export * from "./requiredKeys";
|
|
16
|
+
export * from "./simpleClone";
|
|
17
|
+
export * from "./simplifyType";
|
|
18
|
+
export * from "./sleep";
|
|
19
|
+
export * from "./stringToBytes";
|
|
20
|
+
export * from "./types";
|
|
21
|
+
export * from "./unionToIntersection";
|
|
22
|
+
export * from "./unionToTuple";
|
|
23
|
+
export * from "./uniqueGeneric";
|
|
24
|
+
export * from "./unPartial";
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
function getTypedEntries(object) {
|
|
2
|
+
return Object.entries(object);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function clone(unknownValue) {
|
|
6
|
+
if (!unknownValue) {
|
|
7
|
+
return unknownValue;
|
|
8
|
+
}
|
|
9
|
+
else if (typeof unknownValue !== "object") {
|
|
10
|
+
return unknownValue;
|
|
11
|
+
}
|
|
12
|
+
else if (unknownValue instanceof Array) {
|
|
13
|
+
return unknownValue.map(clone);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
return getTypedEntries(unknownValue).reduce((pv, [key, value]) => {
|
|
17
|
+
pv[key] = clone(value);
|
|
18
|
+
return pv;
|
|
19
|
+
}, {});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function entryUseMapper([key, value], mapper) {
|
|
24
|
+
const ReTypedMapper = mapper;
|
|
25
|
+
return ReTypedMapper[key](value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function escapeRegExp(text) {
|
|
29
|
+
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getTypedKeys(object) {
|
|
33
|
+
return Object.keys(object);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function hasKey(obj, key) {
|
|
37
|
+
return key in obj;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function simpleClone(unknownValue) {
|
|
41
|
+
if (!unknownValue) {
|
|
42
|
+
return unknownValue;
|
|
43
|
+
}
|
|
44
|
+
else if (typeof unknownValue !== "object") {
|
|
45
|
+
return unknownValue;
|
|
46
|
+
}
|
|
47
|
+
else if (unknownValue.constructor?.name === "Object"
|
|
48
|
+
|| unknownValue.constructor === undefined) {
|
|
49
|
+
return getTypedEntries(unknownValue).reduce((pv, [key, value]) => {
|
|
50
|
+
pv[key] = simpleClone(value);
|
|
51
|
+
return pv;
|
|
52
|
+
}, {});
|
|
53
|
+
}
|
|
54
|
+
else if (unknownValue instanceof Array && unknownValue.constructor.name === "Array") {
|
|
55
|
+
return unknownValue.map(simpleClone);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return unknownValue;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function sleep(milliseconde) {
|
|
63
|
+
return new Promise((resolve) => void setTimeout(resolve, milliseconde));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* eslint-disable id-length */
|
|
67
|
+
class InvalidBytesInStringError extends Error {
|
|
68
|
+
input;
|
|
69
|
+
constructor(input) {
|
|
70
|
+
super("Invalid Input");
|
|
71
|
+
this.input = input;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
|
|
75
|
+
const unitMapper = {
|
|
76
|
+
b: 1,
|
|
77
|
+
kb: 1 << 10,
|
|
78
|
+
mb: 1 << 20,
|
|
79
|
+
gb: 1 << 30,
|
|
80
|
+
tb: Math.pow(1024, 4),
|
|
81
|
+
pb: Math.pow(1024, 5),
|
|
82
|
+
};
|
|
83
|
+
function stringToBytes(bytesInString) {
|
|
84
|
+
if (typeof bytesInString === "number") {
|
|
85
|
+
return bytesInString;
|
|
86
|
+
}
|
|
87
|
+
const regExpResults = parseRegExp.exec(bytesInString);
|
|
88
|
+
const floatValue = regExpResults
|
|
89
|
+
? parseFloat(regExpResults[1])
|
|
90
|
+
: parseInt(bytesInString, 10);
|
|
91
|
+
const unit = regExpResults
|
|
92
|
+
? regExpResults[4].toLowerCase()
|
|
93
|
+
: "b";
|
|
94
|
+
if (!hasKey(unitMapper, unit) || isNaN(floatValue)) {
|
|
95
|
+
throw new InvalidBytesInStringError(bytesInString);
|
|
96
|
+
}
|
|
97
|
+
return Math.floor(unitMapper[unit] * floatValue);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class UnPartialError extends Error {
|
|
101
|
+
key;
|
|
102
|
+
partialObject;
|
|
103
|
+
constructor(key, partialObject) {
|
|
104
|
+
super(`The key "${key.toString()}" is missing in partial object.`);
|
|
105
|
+
this.key = key;
|
|
106
|
+
this.partialObject = partialObject;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function unPartial(partialObject, keys) {
|
|
110
|
+
keys.forEach((key) => {
|
|
111
|
+
if (partialObject[key] === undefined) {
|
|
112
|
+
throw new UnPartialError(key, partialObject);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return partialObject;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { InvalidBytesInStringError, UnPartialError, clone, entryUseMapper, escapeRegExp, getTypedEntries, getTypedKeys, hasKey, simpleClone, sleep, stringToBytes, unPartial };
|
package/dist/isAny.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type IsAny<T extends any> = (any extends T ? true : false) extends true ? true : false;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type OverrideInterface<O extends object, T extends object> = Omit<O, keyof T> & T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function simpleClone<T extends unknown = unknown>(unknownValue: T): T;
|
package/dist/sleep.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sleep(milliseconde?: number): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class InvalidBytesInStringError extends Error {
|
|
2
|
+
input: string;
|
|
3
|
+
constructor(input: string);
|
|
4
|
+
}
|
|
5
|
+
declare const unitMapper: {
|
|
6
|
+
b: number;
|
|
7
|
+
kb: number;
|
|
8
|
+
mb: number;
|
|
9
|
+
gb: number;
|
|
10
|
+
tb: number;
|
|
11
|
+
pb: number;
|
|
12
|
+
};
|
|
13
|
+
export type BytesInString = `${number}${keyof typeof unitMapper}`;
|
|
14
|
+
export declare function stringToBytes(bytesInString: BytesInString | number): number;
|
|
15
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ObjectKey } from "./types";
|
|
2
|
+
export declare class UnPartialError extends Error {
|
|
3
|
+
key: ObjectKey;
|
|
4
|
+
partialObject: object;
|
|
5
|
+
constructor(key: ObjectKey, partialObject: object);
|
|
6
|
+
}
|
|
7
|
+
export type UnPartial<T extends object, K extends keyof T> = T & {
|
|
8
|
+
[P in K]-?: Exclude<T[P], undefined>;
|
|
9
|
+
};
|
|
10
|
+
export declare function unPartial<T extends object, K extends keyof T>(partialObject: T, keys: K[]): UnPartial<T, K>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type UnionToIntersection<T> = (T extends any ? (_x: T) => any : never) extends (_x: infer R) => any ? R : never;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GetLastOfUnion } from "./getLastOfUnion";
|
|
2
|
+
export type PushElementToTuple<T extends any[], V> = [...T, V];
|
|
3
|
+
export type UnionToTuple<T, L = GetLastOfUnion<T>, N = [T] extends [never] ? true : false> = true extends N ? [
|
|
4
|
+
] : PushElementToTuple<UnionToTuple<Exclude<T, L>>, L>;
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@duplojs/utils",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"author": "mathcovax",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": "https://github.com/duplojs/utils",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rollup --config && tsc-alias -p tsconfig.build.json",
|
|
10
|
+
"test:tu": "vitest --coverage",
|
|
11
|
+
"test:tu:watch": "vitest --coverage --watch",
|
|
12
|
+
"test:tu:update": "vitest --coverage --update",
|
|
13
|
+
"test:types": "npm run test:types:scripts && npm run integration:test:types",
|
|
14
|
+
"test:types:scripts": "tsc",
|
|
15
|
+
"integration:test:types": "npm -w test/integration run test:types",
|
|
16
|
+
"test:lint": "eslint",
|
|
17
|
+
"test:lint:fix": "eslint --fix",
|
|
18
|
+
"prepare": "husky"
|
|
19
|
+
},
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"import": "./dist/index.mjs",
|
|
24
|
+
"require": "./dist/index.cjs",
|
|
25
|
+
"types": "./dist/index.d.ts"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"workspaces": [
|
|
33
|
+
"test/integration"
|
|
34
|
+
],
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@commitlint/cli": "19.7.1",
|
|
43
|
+
"@commitlint/config-conventional": "19.2.2",
|
|
44
|
+
"@duplojs/eslint": "0.4.0",
|
|
45
|
+
"@rollup/plugin-typescript": "12.1.2",
|
|
46
|
+
"@types/node": "22.1.0",
|
|
47
|
+
"@vitest/coverage-istanbul": "3.0.5",
|
|
48
|
+
"eslint": "9.20.0",
|
|
49
|
+
"husky": "9.1.7",
|
|
50
|
+
"rollup": "4.34.6",
|
|
51
|
+
"rollup-plugin-esbuild": "6.2.0",
|
|
52
|
+
"tsc-alias": "1.8.10",
|
|
53
|
+
"tslib": "2.8.1",
|
|
54
|
+
"tsx": "4.19.2",
|
|
55
|
+
"typescript": "5.7.3",
|
|
56
|
+
"vite-tsconfig-paths": "5.1.4",
|
|
57
|
+
"vitest": "3.0.5"
|
|
58
|
+
},
|
|
59
|
+
"keywords": []
|
|
60
|
+
}
|