Browse Source

nextcloud: Implement notifications API and add push proxy integration tests

pull/19/head
jld3103 3 years ago
parent
commit
978f483f02
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 3
      .gitmodules
  2. 1
      .idea/vcs.xml
  3. 1
      external/nextcloud-notifications
  4. 16
      packages/nextcloud/doc/notifications/AdminNotification.md
  5. 318
      packages/nextcloud/doc/notifications/DefaultApi.md
  6. 15
      packages/nextcloud/doc/notifications/EmptyResponse.md
  7. 16
      packages/nextcloud/doc/notifications/EmptyResponseOcs.md
  8. 15
      packages/nextcloud/doc/notifications/GetNotificationResponse.md
  9. 16
      packages/nextcloud/doc/notifications/GetNotificationResponseOcs.md
  10. 15
      packages/nextcloud/doc/notifications/ListNotificationsResponse.md
  11. 16
      packages/nextcloud/doc/notifications/ListNotificationsResponseOcs.md
  12. 29
      packages/nextcloud/doc/notifications/Notification.md
  13. 19
      packages/nextcloud/doc/notifications/PushNotificationDecryptedSubject.md
  14. 17
      packages/nextcloud/doc/notifications/PushServerDevice.md
  15. 15
      packages/nextcloud/doc/notifications/PushServerRegistrationResponse.md
  16. 16
      packages/nextcloud/doc/notifications/PushServerRegistrationResponseOcs.md
  17. 17
      packages/nextcloud/doc/notifications/PushServerSubscription.md
  18. 5
      packages/nextcloud/lib/nextcloud.dart
  19. 9
      packages/nextcloud/lib/src/client.dart
  20. 16
      packages/nextcloud/lib/src/clients/custom/webdav/client.dart
  21. 1
      packages/nextcloud/lib/src/clients/custom/webdav/webdav.dart
  22. 39
      packages/nextcloud/lib/src/clients/generated/notifications/api.dart
  23. 364
      packages/nextcloud/lib/src/clients/generated/notifications/api/default_api.dart
  24. 329
      packages/nextcloud/lib/src/clients/generated/notifications/api_client.dart
  25. 139
      packages/nextcloud/lib/src/clients/generated/notifications/model/admin_notification.dart
  26. 124
      packages/nextcloud/lib/src/clients/generated/notifications/model/empty_response.dart
  27. 125
      packages/nextcloud/lib/src/clients/generated/notifications/model/empty_response_ocs.dart
  28. 124
      packages/nextcloud/lib/src/clients/generated/notifications/model/get_notification_response.dart
  29. 133
      packages/nextcloud/lib/src/clients/generated/notifications/model/get_notification_response_ocs.dart
  30. 124
      packages/nextcloud/lib/src/clients/generated/notifications/model/list_notifications_response.dart
  31. 125
      packages/nextcloud/lib/src/clients/generated/notifications/model/list_notifications_response_ocs.dart
  32. 316
      packages/nextcloud/lib/src/clients/generated/notifications/model/notification.dart
  33. 187
      packages/nextcloud/lib/src/clients/generated/notifications/model/push_notification_decrypted_subject.dart
  34. 158
      packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_device.dart
  35. 125
      packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_registration_response.dart
  36. 133
      packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_registration_response_ocs.dart
  37. 158
      packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_subscription.dart
  38. 98
      packages/nextcloud/lib/src/clients/notifications.dart
  39. 12
      packages/nextcloud/lib/src/http_client_response_extension.dart
  40. 5
      packages/nextcloud/pubspec.yaml
  41. 48
      packages/nextcloud/test/helper.dart
  42. 220
      packages/nextcloud/test/notifications_test.dart
  43. 12
      packages/nextcloud/test/webdav_test.dart
  44. 389
      specs/notifications.json
  45. 235
      specs/templates/notifications.json
  46. 2
      tool/generate-nextcloud.sh

3
.gitmodules vendored

@ -13,3 +13,6 @@
[submodule "external/nextcloud-notes"]
path = external/nextcloud-notes
url = https://github.com/nextcloud/notes
[submodule "external/nextcloud-notifications"]
path = external/nextcloud-notifications
url = https://github.com/nextcloud/notifications

1
.idea/vcs.xml

@ -4,6 +4,7 @@
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nextcloud-news" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nextcloud-notes" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nextcloud-notifications" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nextcloud-server" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/openapi-generator" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/seti-ui" vcs="Git" />

1
external/nextcloud-notifications vendored

@ -0,0 +1 @@
Subproject commit 62c670f2cf9674b95e2f7b94f7bf0cd3887f3418

16
packages/nextcloud/doc/notifications/AdminNotification.md

@ -0,0 +1,16 @@
# openapi.model.AdminNotification
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**shortMessage** | **String** | | [optional]
**longMessage** | **String** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

318
packages/nextcloud/doc/notifications/DefaultApi.md

