@strapi/utils 5.12.1 → 5.12.3

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.
Files changed (233) hide show
  1. package/dist/async.js +28 -0
  2. package/dist/async.js.map +1 -0
  3. package/dist/async.mjs +24 -0
  4. package/dist/async.mjs.map +1 -0
  5. package/dist/content-types.js +201 -0
  6. package/dist/content-types.js.map +1 -0
  7. package/dist/content-types.mjs +167 -0
  8. package/dist/content-types.mjs.map +1 -0
  9. package/dist/convert-query-params.js +512 -0
  10. package/dist/convert-query-params.js.map +1 -0
  11. package/dist/convert-query-params.mjs +510 -0
  12. package/dist/convert-query-params.mjs.map +1 -0
  13. package/dist/env-helper.js +81 -0
  14. package/dist/env-helper.js.map +1 -0
  15. package/dist/env-helper.mjs +79 -0
  16. package/dist/env-helper.mjs.map +1 -0
  17. package/dist/errors.js +104 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/errors.mjs +88 -0
  20. package/dist/errors.mjs.map +1 -0
  21. package/dist/file.js +57 -0
  22. package/dist/file.js.map +1 -0
  23. package/dist/file.mjs +50 -0
  24. package/dist/file.mjs.map +1 -0
  25. package/dist/format-yup-error.js +19 -0
  26. package/dist/format-yup-error.js.map +1 -0
  27. package/dist/format-yup-error.mjs +17 -0
  28. package/dist/format-yup-error.mjs.map +1 -0
  29. package/dist/hooks.js +86 -0
  30. package/dist/hooks.js.map +1 -0
  31. package/dist/hooks.mjs +80 -0
  32. package/dist/hooks.mjs.map +1 -0
  33. package/dist/import-default.js +9 -0
  34. package/dist/import-default.js.map +1 -0
  35. package/dist/import-default.mjs +7 -0
  36. package/dist/import-default.mjs.map +1 -0
  37. package/dist/index.js +54 -4358
  38. package/dist/index.js.map +1 -1
  39. package/dist/index.mjs +48 -4317
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/machine-id.js +17 -0
  42. package/dist/machine-id.js.map +1 -0
  43. package/dist/machine-id.mjs +15 -0
  44. package/dist/machine-id.mjs.map +1 -0
  45. package/dist/operators.js +79 -0
  46. package/dist/operators.js.map +1 -0
  47. package/dist/operators.mjs +76 -0
  48. package/dist/operators.mjs.map +1 -0
  49. package/dist/package-manager.js +36 -0
  50. package/dist/package-manager.js.map +1 -0
  51. package/dist/package-manager.mjs +33 -0
  52. package/dist/package-manager.mjs.map +1 -0
  53. package/dist/pagination.js +163 -0
  54. package/dist/pagination.js.map +1 -0
  55. package/dist/pagination.mjs +159 -0
  56. package/dist/pagination.mjs.map +1 -0
  57. package/dist/parse-type.js +140 -0
  58. package/dist/parse-type.js.map +1 -0
  59. package/dist/parse-type.mjs +118 -0
  60. package/dist/parse-type.mjs.map +1 -0
  61. package/dist/policy.js +33 -0
  62. package/dist/policy.js.map +1 -0
  63. package/dist/policy.mjs +30 -0
  64. package/dist/policy.mjs.map +1 -0
  65. package/dist/primitives/arrays.js +7 -0
  66. package/dist/primitives/arrays.js.map +1 -0
  67. package/dist/primitives/arrays.mjs +5 -0
  68. package/dist/primitives/arrays.mjs.map +1 -0
  69. package/dist/primitives/dates.js +11 -0
  70. package/dist/primitives/dates.js.map +1 -0
  71. package/dist/primitives/dates.mjs +9 -0
  72. package/dist/primitives/dates.mjs.map +1 -0
  73. package/dist/primitives/objects.js +13 -0
  74. package/dist/primitives/objects.js.map +1 -0
  75. package/dist/primitives/objects.mjs +11 -0
  76. package/dist/primitives/objects.mjs.map +1 -0
  77. package/dist/primitives/strings.js +49 -0
  78. package/dist/primitives/strings.js.map +1 -0
  79. package/dist/primitives/strings.mjs +38 -0
  80. package/dist/primitives/strings.mjs.map +1 -0
  81. package/dist/print-value.js +42 -0
  82. package/dist/print-value.js.map +1 -0
  83. package/dist/print-value.mjs +40 -0
  84. package/dist/print-value.mjs.map +1 -0
  85. package/dist/provider-factory.js +82 -0
  86. package/dist/provider-factory.js.map +1 -0
  87. package/dist/provider-factory.mjs +80 -0
  88. package/dist/provider-factory.mjs.map +1 -0
  89. package/dist/relations.js +54 -0
  90. package/dist/relations.js.map +1 -0
  91. package/dist/relations.mjs +45 -0
  92. package/dist/relations.mjs.map +1 -0
  93. package/dist/sanitize/index.js +195 -0
  94. package/dist/sanitize/index.js.map +1 -0
  95. package/dist/sanitize/index.mjs +194 -0
  96. package/dist/sanitize/index.mjs.map +1 -0
  97. package/dist/sanitize/sanitizers.js +173 -0
  98. package/dist/sanitize/sanitizers.js.map +1 -0
  99. package/dist/sanitize/sanitizers.mjs +166 -0
  100. package/dist/sanitize/sanitizers.mjs.map +1 -0
  101. package/dist/sanitize/visitors/expand-wildcard-populate.js +20 -0
  102. package/dist/sanitize/visitors/expand-wildcard-populate.js.map +1 -0
  103. package/dist/sanitize/visitors/expand-wildcard-populate.mjs +18 -0
  104. package/dist/sanitize/visitors/expand-wildcard-populate.mjs.map +1 -0
  105. package/dist/sanitize/visitors/index.js +22 -0
  106. package/dist/sanitize/visitors/index.js.map +1 -0
  107. package/dist/sanitize/visitors/index.mjs +9 -0
  108. package/dist/sanitize/visitors/index.mjs.map +1 -0
  109. package/dist/sanitize/visitors/remove-disallowed-fields.js +87 -0
  110. package/dist/sanitize/visitors/remove-disallowed-fields.js.map +1 -0
  111. package/dist/sanitize/visitors/remove-disallowed-fields.mjs +85 -0
  112. package/dist/sanitize/visitors/remove-disallowed-fields.mjs.map +1 -0
  113. package/dist/sanitize/visitors/remove-dynamic-zones.js +12 -0
  114. package/dist/sanitize/visitors/remove-dynamic-zones.js.map +1 -0
  115. package/dist/sanitize/visitors/remove-dynamic-zones.mjs +10 -0
  116. package/dist/sanitize/visitors/remove-dynamic-zones.mjs.map +1 -0
  117. package/dist/sanitize/visitors/remove-morph-to-relations.js +12 -0
  118. package/dist/sanitize/visitors/remove-morph-to-relations.js.map +1 -0
  119. package/dist/sanitize/visitors/remove-morph-to-relations.mjs +10 -0
  120. package/dist/sanitize/visitors/remove-morph-to-relations.mjs.map +1 -0
  121. package/dist/sanitize/visitors/remove-password.js +10 -0
  122. package/dist/sanitize/visitors/remove-password.js.map +1 -0
  123. package/dist/sanitize/visitors/remove-password.mjs +8 -0
  124. package/dist/sanitize/visitors/remove-password.mjs.map +1 -0
  125. package/dist/sanitize/visitors/remove-private.js +16 -0
  126. package/dist/sanitize/visitors/remove-private.js.map +1 -0
  127. package/dist/sanitize/visitors/remove-private.mjs +14 -0
  128. package/dist/sanitize/visitors/remove-private.mjs.map +1 -0
  129. package/dist/sanitize/visitors/remove-restricted-fields.js +28 -0
  130. package/dist/sanitize/visitors/remove-restricted-fields.js.map +1 -0
  131. package/dist/sanitize/visitors/remove-restricted-fields.mjs +26 -0
  132. package/dist/sanitize/visitors/remove-restricted-fields.mjs.map +1 -0
  133. package/dist/sanitize/visitors/remove-restricted-relations.js +116 -0
  134. package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -0
  135. package/dist/sanitize/visitors/remove-restricted-relations.mjs +114 -0
  136. package/dist/sanitize/visitors/remove-restricted-relations.mjs.map +1 -0
  137. package/dist/set-creator-fields.js +18 -0
  138. package/dist/set-creator-fields.js.map +1 -0
  139. package/dist/set-creator-fields.mjs +16 -0
  140. package/dist/set-creator-fields.mjs.map +1 -0
  141. package/dist/template.js +18 -0
  142. package/dist/template.js.map +1 -0
  143. package/dist/template.mjs +15 -0
  144. package/dist/template.mjs.map +1 -0
  145. package/dist/traverse/factory.js +158 -0
  146. package/dist/traverse/factory.js.map +1 -0
  147. package/dist/traverse/factory.mjs +156 -0
  148. package/dist/traverse/factory.mjs.map +1 -0
  149. package/dist/traverse/index.js +14 -0
  150. package/dist/traverse/index.js.map +1 -0
  151. package/dist/traverse/index.mjs +5 -0
  152. package/dist/traverse/index.mjs.map +1 -0
  153. package/dist/traverse/query-fields.js +41 -0
  154. package/dist/traverse/query-fields.js.map +1 -0
  155. package/dist/traverse/query-fields.mjs +39 -0
  156. package/dist/traverse/query-fields.mjs.map +1 -0
  157. package/dist/traverse/query-filters.js +114 -0
  158. package/dist/traverse/query-filters.js.map +1 -0
  159. package/dist/traverse/query-filters.mjs +112 -0
  160. package/dist/traverse/query-filters.mjs.map +1 -0
  161. package/dist/traverse/query-populate.js +280 -0
  162. package/dist/traverse/query-populate.js.map +1 -0
  163. package/dist/traverse/query-populate.mjs +278 -0
  164. package/dist/traverse/query-populate.mjs.map +1 -0
  165. package/dist/traverse/query-sort.js +144 -0
  166. package/dist/traverse/query-sort.js.map +1 -0
  167. package/dist/traverse/query-sort.mjs +142 -0
  168. package/dist/traverse/query-sort.mjs.map +1 -0
  169. package/dist/traverse-entity.js +170 -0
  170. package/dist/traverse-entity.js.map +1 -0
  171. package/dist/traverse-entity.mjs +168 -0
  172. package/dist/traverse-entity.mjs.map +1 -0
  173. package/dist/validate/index.js +218 -0
  174. package/dist/validate/index.js.map +1 -0
  175. package/dist/validate/index.mjs +217 -0
  176. package/dist/validate/index.mjs.map +1 -0
  177. package/dist/validate/utils.js +27 -0
  178. package/dist/validate/utils.js.map +1 -0
  179. package/dist/validate/utils.mjs +24 -0
  180. package/dist/validate/utils.mjs.map +1 -0
  181. package/dist/validate/validators.js +369 -0
  182. package/dist/validate/validators.js.map +1 -0
  183. package/dist/validate/validators.mjs +356 -0
  184. package/dist/validate/validators.mjs.map +1 -0
  185. package/dist/validate/visitors/index.js +22 -0
  186. package/dist/validate/visitors/index.js.map +1 -0
  187. package/dist/validate/visitors/index.mjs +9 -0
  188. package/dist/validate/visitors/index.mjs.map +1 -0
  189. package/dist/validate/visitors/throw-disallowed-fields.js +91 -0
  190. package/dist/validate/visitors/throw-disallowed-fields.js.map +1 -0
  191. package/dist/validate/visitors/throw-disallowed-fields.mjs +89 -0
  192. package/dist/validate/visitors/throw-disallowed-fields.mjs.map +1 -0
  193. package/dist/validate/visitors/throw-dynamic-zones.js +16 -0
  194. package/dist/validate/visitors/throw-dynamic-zones.js.map +1 -0
  195. package/dist/validate/visitors/throw-dynamic-zones.mjs +14 -0
  196. package/dist/validate/visitors/throw-dynamic-zones.mjs.map +1 -0
  197. package/dist/validate/visitors/throw-morph-to-relations.js +16 -0
  198. package/dist/validate/visitors/throw-morph-to-relations.js.map +1 -0
  199. package/dist/validate/visitors/throw-morph-to-relations.mjs +14 -0
  200. package/dist/validate/visitors/throw-morph-to-relations.mjs.map +1 -0
  201. package/dist/validate/visitors/throw-password.js +15 -0
  202. package/dist/validate/visitors/throw-password.js.map +1 -0
  203. package/dist/validate/visitors/throw-password.mjs +13 -0
  204. package/dist/validate/visitors/throw-password.mjs.map +1 -0
  205. package/dist/validate/visitors/throw-private.js +20 -0
  206. package/dist/validate/visitors/throw-private.js.map +1 -0
  207. package/dist/validate/visitors/throw-private.mjs +18 -0
  208. package/dist/validate/visitors/throw-private.mjs.map +1 -0
  209. package/dist/validate/visitors/throw-restricted-fields.js +36 -0
  210. package/dist/validate/visitors/throw-restricted-fields.js.map +1 -0
  211. package/dist/validate/visitors/throw-restricted-fields.mjs +34 -0
  212. package/dist/validate/visitors/throw-restricted-fields.mjs.map +1 -0
  213. package/dist/validate/visitors/throw-restricted-relations.js +125 -0
  214. package/dist/validate/visitors/throw-restricted-relations.js.map +1 -0
  215. package/dist/validate/visitors/throw-restricted-relations.mjs +123 -0
  216. package/dist/validate/visitors/throw-restricted-relations.mjs.map +1 -0
  217. package/dist/validate/visitors/throw-unrecognized-fields.js +66 -0
  218. package/dist/validate/visitors/throw-unrecognized-fields.js.map +1 -0
  219. package/dist/validate/visitors/throw-unrecognized-fields.mjs +64 -0
  220. package/dist/validate/visitors/throw-unrecognized-fields.mjs.map +1 -0
  221. package/dist/validators.js +60 -0
  222. package/dist/validators.js.map +1 -0
  223. package/dist/validators.mjs +37 -0
  224. package/dist/validators.mjs.map +1 -0
  225. package/dist/yup.js +101 -0
  226. package/dist/yup.js.map +1 -0
  227. package/dist/yup.mjs +74 -0
  228. package/dist/yup.mjs.map +1 -0
  229. package/dist/zod.js +31 -0
  230. package/dist/zod.js.map +1 -0
  231. package/dist/zod.mjs +29 -0
  232. package/dist/zod.mjs.map +1 -0
  233. package/package.json +3 -3
