@strapi/utils 5.12.1 → 5.12.2

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,194 @@
1
+ import { isArray, omit, cloneDeep } from 'lodash/fp';
2
+ import { getNonWritableAttributes, constants } from '../content-types.mjs';
3
+ import { pipe } from '../async.mjs';
4
+ import * as index from './visitors/index.mjs';
5
+ export { index as visitors };
6
+ import { defaultSanitizeFilters, defaultSanitizeSort, defaultSanitizeFields, defaultSanitizePopulate, defaultSanitizeOutput } from './sanitizers.mjs';
7
+ import * as sanitizers from './sanitizers.mjs';
8
+ export { sanitizers };
9
+ import traverseEntity from '../traverse-entity.mjs';
10
+ import traverseQueryFilters from '../traverse/query-filters.mjs';
11
+ import traverseQuerySort from '../traverse/query-sort.mjs';
12
+ import traverseQueryPopulate from '../traverse/query-populate.mjs';
13
+ import '../traverse/query-fields.mjs';
14
+ import removeRestrictedFields from './visitors/remove-restricted-fields.mjs';
15
+ import removeRestrictedRelations from './visitors/remove-restricted-relations.mjs';
16
+
17
+ const createAPISanitizers = (opts)=>{
18
+ const { getModel } = opts;
19
+ const sanitizeInput = (data, schema, { auth } = {})=>{
20
+ if (!schema) {
21
+ throw new Error('Missing schema in sanitizeInput');
22
+ }
23
+ if (isArray(data)) {
24
+ return Promise.all(data.map((entry)=>sanitizeInput(entry, schema, {
25
+ auth
26
+ })));
27
+ }
28
+ const nonWritableAttributes = getNonWritableAttributes(schema);
29
+ const transforms = [
30
+ // Remove first level ID in inputs
31
+ omit(constants.ID_ATTRIBUTE),
32
+ omit(constants.DOC_ID_ATTRIBUTE),
33
+ // Remove non-writable attributes
34
+ traverseEntity(removeRestrictedFields(nonWritableAttributes), {
35
+ schema,
36
+ getModel
37
+ })
38
+ ];
39
+ if (auth) {
40
+ // Remove restricted relations
41
+ transforms.push(traverseEntity(removeRestrictedRelations(auth), {
42
+ schema,
43
+ getModel
44
+ }));
45
+ }
46
+ // Apply sanitizers from registry if exists
47
+ opts?.sanitizers?.input?.forEach((sanitizer)=>transforms.push(sanitizer(schema)));
48
+ return pipe(...transforms)(data);
49
+ };
50
+ const sanitizeOutput = async (data, schema, { auth } = {})=>{
51
+ if (!schema) {
52
+ throw new Error('Missing schema in sanitizeOutput');
53
+ }
54
+ if (isArray(data)) {
55
+ const res = new Array(data.length);
56
+ for(let i = 0; i < data.length; i += 1){
57
+ res[i] = await sanitizeOutput(data[i], schema, {
58
+ auth
59
+ });
60
+ }
61
+ return res;
62
+ }
63
+ const transforms = [
64
+ (data)=>defaultSanitizeOutput({
65
+ schema,
66
+ getModel
67
+ }, data)
68
+ ];
69
+ if (auth) {
70
+ transforms.push(traverseEntity(removeRestrictedRelations(auth), {
71
+ schema,
72
+ getModel
73
+ }));
74
+ }
75
+ // Apply sanitizers from registry if exists
76
+ opts?.sanitizers?.output?.forEach((sanitizer)=>transforms.push(sanitizer(schema)));
77
+ return pipe(...transforms)(data);
78
+ };
79
+ const sanitizeQuery = async (query, schema, { auth } = {})=>{
80
+ if (!schema) {
81
+ throw new Error('Missing schema in sanitizeQuery');
82
+ }
83
+ const { filters, sort, fields, populate } = query;
84
+ const sanitizedQuery = cloneDeep(query);
85
+ if (filters) {
86
+ Object.assign(sanitizedQuery, {
87
+ filters: await sanitizeFilters(filters, schema, {
88
+ auth
89
+ })
90
+ });
91
+ }
92
+ if (sort) {
93
+ Object.assign(sanitizedQuery, {
94
+ sort: await sanitizeSort(sort, schema, {
95
+ auth
96
+ })
97
+ });
98
+ }
99
+ if (fields) {
100
+ Object.assign(sanitizedQuery, {
101
+ fields: await sanitizeFields(fields, schema)
102
+ });
103
+ }
104
+ if (populate) {
105
+ Object.assign(sanitizedQuery, {
106
+ populate: await sanitizePopulate(populate, schema)
107
+ });
108
+ }
109
+ return sanitizedQuery;
110
+ };
111
+ const sanitizeFilters = (filters, schema, { auth } = {})=>{
112
+ if (!schema) {
113
+ throw new Error('Missing schema in sanitizeFilters');
114
+ }
115
+ if (isArray(filters)) {
116
+ return Promise.all(filters.map((filter)=>sanitizeFilters(filter, schema, {
117
+ auth
118
+ })));
119
+ }
120
+ const transforms = [
121
+ defaultSanitizeFilters({
122
+ schema,
123
+ getModel
124
+ })
125
+ ];
126
+ if (auth) {
127
+ transforms.push(traverseQueryFilters(removeRestrictedRelations(auth), {
128
+ schema,
129
+ getModel
130
+ }));
131
+ }
132
+ return pipe(...transforms)(filters);
133
+ };
134
+ const sanitizeSort = (sort, schema, { auth } = {})=>{
135
+ if (!schema) {
136
+ throw new Error('Missing schema in sanitizeSort');
137
+ }
138
+ const transforms = [
139
+ defaultSanitizeSort({
140
+ schema,
141
+ getModel
142
+ })
143
+ ];
144
+ if (auth) {
145
+ transforms.push(traverseQuerySort(removeRestrictedRelations(auth), {
146
+ schema,
147
+ getModel
148
+ }));
149
+ }
150
+ return pipe(...transforms)(sort);
151
+ };
152
+ const sanitizeFields = (fields, schema)=>{
153
+ if (!schema) {
154
+ throw new Error('Missing schema in sanitizeFields');
155
+ }
156
+ const transforms = [
157
+ defaultSanitizeFields({
158
+ schema,
159
+ getModel
160
+ })
161
+ ];
162
+ return pipe(...transforms)(fields);
163
+ };
164
+ const sanitizePopulate = (populate, schema, { auth } = {})=>{
165
+ if (!schema) {
166
+ throw new Error('Missing schema in sanitizePopulate');
167
+ }
168
+ const transforms = [
169
+ defaultSanitizePopulate({
170
+ schema,
171
+ getModel
172
+ })
173
+ ];
174
+ if (auth) {
175
+ transforms.push(traverseQueryPopulate(removeRestrictedRelations(auth), {
176
+ schema,
177
+ getModel
178
+ }));
179
+ }
180
+ return pipe(...transforms)(populate);
181
+ };
182
+ return {
183
+ input: sanitizeInput,
184
+ output: sanitizeOutput,
185
+ query: sanitizeQuery,
186
+ filters: sanitizeFilters,
187
+ sort: sanitizeSort,
188
+ fields: sanitizeFields,
189
+ populate: sanitizePopulate
190
+ };
191
+ };
192
+
193
+ export { createAPISanitizers };
194
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../../src/sanitize/index.ts"],"sourcesContent":["import { CurriedFunction1 } from 'lodash';\nimport { isArray, cloneDeep, omit } from 'lodash/fp';\n\nimport { constants, getNonWritableAttributes } from '../content-types';\nimport { pipe as pipeAsync } from '../async';\n\nimport * as visitors from './visitors';\nimport * as sanitizers from './sanitizers';\nimport traverseEntity from '../traverse-entity';\n\nimport { traverseQueryFilters, traverseQuerySort, traverseQueryPopulate } from '../traverse';\nimport type { Model, Data } from '../types';\n\nexport interface Options {\n auth?: unknown;\n}\n\nexport interface Sanitizer {\n (schema: Model): CurriedFunction1<Data, Promise<Data>>;\n}\nexport interface SanitizeFunc {\n (data: unknown, schema: Model, options?: Options): Promise<unknown>;\n}\n\nexport interface APIOptions {\n sanitizers?: Sanitizers;\n getModel: (model: string) => Model;\n}\n\nexport interface Sanitizers {\n input?: Sanitizer[];\n output?: Sanitizer[];\n}\n\nconst createAPISanitizers = (opts: APIOptions) => {\n const { getModel } = opts;\n\n const sanitizeInput: SanitizeFunc = (data: unknown, schema: Model, { auth } = {}) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeInput');\n }\n if (isArray(data)) {\n return Promise.all(data.map((entry) => sanitizeInput(entry, schema, { auth })));\n }\n\n const nonWritableAttributes = getNonWritableAttributes(schema);\n\n const transforms = [\n // Remove first level ID in inputs\n omit(constants.ID_ATTRIBUTE),\n omit(constants.DOC_ID_ATTRIBUTE),\n // Remove non-writable attributes\n traverseEntity(visitors.removeRestrictedFields(nonWritableAttributes), { schema, getModel }),\n ];\n\n if (auth) {\n // Remove restricted relations\n transforms.push(\n traverseEntity(visitors.removeRestrictedRelations(auth), { schema, getModel })\n );\n }\n\n // Apply sanitizers from registry if exists\n opts?.sanitizers?.input?.forEach((sanitizer: Sanitizer) => transforms.push(sanitizer(schema)));\n\n return pipeAsync(...transforms)(data as Data);\n };\n\n const sanitizeOutput: SanitizeFunc = async (data, schema: Model, { auth } = {}) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeOutput');\n }\n if (isArray(data)) {\n const res = new Array(data.length);\n for (let i = 0; i < data.length; i += 1) {\n res[i] = await sanitizeOutput(data[i], schema, { auth });\n }\n return res;\n }\n\n const transforms = [\n (data: Data) => sanitizers.defaultSanitizeOutput({ schema, getModel }, data),\n ];\n\n if (auth) {\n transforms.push(\n traverseEntity(visitors.removeRestrictedRelations(auth), { schema, getModel })\n );\n }\n\n // Apply sanitizers from registry if exists\n opts?.sanitizers?.output?.forEach((sanitizer: Sanitizer) => transforms.push(sanitizer(schema)));\n\n return pipeAsync(...transforms)(data as Data);\n };\n\n const sanitizeQuery = async (\n query: Record<string, unknown>,\n schema: Model,\n { auth }: Options = {}\n ) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeQuery');\n }\n const { filters, sort, fields, populate } = query;\n\n const sanitizedQuery = cloneDeep(query);\n\n if (filters) {\n Object.assign(sanitizedQuery, { filters: await sanitizeFilters(filters, schema, { auth }) });\n }\n\n if (sort) {\n Object.assign(sanitizedQuery, { sort: await sanitizeSort(sort, schema, { auth }) });\n }\n\n if (fields) {\n Object.assign(sanitizedQuery, { fields: await sanitizeFields(fields, schema) });\n }\n\n if (populate) {\n Object.assign(sanitizedQuery, { populate: await sanitizePopulate(populate, schema) });\n }\n\n return sanitizedQuery;\n };\n\n const sanitizeFilters: SanitizeFunc = (filters, schema: Model, { auth } = {}) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeFilters');\n }\n if (isArray(filters)) {\n return Promise.all(filters.map((filter) => sanitizeFilters(filter, schema, { auth })));\n }\n\n const transforms = [sanitizers.defaultSanitizeFilters({ schema, getModel })];\n\n if (auth) {\n transforms.push(\n traverseQueryFilters(visitors.removeRestrictedRelations(auth), { schema, getModel })\n );\n }\n\n return pipeAsync(...transforms)(filters);\n };\n\n const sanitizeSort: SanitizeFunc = (sort, schema: Model, { auth } = {}) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeSort');\n }\n const transforms = [sanitizers.defaultSanitizeSort({ schema, getModel })];\n\n if (auth) {\n transforms.push(\n traverseQuerySort(visitors.removeRestrictedRelations(auth), { schema, getModel })\n );\n }\n\n return pipeAsync(...transforms)(sort);\n };\n\n const sanitizeFields: SanitizeFunc = (fields, schema: Model) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizeFields');\n }\n const transforms = [sanitizers.defaultSanitizeFields({ schema, getModel })];\n\n return pipeAsync(...transforms)(fields);\n };\n\n const sanitizePopulate: SanitizeFunc = (populate, schema: Model, { auth } = {}) => {\n if (!schema) {\n throw new Error('Missing schema in sanitizePopulate');\n }\n const transforms = [sanitizers.defaultSanitizePopulate({ schema, getModel })];\n\n if (auth) {\n transforms.push(\n traverseQueryPopulate(visitors.removeRestrictedRelations(auth), { schema, getModel })\n );\n }\n\n return pipeAsync(...transforms)(populate);\n };\n\n return {\n input: sanitizeInput,\n output: sanitizeOutput,\n query: sanitizeQuery,\n filters: sanitizeFilters,\n sort: sanitizeSort,\n fields: sanitizeFields,\n populate: sanitizePopulate,\n };\n};\n\nexport { createAPISanitizers, sanitizers, visitors };\n\nexport type APISanitiers = ReturnType<typeof createAPISanitizers>;\n"],"names":["createAPISanitizers","opts","getModel","sanitizeInput","data","schema","auth","Error","isArray","Promise","all","map","entry","nonWritableAttributes","getNonWritableAttributes","transforms","omit","constants","ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","traverseEntity","visitors","push","sanitizers","input","forEach","sanitizer","pipeAsync","sanitizeOutput","res","Array","length","i","output","sanitizeQuery","query","filters","sort","fields","populate","sanitizedQuery","cloneDeep","Object","assign","sanitizeFilters","sanitizeSort","sanitizeFields","sanitizePopulate","filter","traverseQueryFilters","traverseQuerySort","traverseQueryPopulate"],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ 'use strict';
2
+
3
+ var fp = require('lodash/fp');
4
+ var async = require('../async.js');
5
+ var traverseEntity = require('../traverse-entity.js');
6
+ var contentTypes = require('../content-types.js');
7
+ var queryFilters = require('../traverse/query-filters.js');
8
+ var querySort = require('../traverse/query-sort.js');
9
+ var queryPopulate = require('../traverse/query-populate.js');
10
+ var queryFields = require('../traverse/query-fields.js');
11
+ var removePassword = require('./visitors/remove-password.js');
12
+ var removePrivate = require('./visitors/remove-private.js');
13
+ var removeMorphToRelations = require('./visitors/remove-morph-to-relations.js');
14
+ var removeDynamicZones = require('./visitors/remove-dynamic-zones.js');
15
+ var expandWildcardPopulate = require('./visitors/expand-wildcard-populate.js');
16
+ var operators = require('../operators.js');
17
+
18
+ const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = contentTypes.constants;
19
+ const sanitizePasswords = (ctx)=>async (entity)=>{
20
+ if (!ctx.schema) {
21
+ throw new Error('Missing schema in sanitizePasswords');
22
+ }
23
+ return traverseEntity(removePassword, ctx, entity);
24
+ };
25
+ const defaultSanitizeOutput = async (ctx, entity)=>{
26
+ if (!ctx.schema) {
27
+ throw new Error('Missing schema in defaultSanitizeOutput');
28
+ }
29
+ return traverseEntity((...args)=>{
30
+ removePassword(...args);
31
+ removePrivate(...args);
32
+ }, ctx, entity);
33
+ };
34
+ const defaultSanitizeFilters = fp.curry((ctx, filters)=>{
35
+ if (!ctx.schema) {
36
+ throw new Error('Missing schema in defaultSanitizeFilters');
37
+ }
38
+ return async.pipe(// Remove keys that are not attributes or valid operators
39
+ queryFilters(({ key, attribute }, { remove })=>{
40
+ const isAttribute = !!attribute;
41
+ // ID is not an attribute per se, so we need to make
42
+ // an extra check to ensure we're not checking it
43
+ if ([
44
+ ID_ATTRIBUTE,
45
+ DOC_ID_ATTRIBUTE
46
+ ].includes(key)) {
47
+ return;
48
+ }
49
+ if (!isAttribute && !operators.isOperator(key)) {
50
+ remove(key);
51
+ }
52
+ }, ctx), // Remove dynamic zones from filters
53
+ queryFilters(removeDynamicZones, ctx), // Remove morpTo relations from filters
54
+ queryFilters(removeMorphToRelations, ctx), // Remove passwords from filters
55
+ queryFilters(removePassword, ctx), // Remove private from filters
56
+ queryFilters(removePrivate, ctx), // Remove empty objects
57
+ queryFilters(({ key, value }, { remove })=>{
58
+ if (fp.isObject(value) && fp.isEmpty(value)) {
59
+ remove(key);
60
+ }
61
+ }, ctx))(filters);
62
+ });
63
+ const defaultSanitizeSort = fp.curry((ctx, sort)=>{
64
+ if (!ctx.schema) {
65
+ throw new Error('Missing schema in defaultSanitizeSort');
66
+ }
67
+ return async.pipe(// Remove non attribute keys
68
+ querySort(({ key, attribute }, { remove })=>{
69
+ // ID is not an attribute per se, so we need to make
70
+ // an extra check to ensure we're not checking it
71
+ if ([
72
+ ID_ATTRIBUTE,
73
+ DOC_ID_ATTRIBUTE
74
+ ].includes(key)) {
75
+ return;
76
+ }
77
+ if (!attribute) {
78
+ remove(key);
79
+ }
80
+ }, ctx), // Remove dynamic zones from sort
81
+ querySort(removeDynamicZones, ctx), // Remove morpTo relations from sort
82
+ querySort(removeMorphToRelations, ctx), // Remove private from sort
83
+ querySort(removePrivate, ctx), // Remove passwords from filters
84
+ querySort(removePassword, ctx), // Remove keys for empty non-scalar values
85
+ querySort(({ key, attribute, value }, { remove })=>{
86
+ // ID is not an attribute per se, so we need to make
87
+ // an extra check to ensure we're not removing it
88
+ if ([
89
+ ID_ATTRIBUTE,
90
+ DOC_ID_ATTRIBUTE
91
+ ].includes(key)) {
92
+ return;
93
+ }
94
+ if (!contentTypes.isScalarAttribute(attribute) && fp.isEmpty(value)) {
95
+ remove(key);
96
+ }
97
+ }, ctx))(sort);
98
+ });
99
+ const defaultSanitizeFields = fp.curry((ctx, fields)=>{
100
+ if (!ctx.schema) {
101
+ throw new Error('Missing schema in defaultSanitizeFields');
102
+ }
103
+ return async.pipe(// Only keep scalar attributes
104
+ queryFields(({ key, attribute }, { remove })=>{
105
+ // ID is not an attribute per se, so we need to make
106
+ // an extra check to ensure we're not checking it
107
+ if ([
108
+ ID_ATTRIBUTE,
109
+ DOC_ID_ATTRIBUTE
110
+ ].includes(key)) {
111
+ return;
112
+ }
113
+ if (fp.isNil(attribute) || !contentTypes.isScalarAttribute(attribute)) {
114
+ remove(key);
115
+ }
116
+ }, ctx), // Remove private fields
117
+ queryFields(removePrivate, ctx), // Remove password fields
118
+ queryFields(removePassword, ctx), // Remove nil values from fields array
119
+ (value)=>fp.isArray(value) ? value.filter((field)=>!fp.isNil(field)) : value)(fields);
120
+ });
121
+ const defaultSanitizePopulate = fp.curry((ctx, populate)=>{
122
+ if (!ctx.schema) {
123
+ throw new Error('Missing schema in defaultSanitizePopulate');
124
+ }
125
+ return async.pipe(queryPopulate(expandWildcardPopulate, ctx), queryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set })=>{
126
+ if (attribute) {
127
+ return;
128
+ }
129
+ const parent = {
130
+ key,
131
+ path,
132
+ schema,
133
+ attribute
134
+ };
135
+ if (key === 'sort') {
136
+ set(key, await defaultSanitizeSort({
137
+ schema,
138
+ getModel,
139
+ parent
140
+ }, value));
141
+ }
142
+ if (key === 'filters') {
143
+ set(key, await defaultSanitizeFilters({
144
+ schema,
145
+ getModel,
146
+ parent
147
+ }, value));
148
+ }
149
+ if (key === 'fields') {
150
+ set(key, await defaultSanitizeFields({
151
+ schema,
152
+ getModel,
153
+ parent
154
+ }, value));
155
+ }
156
+ if (key === 'populate') {
157
+ set(key, await defaultSanitizePopulate({
158
+ schema,
159
+ getModel,
160
+ parent
161
+ }, value));
162
+ }
163
+ }, ctx), // Remove private fields
164
+ queryPopulate(removePrivate, ctx))(populate);
165
+ });
166
+
167
+ exports.defaultSanitizeFields = defaultSanitizeFields;
168
+ exports.defaultSanitizeFilters = defaultSanitizeFilters;
169
+ exports.defaultSanitizeOutput = defaultSanitizeOutput;
170
+ exports.defaultSanitizePopulate = defaultSanitizePopulate;
171
+ exports.defaultSanitizeSort = defaultSanitizeSort;
172
+ exports.sanitizePasswords = sanitizePasswords;
173
+ //# sourceMappingURL=sanitizers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizers.js","sources":["../../src/sanitize/sanitizers.ts"],"sourcesContent":["import { curry, isEmpty, isNil, isArray, isObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport traverseEntity from '../traverse-entity';\nimport { isScalarAttribute, constants } from '../content-types';\n\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryPopulate,\n traverseQueryFields,\n} from '../traverse';\n\nimport {\n removePassword,\n removePrivate,\n removeDynamicZones,\n removeMorphToRelations,\n expandWildcardPopulate,\n} from './visitors';\nimport { isOperator } from '../operators';\n\nimport type { Model, Data } from '../types';\nimport type { Parent } from '../traverse/factory';\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n parent?: Parent;\n}\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\nconst sanitizePasswords = (ctx: Context) => async (entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in sanitizePasswords');\n }\n\n return traverseEntity(removePassword, ctx, entity);\n};\n\nconst defaultSanitizeOutput = async (ctx: Context, entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeOutput');\n }\n\n return traverseEntity(\n (...args) => {\n removePassword(...args);\n removePrivate(...args);\n },\n ctx,\n entity\n );\n};\n\nconst defaultSanitizeFilters = curry((ctx: Context, filters: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFilters');\n }\n\n return pipeAsync(\n // Remove keys that are not attributes or valid operators\n traverseQueryFilters(({ key, attribute }, { remove }) => {\n const isAttribute = !!attribute;\n\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isAttribute && !isOperator(key)) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from filters\n traverseQueryFilters(removeDynamicZones, ctx),\n // Remove morpTo relations from filters\n traverseQueryFilters(removeMorphToRelations, ctx),\n // Remove passwords from filters\n traverseQueryFilters(removePassword, ctx),\n // Remove private from filters\n traverseQueryFilters(removePrivate, ctx),\n // Remove empty objects\n traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n )(filters);\n});\n\nconst defaultSanitizeSort = curry((ctx: Context, sort: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeSort');\n }\n\n return pipeAsync(\n // Remove non attribute keys\n traverseQuerySort(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!attribute) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from sort\n traverseQuerySort(removeDynamicZones, ctx),\n // Remove morpTo relations from sort\n traverseQuerySort(removeMorphToRelations, ctx),\n // Remove private from sort\n traverseQuerySort(removePrivate, ctx),\n // Remove passwords from filters\n traverseQuerySort(removePassword, ctx),\n // Remove keys for empty non-scalar values\n traverseQuerySort(({ key, attribute, value }, { remove }) => {\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 remove(key);\n }\n }, ctx)\n )(sort);\n});\n\nconst defaultSanitizeFields = curry((ctx: Context, fields: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFields');\n }\n\n return pipeAsync(\n // Only keep scalar attributes\n traverseQueryFields(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n remove(key);\n }\n }, ctx),\n // Remove private fields\n traverseQueryFields(removePrivate, ctx),\n // Remove password fields\n traverseQueryFields(removePassword, ctx),\n // Remove nil values from fields array\n (value) => (isArray(value) ? value.filter((field) => !isNil(field)) : value)\n )(fields);\n});\n\nconst defaultSanitizePopulate = curry((ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizePopulate');\n }\n\n return pipeAsync(\n traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverseQueryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set }) => {\n if (attribute) {\n return;\n }\n\n const parent = { key, path, schema, attribute } satisfies Parent;\n\n if (key === 'sort') {\n set(key, await defaultSanitizeSort({ schema, getModel, parent }, value));\n }\n\n if (key === 'filters') {\n set(key, await defaultSanitizeFilters({ schema, getModel, parent }, value));\n }\n\n if (key === 'fields') {\n set(key, await defaultSanitizeFields({ schema, getModel, parent }, value));\n }\n\n if (key === 'populate') {\n set(key, await defaultSanitizePopulate({ schema, getModel, parent }, value));\n }\n }, ctx),\n // Remove private fields\n traverseQueryPopulate(removePrivate, ctx)\n )(populate);\n});\n\nexport {\n sanitizePasswords,\n defaultSanitizeOutput,\n defaultSanitizeFilters,\n defaultSanitizeSort,\n defaultSanitizeFields,\n defaultSanitizePopulate,\n};\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","sanitizePasswords","ctx","entity","schema","Error","traverseEntity","removePassword","defaultSanitizeOutput","args","removePrivate","defaultSanitizeFilters","curry","filters","pipeAsync","traverseQueryFilters","key","attribute","remove","isAttribute","includes","isOperator","removeDynamicZones","removeMorphToRelations","value","isObject","isEmpty","defaultSanitizeSort","sort","traverseQuerySort","isScalarAttribute","defaultSanitizeFields","fields","traverseQueryFields","isNil","isArray","filter","field","defaultSanitizePopulate","populate","traverseQueryPopulate","expandWildcardPopulate","getModel","path","set","parent"],"mappings":"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"}
@@ -0,0 +1,166 @@
1
+ import { curry, isObject, isEmpty, isNil, isArray } from 'lodash/fp';
2
+ import { pipe } from '../async.mjs';
3
+ import traverseEntity from '../traverse-entity.mjs';
4
+ import { isScalarAttribute, constants } from '../content-types.mjs';
5
+ import traverseQueryFilters from '../traverse/query-filters.mjs';
6
+ import traverseQuerySort from '../traverse/query-sort.mjs';
7
+ import traverseQueryPopulate from '../traverse/query-populate.mjs';
8
+ import traverseQueryFields from '../traverse/query-fields.mjs';
9
+ import visitor$1 from './visitors/remove-password.mjs';
10
+ import visitor from './visitors/remove-private.mjs';
11
+ import visitor$2 from './visitors/remove-morph-to-relations.mjs';
12
+ import visitor$3 from './visitors/remove-dynamic-zones.mjs';
13
+ import visitor$4 from './visitors/expand-wildcard-populate.mjs';
14
+ import { isOperator } from '../operators.mjs';
15
+
16
+ const { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;
17
+ const sanitizePasswords = (ctx)=>async (entity)=>{
18
+ if (!ctx.schema) {
19
+ throw new Error('Missing schema in sanitizePasswords');
20
+ }
21
+ return traverseEntity(visitor$1, ctx, entity);
22
+ };
23
+ const defaultSanitizeOutput = async (ctx, entity)=>{
24
+ if (!ctx.schema) {
25
+ throw new Error('Missing schema in defaultSanitizeOutput');
26
+ }
27
+ return traverseEntity((...args)=>{
28
+ visitor$1(...args);
29
+ visitor(...args);
30
+ }, ctx, entity);
31
+ };
32
+ const defaultSanitizeFilters = curry((ctx, filters)=>{
33
+ if (!ctx.schema) {
34
+ throw new Error('Missing schema in defaultSanitizeFilters');
35
+ }
36
+ return pipe(// Remove keys that are not attributes or valid operators
37
+ traverseQueryFilters(({ key, attribute }, { remove })=>{
38
+ const isAttribute = !!attribute;
39
+ // ID is not an attribute per se, so we need to make
40
+ // an extra check to ensure we're not checking it
41
+ if ([
42
+ ID_ATTRIBUTE,
43
+ DOC_ID_ATTRIBUTE
44
+ ].includes(key)) {
45
+ return;
46
+ }
47
+ if (!isAttribute && !isOperator(key)) {
48
+ remove(key);
49
+ }
50
+ }, ctx), // Remove dynamic zones from filters
51
+ traverseQueryFilters(visitor$3, ctx), // Remove morpTo relations from filters
52
+ traverseQueryFilters(visitor$2, ctx), // Remove passwords from filters
53
+ traverseQueryFilters(visitor$1, ctx), // Remove private from filters
54
+ traverseQueryFilters(visitor, ctx), // Remove empty objects
55
+ traverseQueryFilters(({ key, value }, { remove })=>{
56
+ if (isObject(value) && isEmpty(value)) {
57
+ remove(key);
58
+ }
59
+ }, ctx))(filters);
60
+ });
61
+ const defaultSanitizeSort = curry((ctx, sort)=>{
62
+ if (!ctx.schema) {
63
+ throw new Error('Missing schema in defaultSanitizeSort');
64
+ }
65
+ return pipe(// Remove non attribute keys
66
+ traverseQuerySort(({ key, attribute }, { remove })=>{
67
+ // ID is not an attribute per se, so we need to make
68
+ // an extra check to ensure we're not checking it
69
+ if ([
70
+ ID_ATTRIBUTE,
71
+ DOC_ID_ATTRIBUTE
72
+ ].includes(key)) {
73
+ return;
74
+ }
75
+ if (!attribute) {
76
+ remove(key);
77
+ }
78
+ }, ctx), // Remove dynamic zones from sort
79
+ traverseQuerySort(visitor$3, ctx), // Remove morpTo relations from sort
80
+ traverseQuerySort(visitor$2, ctx), // Remove private from sort
81
+ traverseQuerySort(visitor, ctx), // Remove passwords from filters
82
+ traverseQuerySort(visitor$1, ctx), // Remove keys for empty non-scalar values
83
+ traverseQuerySort(({ key, attribute, value }, { remove })=>{
84
+ // ID is not an attribute per se, so we need to make
85
+ // an extra check to ensure we're not removing it
86
+ if ([
87
+ ID_ATTRIBUTE,
88
+ DOC_ID_ATTRIBUTE
89
+ ].includes(key)) {
90
+ return;
91
+ }
92
+ if (!isScalarAttribute(attribute) && isEmpty(value)) {
93
+ remove(key);
94
+ }
95
+ }, ctx))(sort);
96
+ });
97
+ const defaultSanitizeFields = curry((ctx, fields)=>{
98
+ if (!ctx.schema) {
99
+ throw new Error('Missing schema in defaultSanitizeFields');
100
+ }
101
+ return pipe(// Only keep scalar attributes
102
+ traverseQueryFields(({ key, attribute }, { remove })=>{
103
+ // ID is not an attribute per se, so we need to make
104
+ // an extra check to ensure we're not checking it
105
+ if ([
106
+ ID_ATTRIBUTE,
107
+ DOC_ID_ATTRIBUTE
108
+ ].includes(key)) {
109
+ return;
110
+ }
111
+ if (isNil(attribute) || !isScalarAttribute(attribute)) {
112
+ remove(key);
113
+ }
114
+ }, ctx), // Remove private fields
115
+ traverseQueryFields(visitor, ctx), // Remove password fields
116
+ traverseQueryFields(visitor$1, ctx), // Remove nil values from fields array
117
+ (value)=>isArray(value) ? value.filter((field)=>!isNil(field)) : value)(fields);
118
+ });
119
+ const defaultSanitizePopulate = curry((ctx, populate)=>{
120
+ if (!ctx.schema) {
121
+ throw new Error('Missing schema in defaultSanitizePopulate');
122
+ }
123
+ return pipe(traverseQueryPopulate(visitor$4, ctx), traverseQueryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set })=>{
124
+ if (attribute) {
125
+ return;
126
+ }
127
+ const parent = {
128
+ key,
129
+ path,
130
+ schema,
131
+ attribute
132
+ };
133
+ if (key === 'sort') {
134
+ set(key, await defaultSanitizeSort({
135
+ schema,
136
+ getModel,
137
+ parent
138
+ }, value));
139
+ }
140
+ if (key === 'filters') {
141
+ set(key, await defaultSanitizeFilters({
142
+ schema,
143
+ getModel,
144
+ parent
145
+ }, value));
146
+ }
147
+ if (key === 'fields') {
148
+ set(key, await defaultSanitizeFields({
149
+ schema,
150
+ getModel,
151
+ parent
152
+ }, value));
153
+ }
154
+ if (key === 'populate') {
155
+ set(key, await defaultSanitizePopulate({
156
+ schema,
157
+ getModel,
158
+ parent
159
+ }, value));
160
+ }
161
+ }, ctx), // Remove private fields
162
+ traverseQueryPopulate(visitor, ctx))(populate);
163
+ });
164
+
165
+ export { defaultSanitizeFields, defaultSanitizeFilters, defaultSanitizeOutput, defaultSanitizePopulate, defaultSanitizeSort, sanitizePasswords };
166
+ //# sourceMappingURL=sanitizers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitizers.mjs","sources":["../../src/sanitize/sanitizers.ts"],"sourcesContent":["import { curry, isEmpty, isNil, isArray, isObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport traverseEntity from '../traverse-entity';\nimport { isScalarAttribute, constants } from '../content-types';\n\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryPopulate,\n traverseQueryFields,\n} from '../traverse';\n\nimport {\n removePassword,\n removePrivate,\n removeDynamicZones,\n removeMorphToRelations,\n expandWildcardPopulate,\n} from './visitors';\nimport { isOperator } from '../operators';\n\nimport type { Model, Data } from '../types';\nimport type { Parent } from '../traverse/factory';\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n parent?: Parent;\n}\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\nconst sanitizePasswords = (ctx: Context) => async (entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in sanitizePasswords');\n }\n\n return traverseEntity(removePassword, ctx, entity);\n};\n\nconst defaultSanitizeOutput = async (ctx: Context, entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeOutput');\n }\n\n return traverseEntity(\n (...args) => {\n removePassword(...args);\n removePrivate(...args);\n },\n ctx,\n entity\n );\n};\n\nconst defaultSanitizeFilters = curry((ctx: Context, filters: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFilters');\n }\n\n return pipeAsync(\n // Remove keys that are not attributes or valid operators\n traverseQueryFilters(({ key, attribute }, { remove }) => {\n const isAttribute = !!attribute;\n\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isAttribute && !isOperator(key)) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from filters\n traverseQueryFilters(removeDynamicZones, ctx),\n // Remove morpTo relations from filters\n traverseQueryFilters(removeMorphToRelations, ctx),\n // Remove passwords from filters\n traverseQueryFilters(removePassword, ctx),\n // Remove private from filters\n traverseQueryFilters(removePrivate, ctx),\n // Remove empty objects\n traverseQueryFilters(({ key, value }, { remove }) => {\n if (isObject(value) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n )(filters);\n});\n\nconst defaultSanitizeSort = curry((ctx: Context, sort: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeSort');\n }\n\n return pipeAsync(\n // Remove non attribute keys\n traverseQuerySort(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!attribute) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from sort\n traverseQuerySort(removeDynamicZones, ctx),\n // Remove morpTo relations from sort\n traverseQuerySort(removeMorphToRelations, ctx),\n // Remove private from sort\n traverseQuerySort(removePrivate, ctx),\n // Remove passwords from filters\n traverseQuerySort(removePassword, ctx),\n // Remove keys for empty non-scalar values\n traverseQuerySort(({ key, attribute, value }, { remove }) => {\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 remove(key);\n }\n }, ctx)\n )(sort);\n});\n\nconst defaultSanitizeFields = curry((ctx: Context, fields: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFields');\n }\n\n return pipeAsync(\n // Only keep scalar attributes\n traverseQueryFields(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n remove(key);\n }\n }, ctx),\n // Remove private fields\n traverseQueryFields(removePrivate, ctx),\n // Remove password fields\n traverseQueryFields(removePassword, ctx),\n // Remove nil values from fields array\n (value) => (isArray(value) ? value.filter((field) => !isNil(field)) : value)\n )(fields);\n});\n\nconst defaultSanitizePopulate = curry((ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizePopulate');\n }\n\n return pipeAsync(\n traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverseQueryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set }) => {\n if (attribute) {\n return;\n }\n\n const parent = { key, path, schema, attribute } satisfies Parent;\n\n if (key === 'sort') {\n set(key, await defaultSanitizeSort({ schema, getModel, parent }, value));\n }\n\n if (key === 'filters') {\n set(key, await defaultSanitizeFilters({ schema, getModel, parent }, value));\n }\n\n if (key === 'fields') {\n set(key, await defaultSanitizeFields({ schema, getModel, parent }, value));\n }\n\n if (key === 'populate') {\n set(key, await defaultSanitizePopulate({ schema, getModel, parent }, value));\n }\n }, ctx),\n // Remove private fields\n traverseQueryPopulate(removePrivate, ctx)\n )(populate);\n});\n\nexport {\n sanitizePasswords,\n defaultSanitizeOutput,\n defaultSanitizeFilters,\n defaultSanitizeSort,\n defaultSanitizeFields,\n defaultSanitizePopulate,\n};\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","sanitizePasswords","ctx","entity","schema","Error","traverseEntity","removePassword","defaultSanitizeOutput","args","removePrivate","defaultSanitizeFilters","curry","filters","pipeAsync","traverseQueryFilters","key","attribute","remove","isAttribute","includes","isOperator","removeDynamicZones","removeMorphToRelations","value","isObject","isEmpty","defaultSanitizeSort","sort","traverseQuerySort","isScalarAttribute","defaultSanitizeFields","fields","traverseQueryFields","isNil","isArray","filter","field","defaultSanitizePopulate","populate","traverseQueryPopulate","expandWildcardPopulate","getModel","path","set","parent"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ const visitor = ({ schema, key, value }, { set })=>{
4
+ if (key === '' && value === '*') {
5
+ const { attributes } = schema;
6
+ const newPopulateQuery = Object.entries(attributes).filter(([, attribute])=>[
7
+ 'relation',
8
+ 'component',
9
+ 'media',
10
+ 'dynamiczone'
11
+ ].includes(attribute.type)).reduce((acc, [key])=>({
12
+ ...acc,
13
+ [key]: true
14
+ }), {});
15
+ set('', newPopulateQuery);
16
+ }
17
+ };
18
+
19
+ module.exports = visitor;
20
+ //# sourceMappingURL=expand-wildcard-populate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expand-wildcard-populate.js","sources":["../../../src/sanitize/visitors/expand-wildcard-populate.ts"],"sourcesContent":["import type { Visitor } from '../../traverse/factory';\n\nconst visitor: Visitor = ({ schema, key, value }, { set }) => {\n if (key === '' && value === '*') {\n const { attributes } = schema;\n\n const newPopulateQuery = Object.entries(attributes)\n .filter(([, attribute]) =>\n ['relation', 'component', 'media', 'dynamiczone'].includes(attribute.type)\n )\n .reduce<Record<string, true>>((acc, [key]) => ({ ...acc, [key]: true }), {});\n\n set('', newPopulateQuery);\n }\n};\n\nexport default visitor;\n"],"names":["visitor","schema","key","value","set","attributes","newPopulateQuery","Object","entries","filter","attribute","includes","type","reduce","acc"],"mappings":";;AAEA,MAAMA,OAAmB,GAAA,CAAC,EAAEC,MAAM,EAAEC,GAAG,EAAEC,KAAK,EAAE,EAAE,EAAEC,GAAG,EAAE,GAAA;IACvD,IAAIF,GAAAA,KAAQ,EAAMC,IAAAA,KAAAA,KAAU,GAAK,EAAA;QAC/B,MAAM,EAAEE,UAAU,EAAE,GAAGJ,MAAAA;QAEvB,MAAMK,gBAAAA,GAAmBC,MAAOC,CAAAA,OAAO,CAACH,UAAAA,CAAAA,CACrCI,MAAM,CAAC,CAAC,GAAGC,SAAAA,CAAU,GACpB;AAAC,gBAAA,UAAA;AAAY,gBAAA,WAAA;AAAa,gBAAA,OAAA;AAAS,gBAAA;AAAc,aAAA,CAACC,QAAQ,CAACD,SAAUE,CAAAA,IAAI,CAE1EC,CAAAA,CAAAA,MAAM,CAAuB,CAACC,GAAK,EAAA,CAACZ,GAAI,CAAA,IAAM;AAAE,gBAAA,GAAGY,GAAG;AAAE,gBAAA,CAACZ,MAAM;AAAK,aAAA,GAAI,EAAC,CAAA;AAE5EE,QAAAA,GAAAA,CAAI,EAAIE,EAAAA,gBAAAA,CAAAA;AACV;AACF;;;;"}
@@ -0,0 +1,18 @@
1
+ const visitor = ({ schema, key, value }, { set })=>{
2
+ if (key === '' && value === '*') {
3
+ const { attributes } = schema;
4
+ const newPopulateQuery = Object.entries(attributes).filter(([, attribute])=>[
5
+ 'relation',
6
+ 'component',
7
+ 'media',
8
+ 'dynamiczone'
9
+ ].includes(attribute.type)).reduce((acc, [key])=>({
10
+ ...acc,
11
+ [key]: true
12
+ }), {});
13
+ set('', newPopulateQuery);
14
+ }
15
+ };
16
+
17
+ export { visitor as default };
18
+ //# sourceMappingURL=expand-wildcard-populate.mjs.map