@strapi/utils 4.6.1 → 4.9.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/async.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export type MapAsync<T = any, R = any> = lodash.CurriedFunction3<
1
+ import { CurriedFunction3 } from 'lodash';
2
+
3
+ export type MapAsync<T = any, R = any> = CurriedFunction3<
2
4
  T[],
3
5
  (element: T, index: number) => R | Promise<R>,
4
6
  { concurrency?: number },
@@ -10,3 +12,10 @@ export type ForEachAsync<T = any, R = any> = (
10
12
  func: (element: T, index: number) => R | Promise<R>,
11
13
  options?: { concurrency?: number }
12
14
  ) => Promise<R[]>;
15
+
16
+ export type ReduceAsync<T = any, V = T, R = V> = CurriedFunction3<
17
+ T[],
18
+ (accumulator: V | R, current: Awaited<T>, index: number) => R | Promise<R>,
19
+ V,
20
+ Promise<R>
21
+ >;
package/lib/async.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const pMap = require('p-map');
4
- const { curry } = require('lodash/fp');
4
+ const { curry, curryN } = require('lodash/fp');
5
5
 
6
6
  function pipeAsync(...methods) {
7
7
  return async (data) => {
@@ -20,6 +20,17 @@ function pipeAsync(...methods) {
20
20
  */
21
21
  const mapAsync = curry(pMap);
22
22
 
23
+ /**
24
+ * @type { import('./async').ReduceAsync }
25
+ */
26
+ const reduceAsync = curryN(2, async (mixedArray, iteratee, initialValue) => {
27
+ let acc = initialValue;
28
+ for (let i = 0; i < mixedArray.length; i += 1) {
29
+ acc = await iteratee(acc, await mixedArray[i], i);
30
+ }
31
+ return acc;
32
+ });
33
+
23
34
  /**
24
35
  * @type { import('./async').ForEachAsync }
25
36
  */
@@ -29,6 +40,7 @@ const forEachAsync = curry(async (array, func, options) => {
29
40
 
30
41
  module.exports = {
31
42
  mapAsync,
43
+ reduceAsync,
32
44
  forEachAsync,
33
45
  pipeAsync,
34
46
  };
@@ -139,6 +139,41 @@ const convertLimitQueryParams = (limitQuery) => {
139
139
  return limitAsANumber;
140
140
  };
141
141
 
142
+ const convertPageQueryParams = (page) => {
143
+ const pageVal = toNumber(page);
144
+
145
+ if (!isInteger(pageVal) || pageVal <= 0) {
146
+ throw new PaginationError(
147
+ `Invalid 'page' parameter. Expected an integer > 0, received: ${page}`
148
+ );
149
+ }
150
+
151
+ return pageVal;
152
+ };
153
+
154
+ const convertPageSizeQueryParams = (pageSize, page) => {
155
+ const pageSizeVal = toNumber(pageSize);
156
+
157
+ if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {
158
+ throw new PaginationError(
159
+ `Invalid 'pageSize' parameter. Expected an integer > 0, received: ${page}`
160
+ );
161
+ }
162
+
163
+ return pageSizeVal;
164
+ };
165
+
166
+ const validatePaginationParams = (page, pageSize, start, limit) => {
167
+ const isPagePagination = !isNil(page) || !isNil(pageSize);
168
+ const isOffsetPagination = !isNil(start) || !isNil(limit);
169
+
170
+ if (isPagePagination && isOffsetPagination) {
171
+ throw new PaginationError(
172
+ 'Invalid pagination attributes. You cannot use page and offset pagination in the same query'
173
+ );
174
+ }
175
+ };
176
+
142
177
  class InvalidPopulateError extends Error {
143
178
  constructor() {
144
179
  super();
@@ -280,8 +315,8 @@ const convertNestedPopulate = (subPopulate, schema) => {
280
315
  throw new Error(`Invalid nested populate. Expected '*' or an object`);
281
316
  }
282
317
 
283
- // TODO: We will need to consider a way to add limitation / pagination
284
- const { sort, filters, fields, populate, count, ordering } = subPopulate;
318
+ const { sort, filters, fields, populate, count, ordering, page, pageSize, start, limit } =
319
+ subPopulate;
285
320
 
286
321
  const query = {};
287
322
 
@@ -309,6 +344,26 @@ const convertNestedPopulate = (subPopulate, schema) => {
309
344
  query.ordering = convertOrderingQueryParams(ordering);
310
345
  }
311
346
 
347
+ validatePaginationParams(page, pageSize, start, limit);
348
+
349
+ if (!isNil(page)) {
350
+ query.page = convertPageQueryParams(page);
351
+ }
352
+
353
+ if (!isNil(pageSize)) {
354
+ query.pageSize = convertPageSizeQueryParams(pageSize, page);
355
+ }
356
+
357
+ if (!isNil(start)) {
358
+ query.offset = convertStartQueryParams(start);
359
+ }
360
+
361
+ if (!isNil(limit)) {
362
+ query.limit = convertLimitQueryParams(limit);
363
+ }
364
+
365
+ convertPublicationStateParams(schema, subPopulate, query);
366
+
312
367
  return query;
313
368
  };
314
369
 
@@ -466,37 +521,14 @@ const transformParamsToQuery = (uid, params) => {
466
521
  query.populate = convertPopulateQueryParams(populate, schema);
467
522
  }
468
523
 
469
- const isPagePagination = !isNil(page) || !isNil(pageSize);
470
- const isOffsetPagination = !isNil(start) || !isNil(limit);
471
-
472
- if (isPagePagination && isOffsetPagination) {
473
- throw new PaginationError(
474
- 'Invalid pagination attributes. You cannot use page and offset pagination in the same query'
475
- );
476
- }
524
+ validatePaginationParams(page, pageSize, start, limit);
477
525
 
478
526
  if (!isNil(page)) {
479
- const pageVal = toNumber(page);
480
-
481
- if (!isInteger(pageVal) || pageVal <= 0) {
482
- throw new PaginationError(
483
- `Invalid 'page' parameter. Expected an integer > 0, received: ${page}`
484
- );
485
- }
486
-
487
- query.page = pageVal;
527
+ query.page = convertPageQueryParams(page);
488
528
  }
489
529
 
490
530
  if (!isNil(pageSize)) {
491
- const pageSizeVal = toNumber(pageSize);
492
-
493
- if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {
494
- throw new PaginationError(
495
- `Invalid 'pageSize' parameter. Expected an integer > 0, received: ${page}`
496
- );
497
- }
498
-
499
- query.pageSize = pageSizeVal;
531
+ query.pageSize = convertPageSizeQueryParams(pageSize, page);
500
532
  }
501
533
 
502
534
  if (!isNil(start)) {
package/lib/index.js CHANGED
@@ -37,7 +37,7 @@ const providerFactory = require('./provider-factory');
37
37
  const pagination = require('./pagination');
38
38
  const sanitize = require('./sanitize');
39
39
  const traverseEntity = require('./traverse-entity');
40
- const { pipeAsync, mapAsync, forEachAsync } = require('./async');
40
+ const { pipeAsync, mapAsync, reduceAsync, forEachAsync } = require('./async');
41
41
  const convertQueryParams = require('./convert-query-params');
42
42
  const importDefault = require('./import-default');
43
43
  const template = require('./template');
@@ -83,6 +83,7 @@ module.exports = {
83
83
  pagination,
84
84
  pipeAsync,
85
85
  mapAsync,
86
+ reduceAsync,
86
87
  forEachAsync,
87
88
  errors,
88
89
  validateYupSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/utils",
3
- "version": "4.6.1",
3
+ "version": "4.9.0-alpha.0",
4
4
  "description": "Shared utilities for the Strapi packages",
5
5
  "keywords": [
6
6
  "strapi",
@@ -46,5 +46,5 @@
46
46
  "node": ">=14.19.1 <=18.x.x",
47
47
  "npm": ">=6.0.0"
48
48
  },
49
- "gitHead": "17a7845e3d453ea2e7911bda6ec25ed196dd5f16"
49
+ "gitHead": "35f783d0dc07db101e7e62cb4d682f751551f452"
50
50
  }