@@ -0,0 +1,369 @@
1
+ 'use strict';
2
+
3
+ var fp = require('lodash/fp');
4
+ var async = require('../async.js');
5
+ var contentTypes = require('../content-types.js');
6
+ var queryFilters = require('../traverse/query-filters.js');
7
+ var querySort = require('../traverse/query-sort.js');
8
+ var queryPopulate = require('../traverse/query-populate.js');
9
+ var queryFields = require('../traverse/query-fields.js');
10
+ var throwPassword = require('./visitors/throw-password.js');
11
+ var throwPrivate = require('./visitors/throw-private.js');
12
+ var utils = require('./utils.js');
13
+ var throwMorphToRelations = require('./visitors/throw-morph-to-relations.js');
14
+ var throwDynamicZones = require('./visitors/throw-dynamic-zones.js');
15
+ require('./visitors/throw-unrecognized-fields.js');
16
+ var operators = require('../operators.js');
17
+ var parseType = require('../parse-type.js');
18
+
19
+ const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = contentTypes.constants;
20
+ const FILTER_TRAVERSALS = [
21
+ 'nonAttributesOperators',
22
+ 'dynamicZones',
23
+ 'morphRelations',
24
+ 'passwords',
25
+ 'private'
26
+ ];
27
+ const validateFilters = utils.asyncCurry(async (ctx, filters, include)=>{
28
+ // TODO: schema checks should check that it is a valid schema with yup
29
+ if (!ctx.schema) {
30
+ throw new Error('Missing schema in defaultValidateFilters');
31
+ }
32
+ // Build the list of functions conditionally
33
+ const functionsToApply = [];
34
+ // keys that are not attributes or valid operators
35
+ if (include.includes('nonAttributesOperators')) {
36
+ functionsToApply.push(queryFilters(({ key, attribute, path })=>{
37
+ // ID is not an attribute per se, so we need to make
38
+ // an extra check to ensure we're not removing it
39
+ if ([
40
+ ID_ATTRIBUTE,
41
+ DOC_ID_ATTRIBUTE
42
+ ].includes(key)) {
43
+ return;
44
+ }
45
+ const isAttribute = !!attribute;
46
+ if (!isAttribute && !operators.isOperator(key)) {
47
+ utils.throwInvalidKey({
48
+ key,
49
+ path: path.attribute
50
+ });
51
+ }
52
+ }, ctx));
53
+ }
54
+ if (include.includes('dynamicZones')) {
55
+ functionsToApply.push(queryFilters(throwDynamicZones, ctx));
56
+ }
57
+ if (include.includes('morphRelations')) {
58
+ functionsToApply.push(queryFilters(throwMorphToRelations, ctx));
59
+ }
60
+ if (include.includes('passwords')) {
61
+ functionsToApply.push(queryFilters(throwPassword, ctx));
62
+ }
63
+ if (include.includes('private')) {
64
+ functionsToApply.push(queryFilters(throwPrivate, ctx));
65
+ }
66
+ // Return directly if no validation functions are provided
67
+ if (functionsToApply.length === 0) {
68
+ return filters;
69
+ }
70
+ return async.pipe(...functionsToApply)(filters);
71
+ });
72
+ const defaultValidateFilters = utils.asyncCurry(async (ctx, filters)=>{
73
+ return validateFilters(ctx, filters, FILTER_TRAVERSALS);
74
+ });
75
+ const SORT_TRAVERSALS = [
76
+ 'nonAttributesOperators',
77
+ 'dynamicZones',
78
+ 'morphRelations',
79
+ 'passwords',
80
+ 'private',
81
+ 'nonScalarEmptyKeys'
82
+ ];
83
+ const validateSort = utils.asyncCurry(async (ctx, sort, include)=>{
84
+ if (!ctx.schema) {
85
+ throw new Error('Missing schema in defaultValidateSort');
86
+ }
87
+ // Build the list of functions conditionally based on the include array
88
+ const functionsToApply = [];
89
+ // Validate non attribute keys
90
+ if (include.includes('nonAttributesOperators')) {
91
+ functionsToApply.push(querySort(({ key, attribute, path })=>{
92
+ // ID is not an attribute per se, so we need to make
93
+ // an extra check to ensure we're not removing it
94
+ if ([
95
+ ID_ATTRIBUTE,
96
+ DOC_ID_ATTRIBUTE
97
+ ].includes(key)) {
98
+ return;
99
+ }
100
+ if (!attribute) {
101
+ utils.throwInvalidKey({
102
+ key,
103
+ path: path.attribute
104
+ });
105
+ }
106
+ }, ctx));
107
+ }
108
+ // Validate dynamic zones from sort
109
+ if (include.includes('dynamicZones')) {
110
+ functionsToApply.push(querySort(throwDynamicZones, ctx));
111
+ }
112
+ // Validate morphTo relations from sort
113
+ if (include.includes('morphRelations')) {
114
+ functionsToApply.push(querySort(throwMorphToRelations, ctx));
115
+ }
116
+ // Validate passwords from sort
117
+ if (include.includes('passwords')) {
118
+ functionsToApply.push(querySort(throwPassword, ctx));
119
+ }
120
+ // Validate private from sort
121
+ if (include.includes('private')) {
122
+ functionsToApply.push(querySort(throwPrivate, ctx));
123
+ }
124
+ // Validate non-scalar empty keys
125
+ if (include.includes('nonScalarEmptyKeys')) {
126
+ functionsToApply.push(querySort(({ key, attribute, value, path })=>{
127
+ // ID is not an attribute per se, so we need to make
128
+ // an extra check to ensure we're not removing it
129
+ if ([
130
+ ID_ATTRIBUTE,
131
+ DOC_ID_ATTRIBUTE
132
+ ].includes(key)) {
133
+ return;
134
+ }
135
+ if (!contentTypes.isScalarAttribute(attribute) && fp.isEmpty(value)) {
136
+ utils.throwInvalidKey({
137
+ key,
138
+ path: path.attribute
139
+ });
140
+ }
141
+ }, ctx));
142
+ }
143
+ // Return directly if no validation functions are provided
144
+ if (functionsToApply.length === 0) {
145
+ return sort;
146
+ }
147
+ return async.pipe(...functionsToApply)(sort);
148
+ });
149
+ const defaultValidateSort = utils.asyncCurry(async (ctx, sort)=>{
150
+ return validateSort(ctx, sort, SORT_TRAVERSALS);
151
+ });
152
+ const FIELDS_TRAVERSALS = [
153
+ 'scalarAttributes',
154
+ 'privateFields',
155
+ 'passwordFields'
156
+ ];
157
+ const validateFields = utils.asyncCurry(async (ctx, fields, include)=>{
158
+ if (!ctx.schema) {
159
+ throw new Error('Missing schema in defaultValidateFields');
160
+ }
161
+ // Build the list of functions conditionally based on the include array
162
+ const functionsToApply = [];
163
+ // Only allow scalar attributes
164
+ if (include.includes('scalarAttributes')) {
165
+ functionsToApply.push(queryFields(({ key, attribute, path })=>{
166
+ // ID is not an attribute per se, so we need to make
167
+ // an extra check to ensure we're not throwing because of it
168
+ if ([
169
+ ID_ATTRIBUTE,
170
+ DOC_ID_ATTRIBUTE
171
+ ].includes(key)) {
172
+ return;
173
+ }
174
+ if (fp.isNil(attribute) || !contentTypes.isScalarAttribute(attribute)) {
175
+ utils.throwInvalidKey({
176
+ key,
177
+ path: path.attribute
178
+ });
179
+ }
180
+ }, ctx));
181
+ }
182
+ // Private fields
183
+ if (include.includes('privateFields')) {
184
+ functionsToApply.push(queryFields(throwPrivate, ctx));
185
+ }
186
+ // Password fields
187
+ if (include.includes('passwordFields')) {
188
+ functionsToApply.push(queryFields(throwPassword, ctx));
189
+ }
190
+ // Return directly if no validation functions are provided
191
+ if (functionsToApply.length === 0) {
192
+ return fields;
193
+ }
194
+ return async.pipe(...functionsToApply)(fields);
195
+ });
196
+ const defaultValidateFields = utils.asyncCurry(async (ctx, fields)=>{
197
+ return validateFields(ctx, fields, FIELDS_TRAVERSALS);
198
+ });
199
+ const POPULATE_TRAVERSALS = [
200
+ 'nonAttributesOperators',
201
+ 'private'
202
+ ];
203
+ const validatePopulate = utils.asyncCurry(async (ctx, populate, includes)=>{
204
+ if (!ctx.schema) {
205
+ throw new Error('Missing schema in defaultValidatePopulate');
206
+ }
207
+ // Build the list of functions conditionally based on the include array
208
+ const functionsToApply = [];
209
+ // Always include the main traversal function
210
+ functionsToApply.push(queryPopulate(async ({ key, path, value, schema, attribute, getModel, parent }, { set })=>{
211
+ /**
212
+ * NOTE: The parent check is done to support "filters" (and the rest of keys) as valid attribute names.
213
+ *
214
+ * The parent will not be an attribute when its a "populate" / "filters" / "sort" ... key.
215
+ * Only in those scenarios the node will be an attribute.
216
+ */ if (!parent?.attribute && attribute) {
217
+ const isPopulatableAttribute = [
218
+ 'relation',
219
+ 'dynamiczone',
220
+ 'component',
221
+ 'media'
222
+ ].includes(attribute.type);
223
+ // Throw on non-populate attributes
224
+ if (!isPopulatableAttribute) {
225
+ utils.throwInvalidKey({
226
+ key,
227
+ path: path.raw
228
+ });
229
+ }
230
+ // Valid populatable attribute, so return
231
+ return;
232
+ }
233
+ // If we're looking at a populate fragment, ensure its target is valid
234
+ if (key === 'on') {
235
+ // Populate fragment should always be an object
236
+ if (!fp.isObject(value)) {
237
+ return utils.throwInvalidKey({
238
+ key,
239
+ path: path.raw
240
+ });
241
+ }
242
+ const targets = Object.keys(value);
243
+ for (const target of targets){
244
+ const model = getModel(target);
245
+ // If a target is invalid (no matching model), then raise an error
246
+ if (!model) {
247
+ utils.throwInvalidKey({
248
+ key: target,
249
+ path: `${path.raw}.${target}`
250
+ });
251
+ }
252
+ }
253
+ // If the fragment's target is fine, then let it pass
254
+ return;
255
+ }
256
+ // Ignore plain wildcards
257
+ if (key === '' && value === '*') {
258
+ return;
259
+ }
260
+ // Ensure count is a boolean
261
+ if (key === 'count') {
262
+ try {
263
+ parseType({
264
+ type: 'boolean',
265
+ value
266
+ });
267
+ return;
268
+ } catch {
269
+ utils.throwInvalidKey({
270
+ key,
271
+ path: path.attribute
272
+ });
273
+ }
274
+ }
275
+ // Allowed boolean-like keywords should be ignored
276
+ try {
277
+ parseType({
278
+ type: 'boolean',
279
+ value: key
280
+ });
281
+ // Key is an allowed boolean-like keyword, skipping validation...
282
+ return;
283
+ } catch {
284
+ // Continue, because it's not a boolean-like
285
+ }
286
+ // Handle nested `sort` validation with custom or default traversals
287
+ if (key === 'sort') {
288
+ set(key, await validateSort({
289
+ schema,
290
+ getModel
291
+ }, value, includes?.sort || SORT_TRAVERSALS));
292
+ return;
293
+ }
294
+ // Handle nested `filters` validation with custom or default traversals
295
+ if (key === 'filters') {
296
+ set(key, await validateFilters({
297
+ schema,
298
+ getModel
299
+ }, value, includes?.filters || FILTER_TRAVERSALS));
300
+ return;
301
+ }
302
+ // Handle nested `fields` validation with custom or default traversals
303
+ if (key === 'fields') {
304
+ set(key, await validateFields({
305
+ schema,
306
+ getModel
307
+ }, value, includes?.fields || FIELDS_TRAVERSALS));
308
+ return;
309
+ }
310
+ // Handle recursive nested `populate` validation with the same include object
311
+ if (key === 'populate') {
312
+ set(key, await validatePopulate({
313
+ schema,
314
+ getModel,
315
+ parent: {
316
+ key,
317
+ path,
318
+ schema,
319
+ attribute
320
+ },
321
+ path
322
+ }, value, includes // pass down the same includes object
323
+ ));
324
+ return;
325
+ }
326
+ // Throw an error if non-attribute operators are included in the populate array
327
+ if (includes?.populate?.includes('nonAttributesOperators')) {
328
+ utils.throwInvalidKey({
329
+ key,
330
+ path: path.attribute
331
+ });
332
+ }
333
+ }, ctx));
334
+ // Conditionally traverse for private fields only if 'private' is included
335
+ if (includes?.populate?.includes('private')) {
336
+ functionsToApply.push(queryPopulate(throwPrivate, ctx));
337
+ }
338
+ // Return directly if no validation functions are provided
339
+ if (functionsToApply.length === 0) {
340
+ return populate;
341
+ }
342
+ return async.pipe(...functionsToApply)(populate);
343
+ });
344
+ const defaultValidatePopulate = utils.asyncCurry(async (ctx, populate)=>{
345
+ if (!ctx.schema) {
346
+ throw new Error('Missing schema in defaultValidatePopulate');
347
+ }
348
+ // Call validatePopulate and include all validations by passing in full traversal arrays
349
+ return validatePopulate(ctx, populate, {
350
+ filters: FILTER_TRAVERSALS,
351
+ sort: SORT_TRAVERSALS,
352
+ fields: FIELDS_TRAVERSALS,
353
+ populate: POPULATE_TRAVERSALS
354
+ });
355
+ });
356
+
357
+ exports.FIELDS_TRAVERSALS = FIELDS_TRAVERSALS;
358
+ exports.FILTER_TRAVERSALS = FILTER_TRAVERSALS;
359
+ exports.POPULATE_TRAVERSALS = POPULATE_TRAVERSALS;
360
+ exports.SORT_TRAVERSALS = SORT_TRAVERSALS;
361
+ exports.defaultValidateFields = defaultValidateFields;
362
+ exports.defaultValidateFilters = defaultValidateFilters;
363
+ exports.defaultValidatePopulate = defaultValidatePopulate;
364
+ exports.defaultValidateSort = defaultValidateSort;
365
+ exports.validateFields = validateFields;
366
+ exports.validateFilters = validateFilters;
367
+ exports.validatePopulate = validatePopulate;
368
+ exports.validateSort = validateSort;
369
+ //# sourceMappingURL=validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.js","sources":["../../src/validate/validators.ts"],"sourcesContent":["import { isEmpty, isNil, isObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport { isScalarAttribute, constants } from '../content-types';\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryFields,\n traverseQueryPopulate,\n} from '../traverse';\nimport { throwPassword, throwPrivate, throwDynamicZones, throwMorphToRelations } from './visitors';\nimport { isOperator } from '../operators';\nimport { asyncCurry, throwInvalidKey } from './utils';\nimport type { Model } from '../types';\nimport parseType from '../parse-type';\nimport type { Parent, Path } from '../traverse/factory';\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n}\n\ninterface PopulateContext extends Context {\n path?: Path;\n parent?: Parent;\n}\n\ntype AnyFunc = (...args: any[]) => any;\n\nexport const FILTER_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n];\n\nexport const validateFilters = asyncCurry(\n async (ctx: Context, filters: unknown, include: (typeof FILTER_TRAVERSALS)[number][]) => {\n // TODO: schema checks should check that it is a valid schema with yup\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFilters');\n }\n\n // Build the list of functions conditionally\n const functionsToApply: Array<AnyFunc> = [];\n\n // keys that are not attributes or valid operators\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQueryFilters(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n const isAttribute = !!attribute;\n\n if (!isAttribute && !isOperator(key)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQueryFilters(throwDynamicZones, ctx));\n }\n\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQueryFilters(throwMorphToRelations, ctx));\n }\n\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQueryFilters(throwPassword, ctx));\n }\n\n if (include.includes('private')) {\n functionsToApply.push(traverseQueryFilters(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return filters;\n }\n\n return pipeAsync(...functionsToApply)(filters);\n }\n);\n\nexport const defaultValidateFilters = asyncCurry(async (ctx: Context, filters: unknown) => {\n return validateFilters(ctx, filters, FILTER_TRAVERSALS);\n});\n\nexport const SORT_TRAVERSALS = [\n 'nonAttributesOperators',\n 'dynamicZones',\n 'morphRelations',\n 'passwords',\n 'private',\n 'nonScalarEmptyKeys',\n];\n\nexport const validateSort = asyncCurry(\n async (ctx: Context, sort: unknown, include: (typeof SORT_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateSort');\n }\n\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Validate non attribute keys\n if (include.includes('nonAttributesOperators')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!attribute) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Validate dynamic zones from sort\n if (include.includes('dynamicZones')) {\n functionsToApply.push(traverseQuerySort(throwDynamicZones, ctx));\n }\n\n // Validate morphTo relations from sort\n if (include.includes('morphRelations')) {\n functionsToApply.push(traverseQuerySort(throwMorphToRelations, ctx));\n }\n\n // Validate passwords from sort\n if (include.includes('passwords')) {\n functionsToApply.push(traverseQuerySort(throwPassword, ctx));\n }\n\n // Validate private from sort\n if (include.includes('private')) {\n functionsToApply.push(traverseQuerySort(throwPrivate, ctx));\n }\n\n // Validate non-scalar empty keys\n if (include.includes('nonScalarEmptyKeys')) {\n functionsToApply.push(\n traverseQuerySort(({ key, attribute, value, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return sort;\n }\n\n return pipeAsync(...functionsToApply)(sort);\n }\n);\n\nexport const defaultValidateSort = asyncCurry(async (ctx: Context, sort: unknown) => {\n return validateSort(ctx, sort, SORT_TRAVERSALS);\n});\n\nexport const FIELDS_TRAVERSALS = ['scalarAttributes', 'privateFields', 'passwordFields'];\n\nexport const validateFields = asyncCurry(\n async (ctx: Context, fields: unknown, include: (typeof FIELDS_TRAVERSALS)[number][]) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidateFields');\n }\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Only allow scalar attributes\n if (include.includes('scalarAttributes')) {\n functionsToApply.push(\n traverseQueryFields(({ key, attribute, path }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not throwing because of it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n throwInvalidKey({ key, path: path.attribute });\n }\n }, ctx)\n );\n }\n\n // Private fields\n if (include.includes('privateFields')) {\n functionsToApply.push(traverseQueryFields(throwPrivate, ctx));\n }\n\n // Password fields\n if (include.includes('passwordFields')) {\n functionsToApply.push(traverseQueryFields(throwPassword, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return fields;\n }\n\n return pipeAsync(...functionsToApply)(fields);\n }\n);\n\nexport const defaultValidateFields = asyncCurry(async (ctx: Context, fields: unknown) => {\n return validateFields(ctx, fields, FIELDS_TRAVERSALS);\n});\n\nexport const POPULATE_TRAVERSALS = ['nonAttributesOperators', 'private'];\n\nexport const validatePopulate = asyncCurry(\n async (\n ctx: PopulateContext,\n populate: unknown,\n includes: {\n fields?: (typeof FIELDS_TRAVERSALS)[number][];\n sort?: (typeof SORT_TRAVERSALS)[number][];\n filters?: (typeof FILTER_TRAVERSALS)[number][];\n populate?: (typeof POPULATE_TRAVERSALS)[number][];\n }\n ) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n // Build the list of functions conditionally based on the include array\n const functionsToApply: Array<AnyFunc> = [];\n\n // Always include the main traversal function\n functionsToApply.push(\n traverseQueryPopulate(\n async ({ key, path, value, schema, attribute, getModel, parent }, { set }) => {\n /**\n * NOTE: The parent check is done to support \"filters\" (and the rest of keys) as valid attribute names.\n *\n * The parent will not be an attribute when its a \"populate\" / \"filters\" / \"sort\" ... key.\n * Only in those scenarios the node will be an attribute.\n */\n if (!parent?.attribute && attribute) {\n const isPopulatableAttribute = [\n 'relation',\n 'dynamiczone',\n 'component',\n 'media',\n ].includes(attribute.type);\n\n // Throw on non-populate attributes\n if (!isPopulatableAttribute) {\n throwInvalidKey({ key, path: path.raw });\n }\n\n // Valid populatable attribute, so return\n return;\n }\n\n // If we're looking at a populate fragment, ensure its target is valid\n if (key === 'on') {\n // Populate fragment should always be an object\n if (!isObject(value)) {\n return throwInvalidKey({ key, path: path.raw });\n }\n\n const targets = Object.keys(value);\n\n for (const target of targets) {\n const model = getModel(target);\n\n // If a target is invalid (no matching model), then raise an error\n if (!model) {\n throwInvalidKey({ key: target, path: `${path.raw}.${target}` });\n }\n }\n\n // If the fragment's target is fine, then let it pass\n return;\n }\n\n // Ignore plain wildcards\n if (key === '' && value === '*') {\n return;\n }\n\n // Ensure count is a boolean\n if (key === 'count') {\n try {\n parseType({ type: 'boolean', value });\n return;\n } catch {\n throwInvalidKey({ key, path: path.attribute });\n }\n }\n\n // Allowed boolean-like keywords should be ignored\n try {\n parseType({ type: 'boolean', value: key });\n // Key is an allowed boolean-like keyword, skipping validation...\n return;\n } catch {\n // Continue, because it's not a boolean-like\n }\n\n // Handle nested `sort` validation with custom or default traversals\n if (key === 'sort') {\n set(\n key,\n await validateSort(\n {\n schema,\n getModel,\n },\n value, // pass the sort value\n includes?.sort || SORT_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `filters` validation with custom or default traversals\n if (key === 'filters') {\n set(\n key,\n await validateFilters(\n {\n schema,\n getModel,\n },\n value, // pass the filters value\n includes?.filters || FILTER_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle nested `fields` validation with custom or default traversals\n if (key === 'fields') {\n set(\n key,\n await validateFields(\n {\n schema,\n getModel,\n },\n value, // pass the fields value\n includes?.fields || FIELDS_TRAVERSALS\n )\n );\n return;\n }\n\n // Handle recursive nested `populate` validation with the same include object\n if (key === 'populate') {\n set(\n key,\n await validatePopulate(\n {\n schema,\n getModel,\n parent: { key, path, schema, attribute },\n path,\n },\n value, // pass the nested populate value\n includes // pass down the same includes object\n )\n );\n return;\n }\n\n // Throw an error if non-attribute operators are included in the populate array\n if (includes?.populate?.includes('nonAttributesOperators')) {\n throwInvalidKey({ key, path: path.attribute });\n }\n },\n ctx\n )\n );\n\n // Conditionally traverse for private fields only if 'private' is included\n if (includes?.populate?.includes('private')) {\n functionsToApply.push(traverseQueryPopulate(throwPrivate, ctx));\n }\n\n // Return directly if no validation functions are provided\n if (functionsToApply.length === 0) {\n return populate;\n }\n\n return pipeAsync(...functionsToApply)(populate);\n }\n);\n\nexport const defaultValidatePopulate = asyncCurry(async (ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultValidatePopulate');\n }\n\n // Call validatePopulate and include all validations by passing in full traversal arrays\n return validatePopulate(ctx, populate, {\n filters: FILTER_TRAVERSALS,\n sort: SORT_TRAVERSALS,\n fields: FIELDS_TRAVERSALS,\n populate: POPULATE_TRAVERSALS,\n });\n});\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","FILTER_TRAVERSALS","validateFilters","asyncCurry","ctx","filters","include","schema","Error","functionsToApply","includes","push","traverseQueryFilters","key","attribute","path","isAttribute","isOperator","throwInvalidKey","throwDynamicZones","throwMorphToRelations","throwPassword","throwPrivate","length","pipeAsync","defaultValidateFilters","SORT_TRAVERSALS","validateSort","sort","traverseQuerySort","value","isScalarAttribute","isEmpty","defaultValidateSort","FIELDS_TRAVERSALS","validateFields","fields","traverseQueryFields","isNil","defaultValidateFields","POPULATE_TRAVERSALS","validatePopulate","populate","traverseQueryPopulate","getModel","parent","set","isPopulatableAttribute","type","raw","isObject","targets","Object","keys","target","model","parseType","defaultValidatePopulate"],"mappings":"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"}