@envind/ts-enum-utils 1.0.0 → 1.0.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 +36 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +13 -10
package/README.md
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+

|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
[](https://bundlephobia.com/package/ts-enum-utils)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# ts-enum-utils
|
|
7
8
|
|
|
8
9
|
Type-safe runtime enums with built-in utilities for TypeScript.
|
|
9
10
|
|
|
11
|
+
|
|
12
|
+
|
|
10
13
|
## Why?
|
|
11
14
|
|
|
12
15
|
TypeScript's native enums have issues:
|
|
@@ -17,6 +20,8 @@ TypeScript's native enums have issues:
|
|
|
17
20
|
|
|
18
21
|
This library gives you **type-safe enums** with **runtime utilities** in ~30 lines.
|
|
19
22
|
|
|
23
|
+
|
|
24
|
+
|
|
20
25
|
## Installation
|
|
21
26
|
|
|
22
27
|
```bash
|
|
@@ -27,6 +32,8 @@ pnpm add ts-enum-utils
|
|
|
27
32
|
yarn add ts-enum-utils
|
|
28
33
|
```
|
|
29
34
|
|
|
35
|
+
|
|
36
|
+
|
|
30
37
|
## Usage
|
|
31
38
|
|
|
32
39
|
```typescript
|
|
@@ -43,6 +50,8 @@ Status.archived; // "archived"
|
|
|
43
50
|
Status.values; // ["pending", "active", "archived"]
|
|
44
51
|
```
|
|
45
52
|
|
|
53
|
+
|
|
54
|
+
|
|
46
55
|
### Type Guard
|
|
47
56
|
|
|
48
57
|
```typescript
|
|
@@ -54,6 +63,8 @@ if (Status.is(userInput)) {
|
|
|
54
63
|
}
|
|
55
64
|
```
|
|
56
65
|
|
|
66
|
+
|
|
67
|
+
|
|
57
68
|
### Validation with Error
|
|
58
69
|
|
|
59
70
|
```typescript
|
|
@@ -62,6 +73,9 @@ const validated = Status.assert(untrustedData);
|
|
|
62
73
|
// Returns the value if valid, throws otherwise
|
|
63
74
|
```
|
|
64
75
|
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
65
79
|
### Extract the Type
|
|
66
80
|
|
|
67
81
|
```typescript
|
|
@@ -73,6 +87,8 @@ const updateStatus = (id: string, status: Status) => {
|
|
|
73
87
|
};
|
|
74
88
|
```
|
|
75
89
|
|
|
90
|
+
|
|
91
|
+
|
|
76
92
|
### Utilities
|
|
77
93
|
|
|
78
94
|
```typescript
|
|
@@ -87,8 +103,12 @@ Status.at(0); // "pending"
|
|
|
87
103
|
Status.at(-1); // "archived"
|
|
88
104
|
```
|
|
89
105
|
|
|
106
|
+
|
|
107
|
+
|
|
90
108
|
## API
|
|
91
109
|
|
|
110
|
+
|
|
111
|
+
|
|
92
112
|
### `createEnum(values)`
|
|
93
113
|
|
|
94
114
|
Creates a type-safe enum object.
|
|
@@ -102,6 +122,8 @@ Creates a type-safe enum object.
|
|
|
102
122
|
| `.indexOf(value)` | Returns the index of a value |
|
|
103
123
|
| `.at(index)` | Returns value at index (supports negative) |
|
|
104
124
|
|
|
125
|
+
|
|
126
|
+
|
|
105
127
|
### `EnumValue<E>`
|
|
106
128
|
|
|
107
129
|
Utility type to extract the union type from an enum.
|
|
@@ -111,6 +133,8 @@ type Status = EnumValue<typeof Status>;
|
|
|
111
133
|
// "pending" | "active" | "archived"
|
|
112
134
|
```
|
|
113
135
|
|
|
136
|
+
|
|
137
|
+
|
|
114
138
|
## Comparison
|
|
115
139
|
|
|
116
140
|
| Feature | Native Enum | ts-enum-utils |
|
|
@@ -122,14 +146,17 @@ type Status = EnumValue<typeof Status>;
|
|
|
122
146
|
| Random | ❌ | ✅ `.random()` |
|
|
123
147
|
| Bundle size | - | ~500B |
|
|
124
148
|
|
|
149
|
+
|
|
150
|
+
|
|
125
151
|
## License
|
|
126
152
|
|
|
127
153
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
128
154
|
|
|
129
|
-
<div align="center">
|
|
130
155
|
|
|
131
|
-
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
**[⭐ Star me on GitHub](https://github.com/envindavsorg/ts-enum-utils)** • **[📦 NPM Package](https://www.npmjs.com/package/@envind/ts-enum-utils)** • **[📚 Documentation](https://github.com/envindavsorg/ts-enum-utils#readme)**
|
|
132
159
|
|
|
133
|
-
|
|
160
|
+
|
|
134
161
|
|
|
135
|
-
|
|
162
|
+
Made with ❤️ by Florin Cuzeac
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["createEnum","values","valueSet","base","value","index","members","v"],"mappings":"aAiBO,IAAMA,CAAAA,CAAiDC,CAAAA,EAAuB,CACnF,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,mCAAmC,CAAA,CAIrD,GADqB,IAAI,GAAA,CAAIA,CAAM,CAAA,CAClB,IAAA,GAASA,CAAAA,CAAO,MAAA,CAC/B,MAAM,IAAI,KAAA,CAAM,4BAA4B,CAAA,CAG9C,IAAMC,CAAAA,CAAW,IAAI,GAAA,CAAYD,CAAM,CAAA,CAEjCE,CAAAA,CAAoB,CACxB,MAAA,CAAAF,CAAAA,CAEA,EAAA,CAAKG,CAAAA,EAAuC,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CAE3F,MAAA,CAASA,CAAAA,EAA8B,CACrC,GAAI,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CACjD,OAAOA,CAAAA,CAET,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAK,CAAA,oBAAA,EAAuBH,CAAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CACzF,CAAA,CAEA,MAAA,CAAQ,IAAiB,CACvB,IAAMI,CAAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,EAAO,CAAIJ,CAAAA,CAAO,MAAM,CAAA,CACtD,OAAOA,CAAAA,CAAOI,CAAK,CACrB,CAAA,CAEA,OAAA,CAAUD,CAAAA,EAA6BH,CAAAA,CAAO,OAAA,CAAQG,CAAK,CAAA,CAE3D,EAAA,CAAKC,CAAAA,EAAyCJ,CAAAA,CAAO,EAAA,CAAGI,CAAK,CAC/D,CAAA,CAEMC,CAAAA,CAAU,MAAA,CAAO,WAAA,CAAYL,CAAAA,CAAO,GAAA,CAAKM,CAAAA,EAAM,CAACA,CAAAA,CAAGA,CAAC,CAAC,CAAC,CAAA,CAE5D,OAAO,MAAA,CAAO,MAAA,CAAO,CAAE,GAAGJ,CAAAA,CAAM,GAAGG,CAAQ,CAAC,CAC9C","file":"index.cjs","sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["createEnum","values","valueSet","base","value","index","members","v"],"mappings":"aAiBO,IAAMA,CAAAA,CAAiDC,CAAAA,EAAuB,CACnF,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,mCAAmC,CAAA,CAIrD,GADqB,IAAI,GAAA,CAAIA,CAAM,CAAA,CAClB,IAAA,GAASA,CAAAA,CAAO,MAAA,CAC/B,MAAM,IAAI,KAAA,CAAM,4BAA4B,CAAA,CAG9C,IAAMC,CAAAA,CAAW,IAAI,GAAA,CAAYD,CAAM,CAAA,CAEjCE,CAAAA,CAAoB,CACxB,MAAA,CAAAF,CAAAA,CAEA,EAAA,CAAKG,CAAAA,EAAuC,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CAE3F,MAAA,CAASA,CAAAA,EAA8B,CACrC,GAAI,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CACjD,OAAOA,CAAAA,CAET,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAK,CAAA,oBAAA,EAAuBH,CAAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CACzF,CAAA,CAEA,MAAA,CAAQ,IAAiB,CACvB,IAAMI,CAAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,EAAO,CAAIJ,CAAAA,CAAO,MAAM,CAAA,CACtD,OAAOA,CAAAA,CAAOI,CAAK,CACrB,CAAA,CAEA,OAAA,CAAUD,CAAAA,EAA6BH,CAAAA,CAAO,OAAA,CAAQG,CAAK,CAAA,CAE3D,EAAA,CAAKC,CAAAA,EAAyCJ,CAAAA,CAAO,EAAA,CAAGI,CAAK,CAC/D,CAAA,CAEMC,CAAAA,CAAU,MAAA,CAAO,WAAA,CAAYL,CAAAA,CAAO,GAAA,CAAKM,CAAAA,EAAM,CAACA,CAAAA,CAAGA,CAAC,CAAC,CAAC,CAAA,CAE5D,OAAO,MAAA,CAAO,MAAA,CAAO,CAAE,GAAGJ,CAAAA,CAAM,GAAGG,CAAQ,CAAC,CAC9C","file":"index.cjs","sourcesContent":["interface EnumBase<T extends readonly string[]> {\n readonly values: T;\n is: (value: unknown) => value is T[number];\n assert: (value: unknown) => T[number];\n random: () => T[number];\n indexOf: (value: T[number]) => number;\n at: (index: number) => T[number] | undefined;\n}\n\ntype EnumMembers<T extends readonly string[]> = {\n readonly [K in T[number]]: K;\n};\n\nexport type Enum<T extends readonly string[]> = EnumBase<T> & EnumMembers<T>;\n\nexport type EnumValue<E extends { values: readonly string[] }> = E[\"values\"][number];\n\nexport const createEnum = <const T extends readonly string[]>(values: T): Enum<T> => {\n if (values.length === 0) {\n throw new Error(\"Enum must have at least one value\");\n }\n\n const uniqueValues = new Set(values);\n if (uniqueValues.size !== values.length) {\n throw new Error(\"Enum values must be unique\");\n }\n\n const valueSet = new Set<string>(values);\n\n const base: EnumBase<T> = {\n values,\n\n is: (value: unknown): value is T[number] => typeof value === \"string\" && valueSet.has(value),\n\n assert: (value: unknown): T[number] => {\n if (typeof value === \"string\" && valueSet.has(value)) {\n return value as T[number];\n }\n throw new Error(`Invalid enum value: \"${value}\". Expected one of: ${values.join(\", \")}`);\n },\n\n random: (): T[number] => {\n const index = Math.floor(Math.random() * values.length);\n return values[index] as T[number];\n },\n\n indexOf: (value: T[number]): number => values.indexOf(value),\n\n at: (index: number): T[number] | undefined => values.at(index) as T[number] | undefined,\n };\n\n const members = Object.fromEntries(values.map((v) => [v, v])) as EnumMembers<T>;\n\n return Object.freeze({ ...base, ...members }) as Enum<T>;\n};\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
interface EnumBase<T extends readonly string[]> {
|
|
2
2
|
readonly values: T;
|
|
3
3
|
is: (value: unknown) => value is T[number];
|
|
4
4
|
assert: (value: unknown) => T[number];
|
|
5
5
|
random: () => T[number];
|
|
6
6
|
indexOf: (value: T[number]) => number;
|
|
7
7
|
at: (index: number) => T[number] | undefined;
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
type EnumMembers<T extends readonly string[]> = {
|
|
10
10
|
readonly [K in T[number]]: K;
|
|
11
11
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
interface EnumBase<T extends readonly string[]> {
|
|
2
2
|
readonly values: T;
|
|
3
3
|
is: (value: unknown) => value is T[number];
|
|
4
4
|
assert: (value: unknown) => T[number];
|
|
5
5
|
random: () => T[number];
|
|
6
6
|
indexOf: (value: T[number]) => number;
|
|
7
7
|
at: (index: number) => T[number] | undefined;
|
|
8
|
-
}
|
|
8
|
+
}
|
|
9
9
|
type EnumMembers<T extends readonly string[]> = {
|
|
10
10
|
readonly [K in T[number]]: K;
|
|
11
11
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["createEnum","values","valueSet","base","value","index","members","v"],"mappings":"AAiBO,IAAMA,CAAAA,CAAiDC,CAAAA,EAAuB,CACnF,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,mCAAmC,CAAA,CAIrD,GADqB,IAAI,GAAA,CAAIA,CAAM,CAAA,CAClB,IAAA,GAASA,CAAAA,CAAO,MAAA,CAC/B,MAAM,IAAI,KAAA,CAAM,4BAA4B,CAAA,CAG9C,IAAMC,CAAAA,CAAW,IAAI,GAAA,CAAYD,CAAM,CAAA,CAEjCE,CAAAA,CAAoB,CACxB,MAAA,CAAAF,CAAAA,CAEA,EAAA,CAAKG,CAAAA,EAAuC,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CAE3F,MAAA,CAASA,CAAAA,EAA8B,CACrC,GAAI,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CACjD,OAAOA,CAAAA,CAET,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAK,CAAA,oBAAA,EAAuBH,CAAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CACzF,CAAA,CAEA,MAAA,CAAQ,IAAiB,CACvB,IAAMI,CAAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,EAAO,CAAIJ,CAAAA,CAAO,MAAM,CAAA,CACtD,OAAOA,CAAAA,CAAOI,CAAK,CACrB,CAAA,CAEA,OAAA,CAAUD,CAAAA,EAA6BH,CAAAA,CAAO,OAAA,CAAQG,CAAK,CAAA,CAE3D,EAAA,CAAKC,CAAAA,EAAyCJ,CAAAA,CAAO,EAAA,CAAGI,CAAK,CAC/D,CAAA,CAEMC,CAAAA,CAAU,MAAA,CAAO,WAAA,CAAYL,CAAAA,CAAO,GAAA,CAAKM,CAAAA,EAAM,CAACA,CAAAA,CAAGA,CAAC,CAAC,CAAC,CAAA,CAE5D,OAAO,MAAA,CAAO,MAAA,CAAO,CAAE,GAAGJ,CAAAA,CAAM,GAAGG,CAAQ,CAAC,CAC9C","file":"index.js","sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["createEnum","values","valueSet","base","value","index","members","v"],"mappings":"AAiBO,IAAMA,CAAAA,CAAiDC,CAAAA,EAAuB,CACnF,GAAIA,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,mCAAmC,CAAA,CAIrD,GADqB,IAAI,GAAA,CAAIA,CAAM,CAAA,CAClB,IAAA,GAASA,CAAAA,CAAO,MAAA,CAC/B,MAAM,IAAI,KAAA,CAAM,4BAA4B,CAAA,CAG9C,IAAMC,CAAAA,CAAW,IAAI,GAAA,CAAYD,CAAM,CAAA,CAEjCE,CAAAA,CAAoB,CACxB,MAAA,CAAAF,CAAAA,CAEA,EAAA,CAAKG,CAAAA,EAAuC,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CAE3F,MAAA,CAASA,CAAAA,EAA8B,CACrC,GAAI,OAAOA,CAAAA,EAAU,QAAA,EAAYF,CAAAA,CAAS,GAAA,CAAIE,CAAK,CAAA,CACjD,OAAOA,CAAAA,CAET,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAK,CAAA,oBAAA,EAAuBH,CAAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CACzF,CAAA,CAEA,MAAA,CAAQ,IAAiB,CACvB,IAAMI,CAAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,MAAA,EAAO,CAAIJ,CAAAA,CAAO,MAAM,CAAA,CACtD,OAAOA,CAAAA,CAAOI,CAAK,CACrB,CAAA,CAEA,OAAA,CAAUD,CAAAA,EAA6BH,CAAAA,CAAO,OAAA,CAAQG,CAAK,CAAA,CAE3D,EAAA,CAAKC,CAAAA,EAAyCJ,CAAAA,CAAO,EAAA,CAAGI,CAAK,CAC/D,CAAA,CAEMC,CAAAA,CAAU,MAAA,CAAO,WAAA,CAAYL,CAAAA,CAAO,GAAA,CAAKM,CAAAA,EAAM,CAACA,CAAAA,CAAGA,CAAC,CAAC,CAAC,CAAA,CAE5D,OAAO,MAAA,CAAO,MAAA,CAAO,CAAE,GAAGJ,CAAAA,CAAM,GAAGG,CAAQ,CAAC,CAC9C","file":"index.js","sourcesContent":["interface EnumBase<T extends readonly string[]> {\n readonly values: T;\n is: (value: unknown) => value is T[number];\n assert: (value: unknown) => T[number];\n random: () => T[number];\n indexOf: (value: T[number]) => number;\n at: (index: number) => T[number] | undefined;\n}\n\ntype EnumMembers<T extends readonly string[]> = {\n readonly [K in T[number]]: K;\n};\n\nexport type Enum<T extends readonly string[]> = EnumBase<T> & EnumMembers<T>;\n\nexport type EnumValue<E extends { values: readonly string[] }> = E[\"values\"][number];\n\nexport const createEnum = <const T extends readonly string[]>(values: T): Enum<T> => {\n if (values.length === 0) {\n throw new Error(\"Enum must have at least one value\");\n }\n\n const uniqueValues = new Set(values);\n if (uniqueValues.size !== values.length) {\n throw new Error(\"Enum values must be unique\");\n }\n\n const valueSet = new Set<string>(values);\n\n const base: EnumBase<T> = {\n values,\n\n is: (value: unknown): value is T[number] => typeof value === \"string\" && valueSet.has(value),\n\n assert: (value: unknown): T[number] => {\n if (typeof value === \"string\" && valueSet.has(value)) {\n return value as T[number];\n }\n throw new Error(`Invalid enum value: \"${value}\". Expected one of: ${values.join(\", \")}`);\n },\n\n random: (): T[number] => {\n const index = Math.floor(Math.random() * values.length);\n return values[index] as T[number];\n },\n\n indexOf: (value: T[number]): number => values.indexOf(value),\n\n at: (index: number): T[number] | undefined => values.at(index) as T[number] | undefined,\n };\n\n const members = Object.fromEntries(values.map((v) => [v, v])) as EnumMembers<T>;\n\n return Object.freeze({ ...base, ...members }) as Enum<T>;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@envind/ts-enum-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Type-safe runtime enums with built-in utilities for TypeScript",
|
|
5
5
|
"author": "Florin Cuzeac",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,16 +29,19 @@
|
|
|
29
29
|
"test": "vitest run",
|
|
30
30
|
"test:watch": "vitest",
|
|
31
31
|
"lint": "biome check .",
|
|
32
|
-
"lint:fix": "biome check --
|
|
32
|
+
"lint:fix": "biome check --fix --unsafe",
|
|
33
33
|
"format": "biome format --write .",
|
|
34
|
-
"prepublishOnly": "pnpm run
|
|
34
|
+
"prepublishOnly": "pnpm run test && pnpm run build",
|
|
35
|
+
"check": "ultracite check",
|
|
36
|
+
"fix": "ultracite fix"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@biomejs/biome": "
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"tsup": "^8.
|
|
40
|
-
"typescript": "^5.
|
|
41
|
-
"
|
|
39
|
+
"@biomejs/biome": "2.3.12",
|
|
40
|
+
"@types/node": "^25.1.0",
|
|
41
|
+
"tsup": "^8.5.1",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"ultracite": "7.1.1",
|
|
44
|
+
"vitest": "^4.0.18"
|
|
42
45
|
},
|
|
43
46
|
"keywords": [
|
|
44
47
|
"typescript",
|
|
@@ -59,5 +62,5 @@
|
|
|
59
62
|
"engines": {
|
|
60
63
|
"node": ">=18"
|
|
61
64
|
},
|
|
62
|
-
"packageManager": "pnpm@10.
|
|
63
|
-
}
|
|
65
|
+
"packageManager": "pnpm@10.28.2"
|
|
66
|
+
}
|