Line data Source code
1 : import 'dart:async';
2 : import 'dart:io';
3 :
4 : import 'package:contentstack/client.dart';
5 : import 'package:contentstack/contentstack.dart';
6 : import 'package:contentstack/src/asset.dart';
7 : import 'package:contentstack/src/asset_query.dart';
8 : import 'package:contentstack/src/image_transform.dart';
9 : import 'package:contentstack/src/sync/publishtype.dart';
10 : import 'package:http/http.dart';
11 :
12 : /// Choosing a Region
13 : /// A Contentstack region refers to the location of the data centers
14 : /// where your organization's data resides
15 : /// * Default [Region](https://www.contentstack.com/docs/developers/contentstack-regions/about-regions/) is: US
16 : // Contact our support team at support@contentstack.com for more details.
17 : enum Region { us, eu }
18 :
19 : /// A stack is like a container that holds the content of your app.
20 : /// Learn more about [Stacks](https://www.contentstack.com/docs/developers/set-up-stack/about-stack/).
21 : class Stack {
22 : Map<String, String> stackHeader = <String, String>{};
23 : final String _apiKey;
24 : final String _deliveryToken;
25 : final String _environment;
26 : final String _host;
27 : final Region region;
28 : final String apiVersion;
29 : HttpClient _client;
30 :
31 : ///
32 : /// Create a new Stack instance with stack's apikey, token,
33 : /// environment name and Optional parameters like.
34 : /// Throws an [ArgumentError] if [apiKey], [deliveryToken]
35 : /// and [environment] is not passed.
36 : /// import 'package:contentstack/contentstack.dart' as contentstack;
37 6 : /// var stack = contentstack.Stack('api_key', 'delivery_token', environment)
38 : ///
39 : /// Example:
40 : ///
41 : /// ```dart
42 6 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
43 : /// ```
44 1 : ///
45 : Stack(this._apiKey, this._deliveryToken, this._environment,
46 1 : {this.apiVersion = 'v3',
47 : this.region = Region.us,
48 24 : String host = 'cdn.contentstack.io',
49 1 : BaseClient client})
50 : : _host = (region == Region.us)
51 : ? host
52 24 : : (host == 'cdn.contentstack.io'
53 1 : ? 'eu-cdn.contentstack.com'
54 : : 'eu-$host') {
55 : // final blank = s == null || s.trim() == '';
56 24 : if (_apiKey.replaceAll(RegExp('\\W'), '').isEmpty ?? true) {
57 1 : throw ArgumentError.notNull('APIkey');
58 : }
59 :
60 12 : if (_deliveryToken.replaceAll(RegExp('\\W'), '').isEmpty ?? true) {
61 6 : throw ArgumentError.notNull('deliveryToken');
62 6 : }
63 6 :
64 : if (_environment.replaceAll(RegExp('\\W'), '').isEmpty ?? true) {
65 : throw ArgumentError.notNull('environment');
66 18 : }
67 :
68 : stackHeader = {
69 : 'api_key': _apiKey,
70 : 'access_token': _deliveryToken,
71 : 'environment': _environment,
72 : };
73 :
74 : _client = HttpClient(stackHeader, client: client, stack: this);
75 : }
76 :
77 : /// It returns apiKey of the Stack
78 : ///
79 : /// Example
80 : /// ```dart
81 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
82 4 : /// var apiKey = stack.apiKey;
83 8 : /// ```
84 : String get apiKey => _apiKey;
85 :
86 : /// It returns delivery token of the Stack
87 : ///
88 : /// Example
89 : ///
90 : /// ```dart
91 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
92 : /// var deliveryToken = stack.deliveryToken;
93 : /// ```
94 : String get deliveryToken => _deliveryToken;
95 :
96 : /// It returns endpoint of the Stack
97 : ///
98 : /// Example
99 : ///
100 1 : /// ```dart
101 2 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
102 : /// var environment = stack.environment;
103 : /// ```
104 : String get endpoint => host;
105 :
106 : /// It returns delivery token of the Environment
107 : ///
108 : /// Example
109 : ///
110 : /// ```dart
111 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
112 : /// var environment = stack.environment;
113 : /// ```
114 : String get environment => _environment;
115 :
116 : /// It returns host of the Stack
117 : ///
118 1 : /// Example
119 2 : ///
120 : /// ```dart
121 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
122 : /// var environment = stack.environment;
123 : /// ```
124 : String get host => _host;
125 :
126 : ///
127 : /// This call fetches the latest version of a specific
128 : /// asset of a particular stack.
129 : /// API Reference :
130 : /// https://www.contentstack.com/docs/developers/apis/content-delivery-api/#single-asset
131 : /// [uid] assetUid
132 1 : ///
133 : /// Example:
134 2 : ///
135 2 : /// ```dart
136 : /// var stack = contentstack.Stack(apiKey, deliveryToken, environment);
137 : /// var asset = stack.asset('uid');
138 : /// ```
139 : ///
140 : Asset asset(String uid) {
141 : return Asset(uid, _client);
142 : }
143 :
144 : ///
145 : /// This call fetches the list of all the assets of a particular stack.
146 : /// It also returns the content of each asset in JSON format.
147 : /// You can also specify the environment of which you wish to get the assets.
148 1 : /// API Reference :
149 2 : /// https://www.contentstack.com/docs/developers/apis/content-delivery-api/#all-assets
150 2 : ///
151 : /// Example:
152 : ///
153 : /// ```dart
154 : /// var stack = contentstack.Stack(apiKey, deliveryToken, environment);
155 : /// var asset = stack.assetQuery();
156 : /// ```
157 : ///
158 : AssetQuery assetQuery() {
159 : return AssetQuery(_client);
160 : }
161 2 :
162 : ///
163 : /// ContentType accepts contentTypeId in as the parameter
164 : /// Returns instance of [ContentType].
165 : /// contentType takes [contentTypeId] as optional parameter
166 : /// If you want get one contentType by their content_type_uid
167 : ///
168 : /// Example:
169 : ///
170 : /// ```dart
171 2 : /// var stack = contentstack.Stack(apiKey, deliveryToken, environment);
172 : /// var contentType = stack.contentType('content_type_id');
173 : /// ```
174 : ///
175 : ContentType contentType([String contentTypeId]) {
176 : return ContentType(contentTypeId, _client);
177 : }
178 :
179 : ///
180 : /// Fetches all Content Types from the Stack.
181 2 : /// This call returns comprehensive information
182 : /// of all the content types available in a particular stack in your account.
183 : /// API Reference: https://www.contentstack.com/docs/apis/content-delivery-api/#content-types
184 : /// [queryParameters] is query parameters for the content_types of type [Map]
185 : /// returns list of content_types
186 : ///
187 : /// Example:
188 : ///
189 : /// ```dart
190 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
191 10 : /// response = stack.getContentTypes(queryParameters);
192 : /// ```
193 : ///
194 : Future<T> getContentTypes<T, K>(Map queryParameters) {
195 : final Uri uri = Uri.https(endpoint, '$apiVersion/content_types');
196 : return _client.sendRequest<T, K>(uri);
197 : }
198 :
199 : ///
200 : /// The Image Delivery API is used to retrieve, manipulate and/or convert image
201 10 : /// files of your Contentstack account and deliver it to your
202 : /// web or mobile properties.
203 : /// {Supported input formats}: JPEG, PNG, WEBP, GIF
204 : /// {Supported output formats}: JPEG (baseline & progressive),
205 : /// PNG, WEBP (lossy & lossless), GIF
206 : /// Read documentation for more details:
207 : /// https://www.contentstack.com/docs/developers/apis/image-delivery-api/#limitations-with-optimizing-image
208 : ///
209 : /// [imageUrl] is the required parameter
210 : ///
211 : /// Example:
212 : ///
213 : /// ```dart
214 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
215 : /// imageTransformation = stack.imageTransform(imageUrl);
216 : /// ```
217 : ///
218 : ImageTransformation imageTransform(String imageUrl) {
219 : return ImageTransformation(imageUrl, _client);
220 : }
221 :
222 1 : ///
223 2 : /// If the result of the initial sync (or subsequent sync)
224 : /// contains more than 100 records, the response would be
225 : /// paginated. It provides pagination token in the response.
226 : /// However, you do not have to use the pagination token
227 : /// manually to get the next batch, the SDK does that
228 : /// automatically until the sync is complete. Pagination token
229 : /// can be used in case you want to fetch only selected batches.
230 : /// It is especially useful if the sync process is
231 : /// interrupted midway (due to network issues, etc.). In such cases,
232 : /// this token can be used to restart the sync
233 : /// process from where it was interrupted.
234 : ///
235 : Future<T> paginationToken<T, K>(String paginationToken) {
236 : final parameters = <String, String>{};
237 : if (paginationToken != null && paginationToken.isNotEmpty) {
238 : parameters['pagination_token'] = paginationToken;
239 : }
240 : return _syncRequest<T, K>(parameters);
241 1 : }
242 4 :
243 2 : ///
244 : /// removeHeader function is to Remove header by [headerKey]
245 : /// It requires header key to delete the header
246 : /// returns [Stack] Instance
247 : ///
248 : /// Example:
249 : /// ```dart
250 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
251 : /// stack = stack..removeHeader('headerKey');
252 : /// ```
253 : void removeHeader(String headerKey) {
254 : if (headerKey != null) {
255 : if (stackHeader.containsKey(headerKey)) {
256 : stackHeader.remove(headerKey);
257 : }
258 : }
259 : }
260 :
261 : /// Adds headers for the request
262 : ///
263 : /// Example:
264 : ///
265 : /// ```dart
266 : /// final stack = contentstack.Stack(apiKey, deliveryToken, environment);
267 : /// stack = stack..setHeader('headerKey', 'headervalue');
268 : /// ```
269 : void setHeader(String key, String value) {
270 : if (key.isNotEmpty && value.isNotEmpty) {
271 : stackHeader[key] = value;
272 : }
273 1 : }
274 :
275 : /////////////////////////////////////////////////
276 : // ---------[Synchronization]---------- //
277 : /////////////////////////////////////////////////
278 1 :
279 1 : /// * [contentTypeUid] -- You can also initialize sync with entries of
280 1 : /// only specific content_type. To do this, use syncContentType and specify
281 1 : /// the content type uid as its value. However, if you do this,
282 : /// the subsequent syncs will only include the entries of the
283 1 : /// specified content_type.
284 1 : ///
285 : /// * [fromDate] -- You can also initialize sync with entries published
286 1 : /// after a specific date. To do this, use from_date
287 1 : /// and specify the start date as its value.
288 : ///
289 : /// * [locale] -- You can also initialize sync with entries of
290 2 : /// only specific locales.
291 1 : /// To do this, use syncLocale and specify the locale code as its value.
292 1 : /// However, if you do this, the subsequent syncs will only include
293 1 : /// the entries of the specified locales.
294 1 : ///
295 1 : /// * [publishType] -- Use the type parameter
296 1 : /// to get a specific type of content.
297 1 : /// If you do not specify any value,
298 1 : /// it will bring all published entries and published assets.
299 1 : ///
300 1 : /// Returns: List Of [SyncResult]
301 1 : ///
302 1 : Future<T> sync<T, K>(
303 1 : {String contentTypeUid,
304 : String fromDate,
305 : String locale,
306 : PublishType publishType}) async {
307 1 : final parameter = <String, String>{};
308 : parameter['init'] = 'true';
309 : if (contentTypeUid != null && contentTypeUid.isNotEmpty) {
310 1 : parameter['content_type_uid'] = contentTypeUid;
311 4 : }
312 4 : if (fromDate != null && fromDate.isNotEmpty) {
313 2 : parameter['from_date'] = fromDate;
314 : }
315 : if (locale != null && locale.isNotEmpty) {
316 : parameter['locale'] = locale;
317 : }
318 : if (publishType != null) {
319 : publishType.when(assetPublished: (result) {
320 : parameter['publish_type'] = 'asset_published';
321 : }, entryPublished: (result) {
322 : parameter['publish_type'] = 'entry_published';
323 : }, assetUnpublished: (result) {
324 : parameter['publish_type'] = 'asset_unpublished';
325 : }, assetDeleted: (result) {
326 : parameter['publish_type'] = 'asset_deleted';
327 : }, entryUnpublished: (result) {
328 : parameter['publish_type'] = 'entry_unpublished';
329 1 : }, entryDeleted: (result) {
330 1 : parameter['publish_type'] = 'entry_deleted';
331 1 : }, contentTypeDeleted: (result) {
332 1 : parameter['publish_type'] = 'content_type_deleted';
333 : });
334 1 : }
335 :
336 : return _syncRequest<T, K>(parameter);
337 : }
338 :
339 : ///
340 : /// You can use the sync token (that you receive after initial sync)
341 : /// to get the updated content next time.
342 : /// sync token fetches only the content that was added after your last sync,
343 : /// and the details of the content that was deleted or updated.
344 1 : ///
345 1 : ///
346 1 : Future<T> syncToken<T, K>(String syncToken) {
347 1 : final parameters = <String, String>{};
348 : if (syncToken != null && syncToken.isNotEmpty) {
349 : parameters['sync_token'] = syncToken;
350 4 : }
351 4 :
352 2 : parameters['environment'] = _client.stackHeaders['environment'];
353 : final Uri uri = Uri.https(endpoint, '$apiVersion/stacks/sync', parameters);
354 : return _client.sendRequest<T, K>(uri);
355 : }
356 :
357 : Future<T> _syncRequest<T, K>(parameters) async {
358 : parameters['environment'] = _client.stackHeaders['environment'];
359 : final Uri uri = Uri.https(endpoint, '$apiVersion/stacks/sync', parameters);
360 : return _client.sendRequest<T, K>(uri);
361 18 : }
362 : }
|