@ -0,0 +1,318 @@
# openapi.api.DefaultApi
## Load the API package
```dart
import 'package:openapi/api.dart';
```
All URIs are relative to *https://localhost:8080/ocs/v1.php/apps/notifications*
Method | HTTP request | Description
------------- | ------------- | -------------
[**deleteAllNotifications**](DefaultApi.md#deleteallnotifications) | **DELETE** /api/v2/notifications |
[**deleteNotification**](DefaultApi.md#deletenotification) | **DELETE** /api/v2/notifications/{id} |
[**getNotification**](DefaultApi.md#getnotification) | **GET** /api/v2/notifications/{id} |
[**listNotifications**](DefaultApi.md#listnotifications) | **GET** /api/v2/notifications |
[**registerDevice**](DefaultApi.md#registerdevice) | **POST** /api/v2/push |
[**removeDevice**](DefaultApi.md#removedevice) | **DELETE** /api/v2/push |
[**sendAdminNotification**](DefaultApi.md#sendadminnotification) | **POST** /api/v2/admin_notifications/{userId} |
# **deleteAllNotifications**
> String deleteAllNotifications()
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
try {
final result = api_instance.deleteAllNotifications();
print(result);
} catch (e) {
print('Exception when calling DefaultApi->deleteAllNotifications: $e\n');
}
```
### Parameters
This endpoint does not need any parameter.
### Return type
**String**
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **deleteNotification**
> EmptyResponse deleteNotification(id)
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
final id = 56; // int |
try {
final result = api_instance.deleteNotification(id);
print(result);
} catch (e) {
print('Exception when calling DefaultApi->deleteNotification: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**id** | **int**| |
### Return type
[**EmptyResponse**](EmptyResponse.md)
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **getNotification**
> GetNotificationResponse getNotification(id)
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
final id = 56; // int |
try {
final result = api_instance.getNotification(id);
print(result);
} catch (e) {
print('Exception when calling DefaultApi->getNotification: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**id** | **int**| |
### Return type
[**GetNotificationResponse**](GetNotificationResponse.md)
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **listNotifications**
> String listNotifications()
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
try {
final result = api_instance.listNotifications();
print(result);
} catch (e) {
print('Exception when calling DefaultApi->listNotifications: $e\n');
}
```
### Parameters
This endpoint does not need any parameter.
### Return type
**String**
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **registerDevice**
> PushServerRegistrationResponse registerDevice(pushServerDevice)
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
final pushServerDevice = PushServerDevice(); // PushServerDevice |
try {
final result = api_instance.registerDevice(pushServerDevice);
print(result);
} catch (e) {
print('Exception when calling DefaultApi->registerDevice: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**pushServerDevice** | [**PushServerDevice**](PushServerDevice.md)| |
### Return type
[**PushServerRegistrationResponse**](PushServerRegistrationResponse.md)
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **removeDevice**
> String removeDevice()
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
try {
final result = api_instance.removeDevice();
print(result);
} catch (e) {
print('Exception when calling DefaultApi->removeDevice: $e\n');
}
```
### Parameters
This endpoint does not need any parameter.
### Return type
**String**
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **sendAdminNotification**
> EmptyResponse sendAdminNotification(userId, adminNotification)
### Example
```dart
import 'package:openapi/api.dart';
// TODO Configure HTTP basic authorization: basic_auth
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').username = 'YOUR_USERNAME'
//defaultApiClient.getAuthentication<HttpBasicAuth>('basic_auth').password = 'YOUR_PASSWORD';
final api_instance = DefaultApi();
final userId = userId_example; // String |
final adminNotification = AdminNotification(); // AdminNotification |
try {
final result = api_instance.sendAdminNotification(userId, adminNotification);
print(result);
} catch (e) {
print('Exception when calling DefaultApi->sendAdminNotification: $e\n');
}
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**userId** | **String**| |
**adminNotification** | [**AdminNotification**](AdminNotification.md)| |
### Return type
[**EmptyResponse**](EmptyResponse.md)
### Authorization
[basic_auth](../README.md#basic_auth)
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

15
packages/nextcloud/doc/notifications/EmptyResponse.md

@ -0,0 +1,15 @@
# openapi.model.EmptyResponse
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**ocs** | [**EmptyResponseOcs**](EmptyResponseOcs.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

16
packages/nextcloud/doc/notifications/EmptyResponseOcs.md

@ -0,0 +1,16 @@
# openapi.model.EmptyResponseOcs
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**meta** | [**Object**](.md) | Stub | [optional]
**data** | **List<String>** | | [optional] [default to const []]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

15
packages/nextcloud/doc/notifications/GetNotificationResponse.md

@ -0,0 +1,15 @@
# openapi.model.GetNotificationResponse
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**ocs** | [**GetNotificationResponseOcs**](GetNotificationResponseOcs.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

16
packages/nextcloud/doc/notifications/GetNotificationResponseOcs.md

@ -0,0 +1,16 @@
# openapi.model.GetNotificationResponseOcs
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**meta** | [**Object**](.md) | Stub | [optional]
**data** | [**Notification**](Notification.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

15
packages/nextcloud/doc/notifications/ListNotificationsResponse.md

@ -0,0 +1,15 @@
# openapi.model.ListNotificationsResponse
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**ocs** | [**ListNotificationsResponseOcs**](ListNotificationsResponseOcs.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

16
packages/nextcloud/doc/notifications/ListNotificationsResponseOcs.md

@ -0,0 +1,16 @@
# openapi.model.ListNotificationsResponseOcs
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**meta** | [**Object**](.md) | Stub | [optional]
**data** | [**List<Notification>**](Notification.md) | | [optional] [default to const []]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

29
packages/nextcloud/doc/notifications/Notification.md

@ -0,0 +1,29 @@
# openapi.model.Notification
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**notificationId** | **int** | | [optional]
**app** | **String** | | [optional]
**user** | **String** | | [optional]
**datetime** | **String** | | [optional]
**objectType** | **String** | | [optional]
**objectId** | **String** | | [optional]
**subject** | **String** | | [optional]
**message** | **String** | | [optional]
**link** | **String** | | [optional]
**subjectRich** | **String** | | [optional]
**subjectRichParameters** | **List<String>** | | [optional] [default to const []]
**messageRich** | **String** | | [optional]
**messageRichParameters** | **List<String>** | | [optional] [default to const []]
**icon** | **String** | | [optional]
**actions** | **List<String>** | | [optional] [default to const []]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

19
packages/nextcloud/doc/notifications/PushNotificationDecryptedSubject.md

@ -0,0 +1,19 @@
# openapi.model.PushNotificationDecryptedSubject
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**nid** | **int** | | [optional]
**app** | **String** | | [optional]
**subject** | **String** | | [optional]
**type** | **String** | | [optional]
**id** | **String** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

17
packages/nextcloud/doc/notifications/PushServerDevice.md

@ -0,0 +1,17 @@
# openapi.model.PushServerDevice
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**pushTokenHash** | **String** | | [optional]
**devicePublicKey** | **String** | | [optional]
**proxyServer** | **String** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

15
packages/nextcloud/doc/notifications/PushServerRegistrationResponse.md

@ -0,0 +1,15 @@
# openapi.model.PushServerRegistrationResponse
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**ocs** | [**PushServerRegistrationResponseOcs**](PushServerRegistrationResponseOcs.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

16
packages/nextcloud/doc/notifications/PushServerRegistrationResponseOcs.md

@ -0,0 +1,16 @@
# openapi.model.PushServerRegistrationResponseOcs
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**meta** | [**Object**](.md) | Stub | [optional]
**data** | [**PushServerSubscription**](PushServerSubscription.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

17
packages/nextcloud/doc/notifications/PushServerSubscription.md

@ -0,0 +1,17 @@
# openapi.model.PushServerSubscription
## Load the model package
```dart
import 'package:openapi/api.dart';
```
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**publicKey** | **String** | | [optional]
**deviceIdentifier** | **String** | | [optional]
**signature** | **String** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

5
packages/nextcloud/lib/nextcloud.dart

@ -1,5 +1,7 @@
library nextcloud;
export 'package:crypton/crypton.dart' show RSAKeypair, RSAPublicKey, RSAPrivateKey;
export 'src/app_type.dart';
export 'src/client.dart';
export 'src/clients/common/api.dart';
@ -11,12 +13,15 @@ export 'src/clients/generated/news/api.dart'
hide ApiClient, serializeAsync, deserializeAsync, DeserializationMessage, DefaultApi;
export 'src/clients/generated/notes/api.dart'
hide ApiClient, serializeAsync, deserializeAsync, DeserializationMessage, DefaultApi;
export 'src/clients/generated/notifications/api.dart'
hide ApiClient, serializeAsync, deserializeAsync, DeserializationMessage, DefaultApi;
export 'src/clients/generated/provisioning_api/api.dart'
hide ApiClient, serializeAsync, deserializeAsync, DeserializationMessage, DefaultApi;
export 'src/clients/generated/user_status/api.dart'
hide ApiClient, serializeAsync, deserializeAsync, DeserializationMessage, DefaultApi;
export 'src/clients/news.dart';
export 'src/clients/notes.dart';
export 'src/clients/notifications.dart';
export 'src/clients/provisioning_api.dart';
export 'src/clients/user_status.dart';
export 'src/clients/webdav.dart';

9
packages/nextcloud/lib/src/client.dart

@ -29,6 +29,11 @@ class NextcloudClient {
authentication,
_addCommonSettings,
);
_notifications = NextcloudNotificationsClient(
baseURL,
authentication,
_addCommonSettings,
);
_provisioningApi = NextcloudProvisioningApiClient(
baseURL,
authentication,
@ -103,6 +108,7 @@ class NextcloudClient {
late NextcloudCoreClient _core;
late NextcloudNewsClient _news;
late NextcloudNotesClient _notes;
late NextcloudNotificationsClient _notifications;
late NextcloudProvisioningApiClient _provisioningApi;
late NextcloudUserStatusClient _userStatus;
@ -118,6 +124,9 @@ class NextcloudClient {
/// Client for Nextcloud Notes app
NextcloudNotesClient get notes => _notes;
/// Client for Nextcloud Notifications API
NextcloudNotificationsClient get notifications => _notifications;
/// Client for Provisioning APIs
NextcloudProvisioningApiClient get provisioningApi => _provisioningApi;

16
packages/nextcloud/lib/src/clients/custom/webdav/client.dart

@ -30,12 +30,6 @@ class WebDavClient {
'http://sabredav.org/ns': 's', // mostly used in error responses
};
Future<Uint8List> _responseToBodyBytes(final HttpClientResponse response) async =>
Uint8List.fromList((await response.toList()).reduce((final value, final element) => [...value, ...element]));
Future<String> _responseToBodyString(final HttpClientResponse response) async =>
utf8.decode(await _responseToBodyBytes(response));
Future<HttpClientResponse> _send(
final String method,
final String url,
@ -66,7 +60,7 @@ class WebDavClient {
if (!expectedCodes.contains(response.statusCode)) {
throw ApiException(
response.statusCode,
await _responseToBodyString(response),
await response.body,
);
}
@ -233,7 +227,7 @@ class WebDavClient {
return treeFromWebDavXml(
basePath,
namespaces,
await _responseToBodyString(response),
await response.body,
)..removeAt(0);
}
@ -284,7 +278,7 @@ class WebDavClient {
return treeFromWebDavXml(
basePath,
namespaces,
await _responseToBodyString(response),
await response.body,
);
}
@ -306,7 +300,7 @@ class WebDavClient {
return fileFromWebDavXml(
basePath,
namespaces,
await _responseToBodyString(response),
await response.body,
);
}
@ -350,7 +344,7 @@ class WebDavClient {
[200, 207],
data: Stream.value(Uint8List.fromList(utf8.encode(builder.buildDocument().toString()))),
);
return checkUpdateFromWebDavXml(await _responseToBodyString(response));
return checkUpdateFromWebDavXml(await response.body);
}
/// Move a file from [sourcePath] to [destinationPath]

1
packages/nextcloud/lib/src/clients/custom/webdav/webdav.dart

@ -6,6 +6,7 @@ import 'dart:typed_data';
import 'package:intl/intl.dart';
import 'package:nextcloud/src/clients/common/api.dart';
import 'package:nextcloud/src/http_client_response_extension.dart';
import 'package:xml/xml.dart';
import 'package:xml/xml.dart' as xml;

39
packages/nextcloud/lib/src/clients/generated/notifications/api.dart

@ -0,0 +1,39 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
library openapi.api;
import 'package:nextcloud/src/clients/common/api.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:intl/intl.dart';
import 'package:meta/meta.dart';
part 'api_client.dart';
part 'api/default_api.dart';
part 'model/admin_notification.dart';
part 'model/empty_response.dart';
part 'model/empty_response_ocs.dart';
part 'model/get_notification_response.dart';
part 'model/get_notification_response_ocs.dart';
part 'model/list_notifications_response.dart';
part 'model/list_notifications_response_ocs.dart';
part 'model/notification.dart';
part 'model/push_notification_decrypted_subject.dart';
part 'model/push_server_device.dart';
part 'model/push_server_registration_response.dart';
part 'model/push_server_registration_response_ocs.dart';
part 'model/push_server_subscription.dart';

364
packages/nextcloud/lib/src/clients/generated/notifications/api/default_api.dart

@ -0,0 +1,364 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class DefaultApi extends ApiInstance<ApiClient> {
DefaultApi(ApiClient apiClient) : super(apiClient);
/// Performs an HTTP 'DELETE /api/v2/notifications' operation and returns the [Response].
Future<Response> deleteAllNotificationsWithHttpInfo() async {
// ignore: prefer_const_declarations
final path = r'/api/v2/notifications';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'DELETE',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
Future<String?> deleteAllNotifications() async {
final response = await deleteAllNotificationsWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'String',
) as String;
}
return null;
}
/// Performs an HTTP 'DELETE /api/v2/notifications/{id}' operation and returns the [Response].
/// Parameters:
///
/// * [int] id (required):
Future<Response> deleteNotificationWithHttpInfo(
int id,
) async {
// ignore: prefer_const_declarations
final path = r'/api/v2/notifications/{id}'.replaceAll('{id}', id.toString());
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'DELETE',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [int] id (required):
Future<EmptyResponse?> deleteNotification(
int id,
) async {
final response = await deleteNotificationWithHttpInfo(
id,
);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'EmptyResponse',
) as EmptyResponse;
}
return null;
}
/// Performs an HTTP 'GET /api/v2/notifications/{id}' operation and returns the [Response].
/// Parameters:
///
/// * [int] id (required):
Future<Response> getNotificationWithHttpInfo(
int id,
) async {
// ignore: prefer_const_declarations
final path = r'/api/v2/notifications/{id}'.replaceAll('{id}', id.toString());
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [int] id (required):
Future<GetNotificationResponse?> getNotification(
int id,
) async {
final response = await getNotificationWithHttpInfo(
id,
);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'GetNotificationResponse',
) as GetNotificationResponse;
}
return null;
}
/// Performs an HTTP 'GET /api/v2/notifications' operation and returns the [Response].
Future<Response> listNotificationsWithHttpInfo() async {
// ignore: prefer_const_declarations
final path = r'/api/v2/notifications';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
Future<String?> listNotifications() async {
final response = await listNotificationsWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'String',
) as String;
}
return null;
}
/// Performs an HTTP 'POST /api/v2/push' operation and returns the [Response].
/// Parameters:
///
/// * [PushServerDevice] pushServerDevice (required):
Future<Response> registerDeviceWithHttpInfo(
PushServerDevice pushServerDevice,
) async {
// ignore: prefer_const_declarations
final path = r'/api/v2/push';
// ignore: prefer_final_locals
Object? postBody = pushServerDevice;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>['application/json'];
return apiClient.invokeAPI(
path,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [PushServerDevice] pushServerDevice (required):
Future<PushServerRegistrationResponse?> registerDevice(
PushServerDevice pushServerDevice,
) async {
final response = await registerDeviceWithHttpInfo(
pushServerDevice,
);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'PushServerRegistrationResponse',
) as PushServerRegistrationResponse;
}
return null;
}
/// Performs an HTTP 'DELETE /api/v2/push' operation and returns the [Response].
Future<Response> removeDeviceWithHttpInfo() async {
// ignore: prefer_const_declarations
final path = r'/api/v2/push';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
path,
'DELETE',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
Future<String?> removeDevice() async {
final response = await removeDeviceWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'String',
) as String;
}
return null;
}
/// Performs an HTTP 'POST /api/v2/admin_notifications/{userId}' operation and returns the [Response].
/// Parameters:
///
/// * [String] userId (required):
///
/// * [AdminNotification] adminNotification (required):
Future<Response> sendAdminNotificationWithHttpInfo(
String userId,
AdminNotification adminNotification,
) async {
// ignore: prefer_const_declarations
final path = r'/api/v2/admin_notifications/{userId}'.replaceAll('{userId}', userId);
// ignore: prefer_final_locals
Object? postBody = adminNotification;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>['application/json'];
return apiClient.invokeAPI(
path,
'POST',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Parameters:
///
/// * [String] userId (required):
///
/// * [AdminNotification] adminNotification (required):
Future<EmptyResponse?> sendAdminNotification(
String userId,
AdminNotification adminNotification,
) async {
final response = await sendAdminNotificationWithHttpInfo(
userId,
adminNotification,
);
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
return await apiClient.deserializeAsync(
await decodeBodyBytes(response),
'EmptyResponse',
) as EmptyResponse;
}
return null;
}
}

329
packages/nextcloud/lib/src/clients/generated/notifications/api_client.dart

@ -0,0 +1,329 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class ApiClient extends BaseApiClient {
ApiClient({this.basePath = 'https://localhost:8080/ocs/v1.php/apps/notifications', this.authentication});
final String basePath;
var _client = Client();
/// Returns the current HTTP [Client] instance to use in this class.
///
/// The return value is guaranteed to never be null.
Client get client => _client;
/// Requests to use a new HTTP [Client] in this class.
set client(Client newClient) {
_client = newClient;
}
final _defaultHeaderMap = <String, String>{};
final Authentication? authentication;
void addDefaultHeader(String key, String value) {
_defaultHeaderMap[key] = value;
}
Map<String, String> get defaultHeaderMap => _defaultHeaderMap;
// We don't use a Map<String, String> for queryParams.
// If collectionFormat is 'multi', a key might appear multiple times.
Future<Response> invokeAPI(
String path,
String method,
List<QueryParam> queryParams,
Object? body,
Map<String, String> headerParams,
Map<String, String> formParams,
String? contentType,
) async {
_updateParamsForAuth(queryParams, headerParams);
headerParams.addAll(_defaultHeaderMap);
if (contentType != null) {
headerParams['Content-Type'] = contentType;
}
final urlEncodedQueryParams = queryParams.map((param) => '$param');
final queryString = urlEncodedQueryParams.isNotEmpty ? '?${urlEncodedQueryParams.join('&')}' : '';
final uri = Uri.parse('$basePath$path$queryString');
try {
// Special case for uploading a single file which isn't a 'multipart/form-data'.
if (body is MultipartFile &&
(contentType == null || !contentType.toLowerCase().startsWith('multipart/form-data'))) {
final request = StreamedRequest(method, uri);
request.headers.addAll(headerParams);
request.contentLength = body.length;
body.finalize().listen(
request.sink.add,
onDone: request.sink.close,
// ignore: avoid_types_on_closure_parameters
onError: (Object error, StackTrace trace) => request.sink.close(),
cancelOnError: true,
);
final response = await _client.send(request);
return Response.fromStream(response);
}
if (body is MultipartRequest) {
final request = MultipartRequest(method, uri);
request.fields.addAll(body.fields);
request.files.addAll(body.files);
request.headers.addAll(body.headers);
request.headers.addAll(headerParams);
final response = await _client.send(request);
return Response.fromStream(response);
}
final msgBody = contentType == 'application/x-www-form-urlencoded' ? formParams : await serializeAsync(body);
final nullableHeaderParams = headerParams.isEmpty ? null : headerParams;
switch (method) {
case 'POST':
return await _client.post(
uri,
headers: nullableHeaderParams,
body: msgBody,
);
case 'PUT':
return await _client.put(
uri,
headers: nullableHeaderParams,
body: msgBody,
);
case 'DELETE':
return await _client.delete(
uri,
headers: nullableHeaderParams,
body: msgBody,
);
case 'PATCH':
return await _client.patch(
uri,
headers: nullableHeaderParams,
body: msgBody,
);
case 'HEAD':
return await _client.head(
uri,
headers: nullableHeaderParams,
);
case 'GET':
return await _client.get(
uri,
headers: nullableHeaderParams,
);
}
} on SocketException catch (error, trace) {
throw ApiException.withInner(
HttpStatus.badRequest,
'Socket operation failed: $method $path',
error,
trace,
);
} on TlsException catch (error, trace) {
throw ApiException.withInner(
HttpStatus.badRequest,
'TLS/SSL communication failed: $method $path',
error,
trace,
);
} on IOException catch (error, trace) {
throw ApiException.withInner(
HttpStatus.badRequest,
'I/O operation failed: $method $path',
error,
trace,
);
} on ClientException catch (error, trace) {
throw ApiException.withInner(
HttpStatus.badRequest,
'HTTP connection failed: $method $path',
error,
trace,
);
} on Exception catch (error, trace) {
throw ApiException.withInner(
HttpStatus.badRequest,
'Exception occurred: $method $path',
error,
trace,
);
}
throw ApiException(
HttpStatus.badRequest,
'Invalid HTTP operation: $method $path',
);
}
Future<dynamic> deserializeAsync(
String json,
String targetType, {
bool growable = false,
}) async =>
// ignore: deprecated_member_use_from_same_package
deserialize(json, targetType, growable: growable);
@Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.')
dynamic deserialize(
String json,
String targetType, {
bool growable = false,
}) {
// Remove all spaces. Necessary for regular expressions as well.
targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments
// If the expected target type is String, nothing to do...
return targetType == 'String' ? json : _deserialize(jsonDecode(json), targetType, growable: growable);
}
// ignore: deprecated_member_use_from_same_package
Future<String> serializeAsync(Object? value) async => serialize(value);
@Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use serializeAsync() instead.')
String serialize(Object? value) => value == null ? '' : json.encode(value);
/// Update query and header parameters based on authentication settings.
void _updateParamsForAuth(
List<QueryParam> queryParams,
Map<String, String> headerParams,
) {
if (authentication != null) {
authentication!.applyToParams(queryParams, headerParams);
}
}
static dynamic _deserialize(dynamic value, String targetType, {bool growable = false}) {
try {
switch (targetType) {
case 'String':
return value is String ? value : value.toString();
case 'int':
return value is int ? value : int.parse('$value');
case 'double':
return value is double ? value : double.parse('$value');
case 'bool':
if (value is bool) {
return value;
}
final valueString = '$value'.toLowerCase();
return valueString == 'true' || valueString == '1';
case 'AdminNotification':
return AdminNotification.fromJson(value);
case 'EmptyResponse':
return EmptyResponse.fromJson(value);
case 'EmptyResponseOcs':
return EmptyResponseOcs.fromJson(value);
case 'GetNotificationResponse':
return GetNotificationResponse.fromJson(value);
case 'GetNotificationResponseOcs':
return GetNotificationResponseOcs.fromJson(value);
case 'ListNotificationsResponse':
return ListNotificationsResponse.fromJson(value);
case 'ListNotificationsResponseOcs':
return ListNotificationsResponseOcs.fromJson(value);
case 'Notification':
return Notification.fromJson(value);
case 'PushNotificationDecryptedSubject':
return PushNotificationDecryptedSubject.fromJson(value);
case 'PushServerDevice':
return PushServerDevice.fromJson(value);
case 'PushServerRegistrationResponse':
return PushServerRegistrationResponse.fromJson(value);
case 'PushServerRegistrationResponseOcs':
return PushServerRegistrationResponseOcs.fromJson(value);
case 'PushServerSubscription':
return PushServerSubscription.fromJson(value);
default:
dynamic match;
if (value is List && (match = apiRegList.firstMatch(targetType)?.group(1)) != null) {
return value
.map<dynamic>((dynamic v) => _deserialize(
v,
match,
growable: growable,
))
.toList(growable: growable);
}
if (value is Set && (match = apiRegSet.firstMatch(targetType)?.group(1)) != null) {
return value
.map<dynamic>((dynamic v) => _deserialize(
v,
match,
growable: growable,
))
.toSet();
}
if (value is Map && (match = apiRegMap.firstMatch(targetType)?.group(1)) != null) {
return Map<String, dynamic>.fromIterables(
value.keys.cast<String>(),
value.values.map<dynamic>((dynamic v) => _deserialize(
v,
match,
growable: growable,
)),
);
}
}
} on Exception catch (error, trace) {
throw ApiException.withInner(
HttpStatus.internalServerError,
'Exception during deserialization.',
error,
trace,
);
}
throw ApiException(
HttpStatus.internalServerError,
'Could not find a suitable class for deserialization',
);
}
}
/// Primarily intended for use in an isolate.
class DeserializationMessage {
const DeserializationMessage({
required this.json,
required this.targetType,
this.growable = false,
});
/// The JSON value to deserialize.
final String json;
/// Target type to deserialize to.
final String targetType;
/// Whether to make deserialized lists or maps growable.
final bool growable;
}
/// Primarily intended for use in an isolate.
Future<dynamic> deserializeAsync(DeserializationMessage message) async {
// Remove all spaces. Necessary for regular expressions as well.
final targetType = message.targetType.replaceAll(' ', '');
// If the expected target type is String, nothing to do...
return targetType == 'String'
? message.json
: ApiClient._deserialize(
jsonDecode(message.json),
targetType,
growable: message.growable,
);
}
/// Primarily intended for use in an isolate.
Future<String> serializeAsync(Object? value) async => value == null ? '' : json.encode(value);

139
packages/nextcloud/lib/src/clients/generated/notifications/model/admin_notification.dart

@ -0,0 +1,139 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class AdminNotification {
/// Returns a new [AdminNotification] instance.
AdminNotification({
this.shortMessage,
this.longMessage,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? shortMessage;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? longMessage;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AdminNotification && other.shortMessage == shortMessage && other.longMessage == longMessage;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(shortMessage == null ? 0 : shortMessage!.hashCode) + (longMessage == null ? 0 : longMessage!.hashCode);
@override
String toString() => 'AdminNotification[shortMessage=$shortMessage, longMessage=$longMessage]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (shortMessage != null) {
_json[r'shortMessage'] = shortMessage;
}
if (longMessage != null) {
_json[r'longMessage'] = longMessage;
}
return _json;
}
/// Returns a new [AdminNotification] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static AdminNotification? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "AdminNotification[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "AdminNotification[$key]" has a null value in JSON.');
});
return true;
}());
return AdminNotification(
shortMessage: mapValueOfType<String>(json, r'shortMessage'),
longMessage: mapValueOfType<String>(json, r'longMessage'),
);
}
return null;
}
static List<AdminNotification>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <AdminNotification>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = AdminNotification.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, AdminNotification> mapFromJson(dynamic json) {
final map = <String, AdminNotification>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = AdminNotification.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of AdminNotification-objects as value to a dart map
static Map<String, List<AdminNotification>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<AdminNotification>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = AdminNotification.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

124
packages/nextcloud/lib/src/clients/generated/notifications/model/empty_response.dart

@ -0,0 +1,124 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class EmptyResponse {
/// Returns a new [EmptyResponse] instance.
EmptyResponse({
this.ocs,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
EmptyResponseOcs? ocs;
@override
bool operator ==(Object other) => identical(this, other) || other is EmptyResponse && other.ocs == ocs;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(ocs == null ? 0 : ocs!.hashCode);
@override
String toString() => 'EmptyResponse[ocs=$ocs]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (ocs != null) {
_json[r'ocs'] = ocs;
}
return _json;
}
/// Returns a new [EmptyResponse] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static EmptyResponse? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "EmptyResponse[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "EmptyResponse[$key]" has a null value in JSON.');
});
return true;
}());
return EmptyResponse(
ocs: EmptyResponseOcs.fromJson(json[r'ocs']),
);
}
return null;
}
static List<EmptyResponse>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <EmptyResponse>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = EmptyResponse.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, EmptyResponse> mapFromJson(dynamic json) {
final map = <String, EmptyResponse>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = EmptyResponse.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of EmptyResponse-objects as value to a dart map
static Map<String, List<EmptyResponse>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<EmptyResponse>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = EmptyResponse.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

125
packages/nextcloud/lib/src/clients/generated/notifications/model/empty_response_ocs.dart

@ -0,0 +1,125 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class EmptyResponseOcs {
/// Returns a new [EmptyResponseOcs] instance.
EmptyResponseOcs({
this.meta,
this.data = const [],
});
/// Stub
Object? meta;
List<String> data;
@override
bool operator ==(Object other) =>
identical(this, other) || other is EmptyResponseOcs && other.meta == meta && other.data == data;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(meta == null ? 0 : meta!.hashCode) + (data.hashCode);
@override
String toString() => 'EmptyResponseOcs[meta=$meta, data=$data]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (meta != null) {
_json[r'meta'] = meta;
}
_json[r'data'] = data;
return _json;
}
/// Returns a new [EmptyResponseOcs] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static EmptyResponseOcs? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "EmptyResponseOcs[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "EmptyResponseOcs[$key]" has a null value in JSON.');
});
return true;
}());
return EmptyResponseOcs(
meta: mapValueOfType<Object>(json, r'meta'),
data: json[r'data'] is List ? (json[r'data'] as List).cast<String>() : const [],
);
}
return null;
}
static List<EmptyResponseOcs>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <EmptyResponseOcs>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = EmptyResponseOcs.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, EmptyResponseOcs> mapFromJson(dynamic json) {
final map = <String, EmptyResponseOcs>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = EmptyResponseOcs.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of EmptyResponseOcs-objects as value to a dart map
static Map<String, List<EmptyResponseOcs>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<EmptyResponseOcs>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = EmptyResponseOcs.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

124
packages/nextcloud/lib/src/clients/generated/notifications/model/get_notification_response.dart

@ -0,0 +1,124 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class GetNotificationResponse {
/// Returns a new [GetNotificationResponse] instance.
GetNotificationResponse({
this.ocs,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
GetNotificationResponseOcs? ocs;
@override
bool operator ==(Object other) => identical(this, other) || other is GetNotificationResponse && other.ocs == ocs;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(ocs == null ? 0 : ocs!.hashCode);
@override
String toString() => 'GetNotificationResponse[ocs=$ocs]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (ocs != null) {
_json[r'ocs'] = ocs;
}
return _json;
}
/// Returns a new [GetNotificationResponse] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static GetNotificationResponse? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "GetNotificationResponse[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "GetNotificationResponse[$key]" has a null value in JSON.');
});
return true;
}());
return GetNotificationResponse(
ocs: GetNotificationResponseOcs.fromJson(json[r'ocs']),
);
}
return null;
}
static List<GetNotificationResponse>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <GetNotificationResponse>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = GetNotificationResponse.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, GetNotificationResponse> mapFromJson(dynamic json) {
final map = <String, GetNotificationResponse>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = GetNotificationResponse.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of GetNotificationResponse-objects as value to a dart map
static Map<String, List<GetNotificationResponse>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<GetNotificationResponse>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = GetNotificationResponse.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

133
packages/nextcloud/lib/src/clients/generated/notifications/model/get_notification_response_ocs.dart

@ -0,0 +1,133 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class GetNotificationResponseOcs {
/// Returns a new [GetNotificationResponseOcs] instance.
GetNotificationResponseOcs({
this.meta,
this.data,
});
/// Stub
Object? meta;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
Notification? data;
@override
bool operator ==(Object other) =>
identical(this, other) || other is GetNotificationResponseOcs && other.meta == meta && other.data == data;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(meta == null ? 0 : meta!.hashCode) + (data == null ? 0 : data!.hashCode);
@override
String toString() => 'GetNotificationResponseOcs[meta=$meta, data=$data]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (meta != null) {
_json[r'meta'] = meta;
}
if (data != null) {
_json[r'data'] = data;
}
return _json;
}
/// Returns a new [GetNotificationResponseOcs] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static GetNotificationResponseOcs? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "GetNotificationResponseOcs[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "GetNotificationResponseOcs[$key]" has a null value in JSON.');
});
return true;
}());
return GetNotificationResponseOcs(
meta: mapValueOfType<Object>(json, r'meta'),
data: Notification.fromJson(json[r'data']),
);
}
return null;
}
static List<GetNotificationResponseOcs>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <GetNotificationResponseOcs>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = GetNotificationResponseOcs.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, GetNotificationResponseOcs> mapFromJson(dynamic json) {
final map = <String, GetNotificationResponseOcs>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = GetNotificationResponseOcs.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of GetNotificationResponseOcs-objects as value to a dart map
static Map<String, List<GetNotificationResponseOcs>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<GetNotificationResponseOcs>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = GetNotificationResponseOcs.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

124
packages/nextcloud/lib/src/clients/generated/notifications/model/list_notifications_response.dart

@ -0,0 +1,124 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class ListNotificationsResponse {
/// Returns a new [ListNotificationsResponse] instance.
ListNotificationsResponse({
this.ocs,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
ListNotificationsResponseOcs? ocs;
@override
bool operator ==(Object other) => identical(this, other) || other is ListNotificationsResponse && other.ocs == ocs;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(ocs == null ? 0 : ocs!.hashCode);
@override
String toString() => 'ListNotificationsResponse[ocs=$ocs]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (ocs != null) {
_json[r'ocs'] = ocs;
}
return _json;
}
/// Returns a new [ListNotificationsResponse] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static ListNotificationsResponse? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "ListNotificationsResponse[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "ListNotificationsResponse[$key]" has a null value in JSON.');
});
return true;
}());
return ListNotificationsResponse(
ocs: ListNotificationsResponseOcs.fromJson(json[r'ocs']),
);
}
return null;
}
static List<ListNotificationsResponse>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <ListNotificationsResponse>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = ListNotificationsResponse.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, ListNotificationsResponse> mapFromJson(dynamic json) {
final map = <String, ListNotificationsResponse>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = ListNotificationsResponse.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of ListNotificationsResponse-objects as value to a dart map
static Map<String, List<ListNotificationsResponse>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<ListNotificationsResponse>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = ListNotificationsResponse.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

125
packages/nextcloud/lib/src/clients/generated/notifications/model/list_notifications_response_ocs.dart

@ -0,0 +1,125 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class ListNotificationsResponseOcs {
/// Returns a new [ListNotificationsResponseOcs] instance.
ListNotificationsResponseOcs({
this.meta,
this.data = const [],
});
/// Stub
Object? meta;
List<Notification> data;
@override
bool operator ==(Object other) =>
identical(this, other) || other is ListNotificationsResponseOcs && other.meta == meta && other.data == data;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(meta == null ? 0 : meta!.hashCode) + (data.hashCode);
@override
String toString() => 'ListNotificationsResponseOcs[meta=$meta, data=$data]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (meta != null) {
_json[r'meta'] = meta;
}
_json[r'data'] = data;
return _json;
}
/// Returns a new [ListNotificationsResponseOcs] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static ListNotificationsResponseOcs? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "ListNotificationsResponseOcs[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "ListNotificationsResponseOcs[$key]" has a null value in JSON.');
});
return true;
}());
return ListNotificationsResponseOcs(
meta: mapValueOfType<Object>(json, r'meta'),
data: Notification.listFromJson(json[r'data']) ?? const [],
);
}
return null;
}
static List<ListNotificationsResponseOcs>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <ListNotificationsResponseOcs>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = ListNotificationsResponseOcs.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, ListNotificationsResponseOcs> mapFromJson(dynamic json) {
final map = <String, ListNotificationsResponseOcs>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = ListNotificationsResponseOcs.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of ListNotificationsResponseOcs-objects as value to a dart map
static Map<String, List<ListNotificationsResponseOcs>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<ListNotificationsResponseOcs>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = ListNotificationsResponseOcs.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

316
packages/nextcloud/lib/src/clients/generated/notifications/model/notification.dart

@ -0,0 +1,316 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class Notification {
/// Returns a new [Notification] instance.
Notification({
this.notificationId,
this.app,
this.user,
this.datetime,
this.objectType,
this.objectId,
this.subject,
this.message,
this.link,
this.subjectRich,
this.subjectRichParameters = const [],
this.messageRich,
this.messageRichParameters = const [],
this.icon,
this.actions = const [],
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? notificationId;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? app;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? user;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? datetime;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? objectType;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? objectId;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? subject;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? message;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? link;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? subjectRich;
List<String> subjectRichParameters;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? messageRich;
List<String> messageRichParameters;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? icon;
List<String> actions;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Notification &&
other.notificationId == notificationId &&
other.app == app &&
other.user == user &&
other.datetime == datetime &&
other.objectType == objectType &&
other.objectId == objectId &&
other.subject == subject &&
other.message == message &&
other.link == link &&
other.subjectRich == subjectRich &&
other.subjectRichParameters == subjectRichParameters &&
other.messageRich == messageRich &&
other.messageRichParameters == messageRichParameters &&
other.icon == icon &&
other.actions == actions;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(notificationId == null ? 0 : notificationId!.hashCode) +
(app == null ? 0 : app!.hashCode) +
(user == null ? 0 : user!.hashCode) +
(datetime == null ? 0 : datetime!.hashCode) +
(objectType == null ? 0 : objectType!.hashCode) +
(objectId == null ? 0 : objectId!.hashCode) +
(subject == null ? 0 : subject!.hashCode) +
(message == null ? 0 : message!.hashCode) +
(link == null ? 0 : link!.hashCode) +
(subjectRich == null ? 0 : subjectRich!.hashCode) +
(subjectRichParameters.hashCode) +
(messageRich == null ? 0 : messageRich!.hashCode) +
(messageRichParameters.hashCode) +
(icon == null ? 0 : icon!.hashCode) +
(actions.hashCode);
@override
String toString() =>
'Notification[notificationId=$notificationId, app=$app, user=$user, datetime=$datetime, objectType=$objectType, objectId=$objectId, subject=$subject, message=$message, link=$link, subjectRich=$subjectRich, subjectRichParameters=$subjectRichParameters, messageRich=$messageRich, messageRichParameters=$messageRichParameters, icon=$icon, actions=$actions]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (notificationId != null) {
_json[r'notification_id'] = notificationId;
}
if (app != null) {
_json[r'app'] = app;
}
if (user != null) {
_json[r'user'] = user;
}
if (datetime != null) {
_json[r'datetime'] = datetime;
}
if (objectType != null) {
_json[r'object_type'] = objectType;
}
if (objectId != null) {
_json[r'object_id'] = objectId;
}
if (subject != null) {
_json[r'subject'] = subject;
}
if (message != null) {
_json[r'message'] = message;
}
if (link != null) {
_json[r'link'] = link;
}
if (subjectRich != null) {
_json[r'subjectRich'] = subjectRich;
}
_json[r'subjectRichParameters'] = subjectRichParameters;
if (messageRich != null) {
_json[r'messageRich'] = messageRich;
}
_json[r'messageRichParameters'] = messageRichParameters;
if (icon != null) {
_json[r'icon'] = icon;
}
_json[r'actions'] = actions;
return _json;
}
/// Returns a new [Notification] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static Notification? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "Notification[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "Notification[$key]" has a null value in JSON.');
});
return true;
}());
return Notification(
notificationId: mapValueOfType<int>(json, r'notification_id'),
app: mapValueOfType<String>(json, r'app'),
user: mapValueOfType<String>(json, r'user'),
datetime: mapValueOfType<String>(json, r'datetime'),
objectType: mapValueOfType<String>(json, r'object_type'),
objectId: mapValueOfType<String>(json, r'object_id'),
subject: mapValueOfType<String>(json, r'subject'),
message: mapValueOfType<String>(json, r'message'),
link: mapValueOfType<String>(json, r'link'),
subjectRich: mapValueOfType<String>(json, r'subjectRich'),
subjectRichParameters:
json[r'subjectRichParameters'] is List ? (json[r'subjectRichParameters'] as List).cast<String>() : const [],
messageRich: mapValueOfType<String>(json, r'messageRich'),
messageRichParameters:
json[r'messageRichParameters'] is List ? (json[r'messageRichParameters'] as List).cast<String>() : const [],
icon: mapValueOfType<String>(json, r'icon'),
actions: json[r'actions'] is List ? (json[r'actions'] as List).cast<String>() : const [],
);
}
return null;
}
static List<Notification>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <Notification>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = Notification.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, Notification> mapFromJson(dynamic json) {
final map = <String, Notification>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = Notification.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of Notification-objects as value to a dart map
static Map<String, List<Notification>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<Notification>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = Notification.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

187
packages/nextcloud/lib/src/clients/generated/notifications/model/push_notification_decrypted_subject.dart

@ -0,0 +1,187 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PushNotificationDecryptedSubject {
/// Returns a new [PushNotificationDecryptedSubject] instance.
PushNotificationDecryptedSubject({
this.nid,
this.app,
this.subject,
this.type,
this.id,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? nid;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? app;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? subject;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? type;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? id;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PushNotificationDecryptedSubject &&
other.nid == nid &&
other.app == app &&
other.subject == subject &&
other.type == type &&
other.id == id;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(nid == null ? 0 : nid!.hashCode) +
(app == null ? 0 : app!.hashCode) +
(subject == null ? 0 : subject!.hashCode) +
(type == null ? 0 : type!.hashCode) +
(id == null ? 0 : id!.hashCode);
@override
String toString() => 'PushNotificationDecryptedSubject[nid=$nid, app=$app, subject=$subject, type=$type, id=$id]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (nid != null) {
_json[r'nid'] = nid;
}
if (app != null) {
_json[r'app'] = app;
}
if (subject != null) {
_json[r'subject'] = subject;
}
if (type != null) {
_json[r'type'] = type;
}
if (id != null) {
_json[r'id'] = id;
}
return _json;
}
/// Returns a new [PushNotificationDecryptedSubject] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PushNotificationDecryptedSubject? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "PushNotificationDecryptedSubject[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "PushNotificationDecryptedSubject[$key]" has a null value in JSON.');
});
return true;
}());
return PushNotificationDecryptedSubject(
nid: mapValueOfType<int>(json, r'nid'),
app: mapValueOfType<String>(json, r'app'),
subject: mapValueOfType<String>(json, r'subject'),
type: mapValueOfType<String>(json, r'type'),
id: mapValueOfType<String>(json, r'id'),
);
}
return null;
}
static List<PushNotificationDecryptedSubject>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PushNotificationDecryptedSubject>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PushNotificationDecryptedSubject.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PushNotificationDecryptedSubject> mapFromJson(dynamic json) {
final map = <String, PushNotificationDecryptedSubject>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushNotificationDecryptedSubject.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PushNotificationDecryptedSubject-objects as value to a dart map
static Map<String, List<PushNotificationDecryptedSubject>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PushNotificationDecryptedSubject>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushNotificationDecryptedSubject.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

158
packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_device.dart

@ -0,0 +1,158 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PushServerDevice {
/// Returns a new [PushServerDevice] instance.
PushServerDevice({
this.pushTokenHash,
this.devicePublicKey,
this.proxyServer,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? pushTokenHash;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? devicePublicKey;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? proxyServer;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PushServerDevice &&
other.pushTokenHash == pushTokenHash &&
other.devicePublicKey == devicePublicKey &&
other.proxyServer == proxyServer;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(pushTokenHash == null ? 0 : pushTokenHash!.hashCode) +
(devicePublicKey == null ? 0 : devicePublicKey!.hashCode) +
(proxyServer == null ? 0 : proxyServer!.hashCode);
@override
String toString() =>
'PushServerDevice[pushTokenHash=$pushTokenHash, devicePublicKey=$devicePublicKey, proxyServer=$proxyServer]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (pushTokenHash != null) {
_json[r'pushTokenHash'] = pushTokenHash;
}
if (devicePublicKey != null) {
_json[r'devicePublicKey'] = devicePublicKey;
}
if (proxyServer != null) {
_json[r'proxyServer'] = proxyServer;
}
return _json;
}
/// Returns a new [PushServerDevice] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PushServerDevice? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "PushServerDevice[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "PushServerDevice[$key]" has a null value in JSON.');
});
return true;
}());
return PushServerDevice(
pushTokenHash: mapValueOfType<String>(json, r'pushTokenHash'),
devicePublicKey: mapValueOfType<String>(json, r'devicePublicKey'),
proxyServer: mapValueOfType<String>(json, r'proxyServer'),
);
}
return null;
}
static List<PushServerDevice>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PushServerDevice>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PushServerDevice.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PushServerDevice> mapFromJson(dynamic json) {
final map = <String, PushServerDevice>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerDevice.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PushServerDevice-objects as value to a dart map
static Map<String, List<PushServerDevice>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PushServerDevice>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerDevice.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

125
packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_registration_response.dart

@ -0,0 +1,125 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PushServerRegistrationResponse {
/// Returns a new [PushServerRegistrationResponse] instance.
PushServerRegistrationResponse({
this.ocs,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
PushServerRegistrationResponseOcs? ocs;
@override
bool operator ==(Object other) =>
identical(this, other) || other is PushServerRegistrationResponse && other.ocs == ocs;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(ocs == null ? 0 : ocs!.hashCode);
@override
String toString() => 'PushServerRegistrationResponse[ocs=$ocs]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (ocs != null) {
_json[r'ocs'] = ocs;
}
return _json;
}
/// Returns a new [PushServerRegistrationResponse] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PushServerRegistrationResponse? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "PushServerRegistrationResponse[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "PushServerRegistrationResponse[$key]" has a null value in JSON.');
});
return true;
}());
return PushServerRegistrationResponse(
ocs: PushServerRegistrationResponseOcs.fromJson(json[r'ocs']),
);
}
return null;
}
static List<PushServerRegistrationResponse>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PushServerRegistrationResponse>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PushServerRegistrationResponse.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PushServerRegistrationResponse> mapFromJson(dynamic json) {
final map = <String, PushServerRegistrationResponse>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerRegistrationResponse.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PushServerRegistrationResponse-objects as value to a dart map
static Map<String, List<PushServerRegistrationResponse>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PushServerRegistrationResponse>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerRegistrationResponse.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

133
packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_registration_response_ocs.dart

@ -0,0 +1,133 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PushServerRegistrationResponseOcs {
/// Returns a new [PushServerRegistrationResponseOcs] instance.
PushServerRegistrationResponseOcs({
this.meta,
this.data,
});
/// Stub
Object? meta;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
PushServerSubscription? data;
@override
bool operator ==(Object other) =>
identical(this, other) || other is PushServerRegistrationResponseOcs && other.meta == meta && other.data == data;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(meta == null ? 0 : meta!.hashCode) + (data == null ? 0 : data!.hashCode);
@override
String toString() => 'PushServerRegistrationResponseOcs[meta=$meta, data=$data]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (meta != null) {
_json[r'meta'] = meta;
}
if (data != null) {
_json[r'data'] = data;
}
return _json;
}
/// Returns a new [PushServerRegistrationResponseOcs] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PushServerRegistrationResponseOcs? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "PushServerRegistrationResponseOcs[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "PushServerRegistrationResponseOcs[$key]" has a null value in JSON.');
});
return true;
}());
return PushServerRegistrationResponseOcs(
meta: mapValueOfType<Object>(json, r'meta'),
data: PushServerSubscription.fromJson(json[r'data']),
);
}
return null;
}
static List<PushServerRegistrationResponseOcs>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PushServerRegistrationResponseOcs>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PushServerRegistrationResponseOcs.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PushServerRegistrationResponseOcs> mapFromJson(dynamic json) {
final map = <String, PushServerRegistrationResponseOcs>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerRegistrationResponseOcs.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PushServerRegistrationResponseOcs-objects as value to a dart map
static Map<String, List<PushServerRegistrationResponseOcs>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PushServerRegistrationResponseOcs>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerRegistrationResponseOcs.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

158
packages/nextcloud/lib/src/clients/generated/notifications/model/push_server_subscription.dart

@ -0,0 +1,158 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
// @dart=2.12
// ignore_for_file: unused_element, unused_import
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: constant_identifier_names
// ignore_for_file: lines_longer_than_80_chars
part of openapi.api;
class PushServerSubscription {
/// Returns a new [PushServerSubscription] instance.
PushServerSubscription({
this.publicKey,
this.deviceIdentifier,
this.signature,
});
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? publicKey;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? deviceIdentifier;
///
/// Please note: This property should have been non-nullable! Since the specification file
/// does not include a default value (using the "default:" property), however, the generated
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? signature;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PushServerSubscription &&
other.publicKey == publicKey &&
other.deviceIdentifier == deviceIdentifier &&
other.signature == signature;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(publicKey == null ? 0 : publicKey!.hashCode) +
(deviceIdentifier == null ? 0 : deviceIdentifier!.hashCode) +
(signature == null ? 0 : signature!.hashCode);
@override
String toString() =>
'PushServerSubscription[publicKey=$publicKey, deviceIdentifier=$deviceIdentifier, signature=$signature]';
Map<String, dynamic> toJson() {
final _json = <String, dynamic>{};
if (publicKey != null) {
_json[r'publicKey'] = publicKey;
}
if (deviceIdentifier != null) {
_json[r'deviceIdentifier'] = deviceIdentifier;
}
if (signature != null) {
_json[r'signature'] = signature;
}
return _json;
}
/// Returns a new [PushServerSubscription] instance and imports its values from
/// [value] if it's a [Map], null otherwise.
// ignore: prefer_constructors_over_static_methods
static PushServerSubscription? fromJson(dynamic value) {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
requiredKeys.forEach((key) {
assert(json.containsKey(key), 'Required key "PushServerSubscription[$key]" is missing from JSON.');
assert(json[key] != null, 'Required key "PushServerSubscription[$key]" has a null value in JSON.');
});
return true;
}());
return PushServerSubscription(
publicKey: mapValueOfType<String>(json, r'publicKey'),
deviceIdentifier: mapValueOfType<String>(json, r'deviceIdentifier'),
signature: mapValueOfType<String>(json, r'signature'),
);
}
return null;
}
static List<PushServerSubscription>? listFromJson(
dynamic json, {
bool growable = false,
}) {
final result = <PushServerSubscription>[];
if (json is List && json.isNotEmpty) {
for (final row in json) {
final value = PushServerSubscription.fromJson(row);
if (value != null) {
result.add(value);
}
}
}
return result.toList(growable: growable);
}
static Map<String, PushServerSubscription> mapFromJson(dynamic json) {
final map = <String, PushServerSubscription>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerSubscription.fromJson(entry.value);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
// maps a json object with a list of PushServerSubscription-objects as value to a dart map
static Map<String, List<PushServerSubscription>> mapListFromJson(
dynamic json, {
bool growable = false,
}) {
final map = <String, List<PushServerSubscription>>{};
if (json is Map && json.isNotEmpty) {
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
for (final entry in json.entries) {
final value = PushServerSubscription.listFromJson(
entry.value,
growable: growable,
);
if (value != null) {
map[entry.key] = value;
}
}
}
return map;
}
/// The list of required keys that must be present in a JSON.
static const requiredKeys = <String>{};
}

