@strapi/utils 4.10.0-beta.0 → 4.10.0-beta.1

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/.eslintignore ADDED
@@ -0,0 +1,3 @@
1
+ node_modules/
2
+ .eslintrc.js
3
+ index.d.ts
package/.eslintrc.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['custom/back'],
4
+ };
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ const utils: any;
2
+
3
+ export default utils;
package/lib/async.js CHANGED
@@ -6,9 +6,8 @@ const { curry, curryN } = require('lodash/fp');
6
6
  function pipeAsync(...methods) {
7
7
  return async (data) => {
8
8
  let res = data;
9
-
10
- for (const method of methods) {
11
- res = await method(res);
9
+ for (let i = 0; i < methods.length; i += 1) {
10
+ res = await methods[i](res);
12
11
  }
13
12
 
14
13
  return res;
@@ -37,12 +37,16 @@ const createContentAPISanitizers = () => {
37
37
  return pipeAsync(...transforms)(data);
38
38
  };
39
39
 
40
- const sanitizeOuput = (data, schema, { auth } = {}) => {
40
+ const sanitizeOutput = async (data, schema, { auth } = {}) => {
41
41
  if (isArray(data)) {
42
- return Promise.all(data.map((entry) => sanitizeOuput(entry, schema, { auth })));
42
+ const res = new Array(data.length);
43
+ for (let i = 0; i < data.length; i += 1) {
44
+ res[i] = await sanitizeOutput(data[i], schema, { auth });
45
+ }
46
+ return res;
43
47
  }
44
48
 
45
- const transforms = [sanitizers.defaultSanitizeOutput(schema)];
49
+ const transforms = [(data) => sanitizers.defaultSanitizeOutput(schema, data)];
46
50
 
47
51
  if (auth) {
48
52
  transforms.push(traverseEntity(visitors.removeRestrictedRelations(auth), { schema }));
@@ -122,7 +126,7 @@ const createContentAPISanitizers = () => {
122
126
 
123
127
  return {
124
128
  input: sanitizeInput,
125
- output: sanitizeOuput,
129
+ output: sanitizeOutput,
126
130
  query: sanitizeQuery,
127
131
  filters: sanitizeFilters,
128
132
  sort: sanitizeSort,
@@ -20,17 +20,20 @@ const {
20
20
  removeMorphToRelations,
21
21
  } = require('./visitors');
22
22
 
23
- const sanitizePasswords = curry((schema, entity) => {
23
+ const sanitizePasswords = (schema) => async (entity) => {
24
24
  return traverseEntity(removePassword, { schema }, entity);
25
- });
26
-
27
- const sanitizePrivates = curry((schema, entity) => {
28
- return traverseEntity(removePrivate, { schema }, entity);
29
- });
25
+ };
30
26
 
31
- const defaultSanitizeOutput = curry((schema, entity) => {
32
- return pipeAsync(sanitizePrivates(schema), sanitizePasswords(schema))(entity);
33
- });
27
+ const defaultSanitizeOutput = async (schema, entity) => {
28
+ return traverseEntity(
29
+ (...args) => {
30
+ removePassword(...args);
31
+ removePrivate(...args);
32
+ },
33
+ { schema },
34
+ entity
35
+ );
36
+ };
34
37
 
35
38
  const defaultSanitizeFilters = curry((schema, filters) => {
36
39
  return pipeAsync(
@@ -140,7 +143,6 @@ const defaultSanitizePopulate = curry((schema, populate) => {
140
143
 
141
144
  module.exports = {
142
145
  sanitizePasswords,
143
- sanitizePrivates,
144
146
  defaultSanitizeOutput,
145
147
  defaultSanitizeFilters,
146
148
  defaultSanitizeSort,
@@ -1,6 +1,42 @@
1
1
  'use strict';
2
2
 
3
- const { cloneDeep, isObject, isArray, isNil, curry } = require('lodash/fp');
3
+ const { clone, isObject, isArray, isNil, curry } = require('lodash/fp');
4
+
5
+ const traverseMorphRelationTarget = async (visitor, path, entry) => {
6
+ const targetSchema = strapi.getModel(entry.__type);
7
+
8
+ const traverseOptions = { schema: targetSchema, path };
9
+
10
+ return traverseEntity(visitor, traverseOptions, entry);
11
+ };
12
+
13
+ const traverseRelationTarget = (schema) => async (visitor, path, entry) => {
14
+ const traverseOptions = { schema, path };
15
+
16
+ return traverseEntity(visitor, traverseOptions, entry);
17
+ };
18
+
19
+ const traverseMediaTarget = async (visitor, path, entry) => {
20
+ const targetSchemaUID = 'plugin::upload.file';
21
+ const targetSchema = strapi.getModel(targetSchemaUID);
22
+
23
+ const traverseOptions = { schema: targetSchema, path };
24
+
25
+ return traverseEntity(visitor, traverseOptions, entry);
26
+ };
27
+
28
+ const traverseComponent = async (visitor, path, schema, entry) => {
29
+ const traverseOptions = { schema, path };
30
+
31
+ return traverseEntity(visitor, traverseOptions, entry);
32
+ };
33
+
34
+ const visitDynamicZoneEntry = async (visitor, path, entry) => {
35
+ const targetSchema = strapi.getModel(entry.__component);
36
+ const traverseOptions = { schema: targetSchema, path };
37
+
38
+ return traverseEntity(visitor, traverseOptions, entry);
39
+ };
4
40
 
5
41
  const traverseEntity = async (visitor, options, entity) => {
6
42
  const { path = { raw: null, attribute: null }, schema } = options;
@@ -11,9 +47,13 @@ const traverseEntity = async (visitor, options, entity) => {
11
47
  }
12
48
 
13
49
  // Don't mutate the original entity object
14
- const copy = cloneDeep(entity);
50
+ // only clone at 1st level as the next level will get clone when traversed
51
+ const copy = clone(entity);
52
+ const visitorUtils = createVisitorUtils({ data: copy });
15
53
 
16
- for (const key of Object.keys(copy)) {
54
+ const keys = Object.keys(copy);
55
+ for (let i = 0; i < keys.length; i += 1) {
56
+ const key = keys[i];
17
57
  // Retrieve the attribute definition associated to the key from the schema
18
58
  const attribute = schema.attributes[key];
19
59
 
@@ -32,7 +72,6 @@ const traverseEntity = async (visitor, options, entity) => {
32
72
 
33
73
  // Visit the current attribute
34
74
  const visitorOptions = { data: copy, schema, key, value: copy[key], attribute, path: newPath };
35
- const visitorUtils = createVisitorUtils({ data: copy });
36
75
 
37
76
  await visitor(visitorOptions, visitorUtils);
38
77
 
@@ -52,58 +91,62 @@ const traverseEntity = async (visitor, options, entity) => {
52
91
  if (isRelation) {
53
92
  const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
54
93
 
55
- const traverseTarget = (entry) => {
56
- // Handle polymorphic relationships
57
- const targetSchemaUID = isMorphRelation ? entry.__type : attribute.target;
58
- const targetSchema = strapi.getModel(targetSchemaUID);
59
-
60
- const traverseOptions = { schema: targetSchema, path: newPath };
94
+ const method = isMorphRelation
95
+ ? traverseMorphRelationTarget
96
+ : traverseRelationTarget(strapi.getModel(attribute.target));
61
97
 
62
- return traverseEntity(visitor, traverseOptions, entry);
63
- };
98
+ if (isArray(value)) {
99
+ const res = new Array(value.length);
100
+ for (let i = 0; i < value.length; i += 1) {
101
+ res[i] = await method(visitor, newPath, value[i]);
102
+ }
103
+ copy[key] = res;
104
+ } else {
105
+ copy[key] = await method(visitor, newPath, value);
106
+ }
64
107
 
65
- // need to update copy
66
- copy[key] = isArray(value)
67
- ? await Promise.all(value.map(traverseTarget))
68
- : await traverseTarget(value);
108
+ continue;
69
109
  }
70
110
 
71
111
  if (isMedia) {
72
- const traverseTarget = (entry) => {
73
- const targetSchemaUID = 'plugin::upload.file';
74
- const targetSchema = strapi.getModel(targetSchemaUID);
75
-
76
- const traverseOptions = { schema: targetSchema, path: newPath };
77
-
78
- return traverseEntity(visitor, traverseOptions, entry);
79
- };
80
-
81
112
  // need to update copy
82
- copy[key] = isArray(value)
83
- ? await Promise.all(value.map(traverseTarget))
84
- : await traverseTarget(value);
113
+ if (isArray(value)) {
114
+ const res = new Array(value.length);
115
+ for (let i = 0; i < value.length; i += 1) {
116
+ res[i] = await traverseMediaTarget(visitor, newPath, value[i]);
117
+ }
118
+ copy[key] = res;
119
+ } else {
120
+ copy[key] = await traverseMediaTarget(visitor, newPath, value);
121
+ }
122
+
123
+ continue;
85
124
  }
86
125
 
87
126
  if (isComponent) {
88
127
  const targetSchema = strapi.getModel(attribute.component);
89
- const traverseOptions = { schema: targetSchema, path: newPath };
90
128
 
91
- const traverseComponent = (entry) => traverseEntity(visitor, traverseOptions, entry);
129
+ if (isArray(value)) {
130
+ const res = new Array(value.length);
131
+ for (let i = 0; i < value.length; i += 1) {
132
+ res[i] = await traverseComponent(visitor, newPath, targetSchema, value[i]);
133
+ }
134
+ copy[key] = res;
135
+ } else {
136
+ copy[key] = await traverseComponent(visitor, newPath, targetSchema, value);
137
+ }
92
138
 
93
- copy[key] = isArray(value)
94
- ? await Promise.all(value.map(traverseComponent))
95
- : await traverseComponent(value);
139
+ continue;
96
140
  }
97
141
 
98
142
  if (isDynamicZone && isArray(value)) {
99
- const visitDynamicZoneEntry = (entry) => {
100
- const targetSchema = strapi.getModel(entry.__component);
101
- const traverseOptions = { schema: targetSchema, path: newPath };
102
-
103
- return traverseEntity(visitor, traverseOptions, entry);
104
- };
143
+ const res = new Array(value.length);
144
+ for (let i = 0; i < value.length; i += 1) {
145
+ res[i] = await visitDynamicZoneEntry(visitor, newPath, value[i]);
146
+ }
147
+ copy[key] = res;
105
148
 
106
- copy[key] = await Promise.all(value.map(visitDynamicZoneEntry));
149
+ continue;
107
150
  }
108
151
  }
109
152
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/utils",
3
- "version": "4.10.0-beta.0",
3
+ "version": "4.10.0-beta.1",
4
4
  "description": "Shared utilities for the Strapi packages",
5
5
  "keywords": [
6
6
  "strapi",
@@ -28,11 +28,14 @@
28
28
  }
29
29
  ],
30
30
  "main": "./lib",
31
+ "types": "./index.d.ts",
31
32
  "directories": {
32
33
  "lib": "./lib"
33
34
  },
34
35
  "scripts": {
35
- "test:unit": "jest --verbose"
36
+ "test:unit": "run -T jest",
37
+ "test:unit:watch": "run -T jest --watch",
38
+ "lint": "run -T eslint ."
36
39
  },
37
40
  "dependencies": {
38
41
  "@sindresorhus/slugify": "1.1.0",
@@ -46,5 +49,5 @@
46
49
  "node": ">=14.19.1 <=18.x.x",
47
50
  "npm": ">=6.0.0"
48
51
  },
49
- "gitHead": "1519ef0e56d27b738f24fc88223797651ad47aaf"
52
+ "gitHead": "95d581b31bee464af42e5d8db408fa578d8532c7"
50
53
  }