base60-codec 0.1.11 โ 0.2.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 +23 -14
- package/dist/index.cjs +54 -16
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +41 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,67 +27,76 @@ Ideal for generating compact, URL-safe IDs with predictable ordering.
|
|
|
27
27
|
|
|
28
28
|
## ๐ Installation
|
|
29
29
|
|
|
30
|
-
```
|
|
30
|
+
```shell
|
|
31
31
|
npm install base60-codec
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## ๐งฉ Quick Usage
|
|
35
35
|
|
|
36
|
-
```
|
|
37
|
-
import {
|
|
36
|
+
```javascript
|
|
37
|
+
import { encodeUUID, decodeUUID } from "base60-codec";
|
|
38
38
|
|
|
39
39
|
const uuid = "550e8400-e29b-41d4-a716-446655440000";
|
|
40
40
|
|
|
41
41
|
// Encode as 22-char Base60
|
|
42
|
-
const encoded =
|
|
42
|
+
const encoded = encodeUUID(uuid);
|
|
43
43
|
console.log(encoded); // e.g. "09EzBRW... (22 chars)"
|
|
44
44
|
|
|
45
45
|
// Decode back to UUID
|
|
46
|
-
console.log(
|
|
46
|
+
console.log(decodeUUID(encoded));
|
|
47
47
|
// โ "550e8400-e29b-41d4-a716-446655440000"
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
๐ก Tip
|
|
51
|
+
If you prefer grouped APIs, you can also import the base60 namespace:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
import base60 from "base60-codec";
|
|
55
|
+
|
|
56
|
+
base60.encodeUUID(uuid);
|
|
57
|
+
```
|
|
58
|
+
|
|
50
59
|
## โจ Features
|
|
51
60
|
|
|
52
61
|
### โ
UUID (128-bit) โ 22 chars
|
|
53
62
|
|
|
54
|
-
```
|
|
63
|
+
```javascript
|
|
55
64
|
encodeUUID(uuid: string): string
|
|
56
65
|
decodeUUID(id: Base60String): string
|
|
57
66
|
```
|
|
58
67
|
|
|
59
68
|
### โ
ULID (26 chars Base32) โ 22 chars
|
|
60
69
|
|
|
61
|
-
```
|
|
70
|
+
```javascript
|
|
62
71
|
encodeULID(ulid: string): Base60String
|
|
63
72
|
decodeULID(id: Base60String): string
|
|
64
73
|
```
|
|
65
74
|
|
|
66
75
|
### โ
Int64 โ 11 chars
|
|
67
76
|
|
|
68
|
-
```
|
|
77
|
+
```javascript
|
|
69
78
|
encodeInt64(num: number | bigint): string
|
|
70
79
|
decodeInt64(id: Base60String): bigint
|
|
71
80
|
```
|
|
72
81
|
|
|
73
82
|
### โ
BigInt encoding
|
|
74
83
|
|
|
75
|
-
```
|
|
84
|
+
```javascript
|
|
76
85
|
encodeBigInt(value: bigint, padLength?: number): string
|
|
77
86
|
decodeToBigInt(text: Base60String): bigint
|
|
78
87
|
```
|
|
79
88
|
|
|
80
89
|
### โ
Safe comparison
|
|
81
90
|
|
|
82
|
-
```
|
|
91
|
+
```javascript
|
|
83
92
|
compareAsBigInt(a: Base60String, b: Base60String): -1 | 0 | 1
|
|
84
93
|
```
|
|
85
94
|
|
|
86
95
|
### โ
Type-safe Base60 string guard
|
|
87
96
|
|
|
88
|
-
```
|
|
97
|
+
```javascript
|
|
89
98
|
if (base60.isValidBase60(text)) {
|
|
90
|
-
// text is now typed as Base60String
|
|
99
|
+
// text is now typed as Base60String
|
|
91
100
|
}
|
|
92
101
|
```
|
|
93
102
|
|
|
@@ -107,7 +116,7 @@ if (base60.isValidBase60(text)) {
|
|
|
107
116
|
|
|
108
117
|
Leading zero bytes are dropped:
|
|
109
118
|
|
|
110
|
-
```
|
|
119
|
+
```javascript
|
|
111
120
|
encodeBytes(Uint8Array([0,1,2]))
|
|
112
121
|
โ
|
|
113
122
|
decodeToBytes(...) โ [1,2]
|
|
@@ -119,7 +128,7 @@ UUID / ULID / Int64 are unaffected because they use fixed 16-byte / 8-byte decod
|
|
|
119
128
|
|
|
120
129
|
## ๐งช Testing
|
|
121
130
|
|
|
122
|
-
```
|
|
131
|
+
```shell
|
|
123
132
|
npm test
|
|
124
133
|
```
|
|
125
134
|
|
package/dist/index.cjs
CHANGED
|
@@ -21,8 +21,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
base60: () => base60,
|
|
24
|
+
compareAsBigInt: () => compareAsBigInt,
|
|
24
25
|
createBase60Codec: () => createBase60Codec,
|
|
25
|
-
|
|
26
|
+
decodeInt64: () => decodeInt64,
|
|
27
|
+
decodeToBigInt: () => decodeToBigInt,
|
|
28
|
+
decodeToBytes: () => decodeToBytes,
|
|
29
|
+
decodeULID: () => decodeULID,
|
|
30
|
+
decodeUUID: () => decodeUUID,
|
|
31
|
+
default: () => index_default,
|
|
32
|
+
encodeBigInt: () => encodeBigInt,
|
|
33
|
+
encodeBytes: () => encodeBytes,
|
|
34
|
+
encodeInt64: () => encodeInt64,
|
|
35
|
+
encodeULID: () => encodeULID,
|
|
36
|
+
encodeUUID: () => encodeUUID,
|
|
37
|
+
isValidBase60: () => isValidBase60
|
|
26
38
|
});
|
|
27
39
|
module.exports = __toCommonJS(index_exports);
|
|
28
40
|
var FIXED_LEN_UUID = 22;
|
|
@@ -71,7 +83,7 @@ function createBase60Codec() {
|
|
|
71
83
|
}
|
|
72
84
|
return bytes;
|
|
73
85
|
}
|
|
74
|
-
function
|
|
86
|
+
function encodeBigInt2(value, padLength) {
|
|
75
87
|
if (value === 0n) {
|
|
76
88
|
return padLength != null ? leftPad(alphabet[0], padLength) : alphabet[0];
|
|
77
89
|
}
|
|
@@ -84,7 +96,7 @@ function createBase60Codec() {
|
|
|
84
96
|
}
|
|
85
97
|
return padLength != null ? leftPad(out, padLength) : out;
|
|
86
98
|
}
|
|
87
|
-
function
|
|
99
|
+
function decodeToBigInt2(text) {
|
|
88
100
|
let v = 0n;
|
|
89
101
|
for (const ch of text) {
|
|
90
102
|
const d = charToValue.get(ch);
|
|
@@ -98,16 +110,16 @@ function createBase60Codec() {
|
|
|
98
110
|
return {
|
|
99
111
|
alphabet,
|
|
100
112
|
encodeBytes(bytes) {
|
|
101
|
-
return
|
|
113
|
+
return encodeBigInt2(bytesToBigInt(bytes));
|
|
102
114
|
},
|
|
103
115
|
decodeToBytes(text) {
|
|
104
|
-
return bigIntToBytes(
|
|
116
|
+
return bigIntToBytes(decodeToBigInt2(text));
|
|
105
117
|
},
|
|
106
|
-
encodeBigInt,
|
|
107
|
-
decodeToBigInt,
|
|
118
|
+
encodeBigInt: encodeBigInt2,
|
|
119
|
+
decodeToBigInt: decodeToBigInt2,
|
|
108
120
|
encodeInt64(value) {
|
|
109
121
|
return leftPad(
|
|
110
|
-
|
|
122
|
+
encodeBigInt2(BigInt(value)),
|
|
111
123
|
FIXED_LEN_INT64
|
|
112
124
|
);
|
|
113
125
|
},
|
|
@@ -115,7 +127,7 @@ function createBase60Codec() {
|
|
|
115
127
|
if (text.length !== FIXED_LEN_INT64) {
|
|
116
128
|
throw new Error(`Expected ${FIXED_LEN_INT64} chars for Base60 Int64`);
|
|
117
129
|
}
|
|
118
|
-
return
|
|
130
|
+
return decodeToBigInt2(text);
|
|
119
131
|
},
|
|
120
132
|
encodeUUID(uuid) {
|
|
121
133
|
const hex = uuid.replace(/-/g, "");
|
|
@@ -125,12 +137,12 @@ function createBase60Codec() {
|
|
|
125
137
|
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
|
|
126
138
|
}
|
|
127
139
|
return leftPad(
|
|
128
|
-
|
|
140
|
+
encodeBigInt2(bytesToBigInt(bytes)),
|
|
129
141
|
FIXED_LEN_UUID
|
|
130
142
|
);
|
|
131
143
|
},
|
|
132
144
|
decodeUUID(text) {
|
|
133
|
-
const bytes = bigIntToBytes(
|
|
145
|
+
const bytes = bigIntToBytes(decodeToBigInt2(text), 16);
|
|
134
146
|
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
135
147
|
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
|
|
136
148
|
},
|
|
@@ -148,14 +160,14 @@ function createBase60Codec() {
|
|
|
148
160
|
if (v === void 0) throw new Error(`Invalid ULID char: ${ch}`);
|
|
149
161
|
value = (value << 5n) + BigInt(v);
|
|
150
162
|
}
|
|
151
|
-
const raw =
|
|
163
|
+
const raw = encodeBigInt2(value);
|
|
152
164
|
return leftPad(raw, FIXED_LEN_ULID);
|
|
153
165
|
},
|
|
154
166
|
decodeULID(text) {
|
|
155
167
|
if (text.length !== 22) {
|
|
156
168
|
throw new Error("Expected 22-char Base60 ULID");
|
|
157
169
|
}
|
|
158
|
-
const value =
|
|
170
|
+
const value = decodeToBigInt2(text);
|
|
159
171
|
const bytes = bigIntToBytes(value, 16);
|
|
160
172
|
let bits = "";
|
|
161
173
|
for (const b of bytes) {
|
|
@@ -170,8 +182,8 @@ function createBase60Codec() {
|
|
|
170
182
|
return ulid;
|
|
171
183
|
},
|
|
172
184
|
compareAsBigInt(a, b) {
|
|
173
|
-
const ai =
|
|
174
|
-
const bi =
|
|
185
|
+
const ai = decodeToBigInt2(a);
|
|
186
|
+
const bi = decodeToBigInt2(b);
|
|
175
187
|
if (ai < bi) return -1;
|
|
176
188
|
if (ai > bi) return 1;
|
|
177
189
|
return 0;
|
|
@@ -185,9 +197,35 @@ function createBase60Codec() {
|
|
|
185
197
|
};
|
|
186
198
|
}
|
|
187
199
|
var base60 = createBase60Codec();
|
|
200
|
+
var {
|
|
201
|
+
encodeBytes,
|
|
202
|
+
decodeToBytes,
|
|
203
|
+
encodeBigInt,
|
|
204
|
+
decodeToBigInt,
|
|
205
|
+
encodeInt64,
|
|
206
|
+
decodeInt64,
|
|
207
|
+
encodeUUID,
|
|
208
|
+
decodeUUID,
|
|
209
|
+
encodeULID,
|
|
210
|
+
decodeULID,
|
|
211
|
+
compareAsBigInt,
|
|
212
|
+
isValidBase60
|
|
213
|
+
} = base60;
|
|
188
214
|
var index_default = base60;
|
|
189
215
|
// Annotate the CommonJS export names for ESM import in node:
|
|
190
216
|
0 && (module.exports = {
|
|
191
217
|
base60,
|
|
192
|
-
|
|
218
|
+
compareAsBigInt,
|
|
219
|
+
createBase60Codec,
|
|
220
|
+
decodeInt64,
|
|
221
|
+
decodeToBigInt,
|
|
222
|
+
decodeToBytes,
|
|
223
|
+
decodeULID,
|
|
224
|
+
decodeUUID,
|
|
225
|
+
encodeBigInt,
|
|
226
|
+
encodeBytes,
|
|
227
|
+
encodeInt64,
|
|
228
|
+
encodeULID,
|
|
229
|
+
encodeUUID,
|
|
230
|
+
isValidBase60
|
|
193
231
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -18,5 +18,17 @@ interface Base60Codec {
|
|
|
18
18
|
}
|
|
19
19
|
declare function createBase60Codec(): Base60Codec;
|
|
20
20
|
declare const base60: Base60Codec;
|
|
21
|
+
declare const encodeBytes: (bytes: Uint8Array) => string;
|
|
22
|
+
declare const decodeToBytes: (text: Base60String) => Uint8Array;
|
|
23
|
+
declare const encodeBigInt: (value: bigint, padLength?: number) => Base60String;
|
|
24
|
+
declare const decodeToBigInt: (text: Base60String) => bigint;
|
|
25
|
+
declare const encodeInt64: (value: number | bigint) => Base60String;
|
|
26
|
+
declare const decodeInt64: (text: Base60String) => bigint;
|
|
27
|
+
declare const encodeUUID: (uuid: string) => Base60String;
|
|
28
|
+
declare const decodeUUID: (text: Base60String) => string;
|
|
29
|
+
declare const encodeULID: (ulid: string) => Base60String;
|
|
30
|
+
declare const decodeULID: (text: Base60String) => string;
|
|
31
|
+
declare const compareAsBigInt: (a: Base60String, b: Base60String) => number;
|
|
32
|
+
declare const isValidBase60: (text: string) => text is Base60String;
|
|
21
33
|
|
|
22
|
-
export { type Base60Codec, type Base60String, base60, createBase60Codec, base60 as default };
|
|
34
|
+
export { type Base60Codec, type Base60String, base60, compareAsBigInt, createBase60Codec, decodeInt64, decodeToBigInt, decodeToBytes, decodeULID, decodeUUID, base60 as default, encodeBigInt, encodeBytes, encodeInt64, encodeULID, encodeUUID, isValidBase60 };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,5 +18,17 @@ interface Base60Codec {
|
|
|
18
18
|
}
|
|
19
19
|
declare function createBase60Codec(): Base60Codec;
|
|
20
20
|
declare const base60: Base60Codec;
|
|
21
|
+
declare const encodeBytes: (bytes: Uint8Array) => string;
|
|
22
|
+
declare const decodeToBytes: (text: Base60String) => Uint8Array;
|
|
23
|
+
declare const encodeBigInt: (value: bigint, padLength?: number) => Base60String;
|
|
24
|
+
declare const decodeToBigInt: (text: Base60String) => bigint;
|
|
25
|
+
declare const encodeInt64: (value: number | bigint) => Base60String;
|
|
26
|
+
declare const decodeInt64: (text: Base60String) => bigint;
|
|
27
|
+
declare const encodeUUID: (uuid: string) => Base60String;
|
|
28
|
+
declare const decodeUUID: (text: Base60String) => string;
|
|
29
|
+
declare const encodeULID: (ulid: string) => Base60String;
|
|
30
|
+
declare const decodeULID: (text: Base60String) => string;
|
|
31
|
+
declare const compareAsBigInt: (a: Base60String, b: Base60String) => number;
|
|
32
|
+
declare const isValidBase60: (text: string) => text is Base60String;
|
|
21
33
|
|
|
22
|
-
export { type Base60Codec, type Base60String, base60, createBase60Codec, base60 as default };
|
|
34
|
+
export { type Base60Codec, type Base60String, base60, compareAsBigInt, createBase60Codec, decodeInt64, decodeToBigInt, decodeToBytes, decodeULID, decodeUUID, base60 as default, encodeBigInt, encodeBytes, encodeInt64, encodeULID, encodeUUID, isValidBase60 };
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ function createBase60Codec() {
|
|
|
45
45
|
}
|
|
46
46
|
return bytes;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
function encodeBigInt2(value, padLength) {
|
|
49
49
|
if (value === 0n) {
|
|
50
50
|
return padLength != null ? leftPad(alphabet[0], padLength) : alphabet[0];
|
|
51
51
|
}
|
|
@@ -58,7 +58,7 @@ function createBase60Codec() {
|
|
|
58
58
|
}
|
|
59
59
|
return padLength != null ? leftPad(out, padLength) : out;
|
|
60
60
|
}
|
|
61
|
-
function
|
|
61
|
+
function decodeToBigInt2(text) {
|
|
62
62
|
let v = 0n;
|
|
63
63
|
for (const ch of text) {
|
|
64
64
|
const d = charToValue.get(ch);
|
|
@@ -72,16 +72,16 @@ function createBase60Codec() {
|
|
|
72
72
|
return {
|
|
73
73
|
alphabet,
|
|
74
74
|
encodeBytes(bytes) {
|
|
75
|
-
return
|
|
75
|
+
return encodeBigInt2(bytesToBigInt(bytes));
|
|
76
76
|
},
|
|
77
77
|
decodeToBytes(text) {
|
|
78
|
-
return bigIntToBytes(
|
|
78
|
+
return bigIntToBytes(decodeToBigInt2(text));
|
|
79
79
|
},
|
|
80
|
-
encodeBigInt,
|
|
81
|
-
decodeToBigInt,
|
|
80
|
+
encodeBigInt: encodeBigInt2,
|
|
81
|
+
decodeToBigInt: decodeToBigInt2,
|
|
82
82
|
encodeInt64(value) {
|
|
83
83
|
return leftPad(
|
|
84
|
-
|
|
84
|
+
encodeBigInt2(BigInt(value)),
|
|
85
85
|
FIXED_LEN_INT64
|
|
86
86
|
);
|
|
87
87
|
},
|
|
@@ -89,7 +89,7 @@ function createBase60Codec() {
|
|
|
89
89
|
if (text.length !== FIXED_LEN_INT64) {
|
|
90
90
|
throw new Error(`Expected ${FIXED_LEN_INT64} chars for Base60 Int64`);
|
|
91
91
|
}
|
|
92
|
-
return
|
|
92
|
+
return decodeToBigInt2(text);
|
|
93
93
|
},
|
|
94
94
|
encodeUUID(uuid) {
|
|
95
95
|
const hex = uuid.replace(/-/g, "");
|
|
@@ -99,12 +99,12 @@ function createBase60Codec() {
|
|
|
99
99
|
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
|
|
100
100
|
}
|
|
101
101
|
return leftPad(
|
|
102
|
-
|
|
102
|
+
encodeBigInt2(bytesToBigInt(bytes)),
|
|
103
103
|
FIXED_LEN_UUID
|
|
104
104
|
);
|
|
105
105
|
},
|
|
106
106
|
decodeUUID(text) {
|
|
107
|
-
const bytes = bigIntToBytes(
|
|
107
|
+
const bytes = bigIntToBytes(decodeToBigInt2(text), 16);
|
|
108
108
|
const hex = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
109
109
|
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
|
|
110
110
|
},
|
|
@@ -122,14 +122,14 @@ function createBase60Codec() {
|
|
|
122
122
|
if (v === void 0) throw new Error(`Invalid ULID char: ${ch}`);
|
|
123
123
|
value = (value << 5n) + BigInt(v);
|
|
124
124
|
}
|
|
125
|
-
const raw =
|
|
125
|
+
const raw = encodeBigInt2(value);
|
|
126
126
|
return leftPad(raw, FIXED_LEN_ULID);
|
|
127
127
|
},
|
|
128
128
|
decodeULID(text) {
|
|
129
129
|
if (text.length !== 22) {
|
|
130
130
|
throw new Error("Expected 22-char Base60 ULID");
|
|
131
131
|
}
|
|
132
|
-
const value =
|
|
132
|
+
const value = decodeToBigInt2(text);
|
|
133
133
|
const bytes = bigIntToBytes(value, 16);
|
|
134
134
|
let bits = "";
|
|
135
135
|
for (const b of bytes) {
|
|
@@ -144,8 +144,8 @@ function createBase60Codec() {
|
|
|
144
144
|
return ulid;
|
|
145
145
|
},
|
|
146
146
|
compareAsBigInt(a, b) {
|
|
147
|
-
const ai =
|
|
148
|
-
const bi =
|
|
147
|
+
const ai = decodeToBigInt2(a);
|
|
148
|
+
const bi = decodeToBigInt2(b);
|
|
149
149
|
if (ai < bi) return -1;
|
|
150
150
|
if (ai > bi) return 1;
|
|
151
151
|
return 0;
|
|
@@ -159,9 +159,35 @@ function createBase60Codec() {
|
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
161
|
var base60 = createBase60Codec();
|
|
162
|
+
var {
|
|
163
|
+
encodeBytes,
|
|
164
|
+
decodeToBytes,
|
|
165
|
+
encodeBigInt,
|
|
166
|
+
decodeToBigInt,
|
|
167
|
+
encodeInt64,
|
|
168
|
+
decodeInt64,
|
|
169
|
+
encodeUUID,
|
|
170
|
+
decodeUUID,
|
|
171
|
+
encodeULID,
|
|
172
|
+
decodeULID,
|
|
173
|
+
compareAsBigInt,
|
|
174
|
+
isValidBase60
|
|
175
|
+
} = base60;
|
|
162
176
|
var index_default = base60;
|
|
163
177
|
export {
|
|
164
178
|
base60,
|
|
179
|
+
compareAsBigInt,
|
|
165
180
|
createBase60Codec,
|
|
166
|
-
|
|
181
|
+
decodeInt64,
|
|
182
|
+
decodeToBigInt,
|
|
183
|
+
decodeToBytes,
|
|
184
|
+
decodeULID,
|
|
185
|
+
decodeUUID,
|
|
186
|
+
index_default as default,
|
|
187
|
+
encodeBigInt,
|
|
188
|
+
encodeBytes,
|
|
189
|
+
encodeInt64,
|
|
190
|
+
encodeULID,
|
|
191
|
+
encodeUUID,
|
|
192
|
+
isValidBase60
|
|
167
193
|
};
|
package/package.json
CHANGED