Skip to content

Commit 440d350

Browse files
Generate Unique IDs on the client-side
1 parent 8d93209 commit 440d350

File tree

12 files changed

+513
-297
lines changed

12 files changed

+513
-297
lines changed

composer.lock

Lines changed: 299 additions & 262 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
package {{ sdk.namespace | caseDot }}
22

3+
import java.time.Instant
4+
import kotlin.math.floor
5+
import kotlin.random.Random
6+
7+
fun uniqid(): String {
8+
val currentTimestamp = Instant.now().toEpochMilli() / 1000.0
9+
val secondsPart = floor(currentTimestamp).toLong()
10+
val microsecondsPart = ((currentTimestamp - secondsPart) * 1_000_000).toLong()
11+
12+
// Convert both parts to hexadecimal format
13+
val hexTimestamp = "%08x%05x".format(secondsPart, microsecondsPart)
14+
return hexTimestamp
15+
}
16+
317
class ID {
418
companion object {
519
fun custom(id: String): String
620
= id
7-
fun unique(): String
8-
= "unique()"
21+
fun unique(padding: Int = 5): String {
22+
val baseId = uniqid()
23+
val randomPadding = (1..padding)
24+
.map { Random.nextInt(0, 16).toString(16) }
25+
.joinToString("")
26+
27+
return baseId + randomPadding
28+
}
929
}
10-
}
30+
}

templates/dart/lib/id.dart.twig

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,35 @@ part of {{ language.params.packageName }};
44
class ID {
55
ID._();
66

7-
/// Have Appwrite generate a unique ID for you.
8-
static String unique() {
9-
return 'unique()';
7+
// Generate a unique ID based on timestamp
8+
// Recreated from https://www.php.net/manual/en/function.uniqid.php
9+
static String _uniqid() {
10+
final now = DateTime.now();
11+
final secondsSinceEpoch = (now.millisecondsSinceEpoch / 1000).floor();
12+
final msecs = now.microsecondsSinceEpoch - secondsSinceEpoch * 1000000;
13+
return secondsSinceEpoch.toRadixString(16) +
14+
msecs.toRadixString(16).padLeft(5, '0');
15+
}
16+
17+
// Generate a unique ID with padding to have a longer ID
18+
// Recreated from https://github.com/utopia-php/database/blob/main/src/Database/ID.php#L13
19+
static String unique({int padding = 7}) {
20+
String id = _uniqid();
21+
22+
if (padding > 0) {
23+
StringBuffer sb = StringBuffer();
24+
for (var i = 0; i < padding; i++) {
25+
sb.write(Random().nextInt(16).toRadixString(16));
26+
}
27+
28+
id += sb.toString();
29+
}
30+
31+
return id;
1032
}
1133

1234
/// Uses [id] as the ID for the resource.
1335
static String custom(String id) {
1436
return id;
1537
}
16-
}
38+
}

templates/deno/src/id.ts.twig

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
11
export class ID {
2+
function uniqid(): string {
3+
const now = new Date();
4+
const secondsSinceEpoch = Math.floor(now.getTime() / 1000);
5+
const msecs = now.getTime() - secondsSinceEpoch * 1000;
6+
const microsecondsPart = msecs * 1000; // Convert milliseconds to microseconds
7+
8+
// Convert to hexadecimal
9+
const hexTimestamp = secondsSinceEpoch.toString(16) + microsecondsPart.toString(16).padStart(5, '0');
10+
return hexTimestamp;
11+
}
12+
213
public static custom(id: string): string {
314
return id
415
}
5-
6-
public static unique(): string {
7-
return 'unique()'
16+
17+
public static unique(padding: number = 5): string {
18+
const baseId = uniqid();
19+
let randomPadding = '';
20+
21+
for (let i = 0; i < padding; i++) {
22+
const randomHexDigit = Math.floor(Math.random() * 16).toString(16);
23+
randomPadding += randomHexDigit;
24+
}
25+
26+
return baseId + randomPadding;
827
}
9-
}
28+
}

templates/dotnet/src/Appwrite/ID.cs.twig

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@ namespace {{ spec.title | caseUcfirst }}
22
{
33
public static class ID
44
{
5-
public static string Unique()
5+
static string UniqID()
66
{
7-
return "unique()";
7+
var now = DateTime.UtcNow;
8+
var secondsSinceEpoch = (long)(now - new DateTime(1970, 1, 1)).TotalSeconds;
9+
var msecs = (now - new DateTime(1970, 1, 1)).TotalMilliseconds - secondsSinceEpoch * 1000;
10+
var microsecondsPart = (long)(msecs * 1000); // Convert milliseconds to microseconds
11+
12+
// Convert to hexadecimal
13+
var hexTimestamp = secondsSinceEpoch.ToString("x") + microsecondsPart.ToString("x").PadLeft(5, '0');
14+
return hexTimestamp;
15+
}
16+
17+
public static string Unique(int padding = 5)
18+
{
19+
var baseId = UniqID();
20+
var randomPadding = "";
21+
22+
for (int i = 0; i < padding; i++)
23+
{
24+
var randomHexDigit = random.Next(0, 16).ToString("x");
25+
randomPadding += randomHexDigit;
26+
}
27+
28+
return baseId + randomPadding;
829
}
930

1031
public static string Custom(string id)
1132
{
1233
return id;
1334
}
1435
}
15-
}
36+
}
Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
package {{ sdk.namespace | caseDot }}
22

