Giter Site home page Giter Site logo

directus-dart's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

directus-dart's Issues

How to get custom user fields?

I'm digging down a rabbit hole:

  1. Subclass DirectusUser to have a type with additional fields
  2. Add an extension to CurrentUser similar to read() readCustomUser() <- didn't really work
  3. Add a CustomUserConverter() <- can't inject this into CurrentUser.read
  4. Implement the client call directly and skip the currentUser accessor <- works but seems smelly.

Is there a way to get a user object with custom fields? If not there should be. If yes can it be documented please.

[Question] Fulltext search

Hello,
Can i get please example how to do fulltext search?
i tried to modify library with query with search param

await DirectusApi.sdk.items('Products').readMany(
              query: Query(fields: ["id,name"], search: 'numb'),
              filters: Filters(
                {
                  'status': Filter.eq("published"),
                },
              ),
            );

with this im getting correctly product, but if i add translation relation, then i really dont know, that leads me to fulltext ability

Thanks!

Relational Filter

I observe a lack of implementation for relational Filter.
How can I implement this with the current filter?

{
	"author": {
		"name": {
			"_eq": "Rijk van Zanten"
		}
	}
}

Cannot log out

Hello, im trying your library, looks good and clean so far, but i met an issue.
Login is without a problem.
Logout has some troubles

calling this in service
Future<dynamic> logout() async {
    Directus sdk = await Directus(API_ENDPOINT).init();
    return await sdk.auth.logout();
  }

in directus

22:06:09 ✨ request completed POST 401 /auth/refresh 7ms

im checking in main.dart if authEndpoint.isLoggedIn() is false

but its true all the time.

seems like Authstorage removeLoginData isnt cleared.

Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'

Hello,

I'm testing Directus Flutter and I come across this error when creating a user :

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
#0      new DirectusResponse package:directus/…/data_classes/directus_response.dart:16
#1      DirectusResponse.fromRequest package:directus/…/data_classes/directus_response.dart:44

I'm on the version :

directus: ^0.7.2

I'm on the latest version of flutter: 3.3.8

My code is:

    final Directus sdk = await Directus(kEndpoint).init();
    
    final DirectusResponse<DirectusUser> response = await sdk.users.createOne(
      DirectusUser(
        email: "[email protected]",
        password: "password",
      ),
    );

In backend, i use the latest version of "directus-project" (self hosted).

Is it a user error on my part, or a problem on the side of the response object

Cannot use on flutter 2.2.3 and MacOS

Hi
I'm trying to use your library to communicate with my Directus installation.

Flutter version: 2.2.3
OS: MacOS 11.2.3

