halkyon/packages/halkyon_base_client/lib/src/protocol/protocol.dart
Tizian 「ティツィアーン」 a3a8ed3890
feat(auth): a password with TOTP on the register, and resets
The register's side of signing in with an address, a password that never
leaves the device (SRP-6a) and a code from an authenticator (ADR 0017),
with members forwarding every step through AccountRegister:

- password.set: salt, Argon2id's costs, SRP's verifier, the public keys
  and the private keys wrapped twice, all made on the device; with the
  address a mailed code proves, an anonymous person becomes identified
  under their ID. It signs in once an authenticator is confirmed.
- passwordSignIn.begin and complete: SRP's two steps with a TOTP or
  recovery code. An address nobody has is answered from a decoy key as
  an account would be; every wrong credential is refused alike.
- authenticator: secrets sealed under totpKey (XChaCha20-Poly1305, bound
  to their row), each code accepted once, ten recovery codes with the
  first, the last one kept.
- accountRecovery: a lost authenticator reset 72 hours after the
  password and a mailed code or the recovery phrase ask, a lost password
  set anew with the phrase's signature, or the account reset with new
  keys 72 hours after a mailed code asks; a mail at each start, a
  sign-in calling it off.
- An account with a password no longer signs in by a mailed code or
  GitHub; no new GitHub account is linked where passwords are offered,
  and from GITHUB_SIGN_IN_ENDS GitHub signs nobody in and its IDs go.

Five tables, added by the module's migration; deletePerson deletes
their rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-22 18:11:10 +02:00

595 lines
22 KiB
Dart

