Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate Appwrite ID's on the Client-Side #779

Merged
merged 24 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ jobs:
run: composer install

- name: Lint
run: composer lint
run: composer lint
172 changes: 90 additions & 82 deletions composer.lock

Large diffs are not rendered by default.

30 changes: 27 additions & 3 deletions templates/android/library/src/main/java/io/package/ID.kt.twig
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
package {{ sdk.namespace | caseDot }}

import java.time.Instant
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
import kotlin.math.floor
import kotlin.random.Random

class ID {
companion object {
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
private fun hexTimestamp(): String {
val now = Instant.now()
val sec = now.epochSecond
val usec = (System.nanoTime() / 1000) % 1000

val hexTimestamp = "%08x%05x".format(sec, usec)

return hexTimestamp
}

fun custom(id: String): String
= id
fun unique(): String
= "unique()"

// Generate a unique ID with padding to have a longer ID
fun unique(padding: Int = 7): String {
val baseId = hexTimestamp()
val randomPadding = (1..padding)
.map { Random.nextInt(0, 16).toString(16) }
.joinToString("")

return baseId + randomPadding
}
}
}
}
29 changes: 25 additions & 4 deletions templates/dart/lib/id.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,34 @@ part of {{ language.params.packageName }};
class ID {
ID._();

/// Have Appwrite generate a unique ID for you.
static String unique() {
return 'unique()';
// Generate an hex ID based on timestamp
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
// Recreated from https://www.php.net/manual/en/function.uniqid.php
static String _hexTimestamp() {
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
final now = DateTime.now();
final sec = (now.millisecondsSinceEpoch / 1000).floor();
final usec = now.microsecondsSinceEpoch - (sec * 1000000);
return sec.toRadixString(16) +
usec.toRadixString(16).padLeft(5, '0');
}

// Generate a unique ID with padding to have a longer ID
static String unique({int padding = 7}) {
String id = _hexTimestamp();

if (padding > 0) {
StringBuffer sb = StringBuffer();
for (var i = 0; i < padding; i++) {
sb.write(Random().nextInt(16).toRadixString(16));
}

id += sb.toString();
}

return id;
}

/// Uses [id] as the ID for the resource.
static String custom(String id) {
return id;
}
}
}
1 change: 1 addition & 0 deletions templates/dart/lib/package.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
library {{ language.params.packageName }};

import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'dart:convert';

Expand Down
4 changes: 2 additions & 2 deletions templates/dart/test/id_test.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'package:flutter_test/flutter_test.dart';