Running your main.dart code, inside the example folder in this project I obtain this, upon running:
Restarted application in 845ms. [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Null check operator used on a null value #0 MethodChannel.binaryMessenger package:flutter/…/services/platform_channel.dart:142 #1 MethodChannel._invokeMethod package:flutter/…/services/platform_channel.dart:148 #2 MethodChannel.invokeMethod package:flutter/…/services/platform_channel.dart:331 #3 MethodChannel.invokeMapMethod package:flutter/…/services/platform_channel.dart:358 #4 MethodChannelSharedPreferencesStore.getAll package:shared_preferences_platform_interface/method_channel_shared_preferences.dart:44 #5 SharedPreferences._getSharedPreferencesMap package:shared_preferences/shared_preferences.dart:180 #6 SharedPreferences.getInstance package:shared_preferences/shared_preferences.dart:56 #7 SharedPreferencesStorage.getItem package:directus/…/adapters/shared_preferences_storage.dart:14 #8 AuthStorage.getLoginData package:directus/…/auth/_auth_storage.dart:29 #9 AuthHandler.init package:directus/…/auth/auth_handler.dart:82 #10 Directus.init package:directus/src/directus.dart:56 #11 main package:redux_saga_beginner_tutorial/main.dart:8 #12 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:142:25) #13 _rootRun (dart:async/zone.dart:1354:13) #14 _CustomZone.run (dart:async/zone.dart:1258:19) #15 _runZoned (dart:async/zone.dart:1789:10) #16 runZonedGuarded (dart:async/zone.dart:1777:12) #17 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:138:5) #18 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19) #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

How to resolve this problem? Am I missing something?
Regards

Сustom authorization

My projects use custom authorization, this library does not allow me to add my own authorization.
Can we think of something?
I also want to organize this library!

Transform the Directus class into Singleton

Hello, first I would like to thank you for the package, it is very useful and well built!

I would like to know if there is a special reason for not using the 'Directus' class as a singleton, so I would keep the same instance to be recovered anywhere in the application.

I did a singleton on a project that I used your package to analyze and see if it would be interesting for the package.

The interesting thing about working with a singleton is that it would be possible to recover the same instance globally.

https://github.com/kellvembarbosa/directus-dart

Login not working

After init

I try to await ask.auth.login.....
but it never completes and code after it never execute not generate a user . for example the print("asf") will never run when I use the login await methode

Future<void> loginDirectus() async {
    final sdk = await Directus('http://localhost:8055').init();

    await sdk.auth
        .login(email: "[email protected]", password: "A@12345678");

    print("asf");
    print("test");
    var user = await sdk.auth.currentUser?.read();
    print(user?.data);
  }

Unable to use typedItems

I am not able to use typedItems in my application.

typedItems need a converter of type ItemsConverter which I can't import. Dart gives me warning when importing files from src folder.

Can you please add import 'package:directus/src/modules/items/items_converter.dart'; to directus.dart outside src folder? It would be really helpful.

By the way, thanks for such a helpful library 🙂

Decide for storage option.

Currently it's hive and sembast.

Hive pros:

  • Super easy API

Hive cons:

  • Has separate versions for Flutter and for VM/AngularDart.

Sembast pros:

  • Same package can be used in Flutter and for VM

Sembast cons:

  • It requires user to provide path for storage, as SDK can't get Flutter documents path
    without depending on Flutter.
  • There is seperate package for Flutter browser

Shared preferences are flutter only.

Secure flutter storage is flutter only, and without web.

Custom field when create user

I create custom user model extend DirectusUser and put phone field and try create user,
result :

import 'package:directus/directus.dart';
import 'package:json_annotation/json_annotation.dart';

class User extends DirectusUser {
  String phone;
  User({email, password, this.phone}) : super(email: email, password: password);

  factory User.fromJson(Map<String, dynamic> json) => User(
        phone: json["phone"],
        email: json["email"],
        password: json["password"],
      );
}
...
final createdUser = sdk.users.createOne(User.fromJson(data));
Undefined binding(s) detected when compiling WHERE. Undefined column(s): [directus_users.phone] query: where "directus_users"."email" = ? or "directus_users"."phone" = ?

phone field not sended :/

Fix failing tests

Around 20 tests are now failing after switching to full null safety.

TypeError on response code 204 - no data

Hello,
thanks for this useful package! I have found a bug that occurs when directus does not send any data back in a response.
That happens when you set permissions for a role on a collection to create items, but not read items.
I am developing an app where you can take surveys anonymously. Because there is no personal identification, my users can create collection items but never read them. If I use the createOne method directus saves it in the database correctly and returns the 204 code.
Then a TypeError happens in your package, because no data is received:

E/flutter ( 6098): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
E/flutter ( 6098): #0      new DirectusResponse
package:directus/…/data_classes/directus_response.dart:16
E/flutter ( 6098): #1      DirectusResponse.fromRequest
package:directus/…/data_classes/directus_response.dart:44

If you need additional information I am happy to provide more. Thanks for your consideration.

await sdk.auth.logout() not working

The sdk.auth.logout() does not log out from the local authenticated user.

Once I use the logout() method and re-open the app, the previous user stays logged in :/

Create seperate `directus_flutter` package

There is no simple way to use package without relaying on some sort of storage, and most of the storage options require a lot of boilerplate to set up. That's why hive has hive package and hive_flutter. Why sembast have sembast and sembast_web.

Or we can simply drop support for non flutter apps, since 99% of dart apps are Flutter apps?
Or we can create directus_base that works without Flutter and directus that works with Flutter?

Write new example

I removed lib folder from example when adding generated files to git ignore

Deep Filter for translations

Hello,

I am trying to deep filter my query like this deep[translations][_filter][languages_code][_eq]="en-US".
Unfortunately, the deep query parameter has to be of Map<String, Query>.
Is there any possibility to filter my subquery/relation?

The data structure is as follows
product -> translations

I tried to use Filter.relation but it returns both languages_codes.

My code looks like this:

await directusSdk.items('product').readMany(
        query: Query(limit: 1, offset: 0, fields: ['sku', 'image', 'translations.*'] ),
        filters: Filters({'and': Filter.and([
          {'sku': Filter.eq(sku)},
          {'translations': Filter.relation('languages_code', Filter.eq(languageCode))}
        ])})
    );

Thank you for your help.
I am using the apstanisic/directus-dart version 0.9.5 and directus 9.23.1.

Filters not working for DateTime?

I have the following code when trying to filter by a DateTime field.
I have also tried using the string 'now' instead of manually creating a DateTime object.

final announcementsList = await sdk.items('announcements').readMany(
            filters: Filters({
          'and': Filter.and([
            {
              "date_effective": Filter.lte(
                  '${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}')
            },
            {
              "date_expired": Filter.gte(
                  '${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}')
            }
        ])
   }));

Any insight would be appreciated. I would like to know if I am doing something wrong.

refresh token interceptor bug fix

final response = await manuallyRefresh();
if (response?.accessToken != null) {
options.headers['authorization'] = 'Bearer ${response!.accessToken}';
} else {
options.headers.remove('authorization');
}

Refresh token interceptor wasn't working. After changing "Authorization" to "authorization" and prepending "Bearer " fixed the issue.

Timeout when user exits app

What happens with timeout when user exits, or is kills flutter app. There should be a way to check before each request if access token in expired

Auth Refresh fails and soft locks users out of the system

Expected Behaviour

When logging back into an app after a refresh token has expired login should work correctly. The user should then be authenticated and be able to access data according to their role.
In the case of a renewal token that has expired, I'd expect the SDK to attempt to login using the usual method at the auth/login endpoint.

Current Behavior

When logging back into an app after a refresh token has expired login get's suck and the user is no longer able to log in at all. Even after calling:

sdk.auth.storage.removeLoginData();

Steps to Reproduce

  • Set up your Directus instance to have an auth token expire quickly
    for example:
ACCESS_TOKEN_TTL=1m
REFRESH_TOKEN_TTL=2m
  • Use the SDK to log into your system using valid credentials:
sdk.auth.login(email: email, password: password)
  • Once you've logged in kill the app
  • Wait for 3 minutes, or enough time for the tokens to expire
  • Try to log in again in the same app

note: clearing out the data from the app fixes the issue.

Context

Building machine: Windows 10

Flutter Doctor output:

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.10, on Microsoft Windows [Version 10.0.19045.2486], locale en-NZ)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.4.2)   
[√] Android Studio (version 2021.3)
[√] VS Code (version 1.74.3)
[√] Connected device (4 available)
[√] HTTP Host Availability