3+
import java.time.Instant
4+
import kotlin.math.floor
5+
import kotlin.random.Random
6+
7+
fun uniqid(): String {
8+
val currentTimestamp = Instant.now().toEpochMilli() / 1000.0
9+
val secondsPart = floor(currentTimestamp).toLong()
10+
val microsecondsPart = ((currentTimestamp - secondsPart) * 1_000_000).toLong()
11+
12+
// Convert both parts to hexadecimal format
13+
val hexTimestamp = "%08x%05x".format(secondsPart, microsecondsPart)
14+
return hexTimestamp
15+
}
16+
317
class ID {
418
companion object {
519
fun custom(id: String): String
620
= id
7-
fun unique(): String
8-
= "unique()"
21+
fun unique(padding: Int = 5): String {
22+
val baseId = uniqid()
23+
val randomPadding = (1..padding)
24+
.map { Random.nextInt(0, 16).toString(16) }
25+
.joinToString("")
26+
27+
return baseId + randomPadding
28+
}
929
}
10-
}
30+
}

templates/node/lib/id.js.twig

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
class ID {
2+
static function uniqid() {
3+
const now = new Date();
4+
const secondsSinceEpoch = Math.floor(now.getTime() / 1000);
5+
const msecs = now.getTime() - secondsSinceEpoch * 1000;
6+
const microsecondsPart = msecs * 1000; // Convert milliseconds to microseconds
27

3-
static unique = () => {
4-
return 'unique()'
8+
// Convert to hexadecimal
9+
const hexTimestamp = secondsSinceEpoch.toString(16) + microsecondsPart.toString(16).padStart(5, '0');
10+
return hexTimestamp;
11+
}
12+
13+
static unique = (padding = 7) => {
14+
const baseId = uniqid();
15+
let randomPadding = '';
16+
17+
for (let i = 0; i < padding; i++) {
18+
const randomHexDigit = Math.floor(Math.random() * 16).toString(16);
19+
randomPadding += randomHexDigit;
20+
}
21+
22+
return baseId + randomPadding;
523
}
624

725
static custom = (id) => {

templates/php/src/ID.php.twig

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@
33
namespace {{ spec.title | caseUcfirst }};
44
55
class ID {
6-
public static function unique(): string
6+
public static function unique(int $padding = 5): string
77
{
8-
return 'unique()';
8+
$uniqid = \uniqid();
9+
10+
if ($padding > 0) {
11+
$bytes = \random_bytes(\max(1, (int)\ceil(($padding / 2)))); // one byte expands to two chars
12+
$uniqid .= \substr(\bin2hex($bytes), 0, $padding);
13+
}
14+
15+
return $uniqid;
916
}
1017
1118
public static function custom(string $id): string
1219
{
1320
return $id;
1421
}
15-
}
22+
}

templates/python/package/id.py.twig

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1+
from datetime import datetime
2+
import random
3+
14
class ID:
5+
@staticmethod
6+
def uniqid():
7+
now = datetime.now()
8+
seconds_since_epoch = int(now.timestamp())
9+
microseconds_part = now.microsecond
10+
hex_timestamp = f'{seconds_since_epoch:08x}{microseconds_part:05x}'
11+
return hex_timestamp
12+
213
@staticmethod
314
def custom(id):
415
return id
516

617
@staticmethod
7-
def unique():
8-
return 'unique()'
18+
def unique(padding = 5):
19+
base_id = uniqid()
20+
random_padding = ''.join(random.choice('0123456789abcdef') for _ in range(padding))
21+
return base_id + random_padding
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1+
require 'securerandom'
2+
3+
def uniqid
4+
now = Time.now
5+
seconds_since_epoch = now.to_i
6+
microseconds_part = now.usec
7+
hex_timestamp = "%08x%05x" % [seconds_since_epoch, microseconds_part]
8+
hex_timestamp
9+
end
10+
111
module {{spec.title | caseUcfirst}}
212
class ID
313
def self.custom(id)
414
id
515
end
6-
7-
def self.unique
8-
'unique()'
16+
17+
def self.unique_id(padding=5)
18+
base_id = uniqid
19+
random_padding = SecureRandom.hex(padding / 2)
20+
random_padding = random_padding[0...padding]
21+
base_id + random_padding
922
end
1023
end
11-
end
24+
end

0 commit comments

Comments
 (0)