98
packages/nextcloud/lib/src/clients/notifications.dart

@ -0,0 +1,98 @@
import 'dart:convert';
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:crypton/crypton.dart';
import 'package:nextcloud/src/clients/common/api.dart';
import 'package:nextcloud/src/clients/generated/notifications/api.dart';
import 'package:nextcloud/src/http_client_response_extension.dart';
// ignore: public_member_api_docs
class NextcloudNotificationsClient extends DefaultApi {
// ignore: public_member_api_docs
NextcloudNotificationsClient(
final String baseURL,
final Authentication authentication,
final ApiClient Function(ApiClient) addCommonSettings,
) : super(
addCommonSettings(
ApiClient(
basePath: '$baseURL/ocs/v1.php/apps/notifications',
authentication: authentication,
),
),
);
@override
@Deprecated('Use registerDeviceAtServer instead')
Future<PushServerRegistrationResponse?> registerDevice(PushServerDevice pushServerDevice) =>
throw Exception('Use registerDeviceAtServer instead');
/// Registers a device at the Nextcloud server
Future<PushServerRegistrationResponse?> registerDeviceAtServer(
final String pushToken,
final RSAPublicKey devicePublicKey,
final String proxyServer,
) {
_validateProxyServerURL(proxyServer);
return super.registerDevice(
PushServerDevice(
pushTokenHash: generatePushTokenHash(pushToken),
devicePublicKey: devicePublicKey.toFormattedPEM(),
proxyServer: proxyServer,
),
);
}
/// Registers a device at the push proxy server
Future registerDeviceAtPushProxy(
final String pushToken,
final PushServerSubscription subscription,
final String proxyServer,
) async {
_validateProxyServerURL(proxyServer);
final request = await HttpClient().postUrl(Uri.parse('${proxyServer}devices'))
..followRedirects = false
..persistentConnection = true;
request.headers.add(HttpHeaders.contentTypeHeader, 'application/x-www-form-urlencoded');
request.add(
utf8.encode(
Uri(
queryParameters: {
'pushToken': pushToken,
'deviceIdentifier': subscription.deviceIdentifier!,
'deviceIdentifierSignature': subscription.signature!,
'userPublicKey': subscription.publicKey!,
},
).query,
),
);
final response = await request.close();
if (response.statusCode != 200) {
throw ApiException(
response.statusCode,
await response.body,
);
}
}
/// Generates the push token hash which is just sha512
String generatePushTokenHash(final String pushToken) => sha512.convert(utf8.encode(pushToken)).toString();
/// Decrypts the subject of a push notification
PushNotificationDecryptedSubject decryptPushNotificationSubject(
final RSAPrivateKey privateKey,
final String subject,
) =>
PushNotificationDecryptedSubject.fromJson(json.decode(privateKey.decrypt(subject)) as Map<String, dynamic>)!;
void _validateProxyServerURL(final String proxyServer) {
if (!proxyServer.endsWith('/')) {
throw Exception('proxyServer URL has to end with a /');
}
}
}

