Skip to content

Commit 3e824af

Browse files
committed
Refactor createIdFromString, add tests
1 parent 912ece5 commit 3e824af

3 files changed

Lines changed: 33 additions & 6 deletions

File tree

.changeset/dry-cobras-listen.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@evolu/common": patch
3+
---
4+
5+
Refactor createIdFromString, add tests

packages/common/src/Type.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,19 +1377,19 @@ export const createId = <B extends string = never>(
13771377
export const createIdFromString = <B extends string = never>(
13781378
value: string,
13791379
): [B] extends [never] ? Id : Id & Brand<B> => {
1380-
const hash = sha256(utf8ToBytes(value)); // 32 bytes = 256 bits
1380+
const hash = sha256(utf8ToBytes(value));
13811381

13821382
let output = "";
13831383
let buffer = 0;
13841384
let bits = 0;
13851385

1386-
for (let i = 0; i < hash.length && output.length < 21; i++) {
1387-
buffer = (buffer << 8) | hash[i]; // push 8 bits
1386+
for (const byte of hash) {
1387+
buffer = (buffer << 8) | byte;
13881388
bits += 8;
13891389

1390-
while (bits >= 6 && output.length < 21) {
1390+
while (bits >= 6 && output.length < idTypeValueLength) {
13911391
bits -= 6;
1392-
const index = (buffer >> bits) & 0b111111; // extract top 6 bits
1392+
const index = (buffer >> bits) & 0b111111;
13931393
output += base64UrlAlphabet[index];
13941394
}
13951395
}

packages/common/test/Type.test.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,8 @@ test("createId", () => {
949949

950950
test("createIdFromString", () => {
951951
const id = createIdFromString("abc");
952-
expect(Id.from(id)).toEqual(ok("QHMpZvrshcOs47aRxCvN-"));
952+
expect(Id.is(id)).toBe(true);
953+
expect(id).toEqual("QHMpZvrshcOs47aRxCvN-");
953954

954955
const id1 = createIdFromString("user-api-123");
955956
const id2 = createIdFromString("user-api-123");
@@ -959,6 +960,27 @@ test("createIdFromString", () => {
959960
expect(id1).toBe(id2); // Deterministic
960961
expectTypeOf<typeof id1>().toEqualTypeOf<Id>();
961962
expectTypeOf<typeof todoId>().toEqualTypeOf<Id & Brand<"Todo">>();
963+
964+
const emptyId = createIdFromString("");
965+
expect(Id.is(emptyId)).toBe(true);
966+
expect(emptyId).toHaveLength(21);
967+
968+
const longString = "a".repeat(1000);
969+
const longId = createIdFromString(longString);
970+
expect(Id.is(longId)).toBe(true);
971+
expect(longId).toHaveLength(21);
972+
973+
const specialId = createIdFromString("test!@#$%^&*()_+-={}[]|\\:;\"'<>?,./");
974+
expect(Id.is(specialId)).toBe(true);
975+
expect(specialId).toHaveLength(21);
976+
977+
const unicodeId = createIdFromString("测试🚀💡");
978+
expect(Id.is(unicodeId)).toBe(true);
979+
expect(unicodeId).toHaveLength(21);
980+
981+
const id3 = createIdFromString("test1");
982+
const id4 = createIdFromString("test2");
983+
expect(id3).not.toBe(id4);
962984
});
963985

964986
test("PositiveNumber", () => {

0 commit comments

Comments
 (0)