• No issues found!

directus sdk version: 0.9.3

Detailed Description

Our testers have noticed that occasionally when trying to log in they'll get locked out of the app and we've worked out it's when the SDK is trying to use an expired renewal token. Since the default renewal token expiry is 7 days this only happens occasionally (until we set the expiry to much shorter).
Looks like the stored token is continued to be attempted and the login never reverts to the normal login methods, even after trying to clear out the stored user auth data.

Need meta params total_count, filter_count

I managed to add my custom fields. uitlaber@10c97a9 Now I can search through collections or other methods. And I can add the meta parameter but the problem get response.
https://docs.directus.io/reference/api/query/meta.html
I tried edit directus_list_response.dart

// ignore: import_of_legacy_library_into_null_safe
import 'package:dio/dio.dart';
import 'package:directus/src/modules/items/items_converter.dart';
import 'package:directus/src/modules/items/map_items_converter.dart';

import 'data_classes.dart';

/// Directus response object when data is [List].
///
/// When response is returning a [List] of items, use this instead of [DirectusRespones].
/// This class is created to properly and type safely convert data.
/// Using [List] respones inside [DirectusRespone] will throw an error. Only this
/// response should be used. It has all the same properties and methods,
/// but adopted when response is [List].
class DirectusListResponse<T> implements DirectusResponse<List<T>> {
  /// Response data.
  @override
  late final List<T> data;

  List<T>? meta;

  /// Manually set data.
  DirectusListResponse.manually(data) : data = data;

  /// Constructor that converts Dio [Response] to [DirectusListResponse].
  /// You can pass converter that is used to convert response [Map] to
  /// proper object, by default it will return [Map].
  DirectusListResponse(Response dioResponse, {ItemsConverter? converter}) {
    converter ??= MapItemsConverter();
    var data = dioResponse.data['data'];
    var meta = dioResponse.data['meta'];

    print(data);

    if (!(data is List)) {
      throw DirectusError(message: 'Data should be a list.');
    } else {
      this.data =
          data.map((item) => converter!.fromJson(item)).cast<T>().toList();
    }

    if ((meta is List)) {
      this.meta =
          meta.map((item) => converter!.fromJson(item)).cast<T>().toList();
    }
  }