12
packages/nextcloud/lib/src/http_client_response_extension.dart

@ -0,0 +1,12 @@
// ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
extension HttpClientResponseBody on HttpClientResponse {
Future<Uint8List> get bodyBytes async =>
Uint8List.fromList((await toList()).reduce((final value, final element) => [...value, ...element]));
Future<String> get body async => utf8.decode(await bodyBytes);
}

5
packages/nextcloud/pubspec.yaml

@ -5,6 +5,8 @@ environment:
sdk: '>=2.17.0 <3.0.0'
dependencies:
crypto: ^3.0.2
crypton: ^2.0.5
http: ^0.13.4
intl: ^0.17.0
meta: ^1.7.0
@ -12,7 +14,8 @@ dependencies:
dev_dependencies:
# coverage: ^1.3.2
crypto: ^3.0.1
nextcloud_push_proxy:
path: ../nextcloud_push_proxy
nit_picking:
git:
url: https://github.com/stack11/dart_nit_picking

48
packages/nextcloud/test/helper.dart

@ -136,10 +136,14 @@ class TestHelper {
final String dockerImageName, {
final String? username = defaultUsername,
final String? password = defaultPassword,
final bool useAppPassword = false,
final AppType appType = AppType.unknown,
final String? userAgentSuffix,
}) async {
final port = 1024 + Random().nextInt(65535 - 1024);
// ignore: prefer_asserts_with_message
assert(!useAppPassword || (username != null && password != null));
final port = randomPort();
final result = await runExecutableArguments(
'docker',
@ -149,6 +153,8 @@ class TestHelper {
'-d',
'-p',
'$port:80',
'--add-host',
'host.docker.internal:host-gateway',
dockerImageName,
],
);
@ -159,11 +165,38 @@ class TestHelper {
final containerID = result.stdout.toString().replaceAll('\n', '');
var clientPassword = password;
if (useAppPassword) {
final inputStream = StreamController<List<int>>();
final process = runExecutableArguments(
'docker',
[
'exec',
'-i',
containerID,
'php',
'-f',
'occ',
'user:add-app-password',
username!,
],
stdin: inputStream.stream,
);
inputStream.add(utf8.encode(password!));
await inputStream.close();
final result = await process;
if (result.exitCode != 0) {
throw Exception('Failed to run generate app password command\n${result.stderr}\n${result.stdout}');
}
clientPassword = (result.stdout as String).split('\n')[1];
}
final client = TestNextcloudClient(
'http://localhost:$port',
containerID,
username: username,
password: password,
password: clientPassword,
appType: appType,
userAgentSuffix: userAgentSuffix,
);
@ -222,6 +255,9 @@ class TestDockerHelper {
generateInstallAppInstruction(app),
],
],
// Required to workaround restrictions for localhost and http only push proxies
'RUN ./occ config:system:set allow_local_remote_servers --value=true',
'RUN sed -i "s/localhost/host.docker.internal/" /usr/src/nextcloud/apps/notifications/lib/Controller/PushController.php',
'ADD overlay /usr/src/nextcloud/',
'',
];
@ -293,3 +329,11 @@ extension ListExtension on List {
extension MapExtension on Map<String, dynamic> {
Map removeNulls() => removeNullsFromMap(this);
}
int randomPort() => 1024 + Random().nextInt(65535 - 1024);
void expectDateInReasonableTimeRange(final DateTime actual, final DateTime expected) {
const duration = Duration(seconds: 5);
expect(actual.isAfter(expected.subtract(duration)), isTrue);
expect(actual.isBefore(expected.add(duration)), isTrue);
}

220
packages/nextcloud/test/notifications_test.dart

@ -0,0 +1,220 @@
import 'dart:async';
import 'package:nextcloud/nextcloud.dart';
import 'package:nextcloud_push_proxy/nextcloud_push_proxy.dart';
import 'package:test/test.dart';
import 'helper.dart';
Future main() async {
final dockerImageName = await TestHelper.prepareDockerImage();
group('notifications', () {
late TestNextcloudClient client;
setUp(() async {
client = await TestHelper.getPreparedClient(
dockerImageName,
username: 'admin',
);
});
tearDown(() => client.destroy());
Future sendTestNotification() async {
await validateResponse<EmptyResponse, void>(
client.notifications,
client.notifications.sendAdminNotificationWithHttpInfo(
'admin',
AdminNotification(
shortMessage: '123',
longMessage: '456',
),
),
);
}
test('Send admin notification', () async {
await sendTestNotification();
});
test('List notifications', () async {
await sendTestNotification();
final startTime = DateTime.now().toUtc();
final response = (await validateResponse<ListNotificationsResponse, void>(
client.notifications,
client.notifications.listNotificationsWithHttpInfo(),
))!;
expect(response.ocs!.data, hasLength(1));
expect(response.ocs!.data[0].notificationId, 1);
expect(response.ocs!.data[0].app, 'admin_notifications');
expect(response.ocs!.data[0].user, 'admin');
expectDateInReasonableTimeRange(DateTime.parse(response.ocs!.data[0].datetime!), startTime);
expect(response.ocs!.data[0].objectType, 'admin_notifications');
expect(response.ocs!.data[0].objectId, isNotNull);
expect(response.ocs!.data[0].subject, '123');
expect(response.ocs!.data[0].message, '456');
expect(response.ocs!.data[0].link, '');
expect(response.ocs!.data[0].subjectRich, '');
expect(response.ocs!.data[0].subjectRichParameters, hasLength(0));
expect(response.ocs!.data[0].messageRich, '');
expect(response.ocs!.data[0].messageRichParameters, hasLength(0));
expect(response.ocs!.data[0].icon, isNotEmpty);
expect(response.ocs!.data[0].actions, hasLength(0));
});
test('Get notification', () async {
await sendTestNotification();
final startTime = DateTime.now().toUtc();
final response = (await validateResponse<GetNotificationResponse, void>(
client.notifications,
client.notifications.getNotificationWithHttpInfo(1),
))!;
expect(response.ocs!.data!.notificationId, 1);
expect(response.ocs!.data!.app, 'admin_notifications');
expect(response.ocs!.data!.user, 'admin');
expectDateInReasonableTimeRange(DateTime.parse(response.ocs!.data!.datetime!), startTime);
expect(response.ocs!.data!.objectType, 'admin_notifications');
expect(response.ocs!.data!.objectId, isNotNull);
expect(response.ocs!.data!.subject, '123');
expect(response.ocs!.data!.message, '456');
expect(response.ocs!.data!.link, '');
expect(response.ocs!.data!.subjectRich, '');
expect(response.ocs!.data!.subjectRichParameters, hasLength(0));
expect(response.ocs!.data!.messageRich, '');
expect(response.ocs!.data!.messageRichParameters, hasLength(0));
expect(response.ocs!.data!.icon, isNotEmpty);
expect(response.ocs!.data!.actions, hasLength(0));
});
test('Delete notification', () async {
await sendTestNotification();
await validateResponse<EmptyResponse, void>(
client.notifications,
client.notifications.deleteNotificationWithHttpInfo(1),
);
final response = (await validateResponse<ListNotificationsResponse, void>(
client.notifications,
client.notifications.listNotificationsWithHttpInfo(),
))!;
expect(response.ocs!.data, hasLength(0));
});
test('Delete all notifications', () async {
await sendTestNotification();
await sendTestNotification();
await validateResponse<EmptyResponse, void>(
client.notifications,
client.notifications.deleteAllNotificationsWithHttpInfo(),
);
final response = (await validateResponse<ListNotificationsResponse, void>(
client.notifications,
client.notifications.listNotificationsWithHttpInfo(),
))!;
expect(response.ocs!.data, hasLength(0));
});
});
group('push notifications', () {
late TestNextcloudClient client;
setUp(() async {
client = await TestHelper.getPreparedClient(
dockerImageName,
username: 'admin',
// We need to use app passwords in order to register push devices
useAppPassword: true,
);
});
tearDown(() => client.destroy());
// The key size has to be 2048, other sizes are not accepted by Nextcloud (at the moment at least)
// ignore: avoid_redundant_argument_values
RSAKeypair generateKeypair() => RSAKeypair.fromRandom(keySize: 2048);
test('Register device and receive notification', () async {
const pushToken = '789';
final port = randomPort();
final keypair = generateKeypair();
final pushProxy = NextcloudPushProxy();
final subscription = (await client.notifications.registerDeviceAtServer(
pushToken,
keypair.publicKey,
'http://host.docker.internal:$port/',
))!
.ocs!
.data!;
expect(subscription.publicKey, hasLength(451));
RSAPublicKey.fromPEM(subscription.publicKey!);
expect(subscription.deviceIdentifier, isNotEmpty);
expect(subscription.signature, isNotEmpty);
final deviceCompleter = Completer();
final notificationCompleter = Completer();
await pushProxy.create(
logging: false,
port: port,
);
pushProxy.onNewDevice.listen((final device) async {
expect(device.pushToken, pushToken);
expect(device.deviceIdentifier, isNotEmpty);
expect(device.deviceIdentifierSignature, isNotEmpty);
expect(device.userPublicKey, isNotEmpty);
deviceCompleter.complete();
});
pushProxy.onNewNotification.listen((final notification) async {
expect(notification.deviceIdentifier, subscription.deviceIdentifier);
expect(notification.pushTokenHash, client.notifications.generatePushTokenHash(pushToken));
expect(notification.subject, isNotEmpty);
expect(notification.signature, isNotEmpty);
expect(notification.priority, 'normal');
expect(notification.type, 'alert');
final decryptedSubject =
client.notifications.decryptPushNotificationSubject(keypair.privateKey, notification.subject);
expect(decryptedSubject.nid, isNotNull);
expect(decryptedSubject.app, 'admin_notifications');
expect(decryptedSubject.subject, '123');
expect(decryptedSubject.type, 'admin_notifications');
expect(decryptedSubject.id, isNotEmpty);
notificationCompleter.complete();
});
await client.notifications.registerDeviceAtPushProxy(
pushToken,
subscription,
'http://localhost:$port/',
);
await client.notifications.sendAdminNotification(
'admin',
AdminNotification(
shortMessage: '123',
longMessage: '456',
),
);
await deviceCompleter.future;
await notificationCompleter.future;
await pushProxy.close();
});
test('Remove push device', () async {
await client.notifications.registerDeviceAtServer(
'789',
generateKeypair().publicKey,
'https://example.com/',
);
await validateResponse<EmptyResponse, void>(
client.notifications,
client.notifications.removeDeviceWithHttpInfo(),
);
});
});
}

12
packages/nextcloud/test/webdav_test.dart

@ -43,8 +43,7 @@ Future main() async {
final file = files.singleWhere((final f) => f.name == 'Nextcloud.png');
expect(file.hasPreview, isTrue);
expect(file.mimeType, 'image/png');
expect(file.lastModified!.isBefore(DateTime.now()), isTrue);
expect(file.lastModified!.isAfter(DateTime.now().subtract(const Duration(seconds: 5))), isTrue);
expectDateInReasonableTimeRange(file.lastModified!, DateTime.now());
expect(file.size!, 50598);
});
@ -154,8 +153,7 @@ Future main() async {
);
expect(file.hasPreview, isTrue);
expect(file.mimeType, 'image/png');
expect(file.lastModified!.isBefore(DateTime.now()), isTrue);
expect(file.lastModified!.isAfter(DateTime.now().subtract(const Duration(seconds: 5))), isTrue);
expectDateInReasonableTimeRange(file.lastModified!, DateTime.now());
expect(file.size!, 50598);
});
@ -176,8 +174,7 @@ Future main() async {
expect(file.isDirectory, isTrue);
expect(file.name, 'test');
expect(file.mimeType, null);
expect(file.lastModified!.isBefore(DateTime.now()), isTrue);
expect(file.lastModified!.isAfter(DateTime.now().subtract(const Duration(seconds: 5))), isTrue);
expectDateInReasonableTimeRange(file.lastModified!, DateTime.now());
expect(file.size!, data.lengthInBytes);
});
@ -225,8 +222,7 @@ Future main() async {
);
expect(file.favorite, isTrue);
expect(file.createdDate!.isAtSameMomentAs(createdDate), isTrue);
expect(file.uploadedDate!.isAfter(uploadTime), isTrue);
expect(file.uploadedDate!.isBefore(DateTime.now()), isTrue);
expectDateInReasonableTimeRange(file.uploadedDate!, uploadTime);
});
test('Set custom properties', () async {

389
specs/notifications.json

@ -0,0 +1,389 @@
{
"openapi": "3.0.3",
"info": {
"title": "Notifications",
"version": "2.12.0",
"description": "This app provides a backend and frontend for the notification API available in Nextcloud.",
"license": {
"name": "agpl"
}
},
"servers": [
{
"url": "https://{hostname}:{port}/ocs/v1.php/apps/notifications",
"variables": {
"hostname": {
"default": "localhost"
},
"port": {
"default": "8080"
}
}
}
],
"security": [
{
"basic_auth": []
}
],
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
}
},
"schemas": {
"OCSMeta": {
"deprecated": true,
"description": "Stub"
},
"AdminNotification": {
"type": "object",
"properties": {
"shortMessage": {
"type": "string"
},
"longMessage": {
"type": "string"
}
}
},
"EmptyResponse": {
"type": "object",
"properties": {
"ocs": {
"type": "object",
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
},
"Notification": {
"type": "object",
"properties": {
"notification_id": {
"type": "integer"
},
"app": {
"type": "string"
},
"user": {
"type": "string"
},
"datetime": {
"type": "string"
},
"object_type": {
"type": "string"
},
"object_id": {
"type": "string"
},
"subject": {
"type": "string"
},
"message": {
"type": "string"
},
"link": {
"type": "string"
},
"subjectRich": {
"type": "string"
},
"subjectRichParameters": {
"type": "array",
"items": {
"description": "TODO",
"type": "string"
}
},
"messageRich": {
"type": "string"
},
"messageRichParameters": {
"type": "array",
"items": {
"description": "TODO",
"type": "string"
}
},
"icon": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"description": "TODO",
"type": "string"
}
}
}
},
"ListNotificationsResponse": {
"type": "object",
"properties": {
"ocs": {
"type": "object",
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Notification"
}
}
}
}
}
},
"GetNotificationResponse": {
"type": "object",
"properties": {
"ocs": {
"type": "object",
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Notification"
}
}
}
}
},
"PushServerDevice": {
"type": "object",
"properties": {
"pushTokenHash": {
"type": "string"
},
"devicePublicKey": {
"type": "string"
},
"proxyServer": {
"type": "string"
}
}
},
"PushServerSubscription": {
"type": "object",
"properties": {
"publicKey": {
"type": "string"
},
"deviceIdentifier": {
"type": "string"
},
"signature": {
"type": "string"
}
}
},
"PushServerRegistrationResponse": {
"type": "object",
"properties": {
"ocs": {
"type": "object",
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/PushServerSubscription"
}
}
}
}
},
"PushNotificationDecryptedSubject": {
"type": "object",
"properties": {
"nid": {
"type": "integer"
},
"app": {
"type": "string"
},
"subject": {
"type": "string"
},
"type": {
"type": "string"
},
"id": {
"type": "string"
}
}
}
}
},
"paths": {
"/api/v2/notifications": {
"get": {
"operationId": "list-notifications",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
},
"delete": {
"operationId": "delete-all-notifications",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/v2/notifications/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
],
"get": {
"operationId": "get-notification",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/GetNotificationResponse"
}
}
}
}
}
},
"delete": {
"operationId": "delete-notification",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmptyResponse"
}
}
}
}
}
}
},
"/api/v2/push": {
"post": {
"operationId": "register-device",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PushServerDevice"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PushServerRegistrationResponse"
}
}
}
}
}
},
"delete": {
"operationId": "remove-device",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/v2/admin_notifications/{userId}": {
"parameters": [
{
"name": "userId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"post": {
"operationId": "send-admin-notification",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AdminNotification"
}
}
}
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EmptyResponse"
}
}
}
}
}
}
}
}
}

