chore: Halkyon Todo's scaffold joins the repository in apps/todo
Its server, client and app as `serverpod create` made them, with the switch to server-side sessions that was waiting uncommitted, as files: its one commit holds the scaffold alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
649499be23
commit
314a901fa1
188 changed files with 16151 additions and 0 deletions
19
apps/todo/.gitignore
vendored
Normal file
19
apps/todo/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Files and directories created by pub
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
|
||||||
|
# Pubspec overrides
|
||||||
|
pubspec_overrides.yaml
|
||||||
|
|
||||||
|
# Agents
|
||||||
|
.dart_skills/
|
||||||
|
.agents/
|
||||||
|
.claude/
|
||||||
|
.gemini/
|
||||||
|
.cursor/
|
||||||
|
.vscode/mcp.json
|
||||||
|
.codex/
|
||||||
|
.mcp.json
|
||||||
|
|
||||||
|
# Serverpod Cloud CLI
|
||||||
|
.scloud/
|
||||||
50
apps/todo/AGENTS.md
Normal file
50
apps/todo/AGENTS.md
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Flutter & Serverpod project
|
||||||
|
|
||||||
|
This project is a Flutter app (frontend) backed by a Serverpod server (backend). Always build the app's backend with Serverpod.
|
||||||
|
Build for multiple users, use Serverpod's built-in authentication, which is already set up in `lib/server.dart`.
|
||||||
|
|
||||||
|
The user starts the server and Flutter app with `serverpod start`. There is no need to check if the server is running: make the changes and call the `serverpod` MCP tools as needed. If the server is not running, an informative error message will be received from the MCP server. Then STOP and ask the user to start it. NEVER start the server yourself. The Flutter app is started along with it, or can be launched from the MCP tool `spawn_flutter_app`.
|
||||||
|
|
||||||
|
While running, `serverpod start` watches for file changes to run incremental code generation and hot reload both the server and the Flutter app.
|
||||||
|
|
||||||
|
Calling `serverpod generate` directly is not needed, but might be useful to troubleshoot when an incremental generation fails.
|
||||||
|
|
||||||
|
ALWAYS use the MCP server instead of the command line. Use the MCP server to:
|
||||||
|
|
||||||
|
- `create_migration` and `apply_migrations` for database (after you change data models).
|
||||||
|
- `create_repair_migration` if the database has drifted out of sync with the migrations.
|
||||||
|
- `tail_server_logs` to read logs from the server.
|
||||||
|
- `tail_flutter_logs` to read the raw stdout/stderr of the Flutter app.
|
||||||
|
- `hot_reload` / `hot_restart` to reload or restart the server and the Flutter app. ALWAYS call `hot_restart` after doing changes in the Flutter app that may not work with normal hot reload (which is automatically applied).
|
||||||
|
- `spawn_flutter_app` to start a Flutter app declared under `serverpod: flutter_apps:` in the server `pubspec.yaml`.
|
||||||
|
- `get_flutter_app_dtd` (Dart tooling daemon) for connecting to the app through the `dart` MCP.
|
||||||
|
|
||||||
|
NEVER edit generated code. The server's `lib/src/generated/` directory and the whole `halkyon_todo_client` package are rewritten by the code generator. Change the `.spy.yaml` models, the endpoints, or `lib/server.dart` instead.
|
||||||
|
|
||||||
|
Migrations are a narrow exception: the `migration.sql` of a generated migration MAY be edited by hand when the generated SQL would lose data — to add a data transformation, or to reach a destructive change through non-destructive steps. Never touch the other files in the migration directory, and keep the schema the SQL ends up with identical to `definition.sql` — new databases are created from that file and never run `migration.sql`.
|
||||||
|
|
||||||
|
Only when the server cannot be started at all, fall back to the CLI in the server package:
|
||||||
|
|
||||||
|
- `serverpod generate` to regenerate the client and the generated server code.
|
||||||
|
- `serverpod create-migration` after changing a model with a `table` (add `--force` for destructive changes). It only writes the migration; `serverpod start` applies pending migrations when it boots the server.
|
||||||
|
|
||||||
|
Tests need no Docker. `config/test.yaml` sets `database.dataPath`, so Serverpod starts and manages the test database (an embedded PostgreSQL) itself, and the project's `docker-compose.yaml` is not used for it. Just run `dart test` in the server package.
|
||||||
|
|
||||||
|
Checklist after doing changes, in this order:
|
||||||
|
|
||||||
|
- `dart analyze` (CLI)
|
||||||
|
- `dart format` (CLI)
|
||||||
|
- `create_migration` and `apply_migrations` (MCP - only if necessary)
|
||||||
|
- Do `serverpod` MCP `hot_restart` if required (hot reload is done automatically). Will also hot restart Flutter app
|
||||||
|
- Run tests, if applicable (`dart test` in the server package)
|
||||||
|
- Check `serverpod` MCP `tail_server_logs` and `tail_flutter_logs` for any issues.
|
||||||
|
|
||||||
|
If the user asks you to test the app:
|
||||||
|
|
||||||
|
1. Use `get_flutter_app_dtd` (`serverpod` MCP) to get the Flutter app's DTD
|
||||||
|
2. Pass the DTD to `connect_dart_tooling_daemon` (`dart` MCP) to connect to the app
|
||||||
|
3. Use `flutter_driver` (`dart` MCP) to navigate through the app
|
||||||
|
|
||||||
|
The app is launched from `halkyon_todo_flutter/lib/driver.dart`, which starts the Flutter driver extension with text entry emulation turned off so the app stays usable by hand. To let the driver type, set `enableTextEntryEmulation: true` there and `hot_restart` the app.
|
||||||
|
|
||||||
|
IMPORTANT: After building the first version of the app, update this AGENTS.md file with information about the app we're building. KEEP the info about the MCP server and the checklist. Remove this paragraph.
|
||||||
1
apps/todo/CLAUDE.md
Normal file
1
apps/todo/CLAUDE.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
@AGENTS.md
|
||||||
13
apps/todo/halkyon_todo_client/.gitignore
vendored
Normal file
13
apps/todo/halkyon_todo_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
apps/todo/halkyon_todo_client/CHANGELOG.md
Normal file
3
apps/todo/halkyon_todo_client/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
- Initial version, created by Stagehand
|
||||||
5
apps/todo/halkyon_todo_client/README.md
Normal file
5
apps/todo/halkyon_todo_client/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# halkyon_todo_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
apps/todo/halkyon_todo_client/analysis_options.yaml
Normal file
16
apps/todo/halkyon_todo_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
apps/todo/halkyon_todo_client/dartdoc_options.yaml
Normal file
5
apps/todo/halkyon_todo_client/dartdoc_options.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
dartdoc:
|
||||||
|
categories:
|
||||||
|
"Endpoint":
|
||||||
|
markdown: doc/endpoint.md
|
||||||
|
name: Endpoint
|
||||||
15
apps/todo/halkyon_todo_client/doc/endpoint.md
Normal file
15
apps/todo/halkyon_todo_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)
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export 'src/protocol/protocol.dart';
|
||||||
|
export 'package:serverpod_client/serverpod_client.dart';
|
||||||
285
apps/todo/halkyon_todo_client/lib/src/protocol/client.dart
Normal file
285
apps/todo/halkyon_todo_client/lib/src/protocol/client.dart
Normal file
|
|
@ -0,0 +1,285 @@
|
||||||
|
/* 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_todo_client/src/protocol/greetings/greeting.dart'
|
||||||
|
as _i5fdz6wc;
|
||||||
|
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',
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<_i5fdz6wc.Greeting> hello(String name) =>
|
||||||
|
caller.callServerEndpoint<_i5fdz6wc.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);
|
||||||
|
greeting = EndpointGreeting(this);
|
||||||
|
modules = Modules(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final EndpointEmailIdp emailIdp;
|
||||||
|
|
||||||
|
late final EndpointGreeting greeting;
|
||||||
|
|
||||||
|
late final Modules modules;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, _isc.EndpointRef> get endpointRefLookup => {
|
||||||
|
'emailIdp': emailIdp,
|
||||||
|
'greeting': greeting,
|
||||||
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, _isc.ModuleEndpointCaller> get moduleLookup => {
|
||||||
|
'serverpod_auth_idp': modules.serverpod_auth_idp,
|
||||||
|
'serverpod_auth_core': modules.serverpod_auth_core,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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
apps/todo/halkyon_todo_client/lib/src/protocol/protocol.dart
Normal file
155
apps/todo/halkyon_todo_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_todo.',
|
||||||
|
'',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_todo', this);
|
||||||
|
_iacc.Protocol().registerHostProtocol('halkyon_todo', this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String getModuleName() => 'halkyon_todo';
|
||||||
|
|
||||||
|
/// 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
apps/todo/halkyon_todo_client/pubspec.yaml
Normal file
11
apps/todo/halkyon_todo_client/pubspec.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
name: halkyon_todo_client
|
||||||
|
description: Starting point for a Serverpod client.
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '^3.12.2'
|
||||||
|
|
||||||
|
resolution: workspace
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
serverpod_auth_idp_client: 4.0.3
|
||||||
|
serverpod_client: 4.0.3
|
||||||
47
apps/todo/halkyon_todo_flutter/.gitignore
vendored
Normal file
47
apps/todo/halkyon_todo_flutter/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
.packages
|
||||||
|
.pub-cache/
|
||||||
|
.pub/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Web related
|
||||||
|
lib/generated_plugin_registrant.dart
|
||||||
|
|
||||||
|
# Symbolization related
|
||||||
|
app.*.symbols
|
||||||
|
|
||||||
|
# Obfuscation related
|
||||||
|
app.*.map.json
|
||||||
|
|
||||||
|
# Android Studio will place build artifacts here
|
||||||
|
/android/app/debug
|
||||||
|
/android/app/profile
|
||||||
|
/android/app/release
|
||||||
|
|
||||||
45
apps/todo/halkyon_todo_flutter/.metadata
Normal file
45
apps/todo/halkyon_todo_flutter/.metadata
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: "6a19cca56475dbfba1478ee68d7bd0c2ef891da1"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: app
|
||||||
|
|
||||||
|
# Tracks metadata for the flutter migrate command
|
||||||
|
migration:
|
||||||
|
platforms:
|
||||||
|
- platform: root
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: android
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: ios
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: linux
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: macos
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: web
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
- platform: windows
|
||||||
|
create_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
base_revision: 6a19cca56475dbfba1478ee68d7bd0c2ef891da1
|
||||||
|
|
||||||
|
# User provided section
|
||||||
|
|
||||||
|
# List of Local paths (relative to this file) that should be
|
||||||
|
# ignored by the migrate tool.
|
||||||
|
#
|
||||||
|
# Files that are not part of the templates will be ignored by default.
|
||||||
|
unmanaged_files:
|
||||||
|
- 'lib/main.dart'
|
||||||
|
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||||
15
apps/todo/halkyon_todo_flutter/README.md
Normal file
15
apps/todo/halkyon_todo_flutter/README.md
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# halkyon_todo_flutter
|
||||||
|
|
||||||
|
A new Flutter project with Serverpod.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
This project is a starting point for a Flutter application that is using
|
||||||
|
Serverpod.
|
||||||
|
|
||||||
|
A great starting point for learning Serverpod is our documentation site at:
|
||||||
|
[https://docs.serverpod.dev](https://docs.serverpod.dev).
|
||||||
|
|
||||||
|
To run the project, first make sure that the server is running, then do:
|
||||||
|
|
||||||
|
flutter run
|
||||||
40
apps/todo/halkyon_todo_flutter/analysis_options.yaml
Normal file
40
apps/todo/halkyon_todo_flutter/analysis_options.yaml
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# This file configures the analyzer, which statically analyzes Dart code to
|
||||||
|
# check for errors, warnings, and lints.
|
||||||
|
#
|
||||||
|
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||||
|
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||||
|
# invoked from the command line by running `flutter analyze`.
|
||||||
|
|
||||||
|
# The following line activates a set of recommended lints for Flutter apps,
|
||||||
|
# packages, and plugins designed to encourage good coding practices.
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
# The lint rules applied to this project can be customized in the
|
||||||
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
# and their documentation is published at
|
||||||
|
# https://dart-lang.github.io/linter/lints/index.html.
|
||||||
|
#
|
||||||
|
# Instead of disabling a lint rule for the entire project in the
|
||||||
|
# section below, it can also be suppressed for a single line of code
|
||||||
|
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||||
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
|
# producing the lint.
|
||||||
|
rules:
|
||||||
|
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||||
|
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
|
|
||||||
|
formatter:
|
||||||
|
trailing_commas: preserve
|
||||||
|
analyzer:
|
||||||
|
exclude:
|
||||||
|
- build/**
|
||||||
|
- android/**
|
||||||
|
- ios/**
|
||||||
|
- web/**
|
||||||
|
- windows/**
|
||||||
|
- macos/**
|
||||||
|
- linux/**
|
||||||
14
apps/todo/halkyon_todo_flutter/android/.gitignore
vendored
Normal file
14
apps/todo/halkyon_todo_flutter/android/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
gradle-wrapper.jar
|
||||||
|
/.gradle
|
||||||
|
/captures/
|
||||||
|
/gradlew
|
||||||
|
/gradlew.bat
|
||||||
|
/local.properties
|
||||||
|
GeneratedPluginRegistrant.java
|
||||||
|
.cxx/
|
||||||
|
|
||||||
|
# Remember to never publicly share your keystore.
|
||||||
|
# See https://flutter.dev/to/reference-keystore
|
||||||
|
key.properties
|
||||||
|
**/*.keystore
|
||||||
|
**/*.jks
|
||||||
49
apps/todo/halkyon_todo_flutter/android/app/build.gradle.kts
Normal file
49
apps/todo/halkyon_todo_flutter/android/app/build.gradle.kts
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
|
id("dev.flutter.flutter-gradle-plugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.example.halkyon_todo_flutter"
|
||||||
|
compileSdk = flutter.compileSdkVersion
|
||||||
|
ndkVersion = flutter.ndkVersion
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
|
applicationId = "com.example.halkyon_todo_flutter"
|
||||||
|
// You can update the following values to match your application needs.
|
||||||
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
|
minSdk = flutter.minSdkVersion
|
||||||
|
targetSdk = flutter.targetSdkVersion
|
||||||
|
// Uses the version code from pubspec.yaml. When using split APKs, 1000 * ABI_VERSION
|
||||||
|
// is added automatically by Flutter. (https://developer.android.com/studio/build/configure-apk-splits#configure-APK-versions)
|
||||||
|
// You can force using the value of versionCode by specifying the `-P force-version-code-ignoring-abi=true`
|
||||||
|
// flag during build.
|
||||||
|
versionCode = flutter.versionCode
|
||||||
|
versionName = flutter.versionName
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// TODO: Add your own signing config for the release build.
|
||||||
|
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||||
|
signingConfig = signingConfigs.getByName("debug")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
compilerOptions {
|
||||||
|
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flutter {
|
||||||
|
source = "../.."
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue