@cloudpss/id 0.5.17

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 ADDED
@@ -0,0 +1,9 @@
1
+ # @cloudpss/id
2
+
3
+ Uuid related utilities.
4
+
5
+ ## API
6
+
7
+ ### uuidToHid(uuid: string): string
8
+
9
+ Transform uuid to corresponding hid (human readable id).
@@ -0,0 +1,10 @@
1
+ import { type UUID } from '../uuid.js';
2
+ /** HID */
3
+ export type HID = `${string}-${string}-${number}`;
4
+ /** 生成 UUID 关联的 HID */
5
+ export declare function uuidToHid(uuid: UUID): HID;
6
+ export declare const HID_PATTERN: RegExp;
7
+ export declare const HID_MIN_LENGTH: number;
8
+ export declare const HID_MAX_LENGTH: number;
9
+ /** 检查是否为有效的 HID */
10
+ export declare function isHid(hid: string | undefined | null): hid is HID;
@@ -0,0 +1,50 @@
1
+ import { isUuid } from '../uuid.js';
2
+ import { ADJECTIVES, ANIMALS } from './vocabulary.js';
3
+ /** 生成 UUID 关联的 HID */
4
+ export function uuidToHid(uuid) {
5
+ if (!isUuid(uuid))
6
+ throw new Error(`Invalid uuid: ${String(uuid)}`);
7
+ // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
8
+ const [a, b, c, d, e] = uuid.split('-', 5);
9
+ const version = c[0];
10
+ let iAdjective, iAnimal, iIndex;
11
+ if (version === '1' || version === '2') {
12
+ // add 4bits of time-low to adjective parts to avoid collusion
13
+ iAdjective = Number.parseInt(`${c.slice(1)}${d.slice(1)}${a.slice(6)}`, 16); // 32bits
14
+ // use node bits as animal to make uuid v1 from same node has same animal name
15
+ iAnimal = Number.parseInt(e, 16); // 48bits
16
+ // use rest bits of time-low and time-mid
17
+ iIndex = Number.parseInt(`${b}${a.slice(0, 6)}`, 16); // 40bits
18
+ }
19
+ else {
20
+ // random bits uuid types, not necessary to use all bits
21
+ iAdjective = Number.parseInt(a, 16);
22
+ iAnimal = Number.parseInt(e, 16);
23
+ iIndex = Number.parseInt(b, 16);
24
+ }
25
+ const adjective = ADJECTIVES[iAdjective % ADJECTIVES.length];
26
+ const animal = ANIMALS[iAnimal % ANIMALS.length];
27
+ const index = (iIndex % 99) + 1;
28
+ return `${adjective}-${animal}-${index}`;
29
+ }
30
+ export const HID_PATTERN = /^[a-z]+-[a-z]+-[1-9][0-9]?$/;
31
+ export const HID_MIN_LENGTH = ADJECTIVES.reduce((a, b) => Math.min(a, b.length), 0) + ANIMALS.reduce((a, b) => Math.min(a, b.length), 0) + 3;
32
+ export const HID_MAX_LENGTH = ADJECTIVES.reduce((a, b) => Math.max(a, b.length), 0) + ANIMALS.reduce((a, b) => Math.max(a, b.length), 0) + 4;
33
+ /** 检查是否为有效的 HID */
34
+ export function isHid(hid) {
35
+ if (typeof hid != 'string')
36
+ return false;
37
+ if (hid.length > HID_MAX_LENGTH)
38
+ return false;
39
+ if (hid.length < HID_MIN_LENGTH)
40
+ return false;
41
+ if (!HID_PATTERN.test(hid))
42
+ return false;
43
+ const [a, b] = hid.split('-');
44
+ if (!ADJECTIVES.includes(a.toLowerCase()))
45
+ return false;
46
+ if (!ANIMALS.includes(b.toLowerCase()))
47
+ return false;
48
+ return true;
49
+ }
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hid/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const ADJECTIVES: readonly string[];
2
+ export declare const ANIMALS: readonly string[];
@@ -0,0 +1,238 @@
1
+ export const ADJECTIVES = Object.freeze([
2
+ 'afraid',
3
+ 'ancient',
4
+ 'angry',
5
+ 'average',
6
+ 'bad',
7
+ 'big',
8
+ 'bitter',
9
+ 'black',
10
+ 'blue',
11
+ 'brave',
12
+ 'breezy',
13
+ 'bright',
14
+ 'brown',
15
+ 'calm',
16
+ 'chatty',
17
+ 'chilly',
18
+ 'clever',
19
+ 'cold',
20
+ 'cowardly',
21
+ 'cuddly',
22
+ 'curly',
23
+ 'curvy',
24
+ 'dangerous',
25
+ 'dry',
26
+ 'dull',
27
+ 'empty',
28
+ 'evil',
29
+ 'fast',
30
+ 'fat',
31
+ 'fluffy',
32
+ 'foolish',
33
+ 'fresh',
34
+ 'friendly',
35
+ 'funny',
36
+ 'fuzzy',
37
+ 'gentle',
38
+ 'giant',
39
+ 'good',
40
+ 'great',
41
+ 'green',
42
+ 'grumpy',
43
+ 'happy',
44
+ 'hard',
45
+ 'heavy',
46
+ 'helpless',
47
+ 'honest',
48
+ 'horrible',
49
+ 'hot',
50
+ 'hungry',
51
+ 'itchy',
52
+ 'jolly',
53
+ 'kind',
54
+ 'lazy',
55
+ 'light',
56
+ 'little',
57
+ 'loud',
58
+ 'lovely',
59
+ 'lucky',
60
+ 'massive',
61
+ 'mean',
62
+ 'mighty',
63
+ 'modern',
64
+ 'moody',
65
+ 'nasty',
66
+ 'neat',
67
+ 'nervous',
68
+ 'new',
69
+ 'nice',
70
+ 'odd',
71
+ 'old',
72
+ 'orange',
73
+ 'ordinary',
74
+ 'perfect',
75
+ 'pink',
76
+ 'plastic',
77
+ 'polite',
78
+ 'popular',
79
+ 'pretty',
80
+ 'proud',
81
+ 'purple',
82
+ 'quick',
83
+ 'quiet',
84
+ 'rare',
85
+ 'red',
86
+ 'rotten',
87
+ 'rude',
88
+ 'selfish',
89
+ 'serious',
90
+ 'shaggy',
91
+ 'sharp',
92
+ 'short',
93
+ 'shy',
94
+ 'silent',
95
+ 'silly',
96
+ 'slimy',
97
+ 'slippery',
98
+ 'smart',
99
+ 'smooth',
100
+ 'soft',
101
+ 'sour',
102
+ 'spicy',
103
+ 'splendid',
104
+ 'spotty',
105
+ 'stale',
106
+ 'strange',
107
+ 'strong',
108
+ 'stupid',
109
+ 'sweet',
110
+ 'swift',
111
+ 'tall',
112
+ 'tame',
113
+ 'tasty',
114
+ 'tender',
115
+ 'terrible',
116
+ 'thin',
117
+ 'tidy',
118
+ 'tiny',
119
+ 'tough',
120
+ 'tricky',
121
+ 'ugly',
122
+ 'unlucky',
123
+ 'warm',
124
+ 'weak',
125
+ 'wet',
126
+ 'white',
127
+ 'wicked',
128
+ 'wise',
129
+ 'witty',
130
+ 'wonderful',
131
+ 'yellow',
132
+ 'young',
133
+ ]);
134
+ export const ANIMALS = Object.freeze([
135
+ 'ape',
136
+ 'baboon',
137
+ 'badger',
138
+ 'bat',
139
+ 'bear',
140
+ 'bird',
141
+ 'bobcat',
142
+ 'bulldog',
143
+ 'bullfrog',
144
+ 'cat',
145
+ 'catfish',
146
+ 'cheetah',
147
+ 'chicken',
148
+ 'chipmunk',
149
+ 'cobra',
150
+ 'cougar',
151
+ 'cow',
152
+ 'crab',
153
+ 'deer',
154
+ 'dingo',
155
+ 'dodo',
156
+ 'dog',
157
+ 'dolphin',
158
+ 'donkey',
159
+ 'dragon',
160
+ 'dragonfly',
161
+ 'duck',
162
+ 'eagle',
163
+ 'earwig',
164
+ 'eel',
165
+ 'elephant',
166
+ 'emu',
167
+ 'falcon',
168
+ 'fireant',
169
+ 'firefox',
170
+ 'fish',
171
+ 'fly',
172
+ 'fox',
173
+ 'frog',
174
+ 'gecko',
175
+ 'goat',
176
+ 'goose',
177
+ 'grasshopper',
178
+ 'horse',
179
+ 'hound',
180
+ 'husky',
181
+ 'impala',
182
+ 'insect',
183
+ 'jellyfish',
184
+ 'kangaroo',
185
+ 'ladybug',
186
+ 'liger',
187
+ 'lion',
188
+ 'lionfish',
189
+ 'lizard',
190
+ 'mayfly',
191
+ 'mole',
192
+ 'monkey',
193
+ 'moose',
194
+ 'moth',
195
+ 'mouse',
196
+ 'mule',
197
+ 'newt',
198
+ 'octopus',
199
+ 'otter',
200
+ 'owl',
201
+ 'panda',
202
+ 'panther',
203
+ 'parrot',
204
+ 'penguin',
205
+ 'pig',
206
+ 'puma',
207
+ 'pug',
208
+ 'quail',
209
+ 'rabbit',
210
+ 'rat',
211
+ 'rattlesnake',
212
+ 'robin',
213
+ 'seahorse',
214
+ 'sheep',
215
+ 'shrimp',
216
+ 'skunk',
217
+ 'sloth',
218
+ 'snail',
219
+ 'snake',
220
+ 'squid',
221
+ 'starfish',
222
+ 'stingray',
223
+ 'swan',
224
+ 'termite',
225
+ 'tiger',
226
+ 'treefrog',
227
+ 'turkey',
228
+ 'turtle',
229
+ 'vampirebat',
230
+ 'walrus',
231
+ 'warthog',
232
+ 'wasp',
233
+ 'wolverine',
234
+ 'wombat',
235
+ 'yak',
236
+ 'zebra',
237
+ ]);
238
+ //# sourceMappingURL=vocabulary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/hid/vocabulary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { type UUID, UUID_PATTERN, UUID_LENGTH, UUID_PATTERN_STRICT, isUuid, isUuidStrict, serializeUUID, deserializeUUID, deserializeUUIDInto, } from './uuid.js';
2
+ export { type HID, HID_PATTERN, HID_MAX_LENGTH, HID_MIN_LENGTH, isHid, uuidToHid } from './hid/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { UUID_PATTERN, UUID_LENGTH, UUID_PATTERN_STRICT, isUuid, isUuidStrict, serializeUUID, deserializeUUID, deserializeUUIDInto, } from './uuid.js';
2
+ export { HID_PATTERN, HID_MAX_LENGTH, HID_MIN_LENGTH, isHid, uuidToHid } from './hid/index.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,aAAa,EACb,eAAe,EACf,mBAAmB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAY,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/uuid.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ /** UUID */
2
+ export type UUID = `${string}-${string}-${string}-${string}-${string}`;
3
+ /** 匹配 UUID 的正则表达式 */
4
+ export declare const UUID_PATTERN: RegExp;
5
+ /** 匹配 **小写** UUID 的正则表达式 */
6
+ export declare const UUID_PATTERN_STRICT: RegExp;
7
+ export declare const UUID_LENGTH: number;
8
+ /** 检查输入是否为 UUID */
9
+ export declare function isUuid(uuid: string | null | undefined): uuid is UUID;
10
+ /** 检查输入是否为 **小写** UUID */
11
+ export declare function isUuidStrict(uuid: string | null | undefined): uuid is UUID;
12
+ /** 将 UUID 序列化为字符串 */
13
+ export declare function serializeUUID(buf: Uint8Array, offset?: number): UUID;
14
+ /** 将 UUID 字符串反序列化 */
15
+ export declare function deserializeUUID(value: UUID): Uint8Array;
16
+ /** 将 UUID 字符串反序列化 */
17
+ export declare function deserializeUUIDInto(value: UUID, buf: Uint8Array, offset?: number): void;
package/dist/uuid.js ADDED
@@ -0,0 +1,144 @@
1
+ /** 匹配 UUID 的正则表达式 */
2
+ export const UUID_PATTERN = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
3
+ /** 匹配 **小写** UUID 的正则表达式 */
4
+ export const UUID_PATTERN_STRICT = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/;
5
+ export const UUID_LENGTH = '00000000-0000-0000-0000-000000000000'.length;
6
+ /** 检查输入是否为 UUID */
7
+ export function isUuid(uuid) {
8
+ return typeof uuid == 'string' && uuid.length === UUID_LENGTH && UUID_PATTERN.test(uuid);
9
+ }
10
+ /** 检查输入是否为 **小写** UUID */
11
+ export function isUuidStrict(uuid) {
12
+ return typeof uuid == 'string' && uuid.length === UUID_LENGTH && UUID_PATTERN_STRICT.test(uuid);
13
+ }
14
+ const kHexBytes = (() => {
15
+ const arr = Array.from({ length: 256 });
16
+ for (let i = 0; i < arr.length; i++) {
17
+ arr[i] = i.toString(16).padStart(2, '0');
18
+ }
19
+ return arr;
20
+ })();
21
+ /** 将 UUID 序列化为字符串 */
22
+ export function serializeUUID(buf, offset = 0) {
23
+ if (buf.length < offset + 16) {
24
+ throw new Error(`Invalid UUID length: ${buf.length} < ${offset + 16}`);
25
+ }
26
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
27
+ return (kHexBytes[buf[offset]] +
28
+ kHexBytes[buf[offset + 1]] +
29
+ kHexBytes[buf[offset + 2]] +
30
+ kHexBytes[buf[offset + 3]] +
31
+ '-' +
32
+ kHexBytes[buf[offset + 4]] +
33
+ kHexBytes[buf[offset + 5]] +
34
+ '-' +
35
+ kHexBytes[buf[offset + 6]] +
36
+ kHexBytes[buf[offset + 7]] +
37
+ '-' +
38
+ kHexBytes[buf[offset + 8]] +
39
+ kHexBytes[buf[offset + 9]] +
40
+ '-' +
41
+ kHexBytes[buf[offset + 10]] +
42
+ kHexBytes[buf[offset + 11]] +
43
+ kHexBytes[buf[offset + 12]] +
44
+ kHexBytes[buf[offset + 13]] +
45
+ kHexBytes[buf[offset + 14]] +
46
+ kHexBytes[buf[offset + 15]]);
47
+ }
48
+ const kHexChars = (() => {
49
+ const arr = Array.from({ length: 128 });
50
+ arr.fill(0);
51
+ arr['1'.charCodeAt(0)] = 1;
52
+ arr['2'.charCodeAt(0)] = 2;
53
+ arr['3'.charCodeAt(0)] = 3;
54
+ arr['4'.charCodeAt(0)] = 4;
55
+ arr['5'.charCodeAt(0)] = 5;
56
+ arr['6'.charCodeAt(0)] = 6;
57
+ arr['7'.charCodeAt(0)] = 7;
58
+ arr['8'.charCodeAt(0)] = 8;
59
+ arr['9'.charCodeAt(0)] = 9;
60
+ arr['a'.charCodeAt(0)] = 10;
61
+ arr['b'.charCodeAt(0)] = 11;
62
+ arr['c'.charCodeAt(0)] = 12;
63
+ arr['d'.charCodeAt(0)] = 13;
64
+ arr['e'.charCodeAt(0)] = 14;
65
+ arr['f'.charCodeAt(0)] = 15;
66
+ arr['A'.charCodeAt(0)] = 10;
67
+ arr['B'.charCodeAt(0)] = 11;
68
+ arr['C'.charCodeAt(0)] = 12;
69
+ arr['D'.charCodeAt(0)] = 13;
70
+ arr['E'.charCodeAt(0)] = 14;
71
+ arr['F'.charCodeAt(0)] = 15;
72
+ return arr;
73
+ })();
74
+ /** 将 UUID 字符串反序列化 */
75
+ export function deserializeUUID(value) {
76
+ if (value.length !== UUID_LENGTH) {
77
+ throw new Error(`Invalid UUID string: ${value}`);
78
+ }
79
+ const buf = new Uint8Array(16);
80
+ deserializeUUIDIntoImpl(value, buf, 0);
81
+ return buf;
82
+ }
83
+ /** 将 UUID 字符串反序列化 */
84
+ export function deserializeUUIDInto(value, buf, offset = 0) {
85
+ if (value.length !== UUID_LENGTH) {
86
+ throw new Error(`Invalid UUID string: ${value}`);
87
+ }
88
+ if (buf.length < offset + 16) {
89
+ throw new Error(`Buffer is too small: ${buf.length} < ${offset + 16}`);
90
+ }
91
+ deserializeUUIDIntoImpl(value, buf, offset);
92
+ }
93
+ /** 将 UUID 字符串反序列化 */
94
+ function deserializeUUIDIntoImpl(value, buf, offset) {
95
+ const byte0 = kHexChars[value.charCodeAt(0) & 0x7f];
96
+ const byte1 = kHexChars[value.charCodeAt(1) & 0x7f];
97
+ buf[offset + 0] = (byte0 << 4) | byte1;
98
+ const byte2 = kHexChars[value.charCodeAt(2) & 0x7f];
99
+ const byte3 = kHexChars[value.charCodeAt(3) & 0x7f];
100
+ buf[offset + 1] = (byte2 << 4) | byte3;
101
+ const byte4 = kHexChars[value.charCodeAt(4) & 0x7f];
102
+ const byte5 = kHexChars[value.charCodeAt(5) & 0x7f];
103
+ buf[offset + 2] = (byte4 << 4) | byte5;
104
+ const byte6 = kHexChars[value.charCodeAt(6) & 0x7f];
105
+ const byte7 = kHexChars[value.charCodeAt(7) & 0x7f];
106
+ buf[offset + 3] = (byte6 << 4) | byte7;
107
+ const byte9 = kHexChars[value.charCodeAt(9) & 0x7f];
108
+ const byte10 = kHexChars[value.charCodeAt(10) & 0x7f];
109
+ buf[offset + 4] = (byte9 << 4) | byte10;
110
+ const byte11 = kHexChars[value.charCodeAt(11) & 0x7f];
111
+ const byte12 = kHexChars[value.charCodeAt(12) & 0x7f];
112
+ buf[offset + 5] = (byte11 << 4) | byte12;
113
+ const byte14 = kHexChars[value.charCodeAt(14) & 0x7f];
114
+ const byte15 = kHexChars[value.charCodeAt(15) & 0x7f];
115
+ buf[offset + 6] = (byte14 << 4) | byte15;
116
+ const byte16 = kHexChars[value.charCodeAt(16) & 0x7f];
117
+ const byte17 = kHexChars[value.charCodeAt(17) & 0x7f];
118
+ buf[offset + 7] = (byte16 << 4) | byte17;
119
+ const byte19 = kHexChars[value.charCodeAt(19) & 0x7f];
120
+ const byte20 = kHexChars[value.charCodeAt(20) & 0x7f];
121
+ buf[offset + 8] = (byte19 << 4) | byte20;
122
+ const byte21 = kHexChars[value.charCodeAt(21) & 0x7f];
123
+ const byte22 = kHexChars[value.charCodeAt(22) & 0x7f];
124
+ buf[offset + 9] = (byte21 << 4) | byte22;
125
+ const byte24 = kHexChars[value.charCodeAt(24) & 0x7f];
126
+ const byte25 = kHexChars[value.charCodeAt(25) & 0x7f];
127
+ buf[offset + 10] = (byte24 << 4) | byte25;
128
+ const byte26 = kHexChars[value.charCodeAt(26) & 0x7f];
129
+ const byte27 = kHexChars[value.charCodeAt(27) & 0x7f];
130
+ buf[offset + 11] = (byte26 << 4) | byte27;
131
+ const byte28 = kHexChars[value.charCodeAt(28) & 0x7f];
132
+ const byte29 = kHexChars[value.charCodeAt(29) & 0x7f];
133
+ buf[offset + 12] = (byte28 << 4) | byte29;
134
+ const byte30 = kHexChars[value.charCodeAt(30) & 0x7f];
135
+ const byte31 = kHexChars[value.charCodeAt(31) & 0x7f];
136
+ buf[offset + 13] = (byte30 << 4) | byte31;
137
+ const byte32 = kHexChars[value.charCodeAt(32) & 0x7f];
138
+ const byte33 = kHexChars[value.charCodeAt(33) & 0x7f];
139
+ buf[offset + 14] = (byte32 << 4) | byte33;
140
+ const byte34 = kHexChars[value.charCodeAt(34) & 0x7f];
141
+ const byte35 = kHexChars[value.charCodeAt(35) & 0x7f];
142
+ buf[offset + 15] = (byte34 << 4) | byte35;
143
+ }
144
+ //# sourceMappingURL=uuid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uuid.js","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1,3 @@
1
+ import { config } from '../../jest.config.js';
2
+
3
+ export default { ...config };
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@cloudpss/id",
3
+ "version": "0.5.17",
4
+ "author": "CloudPSS",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "human readable id",
8
+ "uuid",
9
+ "guid"
10
+ ],
11
+ "type": "module",
12
+ "main": "dist/index.js",
13
+ "module": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "typesVersions": {
16
+ "*": {
17
+ "index.d.ts": [
18
+ "dist/index.d.ts"
19
+ ]
20
+ }
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "start": "pnpm clean && tsc --watch",
30
+ "build": "pnpm clean && tsc",
31
+ "clean": "rimraf dist",
32
+ "test": "NODE_OPTIONS=\"${NODE_OPTIONS:-} --experimental-vm-modules\" jest"
33
+ }
34
+ }
@@ -0,0 +1,53 @@
1
+ import { isUuid, type UUID } from '../uuid.js';
2
+ import { ADJECTIVES, ANIMALS } from './vocabulary.js';
3
+
4
+ /** HID */
5
+ export type HID = `${string}-${string}-${number}`;
6
+
7
+ /** 生成 UUID 关联的 HID */
8
+ export function uuidToHid(uuid: UUID): HID {
9
+ if (!isUuid(uuid)) throw new Error(`Invalid uuid: ${String(uuid)}`);
10
+
11
+ // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
12
+ const [a, b, c, d, e] = uuid.split('-', 5);
13
+ const version = c[0];
14
+ let iAdjective, iAnimal, iIndex;
15
+ if (version === '1' || version === '2') {
16
+ // add 4bits of time-low to adjective parts to avoid collusion
17
+ iAdjective = Number.parseInt(`${c.slice(1)}${d.slice(1)}${a.slice(6)}`, 16); // 32bits
18
+ // use node bits as animal to make uuid v1 from same node has same animal name
19
+ iAnimal = Number.parseInt(e, 16); // 48bits
20
+ // use rest bits of time-low and time-mid
21
+ iIndex = Number.parseInt(`${b}${a.slice(0, 6)}`, 16); // 40bits
22
+ } else {
23
+ // random bits uuid types, not necessary to use all bits
24
+ iAdjective = Number.parseInt(a, 16);
25
+ iAnimal = Number.parseInt(e, 16);
26
+ iIndex = Number.parseInt(b, 16);
27
+ }
28
+
29
+ const adjective = ADJECTIVES[iAdjective % ADJECTIVES.length];
30
+ const animal = ANIMALS[iAnimal % ANIMALS.length];
31
+ const index = (iIndex % 99) + 1;
32
+
33
+ return `${adjective}-${animal}-${index}`;
34
+ }
35
+
36
+ export const HID_PATTERN = /^[a-z]+-[a-z]+-[1-9][0-9]?$/;
37
+ export const HID_MIN_LENGTH =
38
+ ADJECTIVES.reduce((a, b) => Math.min(a, b.length), 0) + ANIMALS.reduce((a, b) => Math.min(a, b.length), 0) + 3;
39
+ export const HID_MAX_LENGTH =
40
+ ADJECTIVES.reduce((a, b) => Math.max(a, b.length), 0) + ANIMALS.reduce((a, b) => Math.max(a, b.length), 0) + 4;
41
+
42
+ /** 检查是否为有效的 HID */
43
+ export function isHid(hid: string | undefined | null): hid is HID {
44
+ if (typeof hid != 'string') return false;
45
+ if (hid.length > HID_MAX_LENGTH) return false;
46
+ if (hid.length < HID_MIN_LENGTH) return false;
47
+ if (!HID_PATTERN.test(hid)) return false;
48
+
49
+ const [a, b] = hid.split('-');
50
+ if (!ADJECTIVES.includes(a.toLowerCase())) return false;
51
+ if (!ANIMALS.includes(b.toLowerCase())) return false;
52
+ return true;
53
+ }
@@ -0,0 +1,238 @@
1
+ export const ADJECTIVES = Object.freeze([
2
+ 'afraid',
3
+ 'ancient',
4
+ 'angry',
5
+ 'average',
6
+ 'bad',
7
+ 'big',
8
+ 'bitter',
9
+ 'black',
10
+ 'blue',
11
+ 'brave',
12
+ 'breezy',
13
+ 'bright',
14
+ 'brown',
15
+ 'calm',
16
+ 'chatty',
17
+ 'chilly',
18
+ 'clever',
19
+ 'cold',
20
+ 'cowardly',
21
+ 'cuddly',
22
+ 'curly',
23
+ 'curvy',
24
+ 'dangerous',
25
+ 'dry',
26
+ 'dull',
27
+ 'empty',
28
+ 'evil',
29
+ 'fast',
30
+ 'fat',
31
+ 'fluffy',
32
+ 'foolish',
33
+ 'fresh',
34
+ 'friendly',
35
+ 'funny',
36
+ 'fuzzy',
37
+ 'gentle',
38
+ 'giant',
39
+ 'good',
40
+ 'great',
41
+ 'green',
42
+ 'grumpy',
43
+ 'happy',
44
+ 'hard',
45
+ 'heavy',
46
+ 'helpless',
47
+ 'honest',
48
+ 'horrible',
49
+ 'hot',
50
+ 'hungry',
51
+ 'itchy',
52
+ 'jolly',
53
+ 'kind',
54
+ 'lazy',
55
+ 'light',
56
+ 'little',
57
+ 'loud',
58
+ 'lovely',
59
+ 'lucky',
60
+ 'massive',
61
+ 'mean',
62
+ 'mighty',
63
+ 'modern',
64
+ 'moody',
65
+ 'nasty',
66
+ 'neat',
67
+ 'nervous',
68
+ 'new',
69
+ 'nice',
70
+ 'odd',
71
+ 'old',
72
+ 'orange',
73
+ 'ordinary',
74
+ 'perfect',
75
+ 'pink',
76
+ 'plastic',
77
+ 'polite',
78
+ 'popular',
79
+ 'pretty',
80
+ 'proud',
81
+ 'purple',
82
+ 'quick',
83
+ 'quiet',
84
+ 'rare',
85
+ 'red',
86
+ 'rotten',
87
+ 'rude',
88
+ 'selfish',
89
+ 'serious',
90
+ 'shaggy',
91
+ 'sharp',
92
+ 'short',
93
+ 'shy',
94
+ 'silent',
95
+ 'silly',
96
+ 'slimy',
97
+ 'slippery',
98
+ 'smart',
99
+ 'smooth',
100
+ 'soft',
101
+ 'sour',
102
+ 'spicy',
103
+ 'splendid',
104
+ 'spotty',
105
+ 'stale',
106
+ 'strange',
107
+ 'strong',
108
+ 'stupid',
109
+ 'sweet',
110
+ 'swift',
111
+ 'tall',
112
+ 'tame',
113
+ 'tasty',
114
+ 'tender',
115
+ 'terrible',
116
+ 'thin',
117
+ 'tidy',
118
+ 'tiny',
119
+ 'tough',
120
+ 'tricky',
121
+ 'ugly',
122
+ 'unlucky',
123
+ 'warm',
124
+ 'weak',
125
+ 'wet',
126
+ 'white',
127
+ 'wicked',
128
+ 'wise',
129
+ 'witty',
130
+ 'wonderful',
131
+ 'yellow',
132
+ 'young',
133
+ ]);
134
+
135
+ export const ANIMALS = Object.freeze([
136
+ 'ape',
137
+ 'baboon',
138
+ 'badger',
139
+ 'bat',
140
+ 'bear',
141
+ 'bird',
142
+ 'bobcat',
143
+ 'bulldog',
144
+ 'bullfrog',
145
+ 'cat',
146
+ 'catfish',
147
+ 'cheetah',
148
+ 'chicken',
149
+ 'chipmunk',
150
+ 'cobra',
151
+ 'cougar',
152
+ 'cow',
153
+ 'crab',
154
+ 'deer',
155
+ 'dingo',
156
+ 'dodo',
157
+ 'dog',
158
+ 'dolphin',
159
+ 'donkey',
160
+ 'dragon',
161
+ 'dragonfly',
162
+ 'duck',
163
+ 'eagle',
164
+ 'earwig',
165
+ 'eel',
166
+ 'elephant',
167
+ 'emu',
168
+ 'falcon',
169
+ 'fireant',
170
+ 'firefox',
171
+ 'fish',
172
+ 'fly',
173
+ 'fox',
174
+ 'frog',
175
+ 'gecko',
176
+ 'goat',
177
+ 'goose',
178
+ 'grasshopper',
179
+ 'horse',
180
+ 'hound',
181
+ 'husky',
182
+ 'impala',
183
+ 'insect',
184
+ 'jellyfish',
185
+ 'kangaroo',
186
+ 'ladybug',
187
+ 'liger',
188
+ 'lion',
189
+ 'lionfish',
190
+ 'lizard',
191
+ 'mayfly',
192
+ 'mole',
193
+ 'monkey',
194
+ 'moose',
195
+ 'moth',
196
+ 'mouse',
197
+ 'mule',
198
+ 'newt',
199
+ 'octopus',
200
+ 'otter',
201
+ 'owl',
202
+ 'panda',
203
+ 'panther',
204
+ 'parrot',
205
+ 'penguin',
206
+ 'pig',
207
+ 'puma',
208
+ 'pug',
209
+ 'quail',
210
+ 'rabbit',
211
+ 'rat',
212
+ 'rattlesnake',
213
+ 'robin',
214
+ 'seahorse',
215
+ 'sheep',
216
+ 'shrimp',
217
+ 'skunk',
218
+ 'sloth',
219
+ 'snail',
220
+ 'snake',
221
+ 'squid',
222
+ 'starfish',
223
+ 'stingray',
224
+ 'swan',
225
+ 'termite',
226
+ 'tiger',
227
+ 'treefrog',
228
+ 'turkey',
229
+ 'turtle',
230
+ 'vampirebat',
231
+ 'walrus',
232
+ 'warthog',
233
+ 'wasp',
234
+ 'wolverine',
235
+ 'wombat',
236
+ 'yak',
237
+ 'zebra',
238
+ ]);
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ export {
2
+ type UUID,
3
+ UUID_PATTERN,
4
+ UUID_LENGTH,
5
+ UUID_PATTERN_STRICT,
6
+ isUuid,
7
+ isUuidStrict,
8
+ serializeUUID,
9
+ deserializeUUID,
10
+ deserializeUUIDInto,
11
+ } from './uuid.js';
12
+ export { type HID, HID_PATTERN, HID_MAX_LENGTH, HID_MIN_LENGTH, isHid, uuidToHid } from './hid/index.js';
package/src/uuid.ts ADDED
@@ -0,0 +1,170 @@
1
+ /** UUID */
2
+ export type UUID = `${string}-${string}-${string}-${string}-${string}`;
3
+
4
+ /** 匹配 UUID 的正则表达式 */
5
+ export const UUID_PATTERN =
6
+ /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
7
+ /** 匹配 **小写** UUID 的正则表达式 */
8
+ export const UUID_PATTERN_STRICT =
9
+ /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/;
10
+ export const UUID_LENGTH = '00000000-0000-0000-0000-000000000000'.length;
11
+
12
+ /** 检查输入是否为 UUID */
13
+ export function isUuid(uuid: string | null | undefined): uuid is UUID {
14
+ return typeof uuid == 'string' && uuid.length === UUID_LENGTH && UUID_PATTERN.test(uuid);
15
+ }
16
+ /** 检查输入是否为 **小写** UUID */
17
+ export function isUuidStrict(uuid: string | null | undefined): uuid is UUID {
18
+ return typeof uuid == 'string' && uuid.length === UUID_LENGTH && UUID_PATTERN_STRICT.test(uuid);
19
+ }
20
+
21
+ const kHexBytes = ((): readonly string[] => {
22
+ const arr = Array.from<string>({ length: 256 });
23
+ for (let i = 0; i < arr.length; i++) {
24
+ arr[i] = i.toString(16).padStart(2, '0');
25
+ }
26
+ return arr;
27
+ })();
28
+
29
+ /** 将 UUID 序列化为字符串 */
30
+ export function serializeUUID(buf: Uint8Array, offset = 0): UUID {
31
+ if (buf.length < offset + 16) {
32
+ throw new Error(`Invalid UUID length: ${buf.length} < ${offset + 16}`);
33
+ }
34
+ // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
35
+ return (kHexBytes[buf[offset]] +
36
+ kHexBytes[buf[offset + 1]] +
37
+ kHexBytes[buf[offset + 2]] +
38
+ kHexBytes[buf[offset + 3]] +
39
+ '-' +
40
+ kHexBytes[buf[offset + 4]] +
41
+ kHexBytes[buf[offset + 5]] +
42
+ '-' +
43
+ kHexBytes[buf[offset + 6]] +
44
+ kHexBytes[buf[offset + 7]] +
45
+ '-' +
46
+ kHexBytes[buf[offset + 8]] +
47
+ kHexBytes[buf[offset + 9]] +
48
+ '-' +
49
+ kHexBytes[buf[offset + 10]] +
50
+ kHexBytes[buf[offset + 11]] +
51
+ kHexBytes[buf[offset + 12]] +
52
+ kHexBytes[buf[offset + 13]] +
53
+ kHexBytes[buf[offset + 14]] +
54
+ kHexBytes[buf[offset + 15]]) as UUID;
55
+ }
56
+
57
+ const kHexChars = ((): readonly number[] => {
58
+ const arr = Array.from<number>({ length: 128 });
59
+ arr.fill(0);
60
+ arr['1'.charCodeAt(0)] = 1;
61
+ arr['2'.charCodeAt(0)] = 2;
62
+ arr['3'.charCodeAt(0)] = 3;
63
+ arr['4'.charCodeAt(0)] = 4;
64
+ arr['5'.charCodeAt(0)] = 5;
65
+ arr['6'.charCodeAt(0)] = 6;
66
+ arr['7'.charCodeAt(0)] = 7;
67
+ arr['8'.charCodeAt(0)] = 8;
68
+ arr['9'.charCodeAt(0)] = 9;
69
+ arr['a'.charCodeAt(0)] = 10;
70
+ arr['b'.charCodeAt(0)] = 11;
71
+ arr['c'.charCodeAt(0)] = 12;
72
+ arr['d'.charCodeAt(0)] = 13;
73
+ arr['e'.charCodeAt(0)] = 14;
74
+ arr['f'.charCodeAt(0)] = 15;
75
+ arr['A'.charCodeAt(0)] = 10;
76
+ arr['B'.charCodeAt(0)] = 11;
77
+ arr['C'.charCodeAt(0)] = 12;
78
+ arr['D'.charCodeAt(0)] = 13;
79
+ arr['E'.charCodeAt(0)] = 14;
80
+ arr['F'.charCodeAt(0)] = 15;
81
+ return arr;
82
+ })();
83
+
84
+ /** 将 UUID 字符串反序列化 */
85
+ export function deserializeUUID(value: UUID): Uint8Array {
86
+ if (value.length !== UUID_LENGTH) {
87
+ throw new Error(`Invalid UUID string: ${value}`);
88
+ }
89
+ const buf = new Uint8Array(16);
90
+ deserializeUUIDIntoImpl(value, buf, 0);
91
+ return buf;
92
+ }
93
+ /** 将 UUID 字符串反序列化 */
94
+ export function deserializeUUIDInto(value: UUID, buf: Uint8Array, offset = 0): void {
95
+ if (value.length !== UUID_LENGTH) {
96
+ throw new Error(`Invalid UUID string: ${value}`);
97
+ }
98
+ if (buf.length < offset + 16) {
99
+ throw new Error(`Buffer is too small: ${buf.length} < ${offset + 16}`);
100
+ }
101
+
102
+ deserializeUUIDIntoImpl(value, buf, offset);
103
+ }
104
+
105
+ /** 将 UUID 字符串反序列化 */
106
+ function deserializeUUIDIntoImpl(value: UUID, buf: Uint8Array, offset: number): void {
107
+ const byte0 = kHexChars[value.charCodeAt(0) & 0x7f];
108
+ const byte1 = kHexChars[value.charCodeAt(1) & 0x7f];
109
+ buf[offset + 0] = (byte0 << 4) | byte1;
110
+
111
+ const byte2 = kHexChars[value.charCodeAt(2) & 0x7f];
112
+ const byte3 = kHexChars[value.charCodeAt(3) & 0x7f];
113
+ buf[offset + 1] = (byte2 << 4) | byte3;
114
+
115
+ const byte4 = kHexChars[value.charCodeAt(4) & 0x7f];
116
+ const byte5 = kHexChars[value.charCodeAt(5) & 0x7f];
117
+ buf[offset + 2] = (byte4 << 4) | byte5;
118
+
119
+ const byte6 = kHexChars[value.charCodeAt(6) & 0x7f];
120
+ const byte7 = kHexChars[value.charCodeAt(7) & 0x7f];
121
+ buf[offset + 3] = (byte6 << 4) | byte7;
122
+
123
+ const byte9 = kHexChars[value.charCodeAt(9) & 0x7f];
124
+ const byte10 = kHexChars[value.charCodeAt(10) & 0x7f];
125
+ buf[offset + 4] = (byte9 << 4) | byte10;
126
+
127
+ const byte11 = kHexChars[value.charCodeAt(11) & 0x7f];
128
+ const byte12 = kHexChars[value.charCodeAt(12) & 0x7f];
129
+ buf[offset + 5] = (byte11 << 4) | byte12;
130
+
131
+ const byte14 = kHexChars[value.charCodeAt(14) & 0x7f];
132
+ const byte15 = kHexChars[value.charCodeAt(15) & 0x7f];
133
+ buf[offset + 6] = (byte14 << 4) | byte15;
134
+
135
+ const byte16 = kHexChars[value.charCodeAt(16) & 0x7f];
136
+ const byte17 = kHexChars[value.charCodeAt(17) & 0x7f];
137
+ buf[offset + 7] = (byte16 << 4) | byte17;
138
+
139
+ const byte19 = kHexChars[value.charCodeAt(19) & 0x7f];
140
+ const byte20 = kHexChars[value.charCodeAt(20) & 0x7f];
141
+ buf[offset + 8] = (byte19 << 4) | byte20;
142
+
143
+ const byte21 = kHexChars[value.charCodeAt(21) & 0x7f];
144
+ const byte22 = kHexChars[value.charCodeAt(22) & 0x7f];
145
+ buf[offset + 9] = (byte21 << 4) | byte22;
146
+
147
+ const byte24 = kHexChars[value.charCodeAt(24) & 0x7f];
148
+ const byte25 = kHexChars[value.charCodeAt(25) & 0x7f];
149
+ buf[offset + 10] = (byte24 << 4) | byte25;
150
+
151
+ const byte26 = kHexChars[value.charCodeAt(26) & 0x7f];
152
+ const byte27 = kHexChars[value.charCodeAt(27) & 0x7f];
153
+ buf[offset + 11] = (byte26 << 4) | byte27;
154
+
155
+ const byte28 = kHexChars[value.charCodeAt(28) & 0x7f];
156
+ const byte29 = kHexChars[value.charCodeAt(29) & 0x7f];
157
+ buf[offset + 12] = (byte28 << 4) | byte29;
158
+
159
+ const byte30 = kHexChars[value.charCodeAt(30) & 0x7f];
160
+ const byte31 = kHexChars[value.charCodeAt(31) & 0x7f];
161
+ buf[offset + 13] = (byte30 << 4) | byte31;
162
+
163
+ const byte32 = kHexChars[value.charCodeAt(32) & 0x7f];
164
+ const byte33 = kHexChars[value.charCodeAt(33) & 0x7f];
165
+ buf[offset + 14] = (byte32 << 4) | byte33;
166
+
167
+ const byte34 = kHexChars[value.charCodeAt(34) & 0x7f];
168
+ const byte35 = kHexChars[value.charCodeAt(35) & 0x7f];
169
+ buf[offset + 15] = (byte34 << 4) | byte35;
170
+ }
package/tests/hid.js ADDED
@@ -0,0 +1,102 @@
1
+ import { uuidToHid, isHid, HID_PATTERN } from '@cloudpss/id';
2
+ import { ADJECTIVES, ANIMALS } from '../dist/hid/vocabulary.js';
3
+
4
+ test('hid pattern', () => {
5
+ expect(HID_PATTERN.test('afraid-ape-1')).toBeTruthy();
6
+ expect(HID_PATTERN.test('afraid-ape-01')).toBeFalsy();
7
+ });
8
+
9
+ test('nil uuid to hid', () => {
10
+ expect(uuidToHid('00000000-0000-0000-0000-000000000000')).toBe('afraid-ape-1');
11
+ });
12
+
13
+ test('uuid v1 to hid', () => {
14
+ expect(uuidToHid('44517964-b8d0-11ed-afa1-0242ac120002')).toBe('fast-mole-3');
15
+ expect(uuidToHid('445183be-b8d0-11ed-afa1-0242ac120002')).toBe('tough-mole-13');
16
+ expect(uuidToHid('44518562-b8d0-11ed-afa1-0242ac120002')).toBe('empty-mole-15');
17
+ expect(uuidToHid('445186de-b8d0-11ed-afa1-0242ac120002')).toBe('cowardly-mole-16');
18
+ expect(uuidToHid('44518828-b8d0-11ed-afa1-0242ac120002')).toBe('soft-mole-18');
19
+ expect(uuidToHid('44518968-b8d0-11ed-afa1-0242ac120002')).toBe('fresh-mole-19');
20
+ expect(uuidToHid('44518aa8-b8d0-11ed-afa1-0242ac120002')).toBe('slippery-mole-20');
21
+ expect(uuidToHid('44518bca-b8d0-11ed-afa1-0242ac120002')).toBe('yellow-mole-21');
22
+ expect(uuidToHid('44518d1e-b8d0-11ed-afa1-0242ac120002')).toBe('shaggy-mole-23');
23
+ expect(uuidToHid('44519098-b8d0-11ed-afa1-0242ac120002')).toBe('purple-mole-26');
24
+ });
25
+
26
+ test('uuid v4 to hid', () => {
27
+ expect(uuidToHid('883F2538-8B9F-4286-BCD4-FA00B44F640E')).toBe('strong-newt-5');
28
+ expect(uuidToHid('A90CDB96-4C41-47C6-943D-DDC2BE4ECC1F')).toBe('sour-liger-19');
29
+ expect(uuidToHid('3A7CDC7D-673A-4B2E-A3BE-BA9E11D3A829')).toBe('hard-panther-93');
30
+ expect(uuidToHid('7EC35103-FF39-4780-A84E-23633A6F043F')).toBe('cuddly-chipmunk-97');
31
+ expect(uuidToHid('B059579C-E5CE-449A-90E2-051C41D6250C')).toBe('modern-bear-25');
32
+ expect(uuidToHid('C608F887-A105-4560-81A3-F1AD3866D2F1')).toBe('lazy-bat-38');
33
+ expect(uuidToHid('96260ABD-CD63-4F39-8560-715756780598')).toBe('calm-badger-11');
34
+ expect(uuidToHid('B2B2AB51-C808-4D14-A4F8-F5872983978F')).toBe('fast-skunk-26');
35
+ expect(uuidToHid('1897F38D-7FBD-4B42-A1AC-63328C47AE44')).toBe('thin-turkey-32');
36
+ expect(uuidToHid('3EA663E5-3CCE-4565-8588-AA4B403F4342')).toBe('purple-impala-24');
37
+ });
38
+
39
+ test('bad uuid to hid', () => {
40
+ // @ts-expect-error 接受其他无效类型
41
+ expect(() => uuidToHid(undefined)).toThrow('Invalid uuid');
42
+ // @ts-expect-error 接受其他无效类型
43
+ expect(() => uuidToHid(1)).toThrow('Invalid uuid');
44
+ // @ts-expect-error 接受其他无效类型
45
+ expect(() => uuidToHid('')).toThrow('Invalid uuid');
46
+ expect(() => uuidToHid('883f2538-8b9f-4286-bcd4-fa00b44f640x')).toThrow('Invalid uuid');
47
+ expect(() => uuidToHid('883f2538-8b9f-7286-bcd4-fa00b44f640a')).toThrow('Invalid uuid');
48
+ expect(() => uuidToHid(' 883f2538-8b9f-4286-bcd4-fa00b44f640a')).toThrow('Invalid uuid');
49
+ });
50
+
51
+ test('valid hid test', () => {
52
+ for (let index = 1; index < 100; index++) {
53
+ expect(isHid(`afraid-ape-${index}`)).toBeTruthy();
54
+ }
55
+
56
+ for (const animal of ANIMALS) {
57
+ for (const adjective of ADJECTIVES) {
58
+ expect(isHid(`${adjective}-${animal}-0`)).toBeFalsy();
59
+ expect(isHid(`${adjective}-${animal}-1`)).toBeTruthy();
60
+ expect(isHid(`${adjective}-${animal}-99`)).toBeTruthy();
61
+ expect(isHid(`${adjective}-${animal}-100`)).toBeFalsy();
62
+ }
63
+ }
64
+
65
+ expect(isHid('big-ape-')).toBeFalsy();
66
+ expect(isHid('big-ape-3')).toBeTruthy();
67
+ expect(isHid('dangerous-rattlesnake-23')).toBeTruthy();
68
+ expect(isHid('dangerous-rattlesnake-123')).toBeFalsy();
69
+ });
70
+
71
+ test('bad hid test', () => {
72
+ // empty
73
+ expect(isHid(undefined)).toBeFalsy();
74
+ expect(isHid(null)).toBeFalsy();
75
+ // @ts-expect-error 接受其他无效类型
76
+ expect(isHid(1)).toBeFalsy();
77
+ expect(isHid('')).toBeFalsy();
78
+ expect(isHid('afraid-ape-1 ')).toBeFalsy();
79
+
80
+ // bad index
81
+ expect(isHid('afraid-ape-0')).toBeFalsy();
82
+ for (let index = 0; index < 10; index++) {
83
+ expect(isHid(`afraid-ape-0${index}`)).toBeFalsy();
84
+ }
85
+ expect(isHid('afraid-ape-100')).toBeFalsy();
86
+ // bad animal
87
+ expect(isHid('afraid-apes-1')).toBeFalsy();
88
+ //bad adjective
89
+ expect(isHid('fear-ape-1')).toBeFalsy();
90
+
91
+ // bad uppercase
92
+ expect(isHid('MASSIVE-NEWt-85')).toBeFalsy();
93
+ expect(isHid('ITCHY-LIGER-74')).toBeFalsy();
94
+ expect(isHid('COWARDLY-PAnther-90')).toBeFalsy();
95
+ expect(isHid('STALE-CHIPMunk-4')).toBeFalsy();
96
+ expect(isHid('MASSIVE-BEAr-35')).toBeFalsy();
97
+ expect(isHid('BIG-BAT-84')).toBeFalsy();
98
+ expect(isHid('HARD-BADGER-62')).toBeFalsy();
99
+ expect(isHid('HELPLESS-SKunk-13')).toBeFalsy();
100
+ expect(isHid('MOODY-TURKEy-12')).toBeFalsy();
101
+ expect(isHid('BREEZY-IMPAla-6')).toBeFalsy();
102
+ });
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../tsconfig",
3
+ "include": ["./"],
4
+ "compilerOptions": {
5
+ "checkJs": true,
6
+ "noEmit": true
7
+ }
8
+ }
package/tests/uuid.js ADDED
@@ -0,0 +1,81 @@
1
+ import {
2
+ UUID_PATTERN,
3
+ UUID_PATTERN_STRICT,
4
+ isUuid,
5
+ isUuidStrict,
6
+ serializeUUID,
7
+ deserializeUUID,
8
+ deserializeUUIDInto,
9
+ } from '@cloudpss/id';
10
+
11
+ test('uuid pattern', () => {
12
+ expect(UUID_PATTERN.test('44517964-b8d0-11ed-afa1-0242ac120002')).toBeTruthy();
13
+ expect(UUID_PATTERN.test('44517964-B8D0-11ED-AFA1-0242AC120002')).toBeTruthy();
14
+ expect(UUID_PATTERN.test('00000000-0000-0000-0000-000000000000')).toBeTruthy();
15
+ expect(UUID_PATTERN.test('44517964-b8d0-a1ed-afa1-0242ac120002')).toBeFalsy();
16
+ });
17
+
18
+ test('uuid pattern strict', () => {
19
+ expect(UUID_PATTERN_STRICT.test('44517964-b8d0-11ed-afa1-0242ac120002')).toBeTruthy();
20
+ expect(UUID_PATTERN_STRICT.test('44517964-B8D0-11ED-AFA1-0242AC120002')).toBeFalsy();
21
+ expect(UUID_PATTERN_STRICT.test('00000000-0000-0000-0000-000000000000')).toBeTruthy();
22
+ expect(UUID_PATTERN_STRICT.test('44517964-b8d0-a1ed-afa1-0242ac120002')).toBeFalsy();
23
+ });
24
+
25
+ test('is uuid', () => {
26
+ expect(isUuid('44517964-b8d0-11ed-afa1-0242ac120002')).toBeTruthy();
27
+ expect(isUuid('44517964-B8D0-11ED-AFA1-0242AC120002')).toBeTruthy();
28
+ expect(isUuid('00000000-0000-0000-0000-000000000000')).toBeTruthy();
29
+ expect(isUuid('44517964-b8d0-a1ed-afa1-0242ac120002')).toBeFalsy();
30
+
31
+ // empty
32
+ expect(isUuid(undefined)).toBeFalsy();
33
+ expect(isUuid(null)).toBeFalsy();
34
+ // @ts-expect-error 接受其他无效类型
35
+ expect(isUuid(1)).toBeFalsy();
36
+ expect(isUuid('')).toBeFalsy();
37
+ expect(isUuid('xxstr')).toBeFalsy();
38
+ expect(isUuid('44517964xb8d0xa1edxafa1x0242ac120002')).toBeFalsy();
39
+ });
40
+
41
+ test('is uuid strict', () => {
42
+ expect(isUuidStrict('44517964-b8d0-11ed-afa1-0242ac120002')).toBeTruthy();
43
+ expect(isUuidStrict('44517964-B8D0-11ED-AFA1-0242AC120002')).toBeFalsy();
44
+ expect(isUuidStrict('00000000-0000-0000-0000-000000000000')).toBeTruthy();
45
+ expect(isUuidStrict('44517964-b8d0-a1ed-afa1-0242ac120002')).toBeFalsy();
46
+
47
+ // empty
48
+ expect(isUuidStrict(undefined)).toBeFalsy();
49
+ expect(isUuidStrict(null)).toBeFalsy();
50
+ // @ts-expect-error 接受其他无效类型
51
+ expect(isUuidStrict(1)).toBeFalsy();
52
+ expect(isUuidStrict('')).toBeFalsy();
53
+ expect(isUuidStrict('xxstr')).toBeFalsy();
54
+ expect(isUuidStrict('44517964xb8d0xa1edxafa1x0242ac120002')).toBeFalsy();
55
+ });
56
+
57
+ test('uuid serialization', () => {
58
+ expect(serializeUUID(deserializeUUID('44517964-B8D0-11ED-AFA1-0242AC120002'))).toBe(
59
+ '44517964-b8d0-11ed-afa1-0242ac120002',
60
+ );
61
+ expect(deserializeUUID('00000000-0000-0000-0000-000000000000')).toEqual(new Uint8Array(16));
62
+ expect(deserializeUUIDInto('00000000-0000-0000-0000-000000000000', new Uint8Array(16))).toBe(undefined);
63
+ const buf = new Uint8Array(16);
64
+ deserializeUUIDInto('00000000-0000-0000-0000-000000000000', buf);
65
+ expect(buf).toEqual(new Uint8Array(16));
66
+
67
+ deserializeUUIDInto('44517964-B8D0-11ED-AFA1-0242AC120002', buf);
68
+ expect(buf).toEqual(deserializeUUID('44517964-B8D0-11ED-AFA1-0242AC120002'));
69
+
70
+ expect(() => serializeUUID(new Uint8Array(15))).toThrow('Invalid UUID length:');
71
+ expect(() => serializeUUID(new Uint8Array(16), 1)).toThrow('Invalid UUID length:');
72
+
73
+ expect(() => deserializeUUID('0-0-0-0-0')).toThrow('Invalid UUID string:');
74
+ expect(() => deserializeUUIDInto('0-0-0-0-0', new Uint8Array(16))).toThrow('Invalid UUID string:');
75
+ expect(() => deserializeUUIDInto('00000000-0000-0000-0000-000000000000', new Uint8Array(15))).toThrow(
76
+ 'Buffer is too small:',
77
+ );
78
+ expect(() => deserializeUUIDInto('00000000-0000-0000-0000-000000000000', new Uint8Array(16), 1)).toThrow(
79
+ 'Buffer is too small:',
80
+ );
81
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../../tsconfig",
3
+ "include": ["./src/"],
4
+ "compilerOptions": {
5
+ "outDir": "./dist"
6
+ }
7
+ }