235
specs/templates/notifications.json

@ -0,0 +1,235 @@
{
"openapi": "3.0.3",
"info": {
"title": "Notifications",
"version": "2.12.0",
"description": "This app provides a backend and frontend for the notification API available in Nextcloud.",
"license": {
"name": "agpl"
}
},
"servers": [
{
"url": "https://{hostname}:{port}/ocs/v1.php/apps/notifications",
"variables": {
"hostname": {
"default": "localhost"
},
"port": {
"default": "8080"
}
}
}
],
"security": [
{
"basic_auth": []
}
],
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
}
}
},
"paths": {
"/api/{apiVersion}/notifications": {
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"get": {
"operationId": "endpoint-listnotifications-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
},
"delete": {
"operationId": "endpoint-deleteallnotifications-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/{apiVersion}/notifications/{id}": {
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "integer"
}
}
],
"get": {
"operationId": "endpoint-getnotification-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
},
"delete": {
"operationId": "endpoint-deletenotification-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/{apiVersion}/push": {
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "TODO"
}
}
],
"post": {
"operationId": "push-registerdevice-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
},
"delete": {
"operationId": "push-removedevice-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/{apiVersion}/admin_notifications/{userId}": {
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "TODO"
}
},
{
"name": "userId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"post": {
"operationId": "api-generatenotification-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/api/{apiVersion}/settings": {
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "TODO"
}
}
],
"post": {
"operationId": "settings-personal-TODO",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
}
}

2
tool/generate-nextcloud.sh

@ -99,6 +99,7 @@ mkdir -p /tmp/nextcloud-harbour
spec_templates_generate external/nextcloud-news false
spec_templates_generate external/nextcloud-notes false
spec_templates_generate external/nextcloud-notifications false
spec_templates_generate external/nextcloud-server/apps/provisioning_api false
spec_templates_generate external/nextcloud-server/apps/user_status false
spec_templates_generate external/nextcloud-server/core true
@ -107,6 +108,7 @@ openapi_generate "common" true
openapi_generate "core" false
openapi_generate "news" false
openapi_generate "notes" false
openapi_generate "notifications" false
openapi_generate "provisioning_api" false
openapi_generate "user_status" false

Loading…
Cancel
Save