@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,114 @@
1
+ import { isArray, isObject } from 'lodash/fp';
2
+ import { isMorphToRelationalAttribute, constants } from '../../content-types.mjs';
3
+ import { VALID_RELATION_ORDERING_KEYS } from '../../relations.mjs';
4
+
5
+ const ACTIONS_TO_VERIFY = [
6
+ 'find'
7
+ ];
8
+ const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = constants;
9
+ var removeRestrictedRelations = ((auth)=>async ({ data, key, attribute, schema }, { remove, set })=>{
10
+ if (!attribute) {
11
+ return;
12
+ }
13
+ const isRelation = attribute.type === 'relation';
14
+ if (!isRelation) {
15
+ return;
16
+ }
17
+ const handleMorphRelation = async ()=>{
18
+ const elements = data[key];
19
+ if ('connect' in elements || 'set' in elements || 'disconnect' in elements) {
20
+ const newValue = {};
21
+ const connect = await handleMorphElements(elements.connect || []);
22
+ const relSet = await handleMorphElements(elements.set || []);
23
+ const disconnect = await handleMorphElements(elements.disconnect || []);
24
+ if (connect.length > 0) {
25
+ newValue.connect = connect;
26
+ }
27
+ if (relSet.length > 0) {
28
+ newValue.set = relSet;
29
+ }
30
+ if (disconnect.length > 0) {
31
+ newValue.disconnect = disconnect;
32
+ }
33
+ // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here
34
+ if ('options' in elements && typeof elements.options === 'object' && elements.options !== null) {
35
+ const filteredOptions = {};
36
+ // Iterate through the keys of elements.options
37
+ Object.keys(elements.options).forEach((key)=>{
38
+ const validator = VALID_RELATION_ORDERING_KEYS[key];
39
+ // Ensure the key exists in VALID_RELATION_ORDERING_KEYS and the validator is defined before calling it
40
+ if (validator && validator(elements.options[key])) {
41
+ filteredOptions[key] = elements.options[key];
42
+ }
43
+ });
44
+ // Assign the filtered options back to newValue
45
+ newValue.options = filteredOptions;
46
+ } else {
47
+ newValue.options = {};
48
+ }
49
+ set(key, newValue);
50
+ } else {
51
+ const newMorphValue = await handleMorphElements(elements);
52
+ if (newMorphValue.length) {
53
+ set(key, newMorphValue);
54
+ }
55
+ }
56
+ };
57
+ const handleMorphElements = async (elements)=>{
58
+ const allowedElements = [];
59
+ if (!isArray(elements)) {
60
+ return allowedElements;
61
+ }
62
+ for (const element of elements){
63
+ if (!isObject(element) || !('__type' in element)) {
64
+ continue;
65
+ }
66
+ const scopes = ACTIONS_TO_VERIFY.map((action)=>`${element.__type}.${action}`);
67
+ const isAllowed = await hasAccessToSomeScopes(scopes, auth);
68
+ if (isAllowed) {
69
+ allowedElements.push(element);
70
+ }
71
+ }
72
+ return allowedElements;
73
+ };
74
+ const handleRegularRelation = async ()=>{
75
+ const scopes = ACTIONS_TO_VERIFY.map((action)=>`${attribute.target}.${action}`);
76
+ const isAllowed = await hasAccessToSomeScopes(scopes, auth);
77
+ // If the authenticated user don't have access to any of the scopes, then remove the field
78
+ if (!isAllowed) {
79
+ remove(key);
80
+ }
81
+ };
82
+ const isCreatorRelation = [
83
+ CREATED_BY_ATTRIBUTE,
84
+ UPDATED_BY_ATTRIBUTE
85
+ ].includes(key);
86
+ // Polymorphic relations
87
+ if (isMorphToRelationalAttribute(attribute)) {
88
+ await handleMorphRelation();
89
+ return;
90
+ }
91
+ // Creator relations
92
+ if (isCreatorRelation && schema.options?.populateCreatorFields) {
93
+ // do nothing
94
+ return;
95
+ }
96
+ // Regular relations
97
+ await handleRegularRelation();
98
+ });
99
+ const hasAccessToSomeScopes = async (scopes, auth)=>{
100
+ for (const scope of scopes){
101
+ try {
102
+ await strapi.auth.verify(auth, {
103
+ scope
104
+ });
105
+ return true;
106
+ } catch {
107
+ continue;
108
+ }
109
+ }
110
+ return false;
111
+ };
112
+
113
+ export { removeRestrictedRelations as default };
114
+ //# sourceMappingURL=remove-restricted-relations.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-restricted-relations.mjs","sources":["../../../src/sanitize/visitors/remove-restricted-relations.ts"],"sourcesContent":["import { isArray, isObject } from 'lodash/fp';\nimport * as contentTypeUtils from '../../content-types';\nimport type { Visitor } from '../../traverse/factory';\nimport { RelationOrderingOptions } from '../../types';\nimport { VALID_RELATION_ORDERING_KEYS } from '../../relations';\n\nconst ACTIONS_TO_VERIFY = ['find'];\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypeUtils.constants;\n\ntype MorphArray = Array<{ __type: string }>;\n\nexport default (auth: unknown): Visitor =>\n async ({ data, key, attribute, schema }, { remove, set }) => {\n if (!attribute) {\n return;\n }\n\n const isRelation = attribute.type === 'relation';\n\n if (!isRelation) {\n return;\n }\n\n const handleMorphRelation = async () => {\n const elements: any = (data as Record<string, MorphArray>)[key];\n\n if ('connect' in elements || 'set' in elements || 'disconnect' in elements) {\n const newValue: Record<string, unknown> = {};\n\n const connect = await handleMorphElements(elements.connect || []);\n const relSet = await handleMorphElements(elements.set || []);\n const disconnect = await handleMorphElements(elements.disconnect || []);\n\n if (connect.length > 0) {\n newValue.connect = connect;\n }\n\n if (relSet.length > 0) {\n newValue.set = relSet;\n }\n\n if (disconnect.length > 0) {\n newValue.disconnect = disconnect;\n }\n\n // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here\n if (\n 'options' in elements &&\n typeof elements.options === 'object' &&\n elements.options !== null\n ) {\n const filteredOptions: RelationOrderingOptions = {};\n\n // Iterate through the keys of elements.options\n Object.keys(elements.options).forEach((key) => {\n const validator = VALID_RELATION_ORDERING_KEYS[key as keyof RelationOrderingOptions];\n\n // Ensure the key exists in VALID_RELATION_ORDERING_KEYS and the validator is defined before calling it\n if (validator && validator(elements.options[key])) {\n filteredOptions[key as keyof RelationOrderingOptions] = elements.options[key];\n }\n });\n\n // Assign the filtered options back to newValue\n newValue.options = filteredOptions;\n } else {\n newValue.options = {};\n }\n\n set(key, newValue);\n } else {\n const newMorphValue = await handleMorphElements(elements);\n\n if (newMorphValue.length) {\n set(key, newMorphValue);\n }\n }\n };\n\n const handleMorphElements = async (elements: any[]) => {\n const allowedElements: Record<string, unknown>[] = [];\n\n if (!isArray(elements)) {\n return allowedElements;\n }\n\n for (const element of elements) {\n if (!isObject(element) || !('__type' in element)) {\n continue;\n }\n\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (isAllowed) {\n allowedElements.push(element);\n }\n }\n\n return allowedElements;\n };\n\n const handleRegularRelation = async () => {\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);\n\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n // If the authenticated user don't have access to any of the scopes, then remove the field\n if (!isAllowed) {\n remove(key);\n }\n };\n\n const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);\n\n // Polymorphic relations\n if (contentTypeUtils.isMorphToRelationalAttribute(attribute)) {\n await handleMorphRelation();\n return;\n }\n\n // Creator relations\n if (isCreatorRelation && schema.options?.populateCreatorFields) {\n // do nothing\n return;\n }\n\n // Regular relations\n await handleRegularRelation();\n };\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n for (const scope of scopes) {\n try {\n await strapi.auth.verify(auth, { scope });\n return true;\n } catch {\n continue;\n }\n }\n\n return false;\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","data","key","attribute","schema","remove","set","isRelation","type","handleMorphRelation","elements","newValue","connect","handleMorphElements","relSet","disconnect","length","options","filteredOptions","Object","keys","forEach","validator","VALID_RELATION_ORDERING_KEYS","newMorphValue","allowedElements","isArray","element","isObject","scopes","map","action","__type","isAllowed","hasAccessToSomeScopes","push","handleRegularRelation","target","isCreatorRelation","includes","populateCreatorFields","scope","strapi","verify"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ var fp = require('lodash/fp');
4
+ var contentTypes = require('./content-types.js');
5
+
6
+ const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;
7
+ const setCreatorFields = ({ user, isEdition = false })=>(data)=>{
8
+ if (isEdition) {
9
+ return fp.assoc(UPDATED_BY_ATTRIBUTE, user.id, data);
10
+ }
11
+ return fp.assign(data, {
12
+ [CREATED_BY_ATTRIBUTE]: user.id,
13
+ [UPDATED_BY_ATTRIBUTE]: user.id
14
+ });
15
+ };
16
+
17
+ module.exports = setCreatorFields;
18
+ //# sourceMappingURL=set-creator-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-creator-fields.js","sources":["../src/set-creator-fields.ts"],"sourcesContent":["import { assign, assoc } from 'lodash/fp';\nimport * as contentTypes from './content-types';\n\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;\n\nexport interface Options {\n user: User;\n isEdition?: boolean;\n}\n\ninterface User {\n id: string | number;\n}\n\nconst setCreatorFields =\n <TData extends object>({ user, isEdition = false }: Options) =>\n <TDataInner extends object = TData>(data: TDataInner) => {\n if (isEdition) {\n return assoc(UPDATED_BY_ATTRIBUTE, user.id, data);\n }\n\n return assign(data, {\n [CREATED_BY_ATTRIBUTE]: user.id,\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n };\n\nexport default setCreatorFields;\n"],"names":["CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypes","setCreatorFields","user","isEdition","data","assoc","id","assign"],"mappings":";;;;;AAGA,MAAM,EAAEA,oBAAoB,EAAEC,oBAAoB,EAAE,GAAGC,sBAAsB;AAWvEC,MAAAA,gBAAAA,GACJ,CAAuB,EAAEC,IAAI,EAAEC,SAAY,GAAA,KAAK,EAAW,GAC3D,CAAoCC,IAAAA,GAAAA;AAClC,QAAA,IAAID,SAAW,EAAA;AACb,YAAA,OAAOE,QAAMN,CAAAA,oBAAAA,EAAsBG,IAAKI,CAAAA,EAAE,EAAEF,IAAAA,CAAAA;AAC9C;AAEA,QAAA,OAAOG,UAAOH,IAAM,EAAA;YAClB,CAACN,oBAAAA,GAAuBI,IAAAA,CAAKI,EAAE;YAC/B,CAACP,oBAAAA,GAAuBG,IAAAA,CAAKI;AAC/B,SAAA,CAAA;AACF;;;;"}
@@ -0,0 +1,16 @@
1
+ import { assoc, assign } from 'lodash/fp';
2
+ import { constants } from './content-types.mjs';
3
+
4
+ const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = constants;
5
+ const setCreatorFields = ({ user, isEdition = false })=>(data)=>{
6
+ if (isEdition) {
7
+ return assoc(UPDATED_BY_ATTRIBUTE, user.id, data);
8
+ }
9
+ return assign(data, {
10
+ [CREATED_BY_ATTRIBUTE]: user.id,
11
+ [UPDATED_BY_ATTRIBUTE]: user.id
12
+ });
13
+ };
14
+
15
+ export { setCreatorFields as default };
16
+ //# sourceMappingURL=set-creator-fields.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-creator-fields.mjs","sources":["../src/set-creator-fields.ts"],"sourcesContent":["import { assign, assoc } from 'lodash/fp';\nimport * as contentTypes from './content-types';\n\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;\n\nexport interface Options {\n user: User;\n isEdition?: boolean;\n}\n\ninterface User {\n id: string | number;\n}\n\nconst setCreatorFields =\n <TData extends object>({ user, isEdition = false }: Options) =>\n <TDataInner extends object = TData>(data: TDataInner) => {\n if (isEdition) {\n return assoc(UPDATED_BY_ATTRIBUTE, user.id, data);\n }\n\n return assign(data, {\n [CREATED_BY_ATTRIBUTE]: user.id,\n [UPDATED_BY_ATTRIBUTE]: user.id,\n });\n };\n\nexport default setCreatorFields;\n"],"names":["CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypes","setCreatorFields","user","isEdition","data","assoc","id","assign"],"mappings":";;;AAGA,MAAM,EAAEA,oBAAoB,EAAEC,oBAAoB,EAAE,GAAGC,SAAsB;AAWvEC,MAAAA,gBAAAA,GACJ,CAAuB,EAAEC,IAAI,EAAEC,SAAY,GAAA,KAAK,EAAW,GAC3D,CAAoCC,IAAAA,GAAAA;AAClC,QAAA,IAAID,SAAW,EAAA;AACb,YAAA,OAAOE,KAAMN,CAAAA,oBAAAA,EAAsBG,IAAKI,CAAAA,EAAE,EAAEF,IAAAA,CAAAA;AAC9C;AAEA,QAAA,OAAOG,OAAOH,IAAM,EAAA;YAClB,CAACN,oBAAAA,GAAuBI,IAAAA,CAAKI,EAAE;YAC/B,CAACP,oBAAAA,GAAuBG,IAAAA,CAAKI;AAC/B,SAAA,CAAA;AACF;;;;"}
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Create a strict interpolation RegExp based on the given variables' name
5
+ */ const createStrictInterpolationRegExp = (allowedVariableNames, flags)=>{
6
+ const oneOfVariables = allowedVariableNames.join('|');
7
+ // 1. We need to match the delimiters: <%= ... %>
8
+ // 2. We accept any number of whitespaces characters before and/or after the variable name: \s* ... \s*
9
+ // 3. We only accept values from the variable list as interpolation variables' name: : (${oneOfVariables})
10
+ return new RegExp(`<%=\\s*(${oneOfVariables})\\s*%>`, flags);
11
+ };
12
+ /**
13
+ * Create a loose interpolation RegExp to match as many groups as possible
14
+ */ const createLooseInterpolationRegExp = (flags)=>new RegExp(/<%=([\s\S]+?)%>/, flags);
15
+
16
+ exports.createLooseInterpolationRegExp = createLooseInterpolationRegExp;
17
+ exports.createStrictInterpolationRegExp = createStrictInterpolationRegExp;
18
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sources":["../src/template.ts"],"sourcesContent":["/**\n * Create a strict interpolation RegExp based on the given variables' name\n */\nconst createStrictInterpolationRegExp = (allowedVariableNames: string[], flags: string) => {\n const oneOfVariables = allowedVariableNames.join('|');\n\n // 1. We need to match the delimiters: <%= ... %>\n // 2. We accept any number of whitespaces characters before and/or after the variable name: \\s* ... \\s*\n // 3. We only accept values from the variable list as interpolation variables' name: : (${oneOfVariables})\n return new RegExp(`<%=\\\\s*(${oneOfVariables})\\\\s*%>`, flags);\n};\n\n/**\n * Create a loose interpolation RegExp to match as many groups as possible\n */\nconst createLooseInterpolationRegExp = (flags: string) => new RegExp(/<%=([\\s\\S]+?)%>/, flags);\n\nexport { createStrictInterpolationRegExp, createLooseInterpolationRegExp };\n"],"names":["createStrictInterpolationRegExp","allowedVariableNames","flags","oneOfVariables","join","RegExp","createLooseInterpolationRegExp"],"mappings":";;AAAA;;IAGA,MAAMA,+BAAkC,GAAA,CAACC,oBAAgCC,EAAAA,KAAAA,GAAAA;IACvE,MAAMC,cAAAA,GAAiBF,oBAAqBG,CAAAA,IAAI,CAAC,GAAA,CAAA;;;;IAKjD,OAAO,IAAIC,OAAO,CAAC,QAAQ,EAAEF,cAAe,CAAA,OAAO,CAAC,EAAED,KAAAA,CAAAA;AACxD;AAEA;;AAEC,UACKI,8BAAiC,GAAA,CAACJ,KAAkB,GAAA,IAAIG,OAAO,iBAAmBH,EAAAA,KAAAA;;;;;"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Create a strict interpolation RegExp based on the given variables' name
3
+ */ const createStrictInterpolationRegExp = (allowedVariableNames, flags)=>{
4
+ const oneOfVariables = allowedVariableNames.join('|');
5
+ // 1. We need to match the delimiters: <%= ... %>
6
+ // 2. We accept any number of whitespaces characters before and/or after the variable name: \s* ... \s*
7
+ // 3. We only accept values from the variable list as interpolation variables' name: : (${oneOfVariables})
8
+ return new RegExp(`<%=\\s*(${oneOfVariables})\\s*%>`, flags);
9
+ };
10
+ /**
11
+ * Create a loose interpolation RegExp to match as many groups as possible
12
+ */ const createLooseInterpolationRegExp = (flags)=>new RegExp(/<%=([\s\S]+?)%>/, flags);
13
+
14
+ export { createLooseInterpolationRegExp, createStrictInterpolationRegExp };
15
+ //# sourceMappingURL=template.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.mjs","sources":["../src/template.ts"],"sourcesContent":["/**\n * Create a strict interpolation RegExp based on the given variables' name\n */\nconst createStrictInterpolationRegExp = (allowedVariableNames: string[], flags: string) => {\n const oneOfVariables = allowedVariableNames.join('|');\n\n // 1. We need to match the delimiters: <%= ... %>\n // 2. We accept any number of whitespaces characters before and/or after the variable name: \\s* ... \\s*\n // 3. We only accept values from the variable list as interpolation variables' name: : (${oneOfVariables})\n return new RegExp(`<%=\\\\s*(${oneOfVariables})\\\\s*%>`, flags);\n};\n\n/**\n * Create a loose interpolation RegExp to match as many groups as possible\n */\nconst createLooseInterpolationRegExp = (flags: string) => new RegExp(/<%=([\\s\\S]+?)%>/, flags);\n\nexport { createStrictInterpolationRegExp, createLooseInterpolationRegExp };\n"],"names":["createStrictInterpolationRegExp","allowedVariableNames","flags","oneOfVariables","join","RegExp","createLooseInterpolationRegExp"],"mappings":"AAAA;;IAGA,MAAMA,+BAAkC,GAAA,CAACC,oBAAgCC,EAAAA,KAAAA,GAAAA;IACvE,MAAMC,cAAAA,GAAiBF,oBAAqBG,CAAAA,IAAI,CAAC,GAAA,CAAA;;;;IAKjD,OAAO,IAAIC,OAAO,CAAC,QAAQ,EAAEF,cAAe,CAAA,OAAO,CAAC,EAAED,KAAAA,CAAAA;AACxD;AAEA;;AAEC,UACKI,8BAAiC,GAAA,CAACJ,KAAkB,GAAA,IAAIG,OAAO,iBAAmBH,EAAAA,KAAAA;;;;"}
@@ -0,0 +1,158 @@
1
+ 'use strict';
2
+
3
+ var fp = require('lodash/fp');
4
+
5
+ const DEFAULT_PATH = {
6
+ raw: null,
7
+ attribute: null
8
+ };
9
+ var traverseFactory = (()=>{
10
+ const state = {
11
+ parsers: [],
12
+ interceptors: [],
13
+ ignore: [],
14
+ handlers: {
15
+ attributes: [],
16
+ common: []
17
+ }
18
+ };
19
+ const traverse = async (visitor, options, data)=>{
20
+ const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};
21
+ // interceptors
22
+ for (const { predicate, handler } of state.interceptors){
23
+ if (predicate(data)) {
24
+ return handler(visitor, options, data, {
25
+ recurse: traverse
26
+ });
27
+ }
28
+ }
29
+ // parsers
30
+ const parser = state.parsers.find((parser)=>parser.predicate(data))?.parser;
31
+ const utils = parser?.(data);
32
+ // Return the data untouched if we don't know how to traverse it
33
+ if (!utils) {
34
+ return data;
35
+ }
36
+ // main loop
37
+ let out = utils.transform(data);
38
+ const keys = utils.keys(out);
39
+ for (const key of keys){
40
+ const attribute = schema?.attributes?.[key];
41
+ const newPath = {
42
+ ...path
43
+ };
44
+ newPath.raw = fp.isNil(path.raw) ? key : `${path.raw}.${key}`;
45
+ if (!fp.isNil(attribute)) {
46
+ newPath.attribute = fp.isNil(path.attribute) ? key : `${path.attribute}.${key}`;
47
+ }
48
+ // visitors
49
+ const visitorOptions = {
50
+ key,
51
+ value: utils.get(key, out),
52
+ attribute,
53
+ schema,
54
+ path: newPath,
55
+ data: out,
56
+ getModel,
57
+ parent
58
+ };
59
+ const transformUtils = {
60
+ remove (key) {
61
+ out = utils.remove(key, out);
62
+ },
63
+ set (key, value) {
64
+ out = utils.set(key, value, out);
65
+ },
66
+ recurse: traverse
67
+ };
68
+ await visitor(visitorOptions, fp.pick([
69
+ 'remove',
70
+ 'set'
71
+ ], transformUtils));
72
+ const value = utils.get(key, out);
73
+ const createContext = ()=>({
74
+ key,
75
+ value,
76
+ attribute,
77
+ schema,
78
+ path: newPath,
79
+ data: out,
80
+ visitor,
81
+ getModel,
82
+ parent
83
+ });
84
+ // ignore
85
+ const ignoreCtx = createContext();
86
+ const shouldIgnore = state.ignore.some((predicate)=>predicate(ignoreCtx));
87
+ if (shouldIgnore) {
88
+ continue;
89
+ }
90
+ // handlers
91
+ const handlers = [
92
+ ...state.handlers.common,
93
+ ...state.handlers.attributes
94
+ ];
95
+ for await (const handler of handlers){
96
+ const ctx = createContext();
97
+ const pass = await handler.predicate(ctx);
98
+ if (pass) {
99
+ await handler.handler(ctx, fp.pick([
100
+ 'recurse',
101
+ 'set'
102
+ ], transformUtils));
103
+ }
104
+ }
105
+ }
106
+ return out;
107
+ };
108
+ return {
109
+ traverse,
110
+ intercept (predicate, handler) {
111
+ state.interceptors.push({
112
+ predicate,
113
+ handler
114
+ });
115
+ return this;
116
+ },
117
+ parse (predicate, parser) {
118
+ state.parsers.push({
119
+ predicate,
120
+ parser
121
+ });
122
+ return this;
123
+ },
124
+ ignore (predicate) {
125
+ state.ignore.push(predicate);
126
+ return this;
127
+ },
128
+ on (predicate, handler) {
129
+ state.handlers.common.push({
130
+ predicate,
131
+ handler
132
+ });
133
+ return this;
134
+ },
135
+ onAttribute (predicate, handler) {
136
+ state.handlers.attributes.push({
137
+ predicate,
138
+ handler
139
+ });
140
+ return this;
141
+ },
142
+ onRelation (handler) {
143
+ return this.onAttribute(({ attribute })=>attribute?.type === 'relation', handler);
144
+ },
145
+ onMedia (handler) {
146
+ return this.onAttribute(({ attribute })=>attribute?.type === 'media', handler);
147
+ },
148
+ onComponent (handler) {
149
+ return this.onAttribute(({ attribute })=>attribute?.type === 'component', handler);
150
+ },
151
+ onDynamicZone (handler) {
152
+ return this.onAttribute(({ attribute })=>attribute?.type === 'dynamiczone', handler);
153
+ }
154
+ };
155
+ });
156
+
157
+ module.exports = traverseFactory;
158
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sources":["../../src/traverse/factory.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-loop-func */\nimport { isNil, pick } from 'lodash/fp';\n\nimport {\n AnyAttribute,\n Attribute,\n ComponentAttribute,\n DynamicZoneAttribute,\n Model,\n RelationalAttribute,\n} from '../types';\n\nexport interface Path {\n raw: string | null;\n attribute: string | null;\n}\n\nexport interface Parent {\n attribute?: Attribute;\n key: string | null;\n path: Path;\n schema: Model;\n}\n\nexport interface TraverseOptions {\n schema: Model;\n path?: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport interface VisitorOptions {\n data: unknown;\n value: unknown;\n schema: Model;\n key: string;\n attribute?: AnyAttribute;\n path: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport type Traverse = (\n visitor: Visitor,\n options: TraverseOptions,\n data: unknown\n) => Promise<unknown>;\n\nexport interface Visitor {\n (visitorOptions: VisitorOptions, opts: Pick<TransformUtils, 'set' | 'remove'>): void;\n}\n\ninterface Interceptor<T = unknown> {\n predicate(data: unknown): data is T;\n handler(\n visitor: Visitor,\n options: TraverseOptions,\n data: T,\n recurseOptions: { recurse: Traverse }\n ): void;\n}\n\ninterface ParseUtils<T> {\n transform(data: T): unknown;\n remove(key: string, data: T): unknown;\n set(key: string, value: unknown, data: T): unknown;\n keys(data: T): string[];\n get(key: string, data: T): unknown;\n}\n\ninterface Parser<T = unknown> {\n predicate(data: unknown): data is T;\n parser(data: T): ParseUtils<T>;\n}\n\ninterface Ignore {\n (ctx: Context): boolean;\n}\n\ninterface AttributeHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\ninterface CommonHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\n\nexport interface TransformUtils {\n remove(key: string): void;\n set(key: string, value: unknown): void;\n recurse: Traverse;\n}\n\ninterface Context<AttributeType = Attribute> {\n key: string;\n value: unknown;\n attribute: AttributeType;\n schema: Model;\n path: Path;\n data: unknown;\n visitor: Visitor;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\ninterface State {\n parsers: Parser[];\n interceptors: Interceptor[];\n ignore: Ignore[];\n handlers: {\n attributes: AttributeHandler[];\n common: CommonHandler[];\n };\n}\n\nconst DEFAULT_PATH = { raw: null, attribute: null } satisfies Path;\n\nexport default () => {\n const state: State = {\n parsers: [],\n interceptors: [],\n ignore: [],\n handlers: {\n attributes: [],\n common: [],\n },\n };\n\n const traverse: Traverse = async (visitor, options, data) => {\n const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};\n\n // interceptors\n for (const { predicate, handler } of state.interceptors) {\n if (predicate(data)) {\n return handler(visitor, options, data, { recurse: traverse });\n }\n }\n\n // parsers\n const parser = state.parsers.find((parser) => parser.predicate(data))?.parser;\n const utils = parser?.(data);\n\n // Return the data untouched if we don't know how to traverse it\n if (!utils) {\n return data;\n }\n\n // main loop\n let out = utils.transform(data);\n const keys = utils.keys(out);\n\n for (const key of keys) {\n const attribute = schema?.attributes?.[key];\n\n const newPath = { ...path };\n\n newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;\n\n if (!isNil(attribute)) {\n newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;\n }\n\n // visitors\n const visitorOptions: VisitorOptions = {\n key,\n value: utils.get(key, out),\n attribute,\n schema,\n path: newPath,\n data: out,\n getModel,\n parent,\n };\n\n const transformUtils: TransformUtils = {\n remove(key) {\n out = utils.remove(key, out);\n },\n set(key, value) {\n out = utils.set(key, value, out);\n },\n recurse: traverse,\n };\n\n await visitor(visitorOptions, pick(['remove', 'set'], transformUtils));\n\n const value = utils.get(key, out);\n\n const createContext = (): Context => ({\n key,\n value,\n attribute,\n schema,\n path: newPath,\n data: out,\n visitor,\n getModel,\n parent,\n });\n\n // ignore\n const ignoreCtx = createContext();\n const shouldIgnore = state.ignore.some((predicate) => predicate(ignoreCtx));\n\n if (shouldIgnore) {\n continue;\n }\n\n // handlers\n const handlers = [...state.handlers.common, ...state.handlers.attributes];\n\n for await (const handler of handlers) {\n const ctx = createContext();\n const pass = await handler.predicate(ctx);\n\n if (pass) {\n await handler.handler(ctx, pick(['recurse', 'set'], transformUtils));\n }\n }\n }\n\n return out;\n };\n\n return {\n traverse,\n\n intercept<T>(predicate: Interceptor<T>['predicate'], handler: Interceptor<T>['handler']) {\n state.interceptors.push({ predicate, handler });\n return this;\n },\n\n parse<T>(predicate: Parser<T>['predicate'], parser: Parser<T>['parser']) {\n state.parsers.push({ predicate, parser });\n return this;\n },\n\n ignore(predicate: Ignore) {\n state.ignore.push(predicate);\n return this;\n },\n\n on(predicate: CommonHandler['predicate'], handler: CommonHandler['handler']) {\n state.handlers.common.push({ predicate, handler });\n return this;\n },\n\n onAttribute(predicate: AttributeHandler['predicate'], handler: AttributeHandler['handler']) {\n state.handlers.attributes.push({ predicate, handler });\n return this;\n },\n\n onRelation(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'relation', handler);\n },\n\n onMedia(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'media', handler);\n },\n\n onComponent(handler: AttributeHandler<ComponentAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'component', handler);\n },\n\n onDynamicZone(handler: AttributeHandler<DynamicZoneAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'dynamiczone', handler);\n },\n };\n};\n"],"names":["DEFAULT_PATH","raw","attribute","state","parsers","interceptors","ignore","handlers","attributes","common","traverse","visitor","options","data","path","parent","schema","getModel","predicate","handler","recurse","parser","find","utils","out","transform","keys","key","newPath","isNil","visitorOptions","value","get","transformUtils","remove","set","pick","createContext","ignoreCtx","shouldIgnore","some","ctx","pass","intercept","push","parse","on","onAttribute","onRelation","type","onMedia","onComponent","onDynamicZone"],"mappings":"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"}
@@ -0,0 +1,156 @@
1
+ import { isNil, pick } from 'lodash/fp';
2
+
3
+ const DEFAULT_PATH = {
4
+ raw: null,
5
+ attribute: null
6
+ };
7
+ var traverseFactory = (()=>{
8
+ const state = {
9
+ parsers: [],
10
+ interceptors: [],
11
+ ignore: [],
12
+ handlers: {
13
+ attributes: [],
14
+ common: []
15
+ }
16
+ };
17
+ const traverse = async (visitor, options, data)=>{
18
+ const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};
19
+ // interceptors
20
+ for (const { predicate, handler } of state.interceptors){
21
+ if (predicate(data)) {
22
+ return handler(visitor, options, data, {
23
+ recurse: traverse
24
+ });
25
+ }
26
+ }
27
+ // parsers
28
+ const parser = state.parsers.find((parser)=>parser.predicate(data))?.parser;
29
+ const utils = parser?.(data);
30
+ // Return the data untouched if we don't know how to traverse it
31
+ if (!utils) {
32
+ return data;
33
+ }
34
+ // main loop
35
+ let out = utils.transform(data);
36
+ const keys = utils.keys(out);
37
+ for (const key of keys){
38
+ const attribute = schema?.attributes?.[key];
39
+ const newPath = {
40
+ ...path
41
+ };
42
+ newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;
43
+ if (!isNil(attribute)) {
44
+ newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;
45
+ }
46
+ // visitors
47
+ const visitorOptions = {
48
+ key,
49
+ value: utils.get(key, out),
50
+ attribute,
51
+ schema,
52
+ path: newPath,
53
+ data: out,
54
+ getModel,
55
+ parent
56
+ };
57
+ const transformUtils = {
58
+ remove (key) {
59
+ out = utils.remove(key, out);
60
+ },
61
+ set (key, value) {
62
+ out = utils.set(key, value, out);
63
+ },
64
+ recurse: traverse
65
+ };
66
+ await visitor(visitorOptions, pick([
67
+ 'remove',
68
+ 'set'
69
+ ], transformUtils));
70
+ const value = utils.get(key, out);
71
+ const createContext = ()=>({
72
+ key,
73
+ value,
74
+ attribute,
75
+ schema,
76
+ path: newPath,
77
+ data: out,
78
+ visitor,
79
+ getModel,
80
+ parent
81
+ });
82
+ // ignore
83
+ const ignoreCtx = createContext();
84
+ const shouldIgnore = state.ignore.some((predicate)=>predicate(ignoreCtx));
85
+ if (shouldIgnore) {
86
+ continue;
87
+ }
88
+ // handlers
89
+ const handlers = [
90
+ ...state.handlers.common,
91
+ ...state.handlers.attributes
92
+ ];
93
+ for await (const handler of handlers){
94
+ const ctx = createContext();
95
+ const pass = await handler.predicate(ctx);
96
+ if (pass) {
97
+ await handler.handler(ctx, pick([
98
+ 'recurse',
99
+ 'set'
100
+ ], transformUtils));
101
+ }
102
+ }
103
+ }
104
+ return out;
105
+ };
106
+ return {
107
+ traverse,
108
+ intercept (predicate, handler) {
109
+ state.interceptors.push({
110
+ predicate,
111
+ handler
112
+ });
113
+ return this;
114
+ },
115
+ parse (predicate, parser) {
116
+ state.parsers.push({
117
+ predicate,
118
+ parser
119
+ });
120
+ return this;
121
+ },
122
+ ignore (predicate) {
123
+ state.ignore.push(predicate);
124
+ return this;
125
+ },
126
+ on (predicate, handler) {
127
+ state.handlers.common.push({
128
+ predicate,
129
+ handler
130
+ });
131
+ return this;
132
+ },
133
+ onAttribute (predicate, handler) {
134
+ state.handlers.attributes.push({
135
+ predicate,
136
+ handler
137
+ });
138
+ return this;
139
+ },
140
+ onRelation (handler) {
141
+ return this.onAttribute(({ attribute })=>attribute?.type === 'relation', handler);
142
+ },
143
+ onMedia (handler) {
144
+ return this.onAttribute(({ attribute })=>attribute?.type === 'media', handler);
145
+ },
146
+ onComponent (handler) {
147
+ return this.onAttribute(({ attribute })=>attribute?.type === 'component', handler);
148
+ },
149
+ onDynamicZone (handler) {
150
+ return this.onAttribute(({ attribute })=>attribute?.type === 'dynamiczone', handler);
151
+ }
152
+ };
153
+ });
154
+
155
+ export { traverseFactory as default };
156
+ //# sourceMappingURL=factory.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.mjs","sources":["../../src/traverse/factory.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-loop-func */\nimport { isNil, pick } from 'lodash/fp';\n\nimport {\n AnyAttribute,\n Attribute,\n ComponentAttribute,\n DynamicZoneAttribute,\n Model,\n RelationalAttribute,\n} from '../types';\n\nexport interface Path {\n raw: string | null;\n attribute: string | null;\n}\n\nexport interface Parent {\n attribute?: Attribute;\n key: string | null;\n path: Path;\n schema: Model;\n}\n\nexport interface TraverseOptions {\n schema: Model;\n path?: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport interface VisitorOptions {\n data: unknown;\n value: unknown;\n schema: Model;\n key: string;\n attribute?: AnyAttribute;\n path: Path;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\nexport type Traverse = (\n visitor: Visitor,\n options: TraverseOptions,\n data: unknown\n) => Promise<unknown>;\n\nexport interface Visitor {\n (visitorOptions: VisitorOptions, opts: Pick<TransformUtils, 'set' | 'remove'>): void;\n}\n\ninterface Interceptor<T = unknown> {\n predicate(data: unknown): data is T;\n handler(\n visitor: Visitor,\n options: TraverseOptions,\n data: T,\n recurseOptions: { recurse: Traverse }\n ): void;\n}\n\ninterface ParseUtils<T> {\n transform(data: T): unknown;\n remove(key: string, data: T): unknown;\n set(key: string, value: unknown, data: T): unknown;\n keys(data: T): string[];\n get(key: string, data: T): unknown;\n}\n\ninterface Parser<T = unknown> {\n predicate(data: unknown): data is T;\n parser(data: T): ParseUtils<T>;\n}\n\ninterface Ignore {\n (ctx: Context): boolean;\n}\n\ninterface AttributeHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\ninterface CommonHandler<AttributeType = Attribute> {\n predicate(ctx: Context<AttributeType>): boolean;\n handler(ctx: Context<AttributeType>, opts: Pick<TransformUtils, 'set' | 'recurse'>): void;\n}\n\nexport interface TransformUtils {\n remove(key: string): void;\n set(key: string, value: unknown): void;\n recurse: Traverse;\n}\n\ninterface Context<AttributeType = Attribute> {\n key: string;\n value: unknown;\n attribute: AttributeType;\n schema: Model;\n path: Path;\n data: unknown;\n visitor: Visitor;\n parent?: Parent;\n getModel(uid: string): Model;\n}\n\ninterface State {\n parsers: Parser[];\n interceptors: Interceptor[];\n ignore: Ignore[];\n handlers: {\n attributes: AttributeHandler[];\n common: CommonHandler[];\n };\n}\n\nconst DEFAULT_PATH = { raw: null, attribute: null } satisfies Path;\n\nexport default () => {\n const state: State = {\n parsers: [],\n interceptors: [],\n ignore: [],\n handlers: {\n attributes: [],\n common: [],\n },\n };\n\n const traverse: Traverse = async (visitor, options, data) => {\n const { path = DEFAULT_PATH, parent, schema, getModel } = options ?? {};\n\n // interceptors\n for (const { predicate, handler } of state.interceptors) {\n if (predicate(data)) {\n return handler(visitor, options, data, { recurse: traverse });\n }\n }\n\n // parsers\n const parser = state.parsers.find((parser) => parser.predicate(data))?.parser;\n const utils = parser?.(data);\n\n // Return the data untouched if we don't know how to traverse it\n if (!utils) {\n return data;\n }\n\n // main loop\n let out = utils.transform(data);\n const keys = utils.keys(out);\n\n for (const key of keys) {\n const attribute = schema?.attributes?.[key];\n\n const newPath = { ...path };\n\n newPath.raw = isNil(path.raw) ? key : `${path.raw}.${key}`;\n\n if (!isNil(attribute)) {\n newPath.attribute = isNil(path.attribute) ? key : `${path.attribute}.${key}`;\n }\n\n // visitors\n const visitorOptions: VisitorOptions = {\n key,\n value: utils.get(key, out),\n attribute,\n schema,\n path: newPath,\n data: out,\n getModel,\n parent,\n };\n\n const transformUtils: TransformUtils = {\n remove(key) {\n out = utils.remove(key, out);\n },\n set(key, value) {\n out = utils.set(key, value, out);\n },\n recurse: traverse,\n };\n\n await visitor(visitorOptions, pick(['remove', 'set'], transformUtils));\n\n const value = utils.get(key, out);\n\n const createContext = (): Context => ({\n key,\n value,\n attribute,\n schema,\n path: newPath,\n data: out,\n visitor,\n getModel,\n parent,\n });\n\n // ignore\n const ignoreCtx = createContext();\n const shouldIgnore = state.ignore.some((predicate) => predicate(ignoreCtx));\n\n if (shouldIgnore) {\n continue;\n }\n\n // handlers\n const handlers = [...state.handlers.common, ...state.handlers.attributes];\n\n for await (const handler of handlers) {\n const ctx = createContext();\n const pass = await handler.predicate(ctx);\n\n if (pass) {\n await handler.handler(ctx, pick(['recurse', 'set'], transformUtils));\n }\n }\n }\n\n return out;\n };\n\n return {\n traverse,\n\n intercept<T>(predicate: Interceptor<T>['predicate'], handler: Interceptor<T>['handler']) {\n state.interceptors.push({ predicate, handler });\n return this;\n },\n\n parse<T>(predicate: Parser<T>['predicate'], parser: Parser<T>['parser']) {\n state.parsers.push({ predicate, parser });\n return this;\n },\n\n ignore(predicate: Ignore) {\n state.ignore.push(predicate);\n return this;\n },\n\n on(predicate: CommonHandler['predicate'], handler: CommonHandler['handler']) {\n state.handlers.common.push({ predicate, handler });\n return this;\n },\n\n onAttribute(predicate: AttributeHandler['predicate'], handler: AttributeHandler['handler']) {\n state.handlers.attributes.push({ predicate, handler });\n return this;\n },\n\n onRelation(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'relation', handler);\n },\n\n onMedia(handler: AttributeHandler<RelationalAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'media', handler);\n },\n\n onComponent(handler: AttributeHandler<ComponentAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'component', handler);\n },\n\n onDynamicZone(handler: AttributeHandler<DynamicZoneAttribute>['handler']) {\n return this.onAttribute(({ attribute }) => attribute?.type === 'dynamiczone', handler);\n },\n };\n};\n"],"names":["DEFAULT_PATH","raw","attribute","state","parsers","interceptors","ignore","handlers","attributes","common","traverse","visitor","options","data","path","parent","schema","getModel","predicate","handler","recurse","parser","find","utils","out","transform","keys","key","newPath","isNil","visitorOptions","value","get","transformUtils","remove","set","pick","createContext","ignoreCtx","shouldIgnore","some","ctx","pass","intercept","push","parse","on","onAttribute","onRelation","type","onMedia","onComponent","onDynamicZone"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ var queryFilters = require('./query-filters.js');
4
+ var querySort = require('./query-sort.js');
5
+ var queryPopulate = require('./query-populate.js');
6
+ var queryFields = require('./query-fields.js');
7
+
8
+
9
+
10
+ exports.traverseQueryFilters = queryFilters;
11
+ exports.traverseQuerySort = querySort;
12
+ exports.traverseQueryPopulate = queryPopulate;
13
+ exports.traverseQueryFields = queryFields;
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
@@ -0,0 +1,5 @@
1
+ export { default as traverseQueryFilters } from './query-filters.mjs';
2
+ export { default as traverseQuerySort } from './query-sort.mjs';
3
+ export { default as traverseQueryPopulate } from './query-populate.mjs';
4
+ export { default as traverseQueryFields } from './query-fields.mjs';
5
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}