  /// Static method that you can pass a closure that should return Dio [Response].
  ///
  /// This will automaticaly convert [Response] to either [DirectusListResponse] or [DirectusError].
  /// Most of the methods that return JSON object with key `data` that is [List]
  /// should be called inside this method.
  /// You can pass converter that is used to convert response [Map] to
  /// proper object, by default it will return [Map].
  static Future<DirectusListResponse<U>> fromRequest<U>(
    Future<Response<dynamic>> Function() func, {
    ItemsConverter? converter,
  }) async {
    converter ??= MapItemsConverter();
    try {
      final response = await func();
      return DirectusListResponse<U>(response, converter: converter);
    } on DioError catch (error) {
      throw DirectusError.fromDio(error);
    }
  }
}

Not working with Dio 4.0.4

Dio client is stuck at sending request when using 4.0.4 version. If I remove first interceptor (DirectusSingleton.instance.client.interceptors.removeAt(0);) it works properly. I don't know why 😕

It is working fine with Dio 4.0.0

Maybe there is a breaking change in Dio interceptor api

logout method not working

Code

 final sdk = await Directus(config.API_URL).init();
  try {
    await sdk.auth.logout();
  } catch (e) {
    print(e);
  }

Send to url POST /auth/refresh return status 401
But doesn't send anything POST /auth/logout

new sdk changes Directus 9.5.2

hey the new sdk switched the SDKs type signature was tweaked to make it consistent with the API's internal services. The .readMany method has been renamed to .readByQuery.

will this SDK receive an update to reflect this?

Filters failed and meta

Hi, i have problem when filtering data

{
"data": [
    {
      "id": 6,
      "status": "published",
      "user_created": "46c84dc4-1340-4469-b580-3f8aa0a567be",
      "date_created": "2021-01-08T11:33:33Z",
      "user_updated": "46c84dc4-1340-4469-b580-3f8aa0a567be",
      "date_updated": "2021-01-09T16:16:21Z",
      "title": "Подарим второе дыхание Рыскуль апай",   
      "required_amount": "180000.00",
      "collected_amount": "0.00",
      "is_finished": false,
      "indigent_id": null,
      "video_url": null,
      "fond_id": "46c84dc4-1340-4469-b580-3f8aa0a567be",
      "photos": [
        {
          "id": 18,
          "projects_id": 6,
          "directus_files_id": "138c98fa-01f0-435f-8783-63a90681ab5b"
        }
      ]
    }
  ]
}

My query

 final result = await sdk.items('projects').readMany(
              query: Query(limit: 5, offset: 0, fields: ['*.*']),
               filters: Filters({'is_finished': Filter.eq('false')})
            );

        result.data.forEach((project) => print(project['title']));

Take error

"filter" must be of type object

Offer a pure dart package

It would be awesome if this package could also be offered as a plain dart package. For example you can create your own packages in flutter and define there your API with this package and keeping the flutter root directory pristine.

fix items -> updateMany

Hi ,
thanks for this awesome package,
please fix the method updateMany in items module , ( ids are now passed in data )

https://docs.directus.io/reference/items.html#update-multiple-items

Future<DirectusListResponse<T>> updateMany({required List<String> ids, required T data}) async {
    if (ids.isEmpty) return DirectusListResponse.manually([]);
    
    final mapData = converter.toJson({ 'keys': ids, 'data': data,});
    
    return DirectusListResponse.fromRequest(
          () =>
          client.patch(
            '$_endpoint',
            data: mapData,
          ),
      converter: converter,
    );
  }

Feature request: Pagination

It would be great if there could be a pagination feature while reading a collection.

P.S. I would love to contribute but since I'm a newbie here, help me understand how to contribute to this repo. Thanks!

Unhandled Exception on Invalid Refresh Token

The Interceptor used for refreshing the token has an unhandled exception. It happens when the server gives error 401 on an invalid refresh token.

Here's the interceptor

Future<void> refreshExpiredTokenInterceptor(
    RequestOptions options,
    RequestInterceptorHandler handler,
  ) async {
    ...

    final response = await manuallyRefresh();
    if (response?.accessToken != null) {
      options.headers['Authorization'] = response!.accessToken;
    } else {
      options.headers.remove('Authorization');
    }

    return handler.next(options);
  }

Here's the method that throws the exception.

Future<AuthResponse?> manuallyRefresh() async {
    ...

    try {
     ...
    } catch (e) {
      client.unlock();
      throw DirectusError.fromDio(e);
    }
    ...
  }

I think it should handle the logout automatically after an invalid refresh token.

Expose transport like JS SDK

It would be nice to have direct access to Dio in order to use custom endpoints in Directus.

btw. Great project!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.