@strapi/utils 4.4.3 → 4.5.0-beta.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.
@@ -106,9 +106,10 @@ const isPrivateAttribute = (model = {}, attributeName) => {
106
106
  const isScalarAttribute = (attribute) => {
107
107
  return !['media', 'component', 'relation', 'dynamiczone'].includes(attribute.type);
108
108
  };
109
- const isMediaAttribute = (attribute) => attribute.type === 'media';
110
- const isRelationalAttribute = (attribute) => attribute.type === 'relation';
111
- const isComponentAttribute = (attribute) => ['component', 'dynamiczone'].includes(attribute.type);
109
+ const isMediaAttribute = (attribute) => attribute && attribute.type === 'media';
110
+ const isRelationalAttribute = (attribute) => attribute && attribute.type === 'relation';
111
+ const isComponentAttribute = (attribute) =>
112
+ attribute && ['component', 'dynamiczone'].includes(attribute.type);
112
113
 
113
114
  const getComponentAttributes = (schema) => {
114
115
  return _.reduce(
@@ -6,10 +6,22 @@
6
6
  * Converts the standard Strapi REST query params to a more usable format for querying
7
7
  * You can read more here: https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#filters
8
8
  */
9
- const { has, isEmpty, isObject, isPlainObject, cloneDeep, get, mergeAll } = require('lodash/fp');
9
+ const {
10
+ has,
11
+ isEmpty,
12
+ isObject,
13
+ isPlainObject,
14
+ cloneDeep,
15
+ get,
16
+ mergeAll,
17
+ isNil,
18
+ toNumber,
19
+ isInteger,
20
+ } = require('lodash/fp');
10
21
  const _ = require('lodash');
11
22
  const parseType = require('./parse-type');
12
23
  const contentTypesUtils = require('./content-types');
24
+ const { PaginationError } = require('./errors');
13
25
 
14
26
  const { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;
15
27
 
@@ -37,6 +49,10 @@ const convertCountQueryParams = (countQuery) => {
37
49
  return parseType({ type: 'boolean', value: countQuery });
38
50
  };
39
51
 
52
+ const convertOrderingQueryParams = (ordering) => {
53
+ return ordering;
54
+ };
55
+
40
56
  /**
41
57
  * Sort query parser
42
58
  * @param {string} sortQuery - ex: id:asc,price:desc
@@ -236,7 +252,7 @@ const convertNestedPopulate = (subPopulate, schema) => {
236
252
  }
237
253
 
238
254
  // TODO: We will need to consider a way to add limitation / pagination
239
- const { sort, filters, fields, populate, count } = subPopulate;
255
+ const { sort, filters, fields, populate, count, ordering } = subPopulate;
240
256
 
241
257
  const query = {};
242
258
 
@@ -260,6 +276,10 @@ const convertNestedPopulate = (subPopulate, schema) => {
260
276
  query.count = convertCountQueryParams(count);
261
277
  }
262
278
 
279
+ if (ordering) {
280
+ query.ordering = convertOrderingQueryParams(ordering);
281
+ }
282
+
263
283
  return query;
264
284
  };
265
285
 
@@ -389,6 +409,80 @@ const convertPublicationStateParams = (type, params = {}, query = {}) => {
389
409
  }
390
410
  };
391
411
 
412
+ const transformParamsToQuery = (uid, params) => {
413
+ // NOTE: can be a CT, a Compo or nothing in the case of polymorphism (DZ & morph relations)
414
+ const schema = strapi.getModel(uid);
415
+
416
+ const query = {};
417
+
418
+ const { _q, sort, filters, fields, populate, page, pageSize, start, limit } = params;
419
+
420
+ if (!isNil(_q)) {
421
+ query._q = _q;
422
+ }
423
+
424
+ if (!isNil(sort)) {
425
+ query.orderBy = convertSortQueryParams(sort);
426
+ }
427
+
428
+ if (!isNil(filters)) {
429
+ query.where = convertFiltersQueryParams(filters, schema);
430
+ }
431
+
432
+ if (!isNil(fields)) {
433
+ query.select = convertFieldsQueryParams(fields);
434
+ }
435
+
436
+ if (!isNil(populate)) {
437
+ query.populate = convertPopulateQueryParams(populate, schema);
438
+ }
439
+
440
+ const isPagePagination = !isNil(page) || !isNil(pageSize);
441
+ const isOffsetPagination = !isNil(start) || !isNil(limit);
442
+
443
+ if (isPagePagination && isOffsetPagination) {
444
+ throw new PaginationError(
445
+ 'Invalid pagination attributes. You cannot use page and offset pagination in the same query'
446
+ );
447
+ }
448
+
449
+ if (!isNil(page)) {
450
+ const pageVal = toNumber(page);
451
+
452
+ if (!isInteger(pageVal) || pageVal <= 0) {
453
+ throw new PaginationError(
454
+ `Invalid 'page' parameter. Expected an integer > 0, received: ${page}`
455
+ );
456
+ }
457
+
458
+ query.page = pageVal;
459
+ }
460
+
461
+ if (!isNil(pageSize)) {
462
+ const pageSizeVal = toNumber(pageSize);
463
+
464
+ if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {
465
+ throw new PaginationError(
466
+ `Invalid 'pageSize' parameter. Expected an integer > 0, received: ${page}`
467
+ );
468
+ }
469
+
470
+ query.pageSize = pageSizeVal;
471
+ }
472
+
473
+ if (!isNil(start)) {
474
+ query.offset = convertStartQueryParams(start);
475
+ }
476
+
477
+ if (!isNil(limit)) {
478
+ query.limit = convertLimitQueryParams(limit);
479
+ }
480
+
481
+ convertPublicationStateParams(schema, params, query);
482
+
483
+ return query;
484
+ };
485
+
392
486
  module.exports = {
393
487
  convertSortQueryParams,
394
488
  convertStartQueryParams,
@@ -397,4 +491,5 @@ module.exports = {
397
491
  convertFiltersQueryParams,
398
492
  convertFieldsQueryParams,
399
493
  convertPublicationStateParams,
494
+ transformParamsToQuery,
400
495
  };
package/lib/index.js CHANGED
@@ -38,6 +38,7 @@ const pagination = require('./pagination');
38
38
  const sanitize = require('./sanitize');
39
39
  const traverseEntity = require('./traverse-entity');
40
40
  const pipeAsync = require('./pipe-async');
41
+ const convertQueryParams = require('./convert-query-params');
41
42
 
42
43
  module.exports = {
43
44
  yup,
@@ -79,4 +80,5 @@ module.exports = {
79
80
  errors,
80
81
  validateYupSchema,
81
82
  validateYupSchemaSync,
83
+ convertQueryParams,
82
84
  };
package/lib/relations.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ const { isRelationalAttribute } = require('./content-types');
4
+
3
5
  const MANY_RELATIONS = ['oneToMany', 'manyToMany'];
4
6
 
5
7
  const getRelationalFields = (contentType) => {
@@ -8,8 +10,21 @@ const getRelationalFields = (contentType) => {
8
10
  });
9
11
  };
10
12
 
13
+ const isOneToAny = (attribute) =>
14
+ isRelationalAttribute(attribute) && ['oneToOne', 'oneToMany'].includes(attribute.relation);
15
+ const isManyToAny = (attribute) =>
16
+ isRelationalAttribute(attribute) && ['manyToMany', 'manyToOne'].includes(attribute.relation);
17
+ const isAnyToOne = (attribute) =>
18
+ isRelationalAttribute(attribute) && ['oneToOne', 'manyToOne'].includes(attribute.relation);
19
+ const isAnyToMany = (attribute) =>
20
+ isRelationalAttribute(attribute) && ['oneToMany', 'manyToMany'].includes(attribute.relation);
21
+
11
22
  module.exports = {
12
23
  getRelationalFields,
24
+ isOneToAny,
25
+ isManyToAny,
26
+ isAnyToOne,
27
+ isAnyToMany,
13
28
  constants: {
14
29
  MANY_RELATIONS,
15
30
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/utils",
3
- "version": "4.4.3",
3
+ "version": "4.5.0-beta.0",
4
4
  "description": "Shared utilities for the Strapi packages",
5
5
  "keywords": [
6
6
  "strapi",
@@ -45,5 +45,5 @@
45
45
  "node": ">=14.19.1 <=18.x.x",
46
46
  "npm": ">=6.0.0"
47
47
  },
48
- "gitHead": "f99314ead7f0fdf82b921b9d8f0282a91e952ca8"
48
+ "gitHead": "ee98b9a9cbb6e0e07e781ff9e87eb170c72e50df"
49
49
  }