Skip to content

Commit

Permalink
Merge pull request #25 from contentstack/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
reeshika-h authored Feb 10, 2025
2 parents 0c796d1 + ee91b8a commit 4defbbc
Show file tree
Hide file tree
Showing 55 changed files with 944 additions and 3,190 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

### **FEB-17-2025**

#### v1.0.0 - v3 migration null support added
#### Removed super_enum lib

## v0.5.1 - Added support for gcp_na region
#### Added support for gcp_na region

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License

Copyright (c) 2012 - 2024 Contentstack. All rights reserved.
Copyright (c) 2012 - 2025 Contentstack. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ final response = imageTransformation..canvas(imageParams)..getUrl();

MIT License

Copyright (c) 2012 - 2021
Copyright (c) 2012 - 2025
[Contentstack](https://www.contentstack.com/). All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
50 changes: 25 additions & 25 deletions lib/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import 'package:http/http.dart' as http;

class HttpClient extends http.BaseClient {
final http.Client _client;
final Stack stack;
final Map<String, String> stackHeaders;
final Stack? stack;
final Map<String, String>? stackHeaders;

factory HttpClient(Map<String, String> headers,
{http.Client client, Stack stack}) {
factory HttpClient(Map<String, String>? headers,
{http.Client? client, Stack? stack}) {
final stackClient = client ?? http.Client();
return HttpClient._internal(stackClient, headers, stack);
}
Expand All @@ -26,13 +26,13 @@ class HttpClient extends http.BaseClient {
return _client.send(request);
}

Future<T> sendRequest<T, K>(Uri uri) async {
stackHeaders[CONTENT_TYPE] = CONTENT_TYPE_VALUE;
stackHeaders[X_USER_AGENT] = X_USER_AGENT_VALUE;
Future<T?> sendRequest<T, K>(Uri uri) async {
stackHeaders![CONTENT_TYPE] = CONTENT_TYPE_VALUE;
stackHeaders![X_USER_AGENT] = X_USER_AGENT_VALUE;
final response = await http
.get(uri, headers: stackHeaders)
.get(uri, headers: stackHeaders as Map<String, String>)
.timeout(const Duration(seconds: TIMEOUT));
Object bodyJson;
Object? bodyJson;
try {
bodyJson = jsonDecode(response.body);
} on FormatException {
Expand All @@ -44,42 +44,42 @@ class HttpClient extends http.BaseClient {
rethrow;
}
if (response.statusCode == 200) {
final Map bodyJson = json.decode(utf8.decode(response.bodyBytes));
if (T == EntryModel && bodyJson.containsKey('entry')) {
final Map? bodyJson = json.decode(utf8.decode(response.bodyBytes));
if (T == EntryModel && bodyJson!.containsKey('entry')) {
return fromJson<T, K>(bodyJson['entry']);
} else if (K == EntryModel && bodyJson.containsKey('entries')) {
} else if (K == EntryModel && bodyJson!.containsKey('entries')) {
return fromJson<T, K>(bodyJson['entries']);
} else if (T == AssetModel && bodyJson.containsKey('asset')) {
} else if (T == AssetModel && bodyJson!.containsKey('asset')) {
return fromJson<T, K>(bodyJson['asset']);
} else if (K == AssetModel && bodyJson.containsKey('assets')) {
} else if (K == AssetModel && bodyJson!.containsKey('assets')) {
return fromJson<T, K>(bodyJson['assets']);
} else if (T == SyncResult && bodyJson.containsKey('items')) {
} else if (T == SyncResult && bodyJson!.containsKey('items')) {
return fromJson<T, K>(bodyJson);
} else {
if (bodyJson.containsKey('entries')) {
var previewResponse = stack.livePreview['entries'];
if (bodyJson!.containsKey('entries')) {
var previewResponse = stack!.livePreview?.entries;
if (previewResponse != null) {
return fromJson<T, K>(mergeLivePreview(bodyJson, previewResponse));
return fromJson<T, K>(mergeLivePreview(bodyJson, Map.fromEntries(previewResponse)));
}
}
return fromJson<T, K>(bodyJson);
}
} else {
return bodyJson;
return fromJson<T, K>(bodyJson) as FutureOr<T?>;
}
}

mergeLivePreview(Map bodyJson, Map previewResponse) {}
mergeLivePreview(Map? bodyJson, Map previewResponse) {}

/// Generic objects as well as List of generic objects
/// (from a JSON list response).
/// First, you need to have a function that checks the type of the
/// generic object and returns the result of the corresponding fromJson call
/// code taken from:
/// https://stackoverflow.com/questions/56271651/how-to-pass-a-generic-type-as-a-parameter-to-a-future-in-flutter
static T fromJson<T, K>(dynamic json) {
static T? fromJson<T, K>(dynamic json) {
if (json is Iterable) {
return _fromJsonList<K>(json) as T;
return _fromJsonList<K>(json as List<dynamic>) as T;
} else if (T == AssetModel) {
return AssetModel.fromJson(json) as T;
} else if (T == EntryModel) {
Expand All @@ -91,14 +91,14 @@ class HttpClient extends http.BaseClient {
}
}

static List<K> _fromJsonList<K>(List jsonList) {
static List<K?>? _fromJsonList<K>(List? jsonList) {
if (jsonList == null) {
return null;
}

final output = <K>[];
final output = <K?>[];
// ignore: prefer_final_in_for_each
for (Map<String, dynamic> json in jsonList) {
for (Map<String, dynamic> json in jsonList as Iterable<Map<String, dynamic>>) {
output.add(fromJson(json));
}
return output;
Expand Down
12 changes: 6 additions & 6 deletions lib/constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ const X_USER_AGENT_VALUE = '$SDK_NAME-v$SDK_VERSION';
const TIMEOUT = 30;

void ifLivePreviewEnable(HttpClient _client) {
final dictLivePreview = _client.stack.livePreview;
final dictLivePreview = _client.stack!.livePreview;
const String AUTH = 'authorization';
if (dictLivePreview.containsKey('enable')) {
_client.stack.removeHeader('access_token');
_client.stack.removeHeader('environment');
_client.stack.setHeader(AUTH, _client.stack.livePreview[AUTH]);
_client.stack.setHost(dictLivePreview['host']);
if (dictLivePreview!.containsKey('enable')) {
_client.stack!.removeHeader('access_token');
_client.stack!.removeHeader('environment');
_client.stack!.setHeader(AUTH, _client.stack!.livePreview![AUTH]);
_client.stack!.setHost(dictLivePreview['host']);
final String errMessage = '''Invalid content_type_uid! Make sure you have
provided same content_type_uid
livePreviewQuery parameter in stack class''';
Expand Down
20 changes: 10 additions & 10 deletions lib/src/asset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import 'package:contentstack/client.dart';
/// Learn more about [Assets](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#get-a-single-asset)
///
class Asset {
final HttpClient _client;
final String _uid;
String _urlPath;
final HttpClient? _client;
final String? _uid;
String? _urlPath;

final Map<String, String> assetParameter = <String, String>{};
final Map<String, String?> assetParameter = <String, String?>{};

/// * [_uid] assetUid:
/// Enter the unique ID of the asset of which you wish to retrieve
Expand All @@ -27,8 +27,8 @@ class Asset {
/// });
///
Asset(this._uid, [this._client]) {
assetParameter['environment'] = _client.stackHeaders['environment'];
_urlPath = '/${_client.stack.apiVersion}/assets';
assetParameter['environment'] = _client!.stackHeaders!['environment'];
_urlPath = '/${_client!.stack!.apiVersion}/assets';
}

///
Expand Down Expand Up @@ -57,13 +57,13 @@ class Asset {
/// }).catchError((error) {
/// print(error['error_code']);
/// });
Future<T> fetch<T, K>() {
if (_uid == null || _uid.isEmpty) {
Future<T?> fetch<T, K>() {
if (_uid == null || _uid!.isEmpty) {
throw Exception('Provide asset uid to fetch single entry');
}
final uri =
Uri.https(_client.stack.endpoint, '$_urlPath/$_uid', assetParameter);
return _client.sendRequest<T, K>(uri);
Uri.https(_client!.stack!.endpoint!, '$_urlPath/$_uid', assetParameter);
return _client!.sendRequest<T, K>(uri);
}

///
Expand Down
14 changes: 7 additions & 7 deletions lib/src/asset_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import 'package:contentstack/src/base_query.dart';
/// You can also specify the environment of which you wish to get the assets.
/// Learn more about [Assets](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#all-assets)
class AssetQuery extends BaseQuery {
final HttpClient _client;
String _urlPath;
final HttpClient? _client;
late String _urlPath;

AssetQuery([this._client]) {
queryParameter['environment'] = _client.stackHeaders['environment'];
_urlPath = '/${_client.stack.apiVersion}/assets';
queryParameter['environment'] = _client!.stackHeaders!['environment'];
_urlPath = '/${_client!.stack!.apiVersion}/assets';
}

///
Expand Down Expand Up @@ -42,9 +42,9 @@ class AssetQuery extends BaseQuery {
/// }).catchError((error) {
/// print(error['error_code']);
/// });
Future<T> find<T, K>() async {
final uri = Uri.https(_client.stack.endpoint, _urlPath, queryParameter);
return _client.sendRequest<T, K>(uri);
Future<T?> find<T, K>() async {
final uri = Uri.https(_client!.stack!.endpoint!, _urlPath, queryParameter);
return _client!.sendRequest<T, K>(uri);
}

///
Expand Down
56 changes: 34 additions & 22 deletions lib/src/base_query.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'package:contentstack/src/enums/operations.dart';
import 'package:contentstack/src/enums/operations_type.dart';

///
/// This is base Query class that contains common
/// functions to query in Entry, Assets and content_type
/// common query for asset & entry
class BaseQuery {
final Map<String, String> queryParameter = <String, String>{};
final Map<String, String?> queryParameter = <String, String?>{};
final Map<String, dynamic> parameter = <String, dynamic>{};

///
Expand Down Expand Up @@ -156,27 +157,38 @@ class BaseQuery {

void where(String fieldUid, QueryOperation queryOperation) {
if (fieldUid != null && fieldUid.isNotEmpty) {
queryOperation.when(equals: (operation) {
parameter[fieldUid] = operation.value;
}, notEquals: (operation) {
parameter[fieldUid] = {'\$ne': operation.value};
}, includes: (operation) {
parameter[fieldUid] = {'\$in': operation.value};
}, excludes: (operation) {
parameter[fieldUid] = {'\$nin': operation.value};
}, isLessThan: (operation) {
parameter[fieldUid] = {'\$lt': operation.value};
}, isLessThanOrEqual: (operation) {
parameter[fieldUid] = {'\$lte': operation.value};
}, isGreaterThan: (operation) {
parameter[fieldUid] = {'\$gt': operation.value};
}, isGreaterThanOrEqual: (operation) {
parameter[fieldUid] = {'\$gte': operation.value};
}, exists: (operation) {
parameter[fieldUid] = {'\$exists': operation.value};
}, matches: (operation) {
parameter[fieldUid] = {'\$regex': operation.regex};
});
switch(queryOperation.operationType) {
case QueryOperationType.Equals:
parameter[fieldUid] = queryOperation.value;
break;
case QueryOperationType.NotEquals:
parameter[fieldUid] = {'\$ne': queryOperation.value};
break;
case QueryOperationType.Includes:
parameter[fieldUid] = {'\$in': queryOperation.value};
break;
case QueryOperationType.Excludes:
parameter[fieldUid] = {'\$nin': queryOperation.value};
break;
case QueryOperationType.IsLessThan:
parameter[fieldUid] = {'\$lt': queryOperation.value};
break;
case QueryOperationType.IsLessThanOrEqual:
parameter[fieldUid] = {'\$lte': queryOperation.value};
break;
case QueryOperationType.IsGreaterThan:
parameter[fieldUid] = {'\$gt': queryOperation.value};
break;
case QueryOperationType.IsGreaterThanOrEqual:
parameter[fieldUid] = {'\$gte': queryOperation.value};
break;
case QueryOperationType.Exists:
parameter[fieldUid] = {'\$exists': queryOperation.value};
break;
case QueryOperationType.Matches:
parameter[fieldUid] = {'\$regex': queryOperation.value};
break;
}
}
}
}
26 changes: 13 additions & 13 deletions lib/src/contenttype.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import 'package:contentstack/contentstack.dart';
/// * Read more about [ContentTypes](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#content-types).
///
class ContentType {
final String _contentTypeUid;
final HttpClient _client;
String urlPath;
final Map<String, String> _queryParameter = <String, String>{};
final String? _contentTypeUid;
final HttpClient? _client;
String? urlPath;
final Map<String, String?> _queryParameter = <String, String?>{};

ContentType([this._contentTypeUid, this._client]) {
_queryParameter['environment'] = _client.stackHeaders['environment'];
if (_contentTypeUid != null && _contentTypeUid.isNotEmpty) {
urlPath = '/${_client.stack.apiVersion}/content_types/$_contentTypeUid';
_queryParameter['environment'] = _client!.stackHeaders!['environment'];
if (_contentTypeUid != null && _contentTypeUid!.isNotEmpty) {
urlPath = '/${_client!.stack!.apiVersion}/content_types/$_contentTypeUid';
}
}

Expand All @@ -45,7 +45,7 @@ class ContentType {
///
/// ```
///
Entry entry({String entryUid}) {
Entry entry({String? entryUid}) {
return Entry(entryUid, _client, _contentTypeUid);
}

Expand All @@ -65,15 +65,15 @@ class ContentType {
/// print(response);
/// ```
///
Future<T> fetch<T, K>([Map<String, dynamic> queryParams]) {
Future<T?> fetch<T, K>([Map<String, dynamic>? queryParams]) {
if (urlPath == null) {
throw Exception('content_type_uid is missing');
}
if (queryParams != null && queryParams.isNotEmpty) {
_queryParameter.addAll(queryParams);
_queryParameter.addAll(queryParams as Map<String, String?>);
}
final uri = Uri.https(_client.stack.endpoint, urlPath, _queryParameter);
return _client.sendRequest<T, K>(uri);
final uri = Uri.https(_client!.stack!.endpoint!, urlPath!, _queryParameter);
return _client!.sendRequest<T, K>(uri);
}

///
Expand All @@ -90,6 +90,6 @@ class ContentType {
/// ```
///
ContentTypeQuery query() {
return ContentTypeQuery(_client);
return ContentTypeQuery(_client!);
}
}
14 changes: 7 additions & 7 deletions lib/src/contenttype_query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import 'package:contentstack/src/base_query.dart';
/// available in a particular stack in your account.
/// [ContentType](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#all-content-types).
class ContentTypeQuery extends BaseQuery {
final HttpClient _client;
String _urlPath;
final HttpClient? _client;
late String _urlPath;

ContentTypeQuery([this._client]) {
queryParameter['environment'] = _client.stackHeaders['environment'];
_urlPath = '/${_client.stack.apiVersion}/content_types';
queryParameter['environment'] = _client!.stackHeaders!['environment'];
_urlPath = '/${_client!.stack!.apiVersion}/content_types';
}

/// This call returns comprehensive information of all the content types
Expand All @@ -27,12 +27,12 @@ class ContentTypeQuery extends BaseQuery {
/// print(response);
/// ```
///
Future<T> find<T, K>({Map<String, String> queryParams}) async {
Future<T?> find<T, K>({Map<String, String>? queryParams}) async {
if (queryParams != null && queryParams.isNotEmpty) {
queryParameter.addAll(queryParams);
}
final uri = Uri.https(_client.stack.endpoint, _urlPath, queryParameter);
return _client.sendRequest<T, K>(uri);
final uri = Uri.https(_client!.stack!.endpoint!, _urlPath, queryParameter);
return _client!.sendRequest<T, K>(uri);
}

///
Expand Down
Loading

0 comments on commit 4defbbc

Please sign in to comment.