void main() {
group('unique()', () {
test('returns unique()', () {
expect(ID.unique(), 'unique()');
test('returns unique ID', () {
expect((ID.unique()).length, 20);
});
});

Expand Down
29 changes: 25 additions & 4 deletions templates/deno/src/id.ts.twig
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
export class ID {
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
static #hexTimestamp(): string {
const now = new Date();
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
const sec = Math.floor(now.getTime() / 1000);
const msec = now.getMilliseconds();

// Convert to hexadecimal
const hexTimestamp = sec.toString(16) + msec.toString(16).padStart(5, '0');
return hexTimestamp;
}

public static custom(id: string): string {
return id
}

public static unique(): string {
return 'unique()'

// Generate a unique ID with padding to have a longer ID
public static unique(padding: number = 7): string {
const baseId = ID.#hexTimestamp();
let randomPadding = '';

for (let i = 0; i < padding; i++) {
const randomHexDigit = Math.floor(Math.random() * 16).toString(16);
randomPadding += randomHexDigit;
}

return baseId + randomPadding;
}
}
}
33 changes: 30 additions & 3 deletions templates/dotnet/src/Appwrite/ID.cs.twig
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
using System;

namespace {{ spec.title | caseUcfirst }}
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
{
public static class ID
{
public static string Unique()
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
private static string HexTimestamp()
{
return "unique()";
var now = DateTime.UtcNow;
var epoch = (now - new DateTime(1970, 1, 1));
var sec = (long)epoch.TotalSeconds;
var usec = (long)((epoch.TotalMilliseconds * 1000) % 1000);

// Convert to hexadecimal
var hexTimestamp = sec.ToString("x") + usec.ToString("x").PadLeft(5, '0');
return hexTimestamp;
}

// Generate a unique ID with padding to have a longer ID
public static string Unique(int padding = 7)
{
var random = new Random();
var baseId = HexTimestamp();
var randomPadding = "";

for (int i = 0; i < padding; i++)
{
var randomHexDigit = random.Next(0, 16).ToString("x");
randomPadding += randomHexDigit;
}

return baseId + randomPadding;
}

public static string Custom(string id)
{
return id;
}
}
}
}
1 change: 1 addition & 0 deletions templates/flutter/lib/package.dart.twig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
library {{ language.params.packageName }};

import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'dart:convert';

Expand Down
29 changes: 26 additions & 3 deletions templates/kotlin/src/main/kotlin/io/appwrite/ID.kt.twig
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
package {{ sdk.namespace | caseDot }}
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved

import java.time.Instant
import kotlin.math.floor
import kotlin.random.Random

class ID {
companion object {
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
private fun hexTimestamp(): String {
val now = Instant.now()
val sec = now.epochSecond
val usec = (System.nanoTime() / 1000) % 1000

val hexTimestamp = "%08x%05x".format(sec, usec)

return hexTimestamp
}

fun custom(id: String): String
= id
fun unique(): String
= "unique()"
// Generate a unique ID with padding to have a longer ID
fun unique(padding: Int = 7): String {
val baseId = ID.hexTimestamp()
val randomPadding = (1..padding)
.map { Random.nextInt(0, 16).toString(16) }
.joinToString("")

return baseId + randomPadding
}
}
}
}
24 changes: 22 additions & 2 deletions templates/node/lib/id.js.twig
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
class ID {
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
static #hexTimestamp = () => {
const now = new Date();
const sec = Math.floor(now.getTime() / 1000);
const msec = now.getMilliseconds();

static unique = () => {
return 'unique()'
// Convert to hexadecimal
const hexTimestamp = sec.toString(16) + msec.toString(16).padStart(5, '0');
return hexTimestamp;
}

// Generate a unique ID with padding to have a longer ID
static unique = (padding = 7) => {
const baseId = ID.#hexTimestamp();
let randomPadding = '';

for (let i = 0; i < padding; i++) {
const randomHexDigit = Math.floor(Math.random() * 16).toString(16);
randomPadding += randomHexDigit;
}

return baseId + randomPadding;
}

static custom = (id) => {
Expand Down
13 changes: 10 additions & 3 deletions templates/php/src/ID.php.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@
namespace {{ spec.title | caseUcfirst }};
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved

class ID {
public static function unique(): string
public static function unique(int $padding = 7): string
{
return 'unique()';
$uniqid = \uniqid();

if ($padding > 0) {
$bytes = \random_bytes(\max(1, (int)\ceil(($padding / 2)))); // one byte expands to two chars
$uniqid .= \substr(\bin2hex($bytes), 0, $padding);
}

return $uniqid;
}

public static function custom(string $id): string
{
return $id;
}
}
}
22 changes: 20 additions & 2 deletions templates/python/package/id.py.twig
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
from datetime import datetime
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved
import math
import os

class ID:
# Generate an hex ID based on timestamp
# Recreated from https://www.php.net/manual/en/function.uniqid.php
@staticmethod
def __hex_timestamp():
now = datetime.now()
sec = int(now.timestamp())
usec = (now.microsecond % 1000)
hex_timestamp = f'{sec:08x}{usec:05x}'
return hex_timestamp

@staticmethod
def custom(id):
return id

# Generate a unique ID with padding to have a longer ID
@staticmethod
def unique():
return 'unique()'
def unique(padding = 7):
base_id = ID.__hex_timestamp()
random_bytes = os.urandom(math.ceil(padding / 2))
random_padding = random_bytes.hex()[:padding]
return base_id + random_padding
24 changes: 20 additions & 4 deletions templates/ruby/lib/container/id.rb.twig
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
require 'securerandom'
PineappleIOnic marked this conversation as resolved.
Show resolved Hide resolved

module {{spec.title | caseUcfirst}}
class ID
def self.custom(id)
id
end

def self.unique
'unique()'

# Generate a unique ID with padding to have a longer ID
def self.unique(padding=7)
base_id = self.hex_timestamp
random_padding = SecureRandom.hex(padding)
random_padding = random_padding[0...padding]
base_id + random_padding
end

#Generate an hex ID based on timestamp
#Recreated from https://www.php.net/manual/en/function.uniqid.php
private_class_method def self.hex_timestamp
now = Time.now
sec = now.to_i
usec = now.usec
hex_timestamp = "%08x%05x" % [sec, usec]
hex_timestamp
end
end
end
end
23 changes: 20 additions & 3 deletions templates/swift/Sources/ID.swift.twig
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import Foundation

public class ID {
// Generate an hex ID based on timestamp
// Recreated from https://www.php.net/manual/en/function.uniqid.php
private static func hexTimestamp() -> String {
let now = Date()
let secs = Int(now.timeIntervalSince1970)
let usec = Int((now.timeIntervalSince1970 - Double(secs)) * 1_000_000)
let hexTimestamp = String(format: "%08x%05x", secs, usec)
return hexTimestamp
}

public static func custom(_ id: String) -> String {
return id
}

public static func unique() -> String {
return "unique()"
// Generate a unique ID with padding to have a longer ID
public static func unique(padding: Int = 7) -> String {
let baseId = Self.hexTimestamp()
let randomPadding = (1...padding).map {
_ in String(format: "%x", Int.random(in: 0..<16))
}.joined()
return baseId + randomPadding
}
}
}
Loading