From 21d70cc6af677b3930c881eb74f03d011949100e Mon Sep 17 00:00:00 2001 From: camka14 Date: Tue, 14 Jan 2025 13:20:18 -0800 Subject: [PATCH 01/29] Initial twig translation of KMP SDK --- src/SDK/Language/KMP.php | 588 ++++++++++++++++++ templates/kmp/.github/workflows/autoclose.yml | 11 + templates/kmp/.github/workflows/publish.yml | 52 ++ templates/kmp/.gitignore | 10 + templates/kmp/CHANGELOG.md.twig | 1 + templates/kmp/LICENSE.md.twig | 1 + templates/kmp/README.md.twig | 76 +++ templates/kmp/androidApp/build.gradle.kts | 47 ++ .../androidApp/src/main/AndroidManifest.xml | 38 ++ .../io/package/android/MainActivity.kt.twig | 23 + .../android/services/MessagingService.kt.twig | 37 ++ .../ui/accounts/AccountsFragment.kt.twig | 85 +++ .../ui/accounts/AccountsViewModel.kt.twig | 116 ++++ .../io/package/android/utils/Client.kt.twig | 15 + .../io/package/android/utils/Event.kt.twig | 27 + .../res/drawable/ic_launcher_background.xml | 170 +++++ .../res/drawable/ic_launcher_foreground.xml | 30 + .../src/main/res/layout/activity_main.xml | 15 + .../src/main/res/layout/fragment_account.xml | 125 ++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../androidApp/src/main/res/values/colors.xml | 10 + .../src/main/res/values/strings.xml | 3 + .../androidApp/src/main/res/values/themes.xml | 16 + templates/kmp/build.gradle.twig | 9 + templates/kmp/gradle.properties | 12 + templates/kmp/gradle/libs.versions.toml | 72 +++ .../kmp/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + templates/kmp/gradlew | 185 ++++++ templates/kmp/gradlew.bat | 89 +++ templates/kmp/settings.gradle.kts | 22 + templates/kmp/shared/build.gradle.twig | 212 +++++++ .../io/package/AllCertsTrustManager.kt.twig | 18 + .../kotlin/io/package/Client.android.kt.twig | 48 ++ .../io/package/HttpClientConfig.kt.twig | 64 ++ .../io/package/KeepAliveService.kt.twig | 13 + .../package/WebAuthComponent.android.kt.twig | 113 ++++ .../cookies/AndroidCookieStorage.kt.twig | 57 ++ .../io/package/cookies/Extensions.kt.twig | 40 ++ .../io/package/cookies/InternalCookie.kt.twig | 49 ++ .../extensions/createOAuth2Session.kt.twig | 16 + .../extensions/createOAuth2Token.kt.twig | 17 + .../FileOperations.android.kt.twig | 23 + .../package/models/InputFile.android.kt.twig | 7 + .../io/package/views/CallbackActivity.kt.twig | 20 + .../webInterface/AndroidParsedUrl.kt.twig | 7 + .../webInterface/UrlParser.android.kt.twig | 11 + .../kotlin/io/package/BaseClient.kt.twig | 349 +++++++++++ .../kotlin/io/package/Client.kt.twig | 8 + .../commonMain/kotlin/io/package/ID.kt.twig | 34 + .../kotlin/io/package/Permission.kt.twig | 62 ++ .../kotlin/io/package/Query.kt.twig | 242 +++++++ .../commonMain/kotlin/io/package/Role.kt.twig | 72 +++ .../kotlin/io/package/Service.kt.twig | 8 + .../io/package/WebAuthComponent.kt.twig | 16 + .../io/package/coroutines/Callback.kt.twig | 19 + .../kotlin/io/package/enums/Enum.kt.twig | 16 + .../io/package/exceptions/Exception.kt.twig | 11 + .../extensions/CollectionExtensions.kt.twig | 13 + .../package/extensions/JsonExtensions.kt.twig | 66 ++ .../package/extensions/TypeExtensions.kt.twig | 9 + .../fileOperations/FileOperations.kt.twig | 5 + .../kotlin/io/package/models/Document.kt.twig | 75 +++ .../io/package/models/InputFile.kt.twig | 34 + .../kotlin/io/package/models/Model.kt.twig | 28 + .../io/package/models/RealtimeModels.kt.twig | 44 ++ .../io/package/models/UploadProgress.kt.twig | 9 + .../serializers/DocumentSerializer.kt.twig | 85 +++ .../DynamicLookupSerializer.kt.twig | 89 +++ .../StringCollectionSeriailizer.kt.twig | 26 + .../io/package/services/Realtime.kt.twig | 216 +++++++ .../io/package/services/Service.kt.twig | 246 ++++++++ .../io/package/webInterface/ParsedUrl.kt.twig | 5 + .../io/package/webInterface/UrlParser.kt.twig | 7 + .../kotlin/io/package/Client.ios.kt.twig | 45 ++ .../io/package/HttpClientConfig.ios.kt.twig | 61 ++ .../io/package/WebAuthComponent.ios.kt.twig | 47 ++ .../package/cookies/IosCookieStorage.kt.twig | 260 ++++++++ .../extensions/createOAuth2Session.kt.twig | 14 + .../extensions/createOAuth2Token.kt.twig | 14 + .../fileOperations/FileOperations.ios.kt.twig | 55 ++ .../io/package/models/InputFile.ios.kt.twig | 7 + .../package/webInterface/IosParsedUrl.kt.twig | 7 + .../webInterface/UrlParser.ios.kt.twig | 27 + .../io/package/AllCertsTrustManager.kt.twig | 21 + .../kotlin/io/package/Client.jvm.kt.twig | 47 ++ .../kotlin/io/package/HttpClient.kt.twig | 64 ++ .../io/package/WebAuthComponent.jvm.kt.twig | 94 +++ .../extensions/createOAuth2Session.kt.twig | 14 + .../extensions/createOAuth2Token.kt.twig | 14 + .../fileOperations/FileOperations.jvm.kt.twig | 23 + .../io/package/models/InputFile.jvm.kt.twig | 7 + .../package/webInterface/JvmParsedUrl.kt.twig | 7 + .../webInterface/UrlParser.jvm.kt.twig | 19 + tests/languages/kmp/Tests.kt | 222 +++++++ 96 files changed, 5479 insertions(+) create mode 100644 src/SDK/Language/KMP.php create mode 100644 templates/kmp/.github/workflows/autoclose.yml create mode 100644 templates/kmp/.github/workflows/publish.yml create mode 100644 templates/kmp/.gitignore create mode 100644 templates/kmp/CHANGELOG.md.twig create mode 100644 templates/kmp/LICENSE.md.twig create mode 100644 templates/kmp/README.md.twig create mode 100644 templates/kmp/androidApp/build.gradle.kts create mode 100644 templates/kmp/androidApp/src/main/AndroidManifest.xml create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/MainActivity.kt.twig create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/services/MessagingService.kt.twig create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsFragment.kt.twig create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsViewModel.kt.twig create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/utils/Client.kt.twig create mode 100644 templates/kmp/androidApp/src/main/java/io/package/android/utils/Event.kt.twig create mode 100644 templates/kmp/androidApp/src/main/res/drawable/ic_launcher_background.xml create mode 100644 templates/kmp/androidApp/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 templates/kmp/androidApp/src/main/res/layout/activity_main.xml create mode 100644 templates/kmp/androidApp/src/main/res/layout/fragment_account.xml create mode 100644 templates/kmp/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 templates/kmp/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 templates/kmp/androidApp/src/main/res/values/colors.xml create mode 100644 templates/kmp/androidApp/src/main/res/values/strings.xml create mode 100644 templates/kmp/androidApp/src/main/res/values/themes.xml create mode 100644 templates/kmp/build.gradle.twig create mode 100644 templates/kmp/gradle.properties create mode 100644 templates/kmp/gradle/libs.versions.toml create mode 100644 templates/kmp/gradle/wrapper/gradle-wrapper.jar create mode 100644 templates/kmp/gradle/wrapper/gradle-wrapper.properties create mode 100644 templates/kmp/gradlew create mode 100644 templates/kmp/gradlew.bat create mode 100644 templates/kmp/settings.gradle.kts create mode 100644 templates/kmp/shared/build.gradle.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/AllCertsTrustManager.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/Client.android.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/HttpClientConfig.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/KeepAliveService.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/WebAuthComponent.android.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/cookies/AndroidCookieStorage.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/cookies/Extensions.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/cookies/InternalCookie.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/fileOperations/FileOperations.android.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/models/InputFile.android.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/views/CallbackActivity.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/webInterface/AndroidParsedUrl.kt.twig create mode 100644 templates/kmp/shared/src/androidMain/kotlin/io/package/webInterface/UrlParser.android.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/BaseClient.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/Client.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/ID.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/Permission.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/Query.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/Role.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/Service.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/WebAuthComponent.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/coroutines/Callback.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/enums/Enum.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/exceptions/Exception.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/extensions/CollectionExtensions.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/extensions/JsonExtensions.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/extensions/TypeExtensions.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/fileOperations/FileOperations.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/models/Document.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/models/InputFile.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/models/Model.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/models/RealtimeModels.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/models/UploadProgress.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/serializers/DocumentSerializer.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/serializers/DynamicLookupSerializer.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/serializers/StringCollectionSeriailizer.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/services/Realtime.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/services/Service.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/webInterface/ParsedUrl.kt.twig create mode 100644 templates/kmp/shared/src/commonMain/kotlin/io/package/webInterface/UrlParser.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/Client.ios.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/HttpClientConfig.ios.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/WebAuthComponent.ios.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/cookies/IosCookieStorage.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/fileOperations/FileOperations.ios.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/models/InputFile.ios.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/webInterface/IosParsedUrl.kt.twig create mode 100644 templates/kmp/shared/src/iosMain/kotlin/io/package/webInterface/UrlParser.ios.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/AllCertsTrustManager.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/Client.jvm.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/HttpClient.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/WebAuthComponent.jvm.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/fileOperations/FileOperations.jvm.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/models/InputFile.jvm.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/webInterface/JvmParsedUrl.kt.twig create mode 100644 templates/kmp/shared/src/jvmMain/kotlin/io/package/webInterface/UrlParser.jvm.kt.twig create mode 100644 tests/languages/kmp/Tests.kt diff --git a/src/SDK/Language/KMP.php b/src/SDK/Language/KMP.php new file mode 100644 index 000000000..803547c19 --- /dev/null +++ b/src/SDK/Language/KMP.php @@ -0,0 +1,588 @@ + 'copy', + 'destination' => '.github/workflows/publish.yml', + 'template' => '/kmp/.github/workflows/publish.yml', + ], +// [ +// 'scope' => 'method', +// 'destination' => 'docs/examples/kotlin/{{service.name | caseLower}}/{{method.name | caseDash}}.md', +// 'template' => '/kmp/docs/kotlin/example.md.twig', +// ], +// [ +// 'scope' => 'method', +// 'destination' => 'docs/examples/java/{{service.name | caseLower}}/{{method.name | caseDash}}.md', +// 'template' => '/kmp/docs/java/example.md.twig', +// ], + + // Gradle files + [ + 'scope' => 'copy', + 'destination' => 'gradle/wrapper/gradle-wrapper.jar', + 'template' => '/kmp/gradle/wrapper/gradle-wrapper.jar', + ], + [ + 'scope' => 'copy', + 'destination' => 'gradle/wrapper/gradle-wrapper.properties', + 'template' => '/kmp/gradle/wrapper/gradle-wrapper.properties', + ], + [ + 'scope' => 'copy', + 'destination' => 'gradle/libs.versions.toml', + 'template' => '/kmp/gradle/libs.versions.toml', + ], + + // Root files + [ + 'scope' => 'copy', + 'destination' => '.gitignore', + 'template' => '/kmp/.gitignore', + ], + [ + 'scope' => 'default', + 'destination' => 'build.gradle', + 'template' => '/kmp/build.gradle.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'settings.gradle.kts', + 'template' => '/kmp/settings.gradle.kts', + ], + [ + 'scope' => 'default', + 'destination' => 'CHANGELOG.md', + 'template' => '/kmp/CHANGELOG.md.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'README.md', + 'template' => '/kmp/README.md.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'LICENSE.md', + 'template' => '/kmp/LICENSE.md.twig', + ], + + // Shared module + [ + 'scope' => 'default', + 'destination' => 'shared/build.gradle', + 'template' => '/kmp/shared/build.gradle.twig', + ], + + // Common Main + // Common Main root files + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/BaseClient.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/BaseClient.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/Client.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/Client.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/ID.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/ID.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/Permission.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/Permission.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/Query.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/Query.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/Role.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/Role.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/Service.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/Service.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/WebAuthComponent.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/WebAuthComponent.kt.twig', + ], + + // Coroutines + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/coroutines/Callback.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/coroutines/Callback.kt.twig', + ], + + // Enums + [ + 'scope' => 'enum', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/enums/{{ enum.name | caseUcfirst }}.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/enums/Enum.kt.twig', + ], + + // Exceptions + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/exceptions/Exception.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/exceptions/Exception.kt.twig', + ], + + // Extensions + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/CollectionExtensions.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/extensions/CollectionExtensions.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/JsonExtensions.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/extensions/JsonExtensions.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/TypeExtensions.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/extensions/TypeExtensions.kt.twig', + ], + + // File Operations + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/fileOperations/FileOperations.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/fileOperations/FileOperations.kt.twig', + ], + + // Models + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/Document.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/Document.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/InputFile.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/InputFile.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/Model.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/Model.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/RealtimeModels.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/RealtimeModels.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/UploadProgress.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/UploadProgress.kt.twig', + ], + + // Serializers + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/serializers/DocumentSerializer.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/serializers/DocumentSerializer.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/serializers/DynamicLookupSerializer.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/serializers/DynamicLookupSerializer.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/serializers/StringCollectionSeriailizer.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/serializers/StringCollectionSeriailizer.kt.twig', + ], + + // Services + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/services/Realtime.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/services/Realtime.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/services/Service.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/services/Service.kt.twig', + ], + + // Web Interface + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/ParsedUrl.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/webInterface/ParsedUrl.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/UrlParser.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/webInterface/UrlParser.kt.twig', + ], + + + // Android Main + // Android Main root files + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/AllCertsTrustManager.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/AllCertsTrustManager.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/Client.android.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/Client.android.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/HttpClientConfig.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/HttpClientConfig.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/KeepAliveService.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/KeepAliveService.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/WebAuthComponent.android.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/WebAuthComponent.android.kt.twig', + ], + + // Cookies + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/AndroidCookieStorage.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/cookies/AndroidCookieStorage.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/Extensions.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/cookies/Extensions.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/InternalCookie.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/cookies/InternalCookie.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/stores/InMemoryCookieStore.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/cookies/stores/InMemoryCookieStore.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/stores/SharedPreferencesCookieStore.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/cookies/stores/SharedPreferencesCookieStore.kt.twig', + ], + + // Extensions + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Session.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Token.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig', + ], + + // File Operations + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/fileOperations/FileOperations.android.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/fileOperations/FileOperations.android.kt.twig', + ], + + // Models + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/models/InputFile.android.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/models/InputFile.android.kt.twig', + ], + + // Views + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/views/CallbackActivity.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/views/CallbackActivity.kt.twig', + ], + + // Web Interface + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/AndroidParsedUrl.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/webInterface/AndroidParsedUrl.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/androidMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/UrlParser.android.kt', + 'template' => '/kmp/shared/src/androidMain/kotlin/io/package/webInterface/UrlParser.android.kt.twig', + ], + + // iOS Main + // iOS Main root files + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/Client.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/Client.ios.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/HttpClientConfig.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/HttpClientConfig.ios.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/WebAuthComponent.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/WebAuthComponent.ios.kt.twig', + ], + + // Cookies + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/cookies/IosCookieStorage.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/cookies/IosCookieStorage.kt.twig', + ], + + // Extensions + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Session.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Token.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig', + ], + + // File Operations + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/fileOperations/FileOperations.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/fileOperations/FileOperations.ios.kt.twig', + ], + + // Models + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/models/InputFile.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/models/InputFile.ios.kt.twig', + ], + + // Web Interface + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/IosParsedUrl.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/webInterface/IosParsedUrl.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/iosMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/UrlParser.ios.kt', + 'template' => '/kmp/shared/src/iosMain/kotlin/io/package/webInterface/UrlParser.ios.kt.twig', + ], + + + // JVM Main + // JVM Main root files + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/AllCertsTrustManager.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/AllCertsTrustManager.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/Client.jvm.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/Client.jvm.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/HttpClient.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/HttpClient.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/WebAuthComponent.jvm.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/WebAuthComponent.jvm.kt.twig', + ], + + // Extensions + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Session.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/extensions/createOAuth2Session.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/extensions/createOAuth2Token.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/extensions/createOAuth2Token.kt.twig', + ], + + // File Operations + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/fileOperations/FileOperations.jvm.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/fileOperations/FileOperations.jvm.kt.twig', + ], + + // Models + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/models/InputFile.jvm.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/models/InputFile.jvm.kt.twig', + ], + + // Web Interface + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/JvmParsedUrl.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/webInterface/JvmParsedUrl.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'shared/src/jvmMain/kotlin/{{ sdk.namespace | caseSlash }}/webInterface/UrlParser.jvm.kt', + 'template' => '/kmp/shared/src/jvmMain/kotlin/io/package/webInterface/UrlParser.jvm.kt.twig', + ], + + + // Android App + // Android App root files + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/AndroidManifest.xml', + 'template' => '/kmp/androidApp/src/main/AndroidManifest.xml', + ], + +// Java files + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/MainActivity.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/MainActivity.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/services/MessagingService.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/services/MessagingService.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/ui/accounts/AccountsFragment.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsFragment.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/ui/accounts/AccountsViewModel.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsViewModel.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/utils/Client.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/utils/Client.kt.twig', + ], + [ + 'scope' => 'default', + 'destination' => 'androidApp/src/main/java/{{ sdk.namespace | caseSlash }}/android/utils/Event.kt', + 'template' => '/kmp/androidApp/src/main/java/io/package/android/utils/Event.kt.twig', + ], + +// Resource files + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/drawable/ic_launcher_background.xml', + 'template' => '/kmp/androidApp/src/main/res/drawable/ic_launcher_background.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/drawable/ic_launcher_foreground.xml', + 'template' => '/kmp/androidApp/src/main/res/drawable/ic_launcher_foreground.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/layout/activity_main.xml', + 'template' => '/kmp/androidApp/src/main/res/layout/activity_main.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/layout/fragment_account.xml', + 'template' => '/kmp/androidApp/src/main/res/layout/fragment_account.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml', + 'template' => '/kmp/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml', + 'template' => '/kmp/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/values/colors.xml', + 'template' => '/kmp/androidApp/src/main/res/values/colors.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/values/strings.xml', + 'template' => '/kmp/androidApp/src/main/res/values/strings.xml', + ], + [ + 'scope' => 'copy', + 'destination' => 'androidApp/src/main/res/values/themes.xml', + 'template' => '/kmp/androidApp/src/main/res/values/themes.xml', + ], + + + // Models, Services, and other common components + [ + 'scope' => 'service', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/services/{{service.name | caseUcfirst}}.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/services/Service.kt.twig', + ], + [ + 'scope' => 'definition', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/models/{{ definition.name | caseUcfirst }}.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/models/Model.kt.twig', + ], + [ + 'scope' => 'enum', + 'destination' => 'shared/src/commonMain/kotlin/{{ sdk.namespace | caseSlash }}/enums/{{ enum.name | caseUcfirst }}.kt', + 'template' => '/kmp/shared/src/commonMain/kotlin/io/package/enums/Enum.kt.twig', + ], + ]; + } +} diff --git a/templates/kmp/.github/workflows/autoclose.yml b/templates/kmp/.github/workflows/autoclose.yml new file mode 100644 index 000000000..4f2a8eedb --- /dev/null +++ b/templates/kmp/.github/workflows/autoclose.yml @@ -0,0 +1,11 @@ +name: Auto-close External Pull Requests + +on: + pull_request_target: + types: [opened, reopened] + +jobs: + auto_close: + uses: appwrite/.github/.github/workflows/autoclose.yml@main + secrets: + GH_AUTO_CLOSE_PR_TOKEN: ${{ secrets.GH_AUTO_CLOSE_PR_TOKEN }} \ No newline at end of file diff --git a/templates/kmp/.github/workflows/publish.yml b/templates/kmp/.github/workflows/publish.yml new file mode 100644 index 000000000..de6a6b8d3 --- /dev/null +++ b/templates/kmp/.github/workflows/publish.yml @@ -0,0 +1,52 @@ +name: Publish to Maven Central + +on: + release: + types: [released] + +jobs: + publish: + name: Release build and publish + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: 17 + distribution: 'temurin' + + - name: Prepare environment + env: + GPG_KEY_CONTENTS: ${{ secrets.GPG_KEY_CONTENTS }} + SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} + run: | + git fetch --unshallow + sudo bash -c "echo '$GPG_KEY_CONTENTS' | base64 -d > '$SIGNING_SECRET_KEY_RING_FILE'" + chmod +x ./gradlew + + - name: Build Release Artifacts + run: ./gradlew assemble + + - name: Generate Documentation + run: ./gradlew dokkaHtml + + - name: Publish to Maven Central + run: | + if ${{ contains(github.event.release.tag_name, '-rc') }}; then + echo "Publishing Snapshot Version ${{ github.event.release.tag_name}}" + ./gradlew publishAllPublicationsToSonatypeRepository + else + echo "Publishing Release Version ${{ github.event.release.tag_name}}" + ./gradlew publishAllPublicationsToSonatypeRepository closeAndReleaseSonatypeStagingRepository + fi + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} + SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} + SDK_VERSION: ${{ github.event.release.tag_name }} diff --git a/templates/kmp/.gitignore b/templates/kmp/.gitignore new file mode 100644 index 000000000..e510fa99d --- /dev/null +++ b/templates/kmp/.gitignore @@ -0,0 +1,10 @@ +*.iml +.gradle +.idea +.DS_Store +build +captures +.externalNativeBuild +.cxx +local.properties +xcuserdata \ No newline at end of file diff --git a/templates/kmp/CHANGELOG.md.twig b/templates/kmp/CHANGELOG.md.twig new file mode 100644 index 000000000..a544d26c9 --- /dev/null +++ b/templates/kmp/CHANGELOG.md.twig @@ -0,0 +1 @@ +{{sdk.changelog}} \ No newline at end of file diff --git a/templates/kmp/LICENSE.md.twig b/templates/kmp/LICENSE.md.twig new file mode 100644 index 000000000..854eb1949 --- /dev/null +++ b/templates/kmp/LICENSE.md.twig @@ -0,0 +1 @@ +{{sdk.licenseContent | raw}} \ No newline at end of file diff --git a/templates/kmp/README.md.twig b/templates/kmp/README.md.twig new file mode 100644 index 000000000..c8db25a40 --- /dev/null +++ b/templates/kmp/README.md.twig @@ -0,0 +1,76 @@ +# {{ spec.title }} {{sdk.name}} SDK + +![Maven Central](https://img.shields.io/maven-central/v/{{ sdk.namespace | caseDot }}/{{ sdk.gitRepoName | caseDash }}.svg?color=green&style=flat-square) +![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square) +![Version](https://img.shields.io/badge/api%20version-{{ spec.version|url_encode }}-blue.svg?style=flat-square) +[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator) +{% if sdk.twitterHandle %} +[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }}) +{% endif %} +{% if sdk.discordChannel %} +[![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }}) +{% endif %} +{% if sdk.warning %} + +{{ sdk.warning|raw }} +{% endif %} + +{{ sdk.description }} + +{% if sdk.logo %} +![{{ spec.title }}]({{ sdk.logo }}) +{% endif %} + +## Installation + +### Gradle + +Appwrite's Android SDK is hosted on Maven Central. In order to fetch the Appwrite SDK, add this to your root level `build.gradle(.kts)` file: + +```groovy +repositories { + mavenCentral() +} +``` + +If you would like to fetch our SNAPSHOT releases, you need to add the SNAPSHOT maven repository to your `build.gradle(.kts)`: + +```groovy +repositories { + maven { + url "https://s01.oss.sonatype.org/content/repositories/snapshots/" + } +} +``` + +Next, add the dependency to your project's `build.gradle(.kts)` file: + +```groovy +implementation("{{ sdk.namespace | caseDot }}:{{ sdk.gitRepoName | caseDash }}:{{ sdk.version }}") +``` + +### Maven +Add this to your project's `pom.xml` file: + +```xml + + + {{ sdk.namespace | caseDot }} + {{ sdk.gitRepoName | caseDash }} + {{sdk.version}} + + +``` + +{% if sdk.gettingStarted %} + +{{ sdk.gettingStarted|raw }} +{% endif %} + +## Contribution + +This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request. + +## License + +Please see the [{{spec.licenseName}} license]({{spec.licenseURL}}) file for more information. \ No newline at end of file diff --git a/templates/kmp/androidApp/build.gradle.kts b/templates/kmp/androidApp/build.gradle.kts new file mode 100644 index 000000000..5d431cd5b --- /dev/null +++ b/templates/kmp/androidApp/build.gradle.kts @@ -0,0 +1,47 @@ +plugins { + alias(libs.plugins.androidApplication) + alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.kotlinx.serialization) +} + +android { + namespace = "io.appwrite.android" + compileSdk = 35 + defaultConfig { + applicationId = "io.appwrite.android" + minSdk = 21 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" + } + buildFeatures { + compose = true + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + buildTypes { + getByName("release") { + isMinifyEnabled = false + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } +} + +dependencies { + implementation(projects.shared) + implementation(libs.compose.ui) + implementation(libs.compose.ui.tooling.preview) + implementation(libs.compose.material3) + implementation(libs.androidx.activity.compose) + debugImplementation(libs.compose.ui.tooling) +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/AndroidManifest.xml b/templates/kmp/androidApp/src/main/AndroidManifest.xml new file mode 100644 index 000000000..3564397e7 --- /dev/null +++ b/templates/kmp/androidApp/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/MainActivity.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/MainActivity.kt.twig new file mode 100644 index 000000000..28f035640 --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/MainActivity.kt.twig @@ -0,0 +1,23 @@ +package {{ sdk.namespace | caseDot }}.android + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.fragment.app.add +import androidx.fragment.app.commit +import {{ sdk.namespace | caseDot }}.android.ui.accounts.AccountsFragment +import {{ sdk.namespace | caseDot }}.android.utils.Client + +class MainActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + Client.create(applicationContext) + + if (savedInstanceState == null) { + supportFragmentManager.commit { + setReorderingAllowed(true) + add(R.id.fragment_container_view) + } + } + } +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/services/MessagingService.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/services/MessagingService.kt.twig new file mode 100644 index 000000000..bf2a2fdd5 --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/services/MessagingService.kt.twig @@ -0,0 +1,37 @@ +package {{ sdk.namespace | caseDot }}.android.services + +import com.google.firebase.messaging.FirebaseMessagingService +import {{ sdk.namespace | caseDot }}.ID +import {{ sdk.namespace | caseDot }}.services.Account +import kotlinx.coroutines.runBlocking + +class MessagingService : FirebaseMessagingService() { + + companion object { + var account: Account? = null + } + + override fun onNewToken(token: String) { + super.onNewToken(token) + + val prefs = getSharedPreferences("example", MODE_PRIVATE) + + prefs.edit().putString("fcmToken", token).apply() + + if (account == null) { + return + } + + val targetId = prefs.getString("targetId", null) + + runBlocking { + if (targetId == null) { + val target = account!!.createPushTarget(ID.unique(), token) + + prefs.edit().putString("targetId", target.id).apply() + } else { + account!!.updatePushTarget(targetId, token) + } + } + } +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsFragment.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsFragment.kt.twig new file mode 100644 index 000000000..94905a61f --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsFragment.kt.twig @@ -0,0 +1,85 @@ +package {{ sdk.namespace | caseDot }}.android.ui.accounts + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.activity.ComponentActivity +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import {{ sdk.namespace | caseDot }}.android.R +import {{ sdk.namespace | caseDot }}.android.databinding.FragmentAccountBinding + + +class AccountsFragment : Fragment() { + + private lateinit var binding: FragmentAccountBinding + private val viewModel: AccountsViewModel by viewModels() + + override fun onCreateView( + inflater: LayoutInflater , + container: ViewGroup? , + savedInstanceState: Bundle? + ): View { + binding = DataBindingUtil.inflate( + inflater, + R.layout.fragment_account, + container, + false + ) + binding.lifecycleOwner = viewLifecycleOwner + + binding.login.setOnClickListener{ + viewModel.onLogin( + binding.email.text.toString(), + binding.password.text.toString(), + context + ?.getSharedPreferences("example", Context.MODE_PRIVATE) + ?.getString("fcmToken", null) ?: "" + ) + } + binding.signup.setOnClickListener{ + viewModel.onSignup( + binding.email.text.toString(), + binding.password.text.toString(), + binding.name.text.toString() + ) + } + binding.getUser.setOnClickListener{ + viewModel.getUser() + } + binding.oAuth.setOnClickListener{ + viewModel.oAuthLogin(activity as ComponentActivity) + } + binding.logout.setOnClickListener{ + viewModel.logout() + } + + viewModel.error.observe(viewLifecycleOwner) { event -> + event?.getContentIfNotHandled()?.let { + Toast.makeText(requireContext(), it.message, Toast.LENGTH_SHORT).show() + } + } + + viewModel.response.observe(viewLifecycleOwner) { event -> + event?.getContentIfNotHandled()?.let { + binding.responseTV.setText(it) + } + } + + viewModel.target.observe(viewLifecycleOwner) { event -> + event?.getContentIfNotHandled()?.let { + context + ?.getSharedPreferences("example", Context.MODE_PRIVATE) + ?.edit() + ?.putString("targetId", it.id) + ?.apply() + } + } + + return binding.root + } +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsViewModel.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsViewModel.kt.twig new file mode 100644 index 000000000..917e84456 --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/ui/accounts/AccountsViewModel.kt.twig @@ -0,0 +1,116 @@ +package {{ sdk.namespace | caseDot }}.android.ui.accounts + +import androidx.activity.ComponentActivity +import androidx.lifecycle.* +import {{ sdk.namespace | caseDot }}.ID +import {{ sdk.namespace | caseDot }}.android.services.MessagingService +import {{ sdk.namespace | caseDot }}.android.utils.Client.client +import {{ sdk.namespace | caseDot }}.android.utils.Event +import {{ sdk.namespace | caseDot }}.enums.OAuthProvider +import {{ sdk.namespace | caseDot }}.exceptions.{{ spec.title | caseUcfirst }}Exception +import {{ sdk.namespace | caseDot }}.extensions.toJson +import {{ sdk.namespace | caseDot }}.models.Target +import {{ sdk.namespace | caseDot }}.services.Account +import kotlinx.coroutines.launch + +class AccountsViewModel : ViewModel() { + + private val _error = MutableLiveData>().apply { value = null } + val error: LiveData> = _error + + private val _response = MutableLiveData>().apply { value = null } + val response: LiveData> = _response + + private val _target = MutableLiveData>().apply { value = null } + val target: LiveData> = _target + + private val account by lazy { + val account = Account(client) + + MessagingService.account = account + + account + } + + fun onLogin( + email: String, + password: String, + token: String?, + ) { + viewModelScope.launch { + try { + val session = account.createEmailPasswordSession( + email, + password + ) + + if (token != null) { + val target = account.createPushTarget(ID.unique(), token) + + _target.postValue(Event(target)) + } + + _response.postValue(Event(session.toJson())) + } catch (e: AppwriteException) { + _error.postValue(Event(e)) + } + } + + } + + fun onSignup(email: String, password: String, name: String) { + viewModelScope.launch { + try { + val user = account.create( + ID.unique(), + email, + password, + name + ) + _response.postValue(Event(user.toJson())) + } catch (e: AppwriteException) { + _error.postValue(Event(e)) + } + } + + } + + fun oAuthLogin(activity: ComponentActivity) { + viewModelScope.launch { + try { + account.createOAuth2Session( + activity, + OAuthProvider.FACEBOOK, + "appwrite-callback-6070749e6acd4://demo.appwrite.io/auth/oauth2/success", + "appwrite-callback-6070749e6acd4://demo.appwrite.io/auth/oauth2/failure" + ) + } catch (e: Exception) { + _error.postValue(Event(e)) + } catch (e: AppwriteException) { + _error.postValue(Event(e)) + } + } + } + + fun getUser() { + viewModelScope.launch { + try { + val user = account.get() + _response.postValue(Event(user.toJson())) + } catch (e: AppwriteException) { + _error.postValue(Event(e)) + } + } + } + + fun logout() { + viewModelScope.launch { + try { + val result = account.deleteSession("current") + _response.postValue(Event(result.toJson())) + } catch (e: AppwriteException) { + _error.postValue(Event(e)) + } + } + } +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/utils/Client.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/utils/Client.kt.twig new file mode 100644 index 000000000..f66e24507 --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/utils/Client.kt.twig @@ -0,0 +1,15 @@ +package {{ sdk.namespace | caseDot }}.android.utils + +import android.content.Context +import io.appwrite.Client + +object Client { + lateinit var client : Client + + fun create(context: Context) { + client = Client(context) + .setEndpoint("http://192.168.4.24/v1") + .setProject("65a8e2b4632c04b1f5da") + .setSelfSigned(true) + } +} \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/java/io/package/android/utils/Event.kt.twig b/templates/kmp/androidApp/src/main/java/io/package/android/utils/Event.kt.twig new file mode 100644 index 000000000..a43a58886 --- /dev/null +++ b/templates/kmp/androidApp/src/main/java/io/package/android/utils/Event.kt.twig @@ -0,0 +1,27 @@ +package {{ sdk.namespace | caseDot }}.android.utils + +/** + * Used as a wrapper for data that is exposed via a LiveData that represents an event. + */ +open class Event(private val content: T) { + + var hasBeenHandled = false + private set // Allow external read but not write + + /** + * Returns the content and prevents its use again. + */ + fun getContentIfNotHandled(): T? { + return if (hasBeenHandled) { + null + } else { + hasBeenHandled = true + content + } + } + + /** + * Returns the content, even if it's already been handled. + */ + fun peekContent(): T = content +} diff --git a/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_background.xml b/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 000000000..07d5da9cb --- /dev/null +++ b/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_foreground.xml b/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 000000000..2b068d114 --- /dev/null +++ b/templates/kmp/androidApp/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/res/layout/activity_main.xml b/templates/kmp/androidApp/src/main/res/layout/activity_main.xml new file mode 100644 index 000000000..7aa7dd7f4 --- /dev/null +++ b/templates/kmp/androidApp/src/main/res/layout/activity_main.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/templates/kmp/androidApp/src/main/res/layout/fragment_account.xml b/templates/kmp/androidApp/src/main/res/layout/fragment_account.xml new file mode 100644 index 000000000..4173be134 --- /dev/null +++ b/templates/kmp/androidApp/src/main/res/layout/fragment_account.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + +