chore: scaffold the Serverpod 4 build
Deviations from a stock `serverpod create`:
- Dropped Flutter web support, for two reasons:
- Appflowy editor had issues in the past, potentially related to the
Flutter-Web IME bridge. Upstream has also open bugs in relation to
that:
- AppFlowy-IO/appflowy-editor#1029 [Bug][Web] Unwanted space on click
and overall space bugs (open)
- AppFlowy-IO/appflowy-editor#782 [Bug] Editor auto-scrolling when
pressing space too quickly if placed inside a scrollable (open)
- Offline-first is a required feature. serverpod_offline_sync's SQLite
support in browsers, maybe via sqlite3.wasm + OPFS, is not
documented.
- SDK constraints raised to ^3.13.0, instead of ^3.12.2, so enjoy the
newest language features.
- Pinned to Flutter 3.47.4 via FVM.
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
commit
e17d99fa51
11 changed files with 17563 additions and 0 deletions
13
halkyon_learn_client/.gitignore
vendored
Normal file
13
halkyon_learn_client/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Files and directories created by pub
|
||||
.dart_tool/
|
||||
.packages
|
||||
|
||||
# Omit committing pubspec.lock for library packages:
|
||||
# https://dart.dev/guides/libraries/private-files#pubspeclock
|
||||
pubspec.lock
|
||||
|
||||
# Conventional directory for build outputs
|
||||
build/
|
||||
|
||||
# Directory created by dartdoc
|
||||
doc/api/
|
||||
3
halkyon_learn_client/CHANGELOG.md
Normal file
3
halkyon_learn_client/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
## 1.0.0
|
||||
|
||||
- Initial version, created by Stagehand
|
||||
5
halkyon_learn_client/README.md
Normal file
5
halkyon_learn_client/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# halkyon_learn_client
|
||||
|
||||
This is your Serverpod client. The code in here is mostly generated by
|
||||
Serverpod, but you may want to make changes if you are adding modules to your
|
||||
project.
|
||||
16
halkyon_learn_client/analysis_options.yaml
Normal file
16
halkyon_learn_client/analysis_options.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Defines a default set of lint rules enforced for
|
||||
# projects at Google. For details and rationale,
|
||||
# see https://github.com/dart-lang/pedantic#enabled-lints.
|
||||
|
||||
# For lint rules and documentation, see http://dart-lang.github.io/linter/lints.
|
||||
# Uncomment to specify additional rules.
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
analyzer:
|
||||
exclude:
|
||||
- lib/src/protocol/**
|
||||
|
||||
formatter:
|
||||
trailing_commas: preserve
|
||||
5
halkyon_learn_client/dartdoc_options.yaml
Normal file
5
halkyon_learn_client/dartdoc_options.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
dartdoc:
|
||||
categories:
|
||||
"Endpoint":
|
||||
markdown: doc/endpoint.md
|
||||
name: Endpoint
|
||||
15
halkyon_learn_client/doc/endpoint.md
Normal file
15
halkyon_learn_client/doc/endpoint.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Callable endpoints
|
||||
|
||||
Each class contains callable methods that will call a method on the server side. These are normally defined in the `endpoint` directory in your server project. This client sends requests to these endpoints and returns the result.
|
||||
|
||||
Example usage:
|
||||
|
||||
```dart
|
||||
// How to use GreetingEndpoint.
|
||||
client.greeting.hello("world!");
|
||||
|
||||
// Generic format.
|
||||
client.<endpoint>.<method>(...);
|
||||
```
|
||||
|
||||
Please see the full official documentation [here](https://docs.serverpod.dev)
|
||||
2
halkyon_learn_client/lib/halkyon_learn_client.dart
Normal file
2
halkyon_learn_client/lib/halkyon_learn_client.dart
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export 'src/protocol/protocol.dart';
|
||||
export 'package:serverpod_client/serverpod_client.dart';
|
||||
331
halkyon_learn_client/lib/src/protocol/client.dart
Normal file
331
halkyon_learn_client/lib/src/protocol/client.dart
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
/* 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: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _ida;
|
||||
import 'package:halkyon_learn_client/src/protocol/greetings/greeting.dart'
|
||||
as _ili0bmg9;
|
||||
import 'package:http/http.dart' as _i85jenna;
|
||||
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 'protocol.dart' as _il2as5qe;
|
||||
|
||||
/// By extending [EmailIdpBaseEndpoint], the email identity provider endpoints
|
||||
/// are made available on the server and enable the corresponding sign-in widget
|
||||
/// on the client.
|
||||
/// {@category Endpoint}
|
||||
class EndpointEmailIdp extends _iaic.EndpointEmailIdpBase {
|
||||
EndpointEmailIdp(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'emailIdp';
|
||||
|
||||
/// Logs in the user and returns a new session.
|
||||
///
|
||||
/// Throws an [EmailAccountLoginException] in case of errors, with reason:
|
||||
/// - [EmailAccountLoginExceptionReason.invalidCredentials] if the email or
|
||||
/// password is incorrect.
|
||||
/// - [EmailAccountLoginExceptionReason.tooManyAttempts] if there have been
|
||||
/// too many failed login attempts.
|
||||
///
|
||||
/// Throws an [AuthUserBlockedException] if the auth user is blocked.
|
||||
@override
|
||||
_ida.Future<_iacc.AuthSuccess> login({
|
||||
required String email,
|
||||
required String password,
|
||||
}) => caller.callServerEndpoint<_iacc.AuthSuccess>(
|
||||
'emailIdp',
|
||||
'login',
|
||||
{
|
||||
'email': email,
|
||||
'password': password,
|
||||
},
|
||||
);
|
||||
|
||||
/// Starts the registration for a new user account with an email-based login
|
||||
/// associated to it.
|
||||
///
|
||||
/// Upon successful completion of this method, an email will have been
|
||||
/// sent to [email] with a verification link, which the user must open to
|
||||
/// complete the registration.
|
||||
///
|
||||
/// Always returns a account request ID, which can be used to complete the
|
||||
/// registration. If the email is already registered, the returned ID will not
|
||||
/// be valid.
|
||||
@override
|
||||
_ida.Future<_isc.UuidValue> startRegistration({required String email}) =>
|
||||
caller.callServerEndpoint<_isc.UuidValue>(
|
||||
'emailIdp',
|
||||
'startRegistration',
|
||||
{'email': email},
|
||||
);
|
||||
|
||||
/// Verifies an account request code and returns a token
|
||||
/// that can be used to complete the account creation.
|
||||
///
|
||||
/// Throws an [EmailAccountRequestException] in case of errors, with reason:
|
||||
/// - [EmailAccountRequestExceptionReason.expired] if the account request has
|
||||
/// already expired.
|
||||
/// - [EmailAccountRequestExceptionReason.policyViolation] if the password
|
||||
/// does not comply with the password policy.
|
||||
/// - [EmailAccountRequestExceptionReason.invalid] if no request exists
|
||||
/// for the given [accountRequestId] or [verificationCode] is invalid.
|
||||
@override
|
||||
_ida.Future<String> verifyRegistrationCode({
|
||||
required _isc.UuidValue accountRequestId,
|
||||
required String verificationCode,
|
||||
}) => caller.callServerEndpoint<String>(
|
||||
'emailIdp',
|
||||
'verifyRegistrationCode',
|
||||
{
|
||||
'accountRequestId': accountRequestId,
|
||||
'verificationCode': verificationCode,
|
||||
},
|
||||
);
|
||||
|
||||
/// Completes a new account registration, creating a new auth user with a
|
||||
/// profile and attaching the given email account to it.
|
||||
///
|
||||
/// Throws an [EmailAccountRequestException] in case of errors, with reason:
|
||||
/// - [EmailAccountRequestExceptionReason.expired] if the account request has
|
||||
/// already expired.
|
||||
/// - [EmailAccountRequestExceptionReason.policyViolation] if the password
|
||||
/// does not comply with the password policy.
|
||||
/// - [EmailAccountRequestExceptionReason.invalid] if the [registrationToken]
|
||||
/// is invalid.
|
||||
///
|
||||
/// Throws an [AuthUserBlockedException] if the auth user is blocked.
|
||||
///
|
||||
/// Returns a session for the newly created user.
|
||||
@override
|
||||
_ida.Future<_iacc.AuthSuccess> finishRegistration({
|
||||
required String registrationToken,
|
||||
required String password,
|
||||
}) => caller.callServerEndpoint<_iacc.AuthSuccess>(
|
||||
'emailIdp',
|
||||
'finishRegistration',
|
||||
{
|
||||
'registrationToken': registrationToken,
|
||||
'password': password,
|
||||
},
|
||||
);
|
||||
|
||||
/// Requests a password reset for [email].
|
||||
///
|
||||
/// If the email address is registered, an email with reset instructions will
|
||||
/// be send out. If the email is unknown, this method will have no effect.
|
||||
///
|
||||
/// Always returns a password reset request ID, which can be used to complete
|
||||
/// the reset. If the email is not registered, the returned ID will not be
|
||||
/// valid.
|
||||
///
|
||||
/// Throws an [EmailAccountPasswordResetException] in case of errors, with reason:
|
||||
/// - [EmailAccountPasswordResetExceptionReason.tooManyAttempts] if the user has
|
||||
/// made too many attempts trying to request a password reset.
|
||||
///
|
||||
@override
|
||||
_ida.Future<_isc.UuidValue> startPasswordReset({required String email}) =>
|
||||
caller.callServerEndpoint<_isc.UuidValue>(
|
||||
'emailIdp',
|
||||
'startPasswordReset',
|
||||
{'email': email},
|
||||
);
|
||||
|
||||
/// Verifies a password reset code and returns a finishPasswordResetToken
|
||||
/// that can be used to finish the password reset.
|
||||
///
|
||||
/// Throws an [EmailAccountPasswordResetException] in case of errors, with reason:
|
||||
/// - [EmailAccountPasswordResetExceptionReason.expired] if the password reset
|
||||
/// request has already expired.
|
||||
/// - [EmailAccountPasswordResetExceptionReason.tooManyAttempts] if the user has
|
||||
/// made too many attempts trying to verify the password reset.
|
||||
/// - [EmailAccountPasswordResetExceptionReason.invalid] if no request exists
|
||||
/// for the given [passwordResetRequestId] or [verificationCode] is invalid.
|
||||
///
|
||||
/// If multiple steps are required to complete the password reset, this endpoint
|
||||
/// should be overridden to return credentials for the next step instead
|
||||
/// of the credentials for setting the password.
|
||||
@override
|
||||
_ida.Future<String> verifyPasswordResetCode({
|
||||
required _isc.UuidValue passwordResetRequestId,
|
||||
required String verificationCode,
|
||||
}) => caller.callServerEndpoint<String>(
|
||||
'emailIdp',
|
||||
'verifyPasswordResetCode',
|
||||
{
|
||||
'passwordResetRequestId': passwordResetRequestId,
|
||||
'verificationCode': verificationCode,
|
||||
},
|
||||
);
|
||||
|
||||
/// Completes a password reset request by setting a new password.
|
||||
///
|
||||
/// The [verificationCode] returned from [verifyPasswordResetCode] is used to
|
||||
/// validate the password reset request.
|
||||
///
|
||||
/// Throws an [EmailAccountPasswordResetException] in case of errors, with reason:
|
||||
/// - [EmailAccountPasswordResetExceptionReason.expired] if the password reset
|
||||
/// request has already expired.
|
||||
/// - [EmailAccountPasswordResetExceptionReason.policyViolation] if the new
|
||||
/// password does not comply with the password policy.
|
||||
/// - [EmailAccountPasswordResetExceptionReason.invalid] if no request exists
|
||||
/// for the given [passwordResetRequestId] or [verificationCode] is invalid.
|
||||
///
|
||||
/// Throws an [AuthUserBlockedException] if the auth user is blocked.
|
||||
@override
|
||||
_ida.Future<void> finishPasswordReset({
|
||||
required String finishPasswordResetToken,
|
||||
required String newPassword,
|
||||
}) => caller.callServerEndpoint<void>(
|
||||
'emailIdp',
|
||||
'finishPasswordReset',
|
||||
{
|
||||
'finishPasswordResetToken': finishPasswordResetToken,
|
||||
'newPassword': newPassword,
|
||||
},
|
||||
);
|
||||
|
||||
@override
|
||||
_ida.Future<bool> hasAccount() => caller.callServerEndpoint<bool>(
|
||||
'emailIdp',
|
||||
'hasAccount',
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
/// By extending [RefreshJwtTokensEndpoint], the JWT token refresh endpoint
|
||||
/// is made available on the server and enables automatic token refresh on the client.
|
||||
/// {@category Endpoint}
|
||||
class EndpointJwtRefresh extends _iacc.EndpointRefreshJwtTokens {
|
||||
EndpointJwtRefresh(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'jwtRefresh';
|
||||
|
||||
/// Creates a new token pair for the given [refreshToken].
|
||||
///
|
||||
/// If [refreshToken] is omitted, cookie-mode web clients fall back to the
|
||||
/// configured HttpOnly refresh cookie. When neither source is present this
|
||||
/// throws [RefreshTokenNotFoundException], the same public "no usable refresh
|
||||
/// credential" exception used for unknown refresh tokens.
|
||||
///
|
||||
/// Can throw the following exceptions:
|
||||
/// -[RefreshTokenMalformedException]: refresh token is malformed and could
|
||||
/// not be parsed. Not expected to happen for tokens issued by the server.
|
||||
/// -[RefreshTokenNotFoundException]: refresh token is unknown to the server.
|
||||
/// Either the token was deleted or generated by a different server.
|
||||
/// -[RefreshTokenExpiredException]: refresh token has expired. Will happen
|
||||
/// only if it has not been used within configured `refreshTokenLifetime`.
|
||||
/// -[RefreshTokenInvalidSecretException]: refresh token is incorrect, meaning
|
||||
/// it does not refer to the current secret refresh token. This indicates
|
||||
/// either a malfunctioning client or a malicious attempt by someone who has
|
||||
/// obtained the refresh token. In this case the underlying refresh token
|
||||
/// will be deleted, and access to it will expire fully when the last access
|
||||
/// token is elapsed.
|
||||
///
|
||||
/// This endpoint is unauthenticated, meaning the client won't include any
|
||||
/// authentication information with the call.
|
||||
@override
|
||||
_ida.Future<_iacc.AuthSuccess> refreshAccessToken({String? refreshToken}) =>
|
||||
caller.callServerEndpoint<_iacc.AuthSuccess>(
|
||||
'jwtRefresh',
|
||||
'refreshAccessToken',
|
||||
{'refreshToken': refreshToken},
|
||||
authenticated: false,
|
||||
);
|
||||
}
|
||||
|
||||
/// This is an example endpoint that returns a greeting message through
|
||||
/// its [hello] method.
|
||||
/// {@category Endpoint}
|
||||
class EndpointGreeting extends _isc.EndpointRef {
|
||||
EndpointGreeting(_isc.EndpointCaller caller) : super(caller);
|
||||
|
||||
@override
|
||||
String get name => 'greeting';
|
||||
|
||||
/// Returns a personalized greeting message: "Hello {name}".
|
||||
_ida.Future<_ili0bmg9.Greeting> hello(String name) =>
|
||||
caller.callServerEndpoint<_ili0bmg9.Greeting>(
|
||||
'greeting',
|
||||
'hello',
|
||||
{'name': name},
|
||||
);
|
||||
}
|
||||
|
||||
class Modules {
|
||||
Modules(Client client) {
|
||||
serverpod_auth_idp = _iaic.Caller(client);
|
||||
serverpod_auth_core = _iacc.Caller(client);
|
||||
}
|
||||
|
||||
late final _iaic.Caller serverpod_auth_idp;
|
||||
|
||||
late final _iacc.Caller serverpod_auth_core;
|
||||
}
|
||||
|
||||
class Client extends _isc.ServerpodClientShared {
|
||||
Client(
|
||||
String host, {
|
||||
dynamic securityContext,
|
||||
Duration? streamingConnectionTimeout,
|
||||
Duration? connectionTimeout,
|
||||
Function(
|
||||
_isc.MethodCallContext,
|
||||
Object,
|
||||
StackTrace,
|
||||
)?
|
||||
onFailedCall,
|
||||
Function(_isc.MethodCallContext)? onSucceededCall,
|
||||
bool? disconnectStreamsOnLostInternetConnection,
|
||||
_i85jenna.Client? httpClientOverride,
|
||||
}) : super(
|
||||
host,
|
||||
_il2as5qe.Protocol(),
|
||||
securityContext: securityContext,
|
||||
streamingConnectionTimeout: streamingConnectionTimeout,
|
||||
connectionTimeout: connectionTimeout,
|
||||
onFailedCall: onFailedCall,
|
||||
onSucceededCall: onSucceededCall,
|
||||
disconnectStreamsOnLostInternetConnection:
|
||||
disconnectStreamsOnLostInternetConnection,
|
||||
httpClientOverride: httpClientOverride,
|
||||
) {
|
||||
emailIdp = EndpointEmailIdp(this);
|
||||
jwtRefresh = EndpointJwtRefresh(this);
|
||||
greeting = EndpointGreeting(this);
|
||||
modules = Modules(this);
|
||||
}
|
||||
|
||||
late final EndpointEmailIdp emailIdp;
|
||||
|
||||
late final EndpointJwtRefresh jwtRefresh;
|
||||
|
||||
late final EndpointGreeting greeting;
|
||||
|
||||
late final Modules modules;
|
||||
|
||||
@override
|
||||
Map<String, _isc.EndpointRef> get endpointRefLookup => {
|
||||
'emailIdp': emailIdp,
|
||||
'jwtRefresh': jwtRefresh,
|
||||
'greeting': greeting,
|
||||
};
|
||||
|
||||
@override
|
||||
Map<String, _isc.ModuleEndpointCaller> get moduleLookup => {
|
||||
'serverpod_auth_idp': modules.serverpod_auth_idp,
|
||||
'serverpod_auth_core': modules.serverpod_auth_core,
|
||||
};
|
||||
}
|
||||
109
halkyon_learn_client/lib/src/protocol/greetings/greeting.dart
Normal file
109
halkyon_learn_client/lib/src/protocol/greetings/greeting.dart
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* 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: no_leading_underscores_for_library_prefixes
|
||||
import 'package:serverpod_client/serverpod_client.dart' as _isc;
|
||||
|
||||
/// A greeting message which can be sent to or from the server.
|
||||
abstract class Greeting
|
||||
implements _isc.SerializableModel, _isc.ProtocolSerialization {
|
||||
Greeting._({
|
||||
required this.message,
|
||||
required this.author,
|
||||
required this.timestamp,
|
||||
});
|
||||
|
||||
factory Greeting({
|
||||
required String message,
|
||||
required String author,
|
||||
required DateTime timestamp,
|
||||
}) = _GreetingImpl;
|
||||
|
||||
factory Greeting.fromJson(Map<String, dynamic> jsonSerialization) {
|
||||
return Greeting(
|
||||
message: jsonSerialization['message'] as String,
|
||||
author: jsonSerialization['author'] as String,
|
||||
timestamp: _isc.DateTimeJsonExtension.fromJson(
|
||||
jsonSerialization['timestamp'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// The greeting message.
|
||||
String message;
|
||||
|
||||
/// The author of the greeting message.
|
||||
String author;
|
||||
|
||||
/// The time when the message was created.
|
||||
DateTime timestamp;
|
||||
|
||||
/// Returns a shallow copy of this [Greeting]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
Greeting copyWith({
|
||||
String? message,
|
||||
String? author,
|
||||
DateTime? timestamp,
|
||||
});
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'__className__': 'Greeting',
|
||||
'message': message,
|
||||
'author': author,
|
||||
'timestamp': timestamp.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJsonForProtocol() {
|
||||
return {
|
||||
'__className__': 'Greeting',
|
||||
'message': message,
|
||||
'author': author,
|
||||
'timestamp': timestamp.toJson(),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return _isc.SerializationManager.encode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class _GreetingImpl extends Greeting {
|
||||
_GreetingImpl({
|
||||
required String message,
|
||||
required String author,
|
||||
required DateTime timestamp,
|
||||
}) : super._(
|
||||
message: message,
|
||||
author: author,
|
||||
timestamp: timestamp,
|
||||
);
|
||||
|
||||
/// Returns a shallow copy of this [Greeting]
|
||||
/// with some or all fields replaced by the given arguments.
|
||||
@_isc.useResult
|
||||
@override
|
||||
Greeting copyWith({
|
||||
String? message,
|
||||
String? author,
|
||||
DateTime? timestamp,
|
||||
}) {
|
||||
return Greeting(
|
||||
message: message ?? this.message,
|
||||
author: author ?? this.author,
|
||||
timestamp: timestamp ?? this.timestamp,
|
||||
);
|
||||
}
|
||||
}
|
||||
155
halkyon_learn_client/lib/src/protocol/protocol.dart
Normal file
155
halkyon_learn_client/lib/src/protocol/protocol.dart
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/* 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: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 'greetings/greeting.dart' as _izw8z7ou;
|
||||
export 'greetings/greeting.dart';
|
||||
export 'client.dart';
|
||||
|
||||
class Protocol extends _isc.SerializationManager {
|
||||
Protocol._();
|
||||
|
||||
factory Protocol() => _instance;
|
||||
|
||||
static final Protocol _instance = Protocol._().._registerHostProtocols();
|
||||
|
||||
static String? getClassNameFromObjectJson(dynamic data) {
|
||||
if (data is! Map) return null;
|
||||
final className = data['__className__'] as String?;
|
||||
return className;
|
||||
}
|
||||
|
||||
@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 == _izw8z7ou.Greeting) {
|
||||
return _izw8z7ou.Greeting.fromJson(data) as T;
|
||||
}
|
||||
if (t == _isc.getType<_izw8z7ou.Greeting?>()) {
|
||||
return (data != null ? _izw8z7ou.Greeting.fromJson(data) : null) 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) {
|
||||
_izw8z7ou.Greeting => 'Greeting',
|
||||
_ => 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_learn.',
|
||||
'',
|
||||
);
|
||||
}
|
||||
|
||||
switch (data) {
|
||||
case _izw8z7ou.Greeting():
|
||||
return 'Greeting';
|
||||
}
|
||||
className = _iaic.Protocol().getClassNameForObject(data);
|
||||
if (className != null) {
|
||||
return className.contains('.')
|
||||
? className
|
||||
: 'serverpod_auth_idp.$className';
|
||||
}
|
||||
className = _iacc.Protocol().getClassNameForObject(data);
|
||||
if (className != null) {
|
||||
return className.contains('.')
|
||||
? className
|
||||
: 'serverpod_auth_core.$className';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic deserializeByClassName(Map<String, dynamic> data) {
|
||||
var dataClassName = data['className'];
|
||||
if (dataClassName is! String) {
|
||||
return super.deserializeByClassName(data);
|
||||
}
|
||||
if (dataClassName == 'Greeting') {
|
||||
return deserialize<_izw8z7ou.Greeting>(data['data']);
|
||||
}
|
||||
if (dataClassName.startsWith('serverpod_auth_idp.')) {
|
||||
data['className'] = dataClassName.substring(19);
|
||||
return _iaic.Protocol().deserializeByClassName(data);
|
||||
}
|
||||
if (dataClassName.startsWith('serverpod_auth_core.')) {
|
||||
data['className'] = dataClassName.substring(20);
|
||||
return _iacc.Protocol().deserializeByClassName(data);
|
||||
}
|
||||
return super.deserializeByClassName(data);
|
||||
}
|
||||
|
||||
void _registerHostProtocols() {
|
||||
_iaic.Protocol().registerHostProtocol('halkyon_learn', this);
|
||||
_iacc.Protocol().registerHostProtocol('halkyon_learn', this);
|
||||
}
|
||||
|
||||
@override
|
||||
String getModuleName() => 'halkyon_learn';
|
||||
|
||||
/// 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}');
|
||||
}
|
||||
}
|
||||
11
halkyon_learn_client/pubspec.yaml
Normal file
11
halkyon_learn_client/pubspec.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
name: halkyon_learn_client
|
||||
description: Starting point for a Serverpod client.
|
||||
|
||||
environment:
|
||||
sdk: '^3.13.0'
|
||||
|
||||
resolution: workspace
|
||||
|
||||
dependencies:
|
||||
serverpod_auth_idp_client: 4.0.0
|
||||
serverpod_client: 4.0.0
|
||||
Loading…
Reference in a new issue