Idgen dart
This commit is contained in:
40
lib/src/idgen_dart_base.dart
Normal file
40
lib/src/idgen_dart_base.dart
Normal file
@ -0,0 +1,40 @@
|
||||
/// Response class for IDs generated by IDGen.
|
||||
class IDGenResponse {
|
||||
final String id;
|
||||
|
||||
IDGenResponse({required this.id});
|
||||
|
||||
factory IDGenResponse.fromJson(Map<String, dynamic> json) {
|
||||
return IDGenResponse(
|
||||
id: json['id'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Response class for keypairs generated by IDGen.
|
||||
class IDKeypairResponse implements IDGenResponse {
|
||||
@override
|
||||
final String id;
|
||||
final String privateID;
|
||||
|
||||
IDKeypairResponse({required this.id, required this.privateID});
|
||||
|
||||
factory IDKeypairResponse.fromJson(Map<String, dynamic> json) {
|
||||
return IDKeypairResponse(
|
||||
id: json['id'],
|
||||
privateID: json['privateID'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom exception for IDGen, thrown when an error occurs when generating an ID.
|
||||
class IDGenException implements Exception {
|
||||
final String message;
|
||||
|
||||
IDGenException(this.message);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return message;
|
||||
}
|
||||
}
|
83
lib/src/idgen_http.dart
Normal file
83
lib/src/idgen_http.dart
Normal file
@ -0,0 +1,83 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:teamhydra_idgen/src/idgen_dart_base.dart';
|
||||
|
||||
class IDGenHTTPWorker {
|
||||
final Dio _dio = Dio();
|
||||
final String _baseURL = 'https://id.hydra.workers.dev';
|
||||
|
||||
final String username;
|
||||
final String token;
|
||||
|
||||
IDGenHTTPWorker({required this.username, required this.token});
|
||||
|
||||
Future<IDGenResponse> generate(
|
||||
String type, Map<String, dynamic>? data) async {
|
||||
try {
|
||||
final response = await _dio.post(_baseURL,
|
||||
data: {
|
||||
'username': username,
|
||||
'token': token,
|
||||
'type': type,
|
||||
...?data,
|
||||
},
|
||||
options: Options(contentType: Headers.jsonContentType));
|
||||
|
||||
return IDGenResponse.fromJson(response.data);
|
||||
} on DioException catch (e) {
|
||||
Map<String, dynamic>? errorData;
|
||||
|
||||
// Do we have a response?
|
||||
if (e.response != null) {
|
||||
// Try decoding the response
|
||||
try {
|
||||
errorData = jsonDecode(e.response!.data);
|
||||
} catch (_) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
if (errorData != null && errorData['error'] != null) {
|
||||
throw IDGenException(
|
||||
'Server rejected ID generation: ${errorData['error']}');
|
||||
} else if (errorData != null) {
|
||||
throw IDGenException('Server rejected ID generation: $errorData');
|
||||
} else {
|
||||
throw IDGenException(
|
||||
'An error occurred during generation ($type): ${e.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw IDGenException(
|
||||
'An unknown error occurred during generation ($type): $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<IDKeypairResponse> generateKeypair() async {
|
||||
try {
|
||||
final response = await _dio.post(_baseURL,
|
||||
data: {
|
||||
'username': username,
|
||||
'token': token,
|
||||
'type': 'keypair',
|
||||
},
|
||||
options: Options(contentType: Headers.jsonContentType));
|
||||
|
||||
return IDKeypairResponse.fromJson(response.data);
|
||||
} on DioException catch (e) {
|
||||
final errorData = e.response?.data;
|
||||
if (errorData != null && errorData['error'] != null) {
|
||||
throw IDGenException(
|
||||
'Server rejected ID generation: ${errorData['error']}');
|
||||
} else if (errorData != null) {
|
||||
throw IDGenException('Server rejected ID generation: $errorData');
|
||||
} else {
|
||||
throw IDGenException(
|
||||
'An error occurred during generation (keypair): ${e.message}');
|
||||
}
|
||||
} catch (e) {
|
||||
throw IDGenException(
|
||||
'An unknown error occurred during generation (keypair): $e');
|
||||
}
|
||||
}
|
||||
}
|
145
lib/src/idgen_main.dart
Normal file
145
lib/src/idgen_main.dart
Normal file
@ -0,0 +1,145 @@
|
||||
import 'package:teamhydra_idgen/src/idgen_http.dart';
|
||||
import 'package:teamhydra_idgen/teamhydra_idgen.dart';
|
||||
|
||||
/// The main class to use when generating an ID
|
||||
///
|
||||
/// All returned IDs are in the form of a [IDGenResponse] object which contains the ID.
|
||||
/// If an error occurs, an [IDGenException] is thrown.
|
||||
class IDGen {
|
||||
final String username;
|
||||
final String token;
|
||||
final IDGenHTTPWorker _worker;
|
||||
|
||||
/// Create a new IDGen class to generate IDs
|
||||
///
|
||||
/// [username] and [token] are required to authenticate with the IDGen API.
|
||||
IDGen({required this.username, required this.token})
|
||||
: _worker = IDGenHTTPWorker(username: username, token: token);
|
||||
|
||||
/// Generate a new UUID V4
|
||||
///
|
||||
/// Returns a [IDGenResponse] object containing the generated ID.
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
Future<IDGenResponse> generateUUIDV4() async {
|
||||
return await _worker.generate('uuid', null);
|
||||
}
|
||||
|
||||
/// Generate a new nanoID
|
||||
///
|
||||
/// Returns a [IDGenResponse] object containing the generated ID.
|
||||
/// Optionally, you can pass a [size] parameter to specify the length of the nanoID, default is 10.
|
||||
/// You can also pass a [alphabet] parameter to specify the characters used in the nanoID, default is provided by the API.
|
||||
///
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
///
|
||||
/// Throws an [ArgumentError] if the size is not between 1 and 256 or the alphabet is empty.
|
||||
Future<IDGenResponse> generateNanoID({int? size, String? alphabet}) async {
|
||||
// Ensure length is between 1 and 256 (if specified)
|
||||
if (size != null && (size < 1 || size > 256)) {
|
||||
throw ArgumentError(
|
||||
'Cannot generate a nanoID with a length of $size, must be between 1 and 256');
|
||||
}
|
||||
|
||||
// Ensure alphabet is not empty (if specified)
|
||||
if (alphabet != null && alphabet.isEmpty) {
|
||||
throw ArgumentError('Cannot generate a nanoID with an empty alphabet');
|
||||
}
|
||||
|
||||
// Ensure alphabet is at least 3 characters long and not longer than 256
|
||||
if (alphabet != null && (alphabet.length < 3 || alphabet.length > 256)) {
|
||||
throw ArgumentError(
|
||||
'Cannot generate a nanoID with an alphabet of length ${alphabet.length}, must be between 3 and 256');
|
||||
}
|
||||
|
||||
return await _worker.generate('nanoid', {
|
||||
if (size != null) 'length': size else 'length': 10,
|
||||
if (alphabet != null) 'alphabet': alphabet,
|
||||
});
|
||||
}
|
||||
|
||||
/// Generate a 2FA code pair
|
||||
///
|
||||
/// Returns a [IDGenResponse] object containing the generated ID.
|
||||
///
|
||||
/// Optionally, you can pass a [length] parameter to specify the length of the 2FA code, default is 6.
|
||||
///
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
///
|
||||
/// Throws an [ArgumentError] if the length is not between 1 and 256.
|
||||
Future<IDGenResponse> generate2FACode({int? length}) async {
|
||||
// Ensure length is between 1 and 256 (if specified)
|
||||
if (length != null && (length < 1 || length > 256)) {
|
||||
throw ArgumentError(
|
||||
'Cannot generate a 2FA code with a length of $length, must be between 1 and 256');
|
||||
}
|
||||
|
||||
return await _worker.generate('2fa', {
|
||||
if (length != null) 'length': length,
|
||||
});
|
||||
}
|
||||
|
||||
/// Generate a license key
|
||||
///
|
||||
/// Returns a [IDGenResponse] object containing the generated ID.
|
||||
/// Keys are generated with a 25 character length, resulting in a 5-5-5-5-5 format.
|
||||
///
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
Future<IDGenResponse> generateLicenseKey() async {
|
||||
return await _worker.generate('license', null);
|
||||
}
|
||||
|
||||
/// Generate word based string
|
||||
///
|
||||
/// Returns a [IDGenResponse] object containing the generated ID.
|
||||
/// Optionally, you can pass a [length] parameter to specify the length of the word based string, default is 5.
|
||||
/// You can also pass a [separator] parameter to specify the separator used in the word based string, options are 'slug', 'title' and 'formal'. Default is 'slug'.
|
||||
///
|
||||
/// Slug: lowercase words separated by hyphens
|
||||
///
|
||||
/// Title: Title case words separated by spaces
|
||||
///
|
||||
/// Formal: Title case words with no spaces or separators
|
||||
///
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
///
|
||||
/// Throws an [ArgumentError] if the length is not between 1 and 16 or the separator is invalid.
|
||||
Future<IDGenResponse> generateWordBasedString(
|
||||
{int? length, String? separator}) async {
|
||||
// Ensure length is between 1 and 256 (if specified)
|
||||
if (length != null && (length < 1 || length > 16)) {
|
||||
throw ArgumentError(
|
||||
'Cannot generate a word based string with a length of $length, must be between 1 and 16');
|
||||
}
|
||||
|
||||
// Ensure separator is valid (if specified)
|
||||
if (separator != null &&
|
||||
separator != 'slug' &&
|
||||
separator != 'title' &&
|
||||
separator != 'formal') {
|
||||
throw ArgumentError(
|
||||
'Cannot generate a word based string with an invalid separator');
|
||||
}
|
||||
|
||||
return await _worker.generate('word', {
|
||||
if (length != null) 'length': length else 'length': 5,
|
||||
if (separator != null) 'style': separator else 'style': 'slug',
|
||||
});
|
||||
}
|
||||
|
||||
/// Generate a snowflake ID
|
||||
///
|
||||
/// Returns a [IDKeypairResponse] object containing
|
||||
///
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
Future<IDGenResponse> generateSnowflakeID() async {
|
||||
return await _worker.generate('snowflake', null);
|
||||
}
|
||||
|
||||
/// Generate a keypair
|
||||
///
|
||||
/// Returns a [IDKeypairResponse] object containing the generated ID and secret key.
|
||||
/// Throws an [IDGenException] if an error occurs.
|
||||
Future<IDKeypairResponse> generateKeypair() async {
|
||||
return await _worker.generateKeypair();
|
||||
}
|
||||
}
|
5
lib/teamhydra_idgen.dart
Normal file
5
lib/teamhydra_idgen.dart
Normal file
@ -0,0 +1,5 @@
|
||||
/// Team Hydra ID Generator Library - Generate unique IDs for your projects, using the IDGen API.
|
||||
library;
|
||||
|
||||
export 'src/idgen_dart_base.dart';
|
||||
export 'src/idgen_main.dart';
|
Reference in New Issue
Block a user