Skip to content

Commit 90ac4e9

Browse files
Merge pull request #27 from contentstack/staging
DX | 17-02-2025
2 parents 0447301 + 826743a commit 90ac4e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1049
-3268
lines changed

.github/workflows/check-branch.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- name: Comment PR
11-
if: github.base_ref == 'master' && github.head_ref != 'next'
11+
if: github.base_ref == 'master' && github.head_ref != 'staging'
1212
uses: thollander/actions-comment-pull-request@v2
1313
with:
1414
message: |
1515
We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch.
1616
- name: Check branch
17-
if: github.base_ref == 'master' && github.head_ref != 'next'
17+
if: github.base_ref == 'master' && github.head_ref != 'staging'
1818
run: |
1919
echo "ERROR: We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch."
2020
exit 1

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
### **FEB-17-2025**
4+
5+
#### v1.0.0 - v3 migration null support added
6+
#### Removed super_enum lib
7+
38
## v0.5.1 - Added support for gcp_na region
49
#### Added support for gcp_na region
510

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MIT License
22

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

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ final response = imageTransformation..canvas(imageParams)..getUrl();
168168

169169
MIT License
170170

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

174174
Permission is hereby granted, free of charge, to any person obtaining a copy

SECURITY.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Security
2+
3+
Contentstack takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations.
4+
5+
If you believe you have found a security vulnerability in any Contentstack-owned repository, please report it to us as described below.
6+
7+
## Reporting Security Issues
8+
9+
**Please do not report security vulnerabilities through public GitHub issues.**
10+
11+
Send email to [[email protected]](mailto:[email protected]).
12+
13+
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.
14+
15+
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
16+
17+
- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
18+
- Full paths of source file(s) related to the manifestation of the issue
19+
- The location of the affected source code (tag/branch/commit or direct URL)
20+
- Any special configuration required to reproduce the issue
21+
- Step-by-step instructions to reproduce the issue
22+
- Proof-of-concept or exploit code (if possible)
23+
- Impact of the issue, including how an attacker might exploit the issue
24+
25+
This information will help us triage your report more quickly.
26+
27+
[https://www.contentstack.com/trust/](https://www.contentstack.com/trust/)

lib/client.dart

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import 'package:http/http.dart' as http;
77

88
class HttpClient extends http.BaseClient {
99
final http.Client _client;
10-
final Stack stack;
11-
final Map<String, String> stackHeaders;
10+
final Stack? stack;
11+
final Map<String, String>? stackHeaders;
1212

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

29-
Future<T> sendRequest<T, K>(Uri uri) async {
30-
stackHeaders[CONTENT_TYPE] = CONTENT_TYPE_VALUE;
31-
stackHeaders[X_USER_AGENT] = X_USER_AGENT_VALUE;
29+
Future<T?> sendRequest<T, K>(Uri uri) async {
30+
stackHeaders![CONTENT_TYPE] = CONTENT_TYPE_VALUE;
31+
stackHeaders![X_USER_AGENT] = X_USER_AGENT_VALUE;
3232
final response = await http
33-
.get(uri, headers: stackHeaders)
33+
.get(uri, headers: stackHeaders as Map<String, String>)
3434
.timeout(const Duration(seconds: TIMEOUT));
35-
Object bodyJson;
35+
Object? bodyJson;
3636
try {
3737
bodyJson = jsonDecode(response.body);
3838
} on FormatException {
@@ -44,42 +44,42 @@ class HttpClient extends http.BaseClient {
4444
rethrow;
4545
}
4646
if (response.statusCode == 200) {
47-
final Map bodyJson = json.decode(utf8.decode(response.bodyBytes));
48-
if (T == EntryModel && bodyJson.containsKey('entry')) {
47+
final Map? bodyJson = json.decode(utf8.decode(response.bodyBytes));
48+
if (T == EntryModel && bodyJson!.containsKey('entry')) {
4949
return fromJson<T, K>(bodyJson['entry']);
50-
} else if (K == EntryModel && bodyJson.containsKey('entries')) {
50+
} else if (K == EntryModel && bodyJson!.containsKey('entries')) {
5151
return fromJson<T, K>(bodyJson['entries']);
52-
} else if (T == AssetModel && bodyJson.containsKey('asset')) {
52+
} else if (T == AssetModel && bodyJson!.containsKey('asset')) {
5353
return fromJson<T, K>(bodyJson['asset']);
54-
} else if (K == AssetModel && bodyJson.containsKey('assets')) {
54+
} else if (K == AssetModel && bodyJson!.containsKey('assets')) {
5555
return fromJson<T, K>(bodyJson['assets']);
56-
} else if (T == SyncResult && bodyJson.containsKey('items')) {
56+
} else if (T == SyncResult && bodyJson!.containsKey('items')) {
5757
return fromJson<T, K>(bodyJson);
5858
} else {
59-
if (bodyJson.containsKey('entries')) {
60-
var previewResponse = stack.livePreview['entries'];
59+
if (bodyJson!.containsKey('entries')) {
60+
var previewResponse = stack!.livePreview?.entries;
6161
if (previewResponse != null) {
62-
return fromJson<T, K>(mergeLivePreview(bodyJson, previewResponse));
62+
return fromJson<T, K>(mergeLivePreview(bodyJson, Map.fromEntries(previewResponse)));
6363
}
6464
}
6565
return fromJson<T, K>(bodyJson);
6666
}
6767
} else {
68-
return bodyJson;
68+
return fromJson<T, K>(bodyJson) as FutureOr<T?>;
6969
}
7070
}
7171

72-
mergeLivePreview(Map bodyJson, Map previewResponse) {}
72+
mergeLivePreview(Map? bodyJson, Map previewResponse) {}
7373

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

94-
static List<K> _fromJsonList<K>(List jsonList) {
94+
static List<K?>? _fromJsonList<K>(List? jsonList) {
9595
if (jsonList == null) {
9696
return null;
9797
}
9898

99-
final output = <K>[];
99+
final output = <K?>[];
100100
// ignore: prefer_final_in_for_each
101-
for (Map<String, dynamic> json in jsonList) {
101+
for (Map<String, dynamic> json in jsonList as Iterable<Map<String, dynamic>>) {
102102
output.add(fromJson(json));
103103
}
104104
return output;

lib/constant.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ const X_USER_AGENT_VALUE = '$SDK_NAME-v$SDK_VERSION';
99
const TIMEOUT = 30;
1010

1111
void ifLivePreviewEnable(HttpClient _client) {
12-
final dictLivePreview = _client.stack.livePreview;
12+
final dictLivePreview = _client.stack!.livePreview;
1313
const String AUTH = 'authorization';
14-
if (dictLivePreview.containsKey('enable')) {
15-
_client.stack.removeHeader('access_token');
16-
_client.stack.removeHeader('environment');
17-
_client.stack.setHeader(AUTH, _client.stack.livePreview[AUTH]);
18-
_client.stack.setHost(dictLivePreview['host']);
14+
if (dictLivePreview!.containsKey('enable')) {
15+
_client.stack!.removeHeader('access_token');
16+
_client.stack!.removeHeader('environment');
17+
_client.stack!.setHeader(AUTH, _client.stack!.livePreview![AUTH]);
18+
_client.stack!.setHost(dictLivePreview['host']);
1919
final String errMessage = '''Invalid content_type_uid! Make sure you have
2020
provided same content_type_uid
2121
livePreviewQuery parameter in stack class''';

lib/src/asset.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import 'package:contentstack/client.dart';
88
/// Learn more about [Assets](https://www.contentstack.com/docs/developers/apis/content-delivery-api/#get-a-single-asset)
99
///
1010
class Asset {
11-
final HttpClient _client;
12-
final String _uid;
13-
String _urlPath;
11+
final HttpClient? _client;
12+
final String? _uid;
13+
String? _urlPath;
1414

15-
final Map<String, String> assetParameter = <String, String>{};
15+
final Map<String, String?> assetParameter = <String, String?>{};
1616

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

3434
///
@@ -57,13 +57,13 @@ class Asset {
5757
/// }).catchError((error) {
5858
/// print(error['error_code']);
5959
/// });
60-
Future<T> fetch<T, K>() {
61-
if (_uid == null || _uid.isEmpty) {
60+
Future<T?> fetch<T, K>() {
61+
if (_uid == null || _uid!.isEmpty) {
6262
throw Exception('Provide asset uid to fetch single entry');
6363
}
6464
final uri =
65-
Uri.https(_client.stack.endpoint, '$_urlPath/$_uid', assetParameter);
66-
return _client.sendRequest<T, K>(uri);
65+
Uri.https(_client!.stack!.endpoint!, '$_urlPath/$_uid', assetParameter);
66+
return _client!.sendRequest<T, K>(uri);
6767
}
6868

6969
///

lib/src/asset_query.dart

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

1414
AssetQuery([this._client]) {
15-
queryParameter['environment'] = _client.stackHeaders['environment'];
16-
_urlPath = '/${_client.stack.apiVersion}/assets';
15+
queryParameter['environment'] = _client!.stackHeaders!['environment'];
16+
_urlPath = '/${_client!.stack!.apiVersion}/assets';
1717
}
1818

1919
///
@@ -42,9 +42,9 @@ class AssetQuery extends BaseQuery {
4242
/// }).catchError((error) {
4343
/// print(error['error_code']);
4444
/// });
45-
Future<T> find<T, K>() async {
46-
final uri = Uri.https(_client.stack.endpoint, _urlPath, queryParameter);
47-
return _client.sendRequest<T, K>(uri);
45+
Future<T?> find<T, K>() async {
46+
final uri = Uri.https(_client!.stack!.endpoint!, _urlPath, queryParameter);
47+
return _client!.sendRequest<T, K>(uri);
4848
}
4949

5050
///

lib/src/base_query.dart

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import 'package:contentstack/src/enums/operations.dart';
2+
import 'package:contentstack/src/enums/operations_type.dart';
23

34
///
45
/// This is base Query class that contains common
56
/// functions to query in Entry, Assets and content_type
67
/// common query for asset & entry
78
class BaseQuery {
8-
final Map<String, String> queryParameter = <String, String>{};
9+
final Map<String, String?> queryParameter = <String, String?>{};
910
final Map<String, dynamic> parameter = <String, dynamic>{};
1011

1112
///
@@ -156,27 +157,38 @@ class BaseQuery {
156157

157158
void where(String fieldUid, QueryOperation queryOperation) {
158159
if (fieldUid != null && fieldUid.isNotEmpty) {
159-
queryOperation.when(equals: (operation) {
160-
parameter[fieldUid] = operation.value;
161-
}, notEquals: (operation) {
162-
parameter[fieldUid] = {'\$ne': operation.value};
163-
}, includes: (operation) {
164-
parameter[fieldUid] = {'\$in': operation.value};
165-
}, excludes: (operation) {
166-
parameter[fieldUid] = {'\$nin': operation.value};
167-
}, isLessThan: (operation) {
168-
parameter[fieldUid] = {'\$lt': operation.value};
169-
}, isLessThanOrEqual: (operation) {
170-
parameter[fieldUid] = {'\$lte': operation.value};
171-
}, isGreaterThan: (operation) {
172-
parameter[fieldUid] = {'\$gt': operation.value};
173-
}, isGreaterThanOrEqual: (operation) {
174-
parameter[fieldUid] = {'\$gte': operation.value};
175-
}, exists: (operation) {
176-
parameter[fieldUid] = {'\$exists': operation.value};
177-
}, matches: (operation) {
178-
parameter[fieldUid] = {'\$regex': operation.regex};
179-
});
160+
switch(queryOperation.operationType) {
161+
case QueryOperationType.Equals:
162+
parameter[fieldUid] = queryOperation.value;
163+
break;
164+
case QueryOperationType.NotEquals:
165+
parameter[fieldUid] = {'\$ne': queryOperation.value};
166+
break;
167+
case QueryOperationType.Includes:
168+
parameter[fieldUid] = {'\$in': queryOperation.value};
169+
break;
170+
case QueryOperationType.Excludes:
171+
parameter[fieldUid] = {'\$nin': queryOperation.value};
172+
break;
173+
case QueryOperationType.IsLessThan:
174+
parameter[fieldUid] = {'\$lt': queryOperation.value};
175+
break;
176+
case QueryOperationType.IsLessThanOrEqual:
177+
parameter[fieldUid] = {'\$lte': queryOperation.value};
178+
break;
179+
case QueryOperationType.IsGreaterThan:
180+
parameter[fieldUid] = {'\$gt': queryOperation.value};
181+
break;
182+
case QueryOperationType.IsGreaterThanOrEqual:
183+
parameter[fieldUid] = {'\$gte': queryOperation.value};
184+
break;
185+
case QueryOperationType.Exists:
186+
parameter[fieldUid] = {'\$exists': queryOperation.value};
187+
break;
188+
case QueryOperationType.Matches:
189+
parameter[fieldUid] = {'\$regex': queryOperation.value};
190+
break;
191+
}
180192
}
181193
}
182194
}

0 commit comments

Comments
 (0)