/* AUTOMATICALLY GENERATED CODE DO NOT MODIFY */
/* To generate run: "serverpod generate" */
// ignore_for_file: implementation_imports
// ignore_for_file: library_private_types_in_public_api
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: public_member_api_docs
// ignore_for_file: type_literal_in_constant_pattern
// ignore_for_file: use_super_parameters
// ignore_for_file: invalid_use_of_internal_member
// ignore_for_file: dead_code, unnecessary_type_check
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'package:halkyon_base_client/src/protocol/password/authenticator.dart'
as _ivfmflch;
import 'package:serverpod_auth_core_client/serverpod_auth_core_client.dart'
as _iacc;
import 'package:serverpod_auth_idp_client/serverpod_auth_idp_client.dart'
as _iaic;
import 'package:serverpod_client/serverpod_client.dart' as _isc;
import 'auth/email_code_accepted.dart' as _iys46ui1;
import 'auth/email_sign_in_refusal.dart' as _ieyvcag1;
import 'auth/email_sign_in_refused_exception.dart' as _iztfgag5;
import 'auth/github_sign_in_refusal.dart' as _ir1gd9p5;
import 'auth/github_sign_in_refused_exception.dart' as _i0xfcu5n;
import 'auth/sign_in_ways.dart' as _ie6tbh85;
import 'instance/instance_basics.dart' as _i8jixqx6;
import 'password/account_reset_kind.dart' as _i91ka1it;
import 'password/authenticator.dart' as _icpzuvvi;
import 'password/authenticator_enrolment.dart' as _iv7tra7v;
import 'password/key_proof_challenge.dart' as _iehtx95q;
import 'password/new_password.dart' as _itvvd6m6;
import 'password/password_challenge.dart' as _iuxisac7;
import 'password/password_costs.dart' as _izp492e5;
import 'password/password_refusal.dart' as _ibfrwdhm;
import 'password/password_refused_exception.dart' as _i4froq5y;
import 'password/password_setup.dart' as _igpggy1y;
import 'password/password_signed_in.dart' as _ipk7gvzy;
import 'password/reset_pending.dart' as _i3y6qzi3;
import 'password/sign_in_challenge_purpose.dart' as _izijxzng;
import 'password/wrapped_keys.dart' as _i6v10ugm;
import 'profile/profile.dart' as _ia5j8fch;
import 'profile/profile_not_found_exception.dart' as _iim3hfcf;
import 'profile/profile_refusal.dart' as _i6j6efd1;
import 'profile/profile_refused_exception.dart' as _idvc5e7p;
export 'auth/email_code_accepted.dart';
export 'auth/email_sign_in_refusal.dart';
export 'auth/email_sign_in_refused_exception.dart';
export 'auth/github_sign_in_refusal.dart';
export 'auth/github_sign_in_refused_exception.dart';
export 'auth/sign_in_ways.dart';
export 'instance/instance_basics.dart';
export 'password/account_reset_kind.dart';
export 'password/authenticator.dart';
export 'password/authenticator_enrolment.dart';
export 'password/key_proof_challenge.dart';
export 'password/new_password.dart';
export 'password/password_challenge.dart';
export 'password/password_costs.dart';
export 'password/password_refusal.dart';
export 'password/password_refused_exception.dart';
export 'password/password_setup.dart';
export 'password/password_signed_in.dart';
export 'password/reset_pending.dart';
export 'password/sign_in_challenge_purpose.dart';
export 'password/wrapped_keys.dart';
export 'profile/profile.dart';
export 'profile/profile_not_found_exception.dart';
export 'profile/profile_refusal.dart';
export 'profile/profile_refused_exception.dart';
export 'client.dart';
class Protocol extends _isc.SerializationManager {
Protocol._();
factory Protocol() => _instance;
static final Protocol _instance = Protocol._();
final Set<_isc.SerializationManager> _hostProtocols = {};
void registerHostProtocol(
String projectName,
_isc.SerializationManager protocol,
) {
_hostProtocols.add(protocol);
}
static String? getClassNameFromObjectJson(dynamic data) {
if (data is! Map) return null;
final className = data['__className__'] as String?;
if (className == null) return null;
if (!className.startsWith('halkyon_base.')) return className;
return className.substring(13);
}
@override
T deserialize<T>(
dynamic data, [
Type? t,
]) {
t ??= T;
final dataClassName = getClassNameFromObjectJson(data);
if (dataClassName != null && dataClassName != getClassNameForType(t)) {
try {
return deserializeByClassName({
'className': dataClassName,
'data': data,
});
} on _isc.DeserializationClassNameNotFoundException catch (_) {
// If the className is not recognized (e.g., older client receiving
// data with a new subtype), fall back to deserializing without the
// className, using the expected type T.
}
}
if (t == _iys46ui1.EmailCodeAccepted) {
return _iys46ui1.EmailCodeAccepted.fromJson(data) as T;
}
if (t == _ieyvcag1.EmailSignInRefusal) {
return _ieyvcag1.EmailSignInRefusal.fromJson(data) as T;
}
if (t == _iztfgag5.EmailSignInRefusedException) {
return _iztfgag5.EmailSignInRefusedException.fromJson(data) as T;
}
if (t == _ir1gd9p5.GitHubSignInRefusal) {
return _ir1gd9p5.GitHubSignInRefusal.fromJson(data) as T;
}
if (t == _i0xfcu5n.GitHubSignInRefusedException) {
return _i0xfcu5n.GitHubSignInRefusedException.fromJson(data) as T;
}
if (t == _ie6tbh85.SignInWays) {
return _ie6tbh85.SignInWays.fromJson(data) as T;
}
if (t == _i8jixqx6.InstanceBasics) {
return _i8jixqx6.InstanceBasics.fromJson(data) as T;
}
if (t == _i91ka1it.AccountResetKind) {
return _i91ka1it.AccountResetKind.fromJson(data) as T;
}
if (t == _icpzuvvi.Authenticator) {
return _icpzuvvi.Authenticator.fromJson(data) as T;
}
if (t == _iv7tra7v.AuthenticatorEnrolment) {
return _iv7tra7v.AuthenticatorEnrolment.fromJson(data) as T;
}
if (t == _iehtx95q.KeyProofChallenge) {
return _iehtx95q.KeyProofChallenge.fromJson(data) as T;
}
if (t == _itvvd6m6.NewPassword) {
return _itvvd6m6.NewPassword.fromJson(data) as T;
}
if (t == _iuxisac7.PasswordChallenge) {
return _iuxisac7.PasswordChallenge.fromJson(data) as T;
}
if (t == _izp492e5.PasswordCosts) {
return _izp492e5.PasswordCosts.fromJson(data) as T;
}
if (t == _ibfrwdhm.PasswordRefusal) {
return _ibfrwdhm.PasswordRefusal.fromJson(data) as T;
}
if (t == _i4froq5y.PasswordRefusedException) {
return _i4froq5y.PasswordRefusedException.fromJson(data) as T;
}
if (t == _igpggy1y.PasswordSetup) {
return _igpggy1y.PasswordSetup.fromJson(data) as T;
}
if (t == _ipk7gvzy.PasswordSignedIn) {
return _ipk7gvzy.PasswordSignedIn.fromJson(data) as T;
}
if (t == _i3y6qzi3.ResetPending) {
return _i3y6qzi3.ResetPending.fromJson(data) as T;
}
if (t == _izijxzng.SignInChallengePurpose) {
return _izijxzng.SignInChallengePurpose.fromJson(data) as T;
}
if (t == _i6v10ugm.WrappedKeys) {
return _i6v10ugm.WrappedKeys.fromJson(data) as T;
}
if (t == _ia5j8fch.Profile) {
return _ia5j8fch.Profile.fromJson(data) as T;
}
if (t == _iim3hfcf.ProfileNotFoundException) {
return _iim3hfcf.ProfileNotFoundException.fromJson(data) as T;
}
if (t == _i6j6efd1.ProfileRefusal) {
return _i6j6efd1.ProfileRefusal.fromJson(data) as T;
}
if (t == _idvc5e7p.ProfileRefusedException) {
return _idvc5e7p.ProfileRefusedException.fromJson(data) as T;
}
if (t == _isc.getType<_iys46ui1.EmailCodeAccepted?>()) {
return (data != null ? _iys46ui1.EmailCodeAccepted.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_ieyvcag1.EmailSignInRefusal?>()) {
return (data != null ? _ieyvcag1.EmailSignInRefusal.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_iztfgag5.EmailSignInRefusedException?>()) {
return (data != null
? _iztfgag5.EmailSignInRefusedException.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_ir1gd9p5.GitHubSignInRefusal?>()) {
return (data != null
? _ir1gd9p5.GitHubSignInRefusal.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_i0xfcu5n.GitHubSignInRefusedException?>()) {
return (data != null
? _i0xfcu5n.GitHubSignInRefusedException.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_ie6tbh85.SignInWays?>()) {
return (data != null ? _ie6tbh85.SignInWays.fromJson(data) : null) as T;
}
if (t == _isc.getType<_i8jixqx6.InstanceBasics?>()) {
return (data != null ? _i8jixqx6.InstanceBasics.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i91ka1it.AccountResetKind?>()) {
return (data != null ? _i91ka1it.AccountResetKind.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_icpzuvvi.Authenticator?>()) {
return (data != null ? _icpzuvvi.Authenticator.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_iv7tra7v.AuthenticatorEnrolment?>()) {
return (data != null
? _iv7tra7v.AuthenticatorEnrolment.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_iehtx95q.KeyProofChallenge?>()) {
return (data != null ? _iehtx95q.KeyProofChallenge.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_itvvd6m6.NewPassword?>()) {
return (data != null ? _itvvd6m6.NewPassword.fromJson(data) : null) as T;
}
if (t == _isc.getType<_iuxisac7.PasswordChallenge?>()) {
return (data != null ? _iuxisac7.PasswordChallenge.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_izp492e5.PasswordCosts?>()) {
return (data != null ? _izp492e5.PasswordCosts.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_ibfrwdhm.PasswordRefusal?>()) {
return (data != null ? _ibfrwdhm.PasswordRefusal.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i4froq5y.PasswordRefusedException?>()) {
return (data != null
? _i4froq5y.PasswordRefusedException.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_igpggy1y.PasswordSetup?>()) {
return (data != null ? _igpggy1y.PasswordSetup.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_ipk7gvzy.PasswordSignedIn?>()) {
return (data != null ? _ipk7gvzy.PasswordSignedIn.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_i3y6qzi3.ResetPending?>()) {
return (data != null ? _i3y6qzi3.ResetPending.fromJson(data) : null) as T;
}
if (t == _isc.getType<_izijxzng.SignInChallengePurpose?>()) {
return (data != null
? _izijxzng.SignInChallengePurpose.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_i6v10ugm.WrappedKeys?>()) {
return (data != null ? _i6v10ugm.WrappedKeys.fromJson(data) : null) as T;
}
if (t == _isc.getType<_ia5j8fch.Profile?>()) {
return (data != null ? _ia5j8fch.Profile.fromJson(data) : null) as T;
}
if (t == _isc.getType<_iim3hfcf.ProfileNotFoundException?>()) {
return (data != null
? _iim3hfcf.ProfileNotFoundException.fromJson(data)
: null)
as T;
}
if (t == _isc.getType<_i6j6efd1.ProfileRefusal?>()) {
return (data != null ? _i6j6efd1.ProfileRefusal.fromJson(data) : null)
as T;
}
if (t == _isc.getType<_idvc5e7p.ProfileRefusedException?>()) {
return (data != null
? _idvc5e7p.ProfileRefusedException.fromJson(data)
: null)
as T;
}
if (t == Set<String>) {
return (data as List).map((e) => deserialize<String>(e)).toSet() as T;
}
if (t == List<String>) {
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
}
if (t == _isc.getType<List<String>?>()) {
return (data != null
? (data as List).map((e) => deserialize<String>(e)).toList()
: null)
as T;
}
if (t == List<String>) {
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
}
if (t == List<_ivfmflch.Authenticator>) {
return (data as List)
.map((e) => deserialize<_ivfmflch.Authenticator>(e))
.toList()
as T;
}
try {
return _iaic.Protocol().deserialize<T>(data, t);
} on _isc.DeserializationTypeNotFoundException catch (_) {}
try {
return _iacc.Protocol().deserialize<T>(data, t);
} on _isc.DeserializationTypeNotFoundException catch (_) {}
return super.deserialize<T>(data, t);
}
static String? getClassNameForType(Type type) {
return switch (type) {
_iys46ui1.EmailCodeAccepted => 'EmailCodeAccepted',
_ieyvcag1.EmailSignInRefusal => 'EmailSignInRefusal',
_iztfgag5.EmailSignInRefusedException => 'EmailSignInRefusedException',
_ir1gd9p5.GitHubSignInRefusal => 'GitHubSignInRefusal',
_i0xfcu5n.GitHubSignInRefusedException => 'GitHubSignInRefusedException',
_ie6tbh85.SignInWays => 'SignInWays',
_i8jixqx6.InstanceBasics => 'InstanceBasics',
_i91ka1it.AccountResetKind => 'AccountResetKind',
_icpzuvvi.Authenticator => 'Authenticator',
_iv7tra7v.AuthenticatorEnrolment => 'AuthenticatorEnrolment',
_iehtx95q.KeyProofChallenge => 'KeyProofChallenge',
_itvvd6m6.NewPassword => 'NewPassword',
_iuxisac7.PasswordChallenge => 'PasswordChallenge',
_izp492e5.PasswordCosts => 'PasswordCosts',
_ibfrwdhm.PasswordRefusal => 'PasswordRefusal',
_i4froq5y.PasswordRefusedException => 'PasswordRefusedException',
_igpggy1y.PasswordSetup => 'PasswordSetup',
_ipk7gvzy.PasswordSignedIn => 'PasswordSignedIn',
_i3y6qzi3.ResetPending => 'ResetPending',
_izijxzng.SignInChallengePurpose => 'SignInChallengePurpose',
_i6v10ugm.WrappedKeys => 'WrappedKeys',
_ia5j8fch.Profile => 'Profile',
_iim3hfcf.ProfileNotFoundException => 'ProfileNotFoundException',
_i6j6efd1.ProfileRefusal => 'ProfileRefusal',
_idvc5e7p.ProfileRefusedException => 'ProfileRefusedException',
_ => null,
};
}
@override
String? getClassNameForObject(Object? data) {
String? className = super.getClassNameForObject(data);
if (className != null) return className;
if (data is Map<String, dynamic> && data['__className__'] is String) {
return (data['__className__'] as String).replaceFirst(
'halkyon_base.',
'',
);
}
switch (data) {
case _iys46ui1.EmailCodeAccepted():
return 'EmailCodeAccepted';
case _ieyvcag1.EmailSignInRefusal():
return 'EmailSignInRefusal';
case _iztfgag5.EmailSignInRefusedException():
return 'EmailSignInRefusedException';
case _ir1gd9p5.GitHubSignInRefusal():
return 'GitHubSignInRefusal';
case _i0xfcu5n.GitHubSignInRefusedException():
return 'GitHubSignInRefusedException';
case _ie6tbh85.SignInWays():
return 'SignInWays';
case _i8jixqx6.InstanceBasics():
return 'InstanceBasics';
case _i91ka1it.AccountResetKind():
return 'AccountResetKind';
case _icpzuvvi.Authenticator():
return 'Authenticator';
case _iv7tra7v.AuthenticatorEnrolment():
return 'AuthenticatorEnrolment';
case _iehtx95q.KeyProofChallenge():
return 'KeyProofChallenge';
case _itvvd6m6.NewPassword():
return 'NewPassword';
case _iuxisac7.PasswordChallenge():
return 'PasswordChallenge';
case _izp492e5.PasswordCosts():
return 'PasswordCosts';
case _ibfrwdhm.PasswordRefusal():
return 'PasswordRefusal';
case _i4froq5y.PasswordRefusedException():
return 'PasswordRefusedException';
case _igpggy1y.PasswordSetup():
return 'PasswordSetup';
case _ipk7gvzy.PasswordSignedIn():
return 'PasswordSignedIn';
case _i3y6qzi3.ResetPending():
return 'ResetPending';
case _izijxzng.SignInChallengePurpose():
return 'SignInChallengePurpose';
case _i6v10ugm.WrappedKeys():
return 'WrappedKeys';
case _ia5j8fch.Profile():
return 'Profile';
case _iim3hfcf.ProfileNotFoundException():
return 'ProfileNotFoundException';
case _i6j6efd1.ProfileRefusal():
return 'ProfileRefusal';
case _idvc5e7p.ProfileRefusedException():
return 'ProfileRefusedException';
}
return null;
}
@override
dynamic deserializeByClassName(Map<String, dynamic> data) {
var dataClassName = data['className'];
if (dataClassName is! String) {
return super.deserializeByClassName(data);
}
if (dataClassName == 'EmailCodeAccepted') {
return deserialize<_iys46ui1.EmailCodeAccepted>(data['data']);
}
if (dataClassName == 'EmailSignInRefusal') {
return deserialize<_ieyvcag1.EmailSignInRefusal>(data['data']);
}
if (dataClassName == 'EmailSignInRefusedException') {
return deserialize<_iztfgag5.EmailSignInRefusedException>(data['data']);
}
if (dataClassName == 'GitHubSignInRefusal') {
return deserialize<_ir1gd9p5.GitHubSignInRefusal>(data['data']);
}
if (dataClassName == 'GitHubSignInRefusedException') {
return deserialize<_i0xfcu5n.GitHubSignInRefusedException>(data['data']);
}
if (dataClassName == 'SignInWays') {
return deserialize<_ie6tbh85.SignInWays>(data['data']);
}
if (dataClassName == 'InstanceBasics') {
return deserialize<_i8jixqx6.InstanceBasics>(data['data']);
}
if (dataClassName == 'AccountResetKind') {
return deserialize<_i91ka1it.AccountResetKind>(data['data']);
}
if (dataClassName == 'Authenticator') {
return deserialize<_icpzuvvi.Authenticator>(data['data']);
}
if (dataClassName == 'AuthenticatorEnrolment') {
return deserialize<_iv7tra7v.AuthenticatorEnrolment>(data['data']);
}
if (dataClassName == 'KeyProofChallenge') {
return deserialize<_iehtx95q.KeyProofChallenge>(data['data']);
}
if (dataClassName == 'NewPassword') {
return deserialize<_itvvd6m6.NewPassword>(data['data']);
}
if (dataClassName == 'PasswordChallenge') {
return deserialize<_iuxisac7.PasswordChallenge>(data['data']);
}
if (dataClassName == 'PasswordCosts') {
return deserialize<_izp492e5.PasswordCosts>(data['data']);
}
if (dataClassName == 'PasswordRefusal') {
return deserialize<_ibfrwdhm.PasswordRefusal>(data['data']);
}
if (dataClassName == 'PasswordRefusedException') {
return deserialize<_i4froq5y.PasswordRefusedException>(data['data']);
}
if (dataClassName == 'PasswordSetup') {
return deserialize<_igpggy1y.PasswordSetup>(data['data']);
}
if (dataClassName == 'PasswordSignedIn') {
return deserialize<_ipk7gvzy.PasswordSignedIn>(data['data']);
}
if (dataClassName == 'ResetPending') {
return deserialize<_i3y6qzi3.ResetPending>(data['data']);
}
if (dataClassName == 'SignInChallengePurpose') {
return deserialize<_izijxzng.SignInChallengePurpose>(data['data']);
}
if (dataClassName == 'WrappedKeys') {
return deserialize<_i6v10ugm.WrappedKeys>(data['data']);
}
if (dataClassName == 'Profile') {
return deserialize<_ia5j8fch.Profile>(data['data']);
}
if (dataClassName == 'ProfileNotFoundException') {
return deserialize<_iim3hfcf.ProfileNotFoundException>(data['data']);
}
if (dataClassName == 'ProfileRefusal') {
return deserialize<_i6j6efd1.ProfileRefusal>(data['data']);
}
if (dataClassName == 'ProfileRefusedException') {
return deserialize<_idvc5e7p.ProfileRefusedException>(data['data']);
}
return super.deserializeByClassName(data);
}
@override
Object? dynamicFieldToJson(
Object? object, {
bool forProtocol = false,
}) {
if ((object is List || object is Set || object is Map) ||
getClassNameForObject(object) != null) {
return super.dynamicFieldToJson(object, forProtocol: forProtocol);
}
for (final protocol in _hostProtocols) {
final className = protocol.getClassNameForObject(object);
if (className == null) continue;
final host = protocol.getModuleName();
final wrapped = {
'className': className.contains('.') ? className : '$host.$className',
'data': object,
};
return forProtocol
? _isc.SerializationManager.toEncodableForProtocol(wrapped)
: _isc.SerializationManager.toEncodable(wrapped);
}
return super.dynamicFieldToJson(object, forProtocol: forProtocol);
}
@override
dynamic deserializeDynamicFieldValue(Object? value) {
if (value == null) return null;
if (value is! Map<String, dynamic> || value['className'] is! String) {
throw FormatException(
'Dynamic fields are encoded as a Map with className and data, but got '
'${value.runtimeType} instead.',
);
}
final className = value['className'] as String;
for (final protocol in _hostProtocols) {
final host = protocol.getModuleName();
final hostPrefix = '$host.';
if (className.startsWith(hostPrefix)) {
final strippedClassName = className.substring(hostPrefix.length);
if (strippedClassName.contains('.')) {
throw FormatException(
'Dynamic field className must not use multiple prefixes: $className',
);
}
final hostData = Map<String, dynamic>.from(value);
hostData['className'] = strippedClassName;
return protocol.deserializeByClassName(hostData);
}
}
if (className.contains('.')) {
for (final protocol in _hostProtocols) {
try {
return protocol.deserializeByClassName(value);
} on _isc.DeserializationClassNameNotFoundException catch (_) {}
}
}
return deserializeByClassName(value);
}
@override
String getModuleName() => 'halkyon_base';
/// Maps any `Record`s known to this [Protocol] to their JSON representation
///
/// Throws in case the record type is not known.
///
/// This method will return `null` (only) for `null` inputs.
Map<String, dynamic>? mapRecordToJson(Record? record) {
if (record == null) {
return null;
}
try {
return _iaic.Protocol().mapRecordToJson(record);
} catch (_) {}
try {
return _iacc.Protocol().mapRecordToJson(record);
} catch (_) {}
throw Exception('Unsupported record type ${record.runtimeType}');
}
}