@strapi/utils 5.52.2 → 5.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/convert-query-params.d.ts.map +1 -1
  2. package/dist/convert-query-params.js +31 -1
  3. package/dist/convert-query-params.js.map +1 -1
  4. package/dist/convert-query-params.mjs +31 -1
  5. package/dist/convert-query-params.mjs.map +1 -1
  6. package/dist/sanitize/index.d.ts.map +1 -1
  7. package/dist/sanitize/index.js +3 -1
  8. package/dist/sanitize/index.js.map +1 -1
  9. package/dist/sanitize/index.mjs +3 -1
  10. package/dist/sanitize/index.mjs.map +1 -1
  11. package/dist/sanitize/visitors/remove-restricted-relations.d.ts.map +1 -1
  12. package/dist/sanitize/visitors/remove-restricted-relations.js +93 -20
  13. package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -1
  14. package/dist/sanitize/visitors/remove-restricted-relations.mjs +94 -21
  15. package/dist/sanitize/visitors/remove-restricted-relations.mjs.map +1 -1
  16. package/dist/traverse/query-populate.d.ts.map +1 -1
  17. package/dist/traverse/query-populate.js +23 -8
  18. package/dist/traverse/query-populate.js.map +1 -1
  19. package/dist/traverse/query-populate.mjs +24 -9
  20. package/dist/traverse/query-populate.mjs.map +1 -1
  21. package/dist/validate/index.d.ts.map +1 -1
  22. package/dist/validate/index.js +2 -8
  23. package/dist/validate/index.js.map +1 -1
  24. package/dist/validate/index.mjs +2 -8
  25. package/dist/validate/index.mjs.map +1 -1
  26. package/dist/validate/visitors/throw-restricted-relations.d.ts.map +1 -1
  27. package/dist/validate/visitors/throw-restricted-relations.js +34 -6
  28. package/dist/validate/visitors/throw-restricted-relations.js.map +1 -1
  29. package/dist/validate/visitors/throw-restricted-relations.mjs +35 -7
  30. package/dist/validate/visitors/throw-restricted-relations.mjs.map +1 -1
  31. package/package.json +4 -4
@@ -1,4 +1,4 @@
1
- import { isArray, isObject } from 'lodash/fp';
1
+ import { isObject, isArray } from 'lodash/fp';
2
2
  import { isMorphToRelationalAttribute, constants } from '../../content-types.mjs';
3
3
  import { VALID_RELATION_ORDERING_KEYS } from '../../relations.mjs';
4
4
 
@@ -28,7 +28,7 @@ const visitRelationAttribute = async (auth, { data, key, attribute, schema }, {
28
28
  if (!elements) {
29
29
  return;
30
30
  }
31
- if ('connect' in elements || 'set' in elements || 'disconnect' in elements) {
31
+ if (isMorphMutationPayload(elements)) {
32
32
  const newValue = {};
33
33
  const connect = await handleMorphElements(elements.connect || []);
34
34
  const relSet = await handleMorphElements(elements.set || []);
@@ -43,36 +43,88 @@ const visitRelationAttribute = async (auth, { data, key, attribute, schema }, {
43
43
  newValue.disconnect = disconnect;
44
44
  }
45
45
  // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here
46
- if ('options' in elements && typeof elements.options === 'object' && elements.options !== null) {
46
+ const options = elements.options;
47
+ if (options && typeof options === 'object') {
47
48
  const filteredOptions = {};
48
- // Iterate through the keys of elements.options
49
- Object.keys(elements.options).forEach((key)=>{
50
- const validator = VALID_RELATION_ORDERING_KEYS[key];
51
- // Ensure the key exists in VALID_RELATION_ORDERING_KEYS and the validator is defined before calling it
52
- if (validator && validator(elements.options[key])) {
53
- filteredOptions[key] = elements.options[key];
49
+ Object.keys(options).forEach((key)=>{
50
+ const optionKey = key;
51
+ const validator = VALID_RELATION_ORDERING_KEYS[optionKey];
52
+ const optionValue = options[key];
53
+ if (validator && validator(optionValue)) {
54
+ filteredOptions[optionKey] = optionValue;
54
55
  }
55
56
  });
56
- // Assign the filtered options back to newValue
57
57
  newValue.options = filteredOptions;
58
58
  } else {
59
59
  newValue.options = {};
60
60
  }
61
61
  set(key, newValue);
62
+ } else if (isMorphPopulatePayload(elements)) {
63
+ const newOn = {};
64
+ for (const [uid, subPopulate] of Object.entries(elements.on)){
65
+ const scopes = ACTIONS_TO_VERIFY.map((action)=>`${uid}.${action}`);
66
+ const isAllowed = await hasAccessToSomeScopes(scopes, auth);
67
+ if (isAllowed) {
68
+ newOn[uid] = subPopulate;
69
+ }
70
+ }
71
+ if (Object.keys(newOn).length === 0) {
72
+ remove(key);
73
+ return;
74
+ }
75
+ const count = isMorphPopulateCount(elements.count) ? true : elements.count;
76
+ set(key, {
77
+ ...elements,
78
+ count,
79
+ on: newOn
80
+ });
62
81
  } else {
63
82
  const newMorphValue = await handleMorphElements(elements);
64
- if (newMorphValue.length) {
83
+ if (!newMorphValue.length) {
84
+ if (isArray(elements) && elements.length === 0) {
85
+ return;
86
+ }
87
+ remove(key);
88
+ return;
89
+ }
90
+ if (isArray(elements)) {
65
91
  set(key, newMorphValue);
92
+ return;
66
93
  }
94
+ set(key, newMorphValue[0]);
67
95
  }
68
96
  };
97
+ const isMorphMutationPayload = (value)=>{
98
+ return isObject(value) && ('connect' in value || 'set' in value || 'disconnect' in value);
99
+ };
100
+ const isMorphPopulateCount = (value)=>value === true || value === 'true';
101
+ const isMorphPopulatePayload = (value)=>{
102
+ return isObject(value) && !('__type' in value) && 'on' in value && isObject(value.on);
103
+ };
104
+ const buildAllowedMorphPopulateFragment = async (subPopulate)=>{
105
+ const newOn = {};
106
+ for (const uid of getRegisteredContentTypeUIDs()){
107
+ const scopes = ACTIONS_TO_VERIFY.map((action)=>`${uid}.${action}`);
108
+ const isAllowed = await hasAccessToSomeScopes(scopes, auth);
109
+ if (isAllowed) {
110
+ newOn[uid] = subPopulate;
111
+ }
112
+ }
113
+ return newOn;
114
+ };
115
+ const isMorphPopulateAllOrCount = (value)=>{
116
+ return value === true || value === 'true' || isObject(value) && 'count' in value && isMorphPopulateCount(value.count) && !('on' in value);
117
+ };
118
+ const isMorphCountOutput = (value)=>{
119
+ return isObject(value) && 'count' in value && typeof value.count === 'number' && Object.keys(value).length === 1;
120
+ };
69
121
  const handleMorphElements = async (elements)=>{
70
122
  const allowedElements = [];
71
- if (!isArray(elements)) {
72
- return allowedElements;
73
- }
74
- for (const element of elements){
75
- if (!isObject(element) || !('__type' in element)) {
123
+ const elementsToCheck = isArray(elements) ? elements : [
124
+ elements
125
+ ];
126
+ for (const element of elementsToCheck){
127
+ if (!isObject(element) || !('__type' in element) || typeof element.__type !== 'string') {
76
128
  continue;
77
129
  }
78
130
  const scopes = ACTIONS_TO_VERIFY.map((action)=>`${element.__type}.${action}`);
@@ -86,7 +138,6 @@ const visitRelationAttribute = async (auth, { data, key, attribute, schema }, {
86
138
  const handleRegularRelation = async ()=>{
87
139
  const scopes = ACTIONS_TO_VERIFY.map((action)=>`${attribute.target}.${action}`);
88
140
  const isAllowed = await hasAccessToSomeScopes(scopes, auth);
89
- // If the authenticated user don't have access to any of the scopes, then remove the field
90
141
  if (!isAllowed) {
91
142
  remove(key);
92
143
  }
@@ -95,17 +146,36 @@ const visitRelationAttribute = async (auth, { data, key, attribute, schema }, {
95
146
  CREATED_BY_ATTRIBUTE,
96
147
  UPDATED_BY_ATTRIBUTE
97
148
  ].includes(key);
98
- // Polymorphic relations
99
149
  if (isMorphToRelationalAttribute(attribute)) {
150
+ const value = data[key];
151
+ if (isMorphPopulatePayload(value)) {
152
+ await handleMorphRelation();
153
+ return;
154
+ }
155
+ if (isMorphPopulateAllOrCount(value)) {
156
+ const newOn = await buildAllowedMorphPopulateFragment(true);
157
+ if (Object.keys(newOn).length === 0) {
158
+ remove(key);
159
+ return;
160
+ }
161
+ set(key, value === true || value === 'true' ? {
162
+ on: newOn
163
+ } : {
164
+ ...value,
165
+ count: true,
166
+ on: newOn
167
+ });
168
+ return;
169
+ }
170
+ if (isMorphCountOutput(value)) {
171
+ return;
172
+ }
100
173
  await handleMorphRelation();
101
174
  return;
102
175
  }
103
- // Creator relations
104
176
  if (isCreatorRelation && schema.options?.populateCreatorFields) {
105
- // do nothing
106
177
  return;
107
178
  }
108
- // Regular relations
109
179
  await handleRegularRelation();
110
180
  };
111
181
  /**
@@ -154,6 +224,9 @@ const hasAccessToSomeScopes = async (scopes, auth)=>{
154
224
  }
155
225
  return false;
156
226
  };
227
+ const getRegisteredContentTypeUIDs = ()=>{
228
+ return Object.values(strapi.contentTypes ?? {}).map((model)=>model.uid).filter((uid)=>typeof uid === 'string');
229
+ };
157
230
 
158
231
  export { removeRestrictedRelations as default };
159
232
  //# sourceMappingURL=remove-restricted-relations.mjs.map
@@ -1 +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 (visitorOptions, visitorUtils) => {\n const { attribute } = visitorOptions;\n\n // Deliberately not an `async` function. This visitor is invoked for every key of\n // every node of every entity, and only relation attributes need any work at all.\n // Declaring it `async` meant each of those keys allocated a promise purely to\n // resolve it immediately, and the traversal then awaited it. Returning early\n // without a promise lets the traversal stay synchronous for the common case.\n if (!attribute || attribute.type !== 'relation') {\n return;\n }\n\n return visitRelationAttribute(auth, visitorOptions, visitorUtils) as unknown as void;\n };\n\nconst visitRelationAttribute = async (\n auth: unknown,\n { data, key, attribute, schema }: Parameters<Visitor>[0],\n { remove, set }: Parameters<Visitor>[1]\n) => {\n // Narrowing only; the caller reaches this for relation attributes exclusively.\n if (!attribute) {\n return;\n }\n\n const handleMorphRelation = async () => {\n const elements: any = (data as Record<string, MorphArray>)[key];\n\n if (!elements) {\n return;\n }\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\n/**\n * Per-`auth` memo of scope decisions.\n *\n * The decision for a given scope depends only on the ability carried by `auth`, which is\n * built once per request and not mutated while the response is sanitized. Sanitizing a\n * list re-asks the same question for every entity, so a 25-entity page with four\n * relations asked ~100 identical questions; each denial also constructed an Error, and\n * capturing a stack trace is by far the most expensive part of that.\n *\n * Keyed weakly on the `auth` object so entries are collected with the request.\n */\nconst scopeDecisionCache = new WeakMap<object, Map<string, boolean>>();\n\nconst canAccessScope = async (scope: string, auth: unknown): Promise<boolean> => {\n const cacheable = typeof auth === 'object' && auth !== null;\n\n let decisions: Map<string, boolean> | undefined;\n\n if (cacheable) {\n decisions = scopeDecisionCache.get(auth as object);\n\n if (decisions === undefined) {\n decisions = new Map();\n scopeDecisionCache.set(auth as object, decisions);\n } else {\n const cached = decisions.get(scope);\n if (cached !== undefined) {\n return cached;\n }\n }\n }\n\n let allowed: boolean;\n try {\n await strapi.auth.verify(auth, { scope });\n allowed = true;\n } catch {\n allowed = false;\n }\n\n decisions?.set(scope, allowed);\n\n return allowed;\n};\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n for (const scope of scopes) {\n if (await canAccessScope(scope, auth)) {\n return true;\n }\n }\n\n return false;\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","visitorOptions","visitorUtils","attribute","type","visitRelationAttribute","data","key","schema","remove","set","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","scopeDecisionCache","WeakMap","canAccessScope","scope","cacheable","decisions","get","undefined","Map","cached","allowed","strapi","verify"],"mappings":"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"}
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 { Model, RelationOrderingOptions } from '../../types';\nimport type { Visitor } from '../../traverse/factory';\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 }>;\ntype MorphElement = Record<string, unknown> & { __type: string };\ntype MorphMutationPayload = {\n connect?: unknown;\n set?: unknown;\n disconnect?: unknown;\n options?: Record<string, unknown> | null;\n};\ntype MorphPopulatePayload = {\n on: Record<string, unknown>;\n count?: unknown;\n};\n\nexport default (auth: unknown): Visitor =>\n (visitorOptions, visitorUtils) => {\n const { attribute } = visitorOptions;\n\n // Deliberately not an `async` function. This visitor is invoked for every key of\n // every node of every entity, and only relation attributes need any work at all.\n // Declaring it `async` meant each of those keys allocated a promise purely to\n // resolve it immediately, and the traversal then awaited it. Returning early\n // without a promise lets the traversal stay synchronous for the common case.\n if (!attribute || attribute.type !== 'relation') {\n return;\n }\n\n return visitRelationAttribute(auth, visitorOptions, visitorUtils) as unknown as void;\n };\n\nconst visitRelationAttribute = async (\n auth: unknown,\n { data, key, attribute, schema }: Parameters<Visitor>[0],\n { remove, set }: Parameters<Visitor>[1]\n) => {\n // Narrowing only; the caller reaches this for relation attributes exclusively.\n if (!attribute) {\n return;\n }\n\n const handleMorphRelation = async () => {\n const elements = (data as Record<string, MorphArray | MorphElement | MorphMutationPayload>)[\n key\n ];\n\n if (!elements) {\n return;\n }\n\n if (isMorphMutationPayload(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 const options = elements.options;\n if (options && typeof options === 'object') {\n const filteredOptions: RelationOrderingOptions = {};\n\n Object.keys(options).forEach((key) => {\n const optionKey = key as keyof RelationOrderingOptions;\n const validator = VALID_RELATION_ORDERING_KEYS[optionKey];\n const optionValue = options[key];\n\n if (validator && validator(optionValue)) {\n filteredOptions[optionKey] = optionValue as RelationOrderingOptions[typeof optionKey];\n }\n });\n\n newValue.options = filteredOptions;\n } else {\n newValue.options = {};\n }\n\n set(key, newValue);\n } else if (isMorphPopulatePayload(elements)) {\n const newOn: Record<string, unknown> = {};\n\n for (const [uid, subPopulate] of Object.entries(elements.on)) {\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${uid}.${action}`);\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (isAllowed) {\n newOn[uid] = subPopulate;\n }\n }\n\n if (Object.keys(newOn).length === 0) {\n remove(key);\n return;\n }\n\n const count = isMorphPopulateCount(elements.count) ? true : elements.count;\n set(key, { ...elements, count, on: newOn });\n } else {\n const newMorphValue = await handleMorphElements(elements);\n\n if (!newMorphValue.length) {\n if (isArray(elements) && elements.length === 0) {\n return;\n }\n\n remove(key);\n return;\n }\n\n if (isArray(elements)) {\n set(key, newMorphValue);\n return;\n }\n\n set(key, newMorphValue[0]);\n }\n };\n\n const isMorphMutationPayload = (value: unknown): value is MorphMutationPayload => {\n return isObject(value) && ('connect' in value || 'set' in value || 'disconnect' in value);\n };\n\n const isMorphPopulateCount = (value: unknown) => value === true || value === 'true';\n\n const isMorphPopulatePayload = (value: unknown): value is MorphPopulatePayload => {\n return isObject(value) && !('__type' in value) && 'on' in value && isObject(value.on);\n };\n\n const buildAllowedMorphPopulateFragment = async (subPopulate: unknown) => {\n const newOn: Record<string, unknown> = {};\n\n for (const uid of getRegisteredContentTypeUIDs()) {\n const scopes = ACTIONS_TO_VERIFY.map((action) => `${uid}.${action}`);\n const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (isAllowed) {\n newOn[uid] = subPopulate;\n }\n }\n\n return newOn;\n };\n\n const isMorphPopulateAllOrCount = (value: unknown): value is true | 'true' | { count: true } => {\n return (\n value === true ||\n value === 'true' ||\n (isObject(value) && 'count' in value && isMorphPopulateCount(value.count) && !('on' in value))\n );\n };\n\n const isMorphCountOutput = (value: unknown): value is { count: number } => {\n return (\n isObject(value) &&\n 'count' in value &&\n typeof value.count === 'number' &&\n Object.keys(value).length === 1\n );\n };\n\n const handleMorphElements = async (elements: unknown) => {\n const allowedElements: Record<string, unknown>[] = [];\n const elementsToCheck = isArray(elements) ? elements : [elements];\n\n for (const element of elementsToCheck) {\n if (!isObject(element) || !('__type' in element) || typeof element.__type !== 'string') {\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 const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n if (!isAllowed) {\n remove(key);\n }\n };\n\n const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);\n\n if (contentTypeUtils.isMorphToRelationalAttribute(attribute)) {\n const value = (data as Record<string, unknown>)[key];\n\n if (isMorphPopulatePayload(value)) {\n await handleMorphRelation();\n return;\n }\n\n if (isMorphPopulateAllOrCount(value)) {\n const newOn = await buildAllowedMorphPopulateFragment(true);\n\n if (Object.keys(newOn).length === 0) {\n remove(key);\n return;\n }\n\n set(\n key,\n value === true || value === 'true' ? { on: newOn } : { ...value, count: true, on: newOn }\n );\n return;\n }\n\n if (isMorphCountOutput(value)) {\n return;\n }\n\n await handleMorphRelation();\n return;\n }\n\n if (isCreatorRelation && schema.options?.populateCreatorFields) {\n return;\n }\n\n await handleRegularRelation();\n};\n\n/**\n * Per-`auth` memo of scope decisions.\n *\n * The decision for a given scope depends only on the ability carried by `auth`, which is\n * built once per request and not mutated while the response is sanitized. Sanitizing a\n * list re-asks the same question for every entity, so a 25-entity page with four\n * relations asked ~100 identical questions; each denial also constructed an Error, and\n * capturing a stack trace is by far the most expensive part of that.\n *\n * Keyed weakly on the `auth` object so entries are collected with the request.\n */\nconst scopeDecisionCache = new WeakMap<object, Map<string, boolean>>();\n\nconst canAccessScope = async (scope: string, auth: unknown): Promise<boolean> => {\n const cacheable = typeof auth === 'object' && auth !== null;\n\n let decisions: Map<string, boolean> | undefined;\n\n if (cacheable) {\n decisions = scopeDecisionCache.get(auth as object);\n\n if (decisions === undefined) {\n decisions = new Map();\n scopeDecisionCache.set(auth as object, decisions);\n } else {\n const cached = decisions.get(scope);\n if (cached !== undefined) {\n return cached;\n }\n }\n }\n\n let allowed: boolean;\n try {\n await strapi.auth.verify(auth, { scope });\n allowed = true;\n } catch {\n allowed = false;\n }\n\n decisions?.set(scope, allowed);\n\n return allowed;\n};\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n for (const scope of scopes) {\n if (await canAccessScope(scope, auth)) {\n return true;\n }\n }\n\n return false;\n};\n\nconst getRegisteredContentTypeUIDs = () => {\n return (Object.values(strapi.contentTypes ?? {}) as Model[])\n .map((model) => model.uid)\n .filter((uid): uid is string => typeof uid === 'string');\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","visitorOptions","visitorUtils","attribute","type","visitRelationAttribute","data","key","schema","remove","set","handleMorphRelation","elements","isMorphMutationPayload","newValue","connect","handleMorphElements","relSet","disconnect","length","options","filteredOptions","Object","keys","forEach","optionKey","validator","VALID_RELATION_ORDERING_KEYS","optionValue","isMorphPopulatePayload","newOn","uid","subPopulate","entries","on","scopes","map","action","isAllowed","hasAccessToSomeScopes","count","isMorphPopulateCount","newMorphValue","isArray","value","isObject","buildAllowedMorphPopulateFragment","getRegisteredContentTypeUIDs","isMorphPopulateAllOrCount","isMorphCountOutput","allowedElements","elementsToCheck","element","__type","push","handleRegularRelation","target","isCreatorRelation","includes","populateCreatorFields","scopeDecisionCache","WeakMap","canAccessScope","scope","cacheable","decisions","get","undefined","Map","cached","allowed","strapi","verify","values","contentTypes","model","filter"],"mappings":";;;;AAMA,MAAMA,iBAAAA,GAAoB;AAAC,IAAA;AAAO,CAAA;AAClC,MAAM,EAAEC,oBAAoB,EAAEC,oBAAoB,EAAE,GAAGC,SAA0B;AAejF,gCAAe,CAAA,CAACC,IAAAA,GACd,CAACC,cAAAA,EAAgBC,YAAAA,GAAAA;QACf,MAAM,EAAEC,SAAS,EAAE,GAAGF,cAAAA;;;;;;AAOtB,QAAA,IAAI,CAACE,SAAAA,IAAaA,SAAAA,CAAUC,IAAI,KAAK,UAAA,EAAY;AAC/C,YAAA;AACF,QAAA;QAEA,OAAOC,sBAAAA,CAAuBL,MAAMC,cAAAA,EAAgBC,YAAAA,CAAAA;AACtD,IAAA,CAAA;AAEF,MAAMG,yBAAyB,OAC7BL,IAAAA,EACA,EAAEM,IAAI,EAAEC,GAAG,EAAEJ,SAAS,EAAEK,MAAM,EAA0B,EACxD,EAAEC,MAAM,EAAEC,GAAG,EAA0B,GAAA;;AAGvC,IAAA,IAAI,CAACP,SAAAA,EAAW;AACd,QAAA;AACF,IAAA;AAEA,IAAA,MAAMQ,mBAAAA,GAAsB,UAAA;AAC1B,QAAA,MAAMC,QAAAA,GAAYN,IAAyE,CACzFC,GAAAA,CACD;AAED,QAAA,IAAI,CAACK,QAAAA,EAAU;AACb,YAAA;AACF,QAAA;AAEA,QAAA,IAAIC,uBAAuBD,QAAAA,CAAAA,EAAW;AACpC,YAAA,MAAME,WAAoC,EAAC;AAE3C,YAAA,MAAMC,UAAU,MAAMC,mBAAAA,CAAoBJ,QAAAA,CAASG,OAAO,IAAI,EAAE,CAAA;AAChE,YAAA,MAAME,SAAS,MAAMD,mBAAAA,CAAoBJ,QAAAA,CAASF,GAAG,IAAI,EAAE,CAAA;AAC3D,YAAA,MAAMQ,aAAa,MAAMF,mBAAAA,CAAoBJ,QAAAA,CAASM,UAAU,IAAI,EAAE,CAAA;YAEtE,IAAIH,OAAAA,CAAQI,MAAM,GAAG,CAAA,EAAG;AACtBL,gBAAAA,QAAAA,CAASC,OAAO,GAAGA,OAAAA;AACrB,YAAA;YAEA,IAAIE,MAAAA,CAAOE,MAAM,GAAG,CAAA,EAAG;AACrBL,gBAAAA,QAAAA,CAASJ,GAAG,GAAGO,MAAAA;AACjB,YAAA;YAEA,IAAIC,UAAAA,CAAWC,MAAM,GAAG,CAAA,EAAG;AACzBL,gBAAAA,QAAAA,CAASI,UAAU,GAAGA,UAAAA;AACxB,YAAA;;YAGA,MAAME,OAAAA,GAAUR,SAASQ,OAAO;YAChC,IAAIA,OAAAA,IAAW,OAAOA,OAAAA,KAAY,QAAA,EAAU;AAC1C,gBAAA,MAAMC,kBAA2C,EAAC;AAElDC,gBAAAA,MAAAA,CAAOC,IAAI,CAACH,OAAAA,CAAAA,CAASI,OAAO,CAAC,CAACjB,GAAAA,GAAAA;AAC5B,oBAAA,MAAMkB,SAAAA,GAAYlB,GAAAA;oBAClB,MAAMmB,SAAAA,GAAYC,4BAA4B,CAACF,SAAAA,CAAU;oBACzD,MAAMG,WAAAA,GAAcR,OAAO,CAACb,GAAAA,CAAI;oBAEhC,IAAImB,SAAAA,IAAaA,UAAUE,WAAAA,CAAAA,EAAc;wBACvCP,eAAe,CAACI,UAAU,GAAGG,WAAAA;AAC/B,oBAAA;AACF,gBAAA,CAAA,CAAA;AAEAd,gBAAAA,QAAAA,CAASM,OAAO,GAAGC,eAAAA;YACrB,CAAA,MAAO;gBACLP,QAAAA,CAASM,OAAO,GAAG,EAAC;AACtB,YAAA;AAEAV,YAAAA,GAAAA,CAAIH,GAAAA,EAAKO,QAAAA,CAAAA;QACX,CAAA,MAAO,IAAIe,uBAAuBjB,QAAAA,CAAAA,EAAW;AAC3C,YAAA,MAAMkB,QAAiC,EAAC;YAExC,KAAK,MAAM,CAACC,GAAAA,EAAKC,WAAAA,CAAY,IAAIV,OAAOW,OAAO,CAACrB,QAAAA,CAASsB,EAAE,CAAA,CAAG;gBAC5D,MAAMC,MAAAA,GAASvC,iBAAAA,CAAkBwC,GAAG,CAAC,CAACC,SAAW,CAAA,EAAGN,GAAAA,CAAI,CAAC,EAAEM,MAAAA,CAAAA,CAAQ,CAAA;gBACnE,MAAMC,SAAAA,GAAY,MAAMC,qBAAAA,CAAsBJ,MAAAA,EAAQnC,IAAAA,CAAAA;AAEtD,gBAAA,IAAIsC,SAAAA,EAAW;oBACbR,KAAK,CAACC,IAAI,GAAGC,WAAAA;AACf,gBAAA;AACF,YAAA;AAEA,YAAA,IAAIV,OAAOC,IAAI,CAACO,KAAAA,CAAAA,CAAOX,MAAM,KAAK,CAAA,EAAG;gBACnCV,MAAAA,CAAOF,GAAAA,CAAAA;AACP,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMiC,QAAQC,oBAAAA,CAAqB7B,QAAAA,CAAS4B,KAAK,CAAA,GAAI,IAAA,GAAO5B,SAAS4B,KAAK;AAC1E9B,YAAAA,GAAAA,CAAIH,GAAAA,EAAK;AAAE,gBAAA,GAAGK,QAAQ;AAAE4B,gBAAAA,KAAAA;gBAAON,EAAAA,EAAIJ;AAAM,aAAA,CAAA;QAC3C,CAAA,MAAO;YACL,MAAMY,aAAAA,GAAgB,MAAM1B,mBAAAA,CAAoBJ,QAAAA,CAAAA;YAEhD,IAAI,CAAC8B,aAAAA,CAAcvB,MAAM,EAAE;AACzB,gBAAA,IAAIwB,OAAAA,CAAQ/B,QAAAA,CAAAA,IAAaA,QAAAA,CAASO,MAAM,KAAK,CAAA,EAAG;AAC9C,oBAAA;AACF,gBAAA;gBAEAV,MAAAA,CAAOF,GAAAA,CAAAA;AACP,gBAAA;AACF,YAAA;AAEA,YAAA,IAAIoC,QAAQ/B,QAAAA,CAAAA,EAAW;AACrBF,gBAAAA,GAAAA,CAAIH,GAAAA,EAAKmC,aAAAA,CAAAA;AACT,gBAAA;AACF,YAAA;YAEAhC,GAAAA,CAAIH,GAAAA,EAAKmC,aAAa,CAAC,CAAA,CAAE,CAAA;AAC3B,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM7B,yBAAyB,CAAC+B,KAAAA,GAAAA;QAC9B,OAAOC,QAAAA,CAASD,WAAW,SAAA,IAAaA,SAAS,KAAA,IAASA,KAAAA,IAAS,gBAAgBA,KAAI,CAAA;AACzF,IAAA,CAAA;AAEA,IAAA,MAAMH,oBAAAA,GAAuB,CAACG,KAAAA,GAAmBA,KAAAA,KAAU,QAAQA,KAAAA,KAAU,MAAA;AAE7E,IAAA,MAAMf,yBAAyB,CAACe,KAAAA,GAAAA;QAC9B,OAAOC,QAAAA,CAASD,KAAAA,CAAAA,IAAU,EAAE,QAAA,IAAYA,KAAI,CAAA,IAAM,IAAA,IAAQA,KAAAA,IAASC,QAAAA,CAASD,KAAAA,CAAMV,EAAE,CAAA;AACtF,IAAA,CAAA;AAEA,IAAA,MAAMY,oCAAoC,OAAOd,WAAAA,GAAAA;AAC/C,QAAA,MAAMF,QAAiC,EAAC;QAExC,KAAK,MAAMC,OAAOgB,4BAAAA,EAAAA,CAAgC;YAChD,MAAMZ,MAAAA,GAASvC,iBAAAA,CAAkBwC,GAAG,CAAC,CAACC,SAAW,CAAA,EAAGN,GAAAA,CAAI,CAAC,EAAEM,MAAAA,CAAAA,CAAQ,CAAA;YACnE,MAAMC,SAAAA,GAAY,MAAMC,qBAAAA,CAAsBJ,MAAAA,EAAQnC,IAAAA,CAAAA;AAEtD,YAAA,IAAIsC,SAAAA,EAAW;gBACbR,KAAK,CAACC,IAAI,GAAGC,WAAAA;AACf,YAAA;AACF,QAAA;QAEA,OAAOF,KAAAA;AACT,IAAA,CAAA;AAEA,IAAA,MAAMkB,4BAA4B,CAACJ,KAAAA,GAAAA;AACjC,QAAA,OACEA,KAAAA,KAAU,IAAA,IACVA,KAAAA,KAAU,MAAA,IACTC,SAASD,KAAAA,CAAAA,IAAU,OAAA,IAAWA,KAAAA,IAASH,oBAAAA,CAAqBG,MAAMJ,KAAK,CAAA,IAAK,EAAE,QAAQI,KAAI,CAAA;AAE/F,IAAA,CAAA;AAEA,IAAA,MAAMK,qBAAqB,CAACL,KAAAA,GAAAA;AAC1B,QAAA,OACEC,QAAAA,CAASD,KAAAA,CAAAA,IACT,OAAA,IAAWA,KAAAA,IACX,OAAOA,KAAAA,CAAMJ,KAAK,KAAK,QAAA,IACvBlB,MAAAA,CAAOC,IAAI,CAACqB,KAAAA,CAAAA,CAAOzB,MAAM,KAAK,CAAA;AAElC,IAAA,CAAA;AAEA,IAAA,MAAMH,sBAAsB,OAAOJ,QAAAA,GAAAA;AACjC,QAAA,MAAMsC,kBAA6C,EAAE;QACrD,MAAMC,eAAAA,GAAkBR,OAAAA,CAAQ/B,QAAAA,CAAAA,GAAYA,QAAAA,GAAW;AAACA,YAAAA;AAAS,SAAA;QAEjE,KAAK,MAAMwC,WAAWD,eAAAA,CAAiB;AACrC,YAAA,IAAI,CAACN,QAAAA,CAASO,OAAAA,CAAAA,IAAY,EAAE,QAAA,IAAYA,OAAM,CAAA,IAAM,OAAOA,OAAAA,CAAQC,MAAM,KAAK,QAAA,EAAU;AACtF,gBAAA;AACF,YAAA;AAEA,YAAA,MAAMlB,MAAAA,GAASvC,iBAAAA,CAAkBwC,GAAG,CAAC,CAACC,MAAAA,GAAW,CAAA,EAAGe,OAAAA,CAAQC,MAAM,CAAC,CAAC,EAAEhB,MAAAA,CAAAA,CAAQ,CAAA;YAC9E,MAAMC,SAAAA,GAAY,MAAMC,qBAAAA,CAAsBJ,MAAAA,EAAQnC,IAAAA,CAAAA;AAEtD,YAAA,IAAIsC,SAAAA,EAAW;AACbY,gBAAAA,eAAAA,CAAgBI,IAAI,CAACF,OAAAA,CAAAA;AACvB,YAAA;AACF,QAAA;QAEA,OAAOF,eAAAA;AACT,IAAA,CAAA;AAEA,IAAA,MAAMK,qBAAAA,GAAwB,UAAA;AAC5B,QAAA,MAAMpB,MAAAA,GAASvC,iBAAAA,CAAkBwC,GAAG,CAAC,CAACC,MAAAA,GAAW,CAAA,EAAGlC,SAAAA,CAAUqD,MAAM,CAAC,CAAC,EAAEnB,MAAAA,CAAAA,CAAQ,CAAA;QAChF,MAAMC,SAAAA,GAAY,MAAMC,qBAAAA,CAAsBJ,MAAAA,EAAQnC,IAAAA,CAAAA;AAEtD,QAAA,IAAI,CAACsC,SAAAA,EAAW;YACd7B,MAAAA,CAAOF,GAAAA,CAAAA;AACT,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAMkD,iBAAAA,GAAoB;AAAC5D,QAAAA,oBAAAA;AAAsBC,QAAAA;AAAqB,KAAA,CAAC4D,QAAQ,CAACnD,GAAAA,CAAAA;IAEhF,IAAIR,4BAA6C,CAACI,SAAAA,CAAAA,EAAY;AAC5D,QAAA,MAAMyC,KAAAA,GAAStC,IAAgC,CAACC,GAAAA,CAAI;AAEpD,QAAA,IAAIsB,uBAAuBe,KAAAA,CAAAA,EAAQ;YACjC,MAAMjC,mBAAAA,EAAAA;AACN,YAAA;AACF,QAAA;AAEA,QAAA,IAAIqC,0BAA0BJ,KAAAA,CAAAA,EAAQ;YACpC,MAAMd,KAAAA,GAAQ,MAAMgB,iCAAAA,CAAkC,IAAA,CAAA;AAEtD,YAAA,IAAIxB,OAAOC,IAAI,CAACO,KAAAA,CAAAA,CAAOX,MAAM,KAAK,CAAA,EAAG;gBACnCV,MAAAA,CAAOF,GAAAA,CAAAA;AACP,gBAAA;AACF,YAAA;AAEAG,YAAAA,GAAAA,CACEH,GAAAA,EACAqC,KAAAA,KAAU,IAAA,IAAQA,KAAAA,KAAU,MAAA,GAAS;gBAAEV,EAAAA,EAAIJ;aAAM,GAAI;AAAE,gBAAA,GAAGc,KAAK;gBAAEJ,KAAAA,EAAO,IAAA;gBAAMN,EAAAA,EAAIJ;AAAM,aAAA,CAAA;AAE1F,YAAA;AACF,QAAA;AAEA,QAAA,IAAImB,mBAAmBL,KAAAA,CAAAA,EAAQ;AAC7B,YAAA;AACF,QAAA;QAEA,MAAMjC,mBAAAA,EAAAA;AACN,QAAA;AACF,IAAA;AAEA,IAAA,IAAI8C,iBAAAA,IAAqBjD,MAAAA,CAAOY,OAAO,EAAEuC,qBAAAA,EAAuB;AAC9D,QAAA;AACF,IAAA;IAEA,MAAMJ,qBAAAA,EAAAA;AACR,CAAA;AAEA;;;;;;;;;;IAWA,MAAMK,qBAAqB,IAAIC,OAAAA,EAAAA;AAE/B,MAAMC,cAAAA,GAAiB,OAAOC,KAAAA,EAAe/D,IAAAA,GAAAA;AAC3C,IAAA,MAAMgE,SAAAA,GAAY,OAAOhE,IAAAA,KAAS,QAAA,IAAYA,IAAAA,KAAS,IAAA;IAEvD,IAAIiE,SAAAA;AAEJ,IAAA,IAAID,SAAAA,EAAW;QACbC,SAAAA,GAAYL,kBAAAA,CAAmBM,GAAG,CAAClE,IAAAA,CAAAA;AAEnC,QAAA,IAAIiE,cAAcE,SAAAA,EAAW;AAC3BF,YAAAA,SAAAA,GAAY,IAAIG,GAAAA,EAAAA;YAChBR,kBAAAA,CAAmBlD,GAAG,CAACV,IAAAA,EAAgBiE,SAAAA,CAAAA;QACzC,CAAA,MAAO;YACL,MAAMI,MAAAA,GAASJ,SAAAA,CAAUC,GAAG,CAACH,KAAAA,CAAAA;AAC7B,YAAA,IAAIM,WAAWF,SAAAA,EAAW;gBACxB,OAAOE,MAAAA;AACT,YAAA;AACF,QAAA;AACF,IAAA;IAEA,IAAIC,OAAAA;IACJ,IAAI;AACF,QAAA,MAAMC,MAAAA,CAAOvE,IAAI,CAACwE,MAAM,CAACxE,IAAAA,EAAM;AAAE+D,YAAAA;AAAM,SAAA,CAAA;QACvCO,OAAAA,GAAU,IAAA;AACZ,IAAA,CAAA,CAAE,OAAM;QACNA,OAAAA,GAAU,KAAA;AACZ,IAAA;AAEAL,IAAAA,SAAAA,EAAWvD,IAAIqD,KAAAA,EAAOO,OAAAA,CAAAA;IAEtB,OAAOA,OAAAA;AACT,CAAA;AAEA,MAAM/B,qBAAAA,GAAwB,OAAOJ,MAAAA,EAAkBnC,IAAAA,GAAAA;IACrD,KAAK,MAAM+D,SAAS5B,MAAAA,CAAQ;QAC1B,IAAI,MAAM2B,cAAAA,CAAeC,KAAAA,EAAO/D,IAAAA,CAAAA,EAAO;YACrC,OAAO,IAAA;AACT,QAAA;AACF,IAAA;IAEA,OAAO,KAAA;AACT,CAAA;AAEA,MAAM+C,4BAAAA,GAA+B,IAAA;IACnC,OAAQzB,OAAOmD,MAAM,CAACF,OAAOG,YAAY,IAAI,EAAC,CAAA,CAC3CtC,GAAG,CAAC,CAACuC,KAAAA,GAAUA,MAAM5C,GAAG,CAAA,CACxB6C,MAAM,CAAC,CAAC7C,GAAAA,GAAuB,OAAOA,GAAAA,KAAQ,QAAA,CAAA;AACnD,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"query-populate.d.ts","sourceRoot":"","sources":["../../src/traverse/query-populate.ts"],"names":[],"mappings":";AAuUA,wBAAwC"}
1
+ {"version":3,"file":"query-populate.d.ts","sourceRoot":"","sources":["../../src/traverse/query-populate.ts"],"names":[],"mappings":";AA2UA,wBAAwC"}
@@ -45,12 +45,18 @@ const populate = factory().intercept(isPopulateString, async (visitor, options,
45
45
  populate
46
46
  ]);
47
47
  const traversedPopulate = await recurse(visitor, options, populateObject);
48
- const [result] = objectPopulateToPaths(traversedPopulate);
49
- return result;
50
- })// Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items
48
+ const paths = objectPopulateToPaths(traversedPopulate);
49
+ // Dot notation cannot represent polymorphic `on` fragments. Keep the object form
50
+ // when a visitor adds one, rather than trying to serialize it as nested `populate`.
51
+ return paths ? paths[0] : traversedPopulate;
52
+ })// Array of strings ['foo', 'bar.baz'] => traverse as one object, then serialize when possible
51
53
  .intercept(isStringArray, async (visitor, options, populate, { recurse })=>{
52
- const paths = await Promise.all(populate.map((subClause)=>recurse(visitor, options, subClause)));
53
- return paths.filter((item)=>!fp.isNil(item));
54
+ const populateObject = pathsToObjectPopulate(populate);
55
+ const traversedPopulate = await recurse(visitor, options, populateObject);
56
+ const paths = objectPopulateToPaths(traversedPopulate);
57
+ // A string array cannot hold polymorphic `on` fragments. Return the sanitized object
58
+ // as a whole when one is present, so consumers receive a valid populate representation.
59
+ return paths ?? traversedPopulate;
54
60
  }).intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate)=>{
55
61
  throwQsArrayLimitPopulateError(Object.keys(populate).length);
56
62
  })// for wildcard, generate custom utilities to modify the values
@@ -198,7 +204,10 @@ isKeyword('populate'), async ({ key, visitor, path, value, schema, getModel, att
198
204
  }, {
199
205
  on: value?.on
200
206
  });
201
- set(key, newValue);
207
+ set(key, {
208
+ ...value,
209
+ ...newValue
210
+ });
202
211
  return;
203
212
  }
204
213
  const targetSchemaUID = attribute.target;
@@ -282,11 +291,17 @@ const objectPopulateToPaths = (input)=>{
282
291
  if (value === true) {
283
292
  paths.push(currentPath);
284
293
  } else {
285
- traverse(value.populate, currentPath);
294
+ const nestedPopulate = value.populate;
295
+ if (!nestedPopulate || !traverse(nestedPopulate, currentPath)) {
296
+ return false;
297
+ }
286
298
  }
287
299
  }
300
+ return true;
301
+ }
302
+ if (!traverse(input, '')) {
303
+ return undefined;
288
304
  }
289
- traverse(input, '');
290
305
  return paths;
291
306
  };
292
307
  const pathsToObjectPopulate = (input)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"query-populate.js","sources":["../../src/traverse/query-populate.ts"],"sourcesContent":["import {\n curry,\n isString,\n isArray,\n isEmpty,\n split,\n isObject,\n trim,\n constant,\n isNil,\n identity,\n cloneDeep,\n join,\n first,\n} from 'lodash/fp';\n\nimport traverseFactory, { type Parent } from './factory';\nimport { Attribute } from '../types';\nimport { isMorphToRelationalAttribute } from '../content-types';\nimport { ValidationError } from '../errors';\n\nconst DEFAULT_QS_ARRAY_LIMIT = 100;\n\n/**\n * Detects objects with consecutive numeric string keys and string values — the shape `qs`\n * produces when indexed array notation exceeds `arrayLimit` (see #25632).\n */\nconst isQsArrayLimitPopulateObject = (value: unknown): value is Record<string, string> => {\n if (!isObject(value) || isArray(value)) {\n return false;\n }\n\n const keys = Object.keys(value);\n\n if (keys.length === 0 || keys.length <= DEFAULT_QS_ARRAY_LIMIT) {\n return false;\n }\n\n const hasConsecutiveNumericKeys = keys.every((key, index) => key === String(index));\n\n if (!hasConsecutiveNumericKeys) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n};\n\nconst throwQsArrayLimitPopulateError = (entryCount: number) => {\n throw new ValidationError(\n `Too many populate entries (${entryCount}). The maximum number of populate entries when using array notation is ${DEFAULT_QS_ARRAY_LIMIT}. ` +\n 'Consider using object notation (populate[field]=true), nested population, or reducing the number of fields.'\n );\n};\n\nconst isKeyword = (keyword: string) => {\n return ({ key, attribute }: { key: string; attribute: Attribute }) => {\n return !attribute && keyword === key;\n };\n};\n\nconst isWildcard = (value: unknown): value is '*' => value === '*';\n\nconst isPopulateString = (value: unknown): value is string => {\n return isString(value) && !isWildcard(value);\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\nconst isObj = (value: unknown): value is Record<string, unknown> => isObject(value);\n\nconst populate = traverseFactory()\n .intercept(isPopulateString, async (visitor, options, populate, { recurse }) => {\n /**\n * Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)\n * This gives a consistent structure to track the \"parent\" node of each nested populate clause\n */\n const populateObject = pathsToObjectPopulate([populate]);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const [result] = objectPopulateToPaths(traversedPopulate);\n\n return result;\n })\n // Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items\n .intercept(isStringArray, async (visitor, options, populate, { recurse }) => {\n const paths = await Promise.all(\n populate.map((subClause) => recurse(visitor, options, subClause))\n );\n\n return paths.filter((item) => !isNil(item));\n })\n .intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate) => {\n throwQsArrayLimitPopulateError(Object.keys(populate).length);\n })\n // for wildcard, generate custom utilities to modify the values\n .parse(isWildcard, () => ({\n /**\n * Since value is '*', we don't need to transform it\n */\n transform: identity,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given key, it returns the data ('*')\n */\n get: (_key, data) => data,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given `key`, use `value` as the new `data`\n */\n set: (_key, value) => value,\n\n /**\n * '*' isn't a key/value structure, but we need to simulate at least one to enable\n * the data traversal. We're using '' since it represents a falsy string value\n */\n keys: constant(['']),\n\n /**\n * Removing '*' means setting it to undefined, regardless of the given key\n */\n remove: constant(undefined),\n }))\n\n // Parse string values\n .parse(isString, () => {\n const tokenize = split('.');\n const recompose = join('.');\n\n return {\n transform: trim,\n\n remove(key, data) {\n const [root] = tokenize(data);\n\n return root === key ? undefined : data;\n },\n\n set(key, value, data) {\n const [root] = tokenize(data);\n\n if (root !== key) {\n return data;\n }\n\n return isNil(value) || isEmpty(value) ? root : `${root}.${value}`;\n },\n\n keys(data) {\n const v = first(tokenize(data));\n return v ? [v] : [];\n },\n\n get(key, data) {\n const [root, ...rest] = tokenize(data);\n\n return key === root ? recompose(rest) : undefined;\n },\n };\n })\n // Parse object values\n .parse(isObj, () => ({\n transform: cloneDeep,\n\n remove(key, data) {\n // eslint-disable-next-line no-unused-vars\n const { [key]: ignored, ...rest } = data;\n\n return rest;\n },\n\n set(key, value, data) {\n return { ...data, [key]: value };\n },\n\n keys(data) {\n return Object.keys(data);\n },\n\n get(key, data) {\n return data[key];\n },\n }))\n .ignore(({ key, attribute, parent }) => {\n // We don't want to recurse using traversePopulate for query keywords.\n // Instead, the visitors handle them with the appropriate traversal (sort, filters, etc.).\n //\n // When a keyword name (e.g. 'filters') also exists as an attribute in the schema,\n // we still treat it as a keyword if we're inside a nested populate context\n // (parent is an attribute). This prevents the traverse from recursing into\n // component/relation attributes named 'filters' with query filter data,\n // which would cause \"Invalid key\" validation errors (issue #21338).\n //\n // The attribute can still be populated explicitly via `populate: { filters: true }`.\n return ['sort', 'filters', 'fields'].includes(key) && (!attribute || !!parent?.attribute);\n })\n .on(\n // Handle recursion on populate.\"populate\"\n isKeyword('populate'),\n async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse }) => {\n const parent: Parent = { key, path, schema, attribute };\n\n const newValue = await recurse(visitor, { schema, path, getModel, parent }, value);\n\n set(key, newValue);\n }\n )\n .on(\n isKeyword('on'),\n async ({ key, visitor, path, value, getModel, parent }, { set, recurse }) => {\n const newOn: Record<string, unknown> = {};\n\n if (!isObj(value)) {\n return;\n }\n\n for (const [uid, subPopulate] of Object.entries(value)) {\n const model = getModel(uid);\n const newPath = { ...path, raw: `${path.raw}[${uid}]` };\n\n newOn[uid] = await recurse(\n visitor,\n { schema: model, path: newPath, getModel, parent },\n subPopulate\n );\n }\n\n set(key, newOn);\n }\n )\n // Handle populate on relation\n .onRelation(\n async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n if (isMorphToRelationalAttribute(attribute)) {\n // Don't traverse values that cannot be parsed\n if (!isObject(value) || !('on' in value && isObject(value?.on))) {\n return;\n }\n\n // If there is a populate fragment defined, traverse it\n const newValue = await recurse(\n visitor,\n { schema, path, getModel, parent },\n { on: value?.on }\n );\n\n set(key, newValue);\n\n return;\n }\n\n const targetSchemaUID = attribute.target;\n const targetSchema = getModel(targetSchemaUID!);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on media\n .onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchemaUID = 'plugin::upload.file';\n const targetSchema = getModel(targetSchemaUID);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n })\n // Handle populate on components\n .onComponent(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchema = getModel(attribute.component);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on dynamic zones\n .onDynamicZone(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse }) => {\n if (isNil(value) || !isObject(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n // Handle fragment syntax\n if ('on' in value && value.on) {\n const newOn = await recurse(visitor, { schema, path, getModel, parent }, { on: value.on });\n\n set(key, newOn);\n }\n }\n );\n\nexport default curry(populate.traverse);\n\ntype PopulateObject = {\n [key: string]: true | { populate: PopulateObject };\n};\n\nconst objectPopulateToPaths = (input: PopulateObject): string[] => {\n const paths: string[] = [];\n\n function traverse(currentObj: PopulateObject, parentPath: string) {\n for (const [key, value] of Object.entries(currentObj)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key;\n if (value === true) {\n paths.push(currentPath);\n } else {\n traverse((value as { populate: PopulateObject }).populate, currentPath);\n }\n }\n }\n\n traverse(input, '');\n\n return paths;\n};\n\nconst pathsToObjectPopulate = (input: string[]): PopulateObject => {\n const result: PopulateObject = {};\n\n function traverse(object: PopulateObject, keys: string[]): void {\n const [first, ...rest] = keys;\n if (rest.length === 0) {\n object[first] = true;\n } else {\n if (!object[first] || typeof object[first] === 'boolean') {\n object[first] = { populate: {} };\n }\n traverse((object[first] as { populate: PopulateObject }).populate, rest);\n }\n }\n\n input.forEach((clause) => traverse(result, clause.split('.')));\n\n return result;\n};\n"],"names":["DEFAULT_QS_ARRAY_LIMIT","isQsArrayLimitPopulateObject","value","isObject","isArray","keys","Object","length","hasConsecutiveNumericKeys","every","key","index","String","values","entry","throwQsArrayLimitPopulateError","entryCount","ValidationError","isKeyword","keyword","attribute","isWildcard","isPopulateString","isString","isStringArray","isObj","populate","traverseFactory","intercept","visitor","options","recurse","populateObject","pathsToObjectPopulate","traversedPopulate","result","objectPopulateToPaths","paths","Promise","all","map","subClause","filter","item","isNil","_visitor","_options","parse","transform","identity","get","_key","data","set","constant","remove","undefined","tokenize","split","recompose","join","trim","root","isEmpty","v","first","rest","cloneDeep","ignored","ignore","parent","includes","on","path","schema","getModel","newValue","newOn","uid","subPopulate","entries","model","newPath","raw","onRelation","isMorphToRelationalAttribute","targetSchemaUID","target","targetSchema","onMedia","onComponent","component","onDynamicZone","curry","traverse","input","currentObj","parentPath","currentPath","push","object","forEach","clause"],"mappings":"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"}
1
+ {"version":3,"file":"query-populate.js","sources":["../../src/traverse/query-populate.ts"],"sourcesContent":["import {\n curry,\n isString,\n isArray,\n isEmpty,\n split,\n isObject,\n trim,\n constant,\n isNil,\n identity,\n cloneDeep,\n join,\n first,\n} from 'lodash/fp';\n\nimport traverseFactory, { type Parent } from './factory';\nimport { Attribute } from '../types';\nimport { isMorphToRelationalAttribute } from '../content-types';\nimport { ValidationError } from '../errors';\n\nconst DEFAULT_QS_ARRAY_LIMIT = 100;\n\n/**\n * Detects objects with consecutive numeric string keys and string values — the shape `qs`\n * produces when indexed array notation exceeds `arrayLimit` (see #25632).\n */\nconst isQsArrayLimitPopulateObject = (value: unknown): value is Record<string, string> => {\n if (!isObject(value) || isArray(value)) {\n return false;\n }\n\n const keys = Object.keys(value);\n\n if (keys.length === 0 || keys.length <= DEFAULT_QS_ARRAY_LIMIT) {\n return false;\n }\n\n const hasConsecutiveNumericKeys = keys.every((key, index) => key === String(index));\n\n if (!hasConsecutiveNumericKeys) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n};\n\nconst throwQsArrayLimitPopulateError = (entryCount: number) => {\n throw new ValidationError(\n `Too many populate entries (${entryCount}). The maximum number of populate entries when using array notation is ${DEFAULT_QS_ARRAY_LIMIT}. ` +\n 'Consider using object notation (populate[field]=true), nested population, or reducing the number of fields.'\n );\n};\n\nconst isKeyword = (keyword: string) => {\n return ({ key, attribute }: { key: string; attribute: Attribute }) => {\n return !attribute && keyword === key;\n };\n};\n\nconst isWildcard = (value: unknown): value is '*' => value === '*';\n\nconst isPopulateString = (value: unknown): value is string => {\n return isString(value) && !isWildcard(value);\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\nconst isObj = (value: unknown): value is Record<string, unknown> => isObject(value);\n\nconst populate = traverseFactory()\n .intercept(isPopulateString, async (visitor, options, populate, { recurse }) => {\n /**\n * Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)\n * This gives a consistent structure to track the \"parent\" node of each nested populate clause\n */\n const populateObject = pathsToObjectPopulate([populate]);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const paths = objectPopulateToPaths(traversedPopulate);\n\n // Dot notation cannot represent polymorphic `on` fragments. Keep the object form\n // when a visitor adds one, rather than trying to serialize it as nested `populate`.\n return paths ? paths[0] : traversedPopulate;\n })\n // Array of strings ['foo', 'bar.baz'] => traverse as one object, then serialize when possible\n .intercept(isStringArray, async (visitor, options, populate, { recurse }) => {\n const populateObject = pathsToObjectPopulate(populate);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const paths = objectPopulateToPaths(traversedPopulate);\n\n // A string array cannot hold polymorphic `on` fragments. Return the sanitized object\n // as a whole when one is present, so consumers receive a valid populate representation.\n return paths ?? traversedPopulate;\n })\n .intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate) => {\n throwQsArrayLimitPopulateError(Object.keys(populate).length);\n })\n // for wildcard, generate custom utilities to modify the values\n .parse(isWildcard, () => ({\n /**\n * Since value is '*', we don't need to transform it\n */\n transform: identity,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given key, it returns the data ('*')\n */\n get: (_key, data) => data,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given `key`, use `value` as the new `data`\n */\n set: (_key, value) => value,\n\n /**\n * '*' isn't a key/value structure, but we need to simulate at least one to enable\n * the data traversal. We're using '' since it represents a falsy string value\n */\n keys: constant(['']),\n\n /**\n * Removing '*' means setting it to undefined, regardless of the given key\n */\n remove: constant(undefined),\n }))\n\n // Parse string values\n .parse(isString, () => {\n const tokenize = split('.');\n const recompose = join('.');\n\n return {\n transform: trim,\n\n remove(key, data) {\n const [root] = tokenize(data);\n\n return root === key ? undefined : data;\n },\n\n set(key, value, data) {\n const [root] = tokenize(data);\n\n if (root !== key) {\n return data;\n }\n\n return isNil(value) || isEmpty(value) ? root : `${root}.${value}`;\n },\n\n keys(data) {\n const v = first(tokenize(data));\n return v ? [v] : [];\n },\n\n get(key, data) {\n const [root, ...rest] = tokenize(data);\n\n return key === root ? recompose(rest) : undefined;\n },\n };\n })\n // Parse object values\n .parse(isObj, () => ({\n transform: cloneDeep,\n\n remove(key, data) {\n // eslint-disable-next-line no-unused-vars\n const { [key]: ignored, ...rest } = data;\n\n return rest;\n },\n\n set(key, value, data) {\n return { ...data, [key]: value };\n },\n\n keys(data) {\n return Object.keys(data);\n },\n\n get(key, data) {\n return data[key];\n },\n }))\n .ignore(({ key, attribute, parent }) => {\n // We don't want to recurse using traversePopulate for query keywords.\n // Instead, the visitors handle them with the appropriate traversal (sort, filters, etc.).\n //\n // When a keyword name (e.g. 'filters') also exists as an attribute in the schema,\n // we still treat it as a keyword if we're inside a nested populate context\n // (parent is an attribute). This prevents the traverse from recursing into\n // component/relation attributes named 'filters' with query filter data,\n // which would cause \"Invalid key\" validation errors (issue #21338).\n //\n // The attribute can still be populated explicitly via `populate: { filters: true }`.\n return ['sort', 'filters', 'fields'].includes(key) && (!attribute || !!parent?.attribute);\n })\n .on(\n // Handle recursion on populate.\"populate\"\n isKeyword('populate'),\n async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse }) => {\n const parent: Parent = { key, path, schema, attribute };\n\n const newValue = await recurse(visitor, { schema, path, getModel, parent }, value);\n\n set(key, newValue);\n }\n )\n .on(\n isKeyword('on'),\n async ({ key, visitor, path, value, getModel, parent }, { set, recurse }) => {\n const newOn: Record<string, unknown> = {};\n\n if (!isObj(value)) {\n return;\n }\n\n for (const [uid, subPopulate] of Object.entries(value)) {\n const model = getModel(uid);\n const newPath = { ...path, raw: `${path.raw}[${uid}]` };\n\n newOn[uid] = await recurse(\n visitor,\n { schema: model, path: newPath, getModel, parent },\n subPopulate\n );\n }\n\n set(key, newOn);\n }\n )\n // Handle populate on relation\n .onRelation(\n async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n if (isMorphToRelationalAttribute(attribute)) {\n // Don't traverse values that cannot be parsed\n if (!isObject(value) || !('on' in value && isObject(value?.on))) {\n return;\n }\n\n // If there is a populate fragment defined, traverse it\n const newValue = await recurse(\n visitor,\n { schema, path, getModel, parent },\n { on: value?.on }\n );\n\n set(key, { ...value, ...(newValue as Record<string, unknown>) });\n\n return;\n }\n\n const targetSchemaUID = attribute.target;\n const targetSchema = getModel(targetSchemaUID!);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on media\n .onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchemaUID = 'plugin::upload.file';\n const targetSchema = getModel(targetSchemaUID);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n })\n // Handle populate on components\n .onComponent(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchema = getModel(attribute.component);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on dynamic zones\n .onDynamicZone(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse }) => {\n if (isNil(value) || !isObject(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n // Handle fragment syntax\n if ('on' in value && value.on) {\n const newOn = await recurse(visitor, { schema, path, getModel, parent }, { on: value.on });\n\n set(key, newOn);\n }\n }\n );\n\nexport default curry(populate.traverse);\n\ntype PopulateObject = {\n [key: string]: true | { populate: PopulateObject };\n};\n\nconst objectPopulateToPaths = (input: PopulateObject): string[] | undefined => {\n const paths: string[] = [];\n\n function traverse(currentObj: PopulateObject, parentPath: string): boolean {\n for (const [key, value] of Object.entries(currentObj)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key;\n if (value === true) {\n paths.push(currentPath);\n } else {\n const nestedPopulate = (value as { populate?: PopulateObject }).populate;\n\n if (!nestedPopulate || !traverse(nestedPopulate, currentPath)) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n if (!traverse(input, '')) {\n return undefined;\n }\n\n return paths;\n};\n\nconst pathsToObjectPopulate = (input: string[]): PopulateObject => {\n const result: PopulateObject = {};\n\n function traverse(object: PopulateObject, keys: string[]): void {\n const [first, ...rest] = keys;\n if (rest.length === 0) {\n object[first] = true;\n } else {\n if (!object[first] || typeof object[first] === 'boolean') {\n object[first] = { populate: {} };\n }\n traverse((object[first] as { populate: PopulateObject }).populate, rest);\n }\n }\n\n input.forEach((clause) => traverse(result, clause.split('.')));\n\n return result;\n};\n"],"names":["DEFAULT_QS_ARRAY_LIMIT","isQsArrayLimitPopulateObject","value","isObject","isArray","keys","Object","length","hasConsecutiveNumericKeys","every","key","index","String","values","entry","throwQsArrayLimitPopulateError","entryCount","ValidationError","isKeyword","keyword","attribute","isWildcard","isPopulateString","isString","isStringArray","isObj","populate","traverseFactory","intercept","visitor","options","recurse","populateObject","pathsToObjectPopulate","traversedPopulate","paths","objectPopulateToPaths","_visitor","_options","parse","transform","identity","get","_key","data","set","constant","remove","undefined","tokenize","split","recompose","join","trim","root","isNil","isEmpty","v","first","rest","cloneDeep","ignored","ignore","parent","includes","on","path","schema","getModel","newValue","newOn","uid","subPopulate","entries","model","newPath","raw","onRelation","isMorphToRelationalAttribute","targetSchemaUID","target","targetSchema","onMedia","onComponent","component","onDynamicZone","curry","traverse","input","currentObj","parentPath","currentPath","push","nestedPopulate","result","object","forEach","clause"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { isNil, identity, constant, isString, split, join, trim, first, isEmpty, cloneDeep, isObject, curry, isArray } from 'lodash/fp';
1
+ import { identity, constant, isString, split, join, trim, first, isNil, isEmpty, cloneDeep, isObject, curry, isArray } from 'lodash/fp';
2
2
  import traverseFactory from './factory.mjs';
3
3
  import { isMorphToRelationalAttribute } from '../content-types.mjs';
4
4
  import { ValidationError } from '../errors.mjs';
@@ -43,12 +43,18 @@ const populate = traverseFactory().intercept(isPopulateString, async (visitor, o
43
43
  populate
44
44
  ]);
45
45
  const traversedPopulate = await recurse(visitor, options, populateObject);
46
- const [result] = objectPopulateToPaths(traversedPopulate);
47
- return result;
48
- })// Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items
46
+ const paths = objectPopulateToPaths(traversedPopulate);
47
+ // Dot notation cannot represent polymorphic `on` fragments. Keep the object form
48
+ // when a visitor adds one, rather than trying to serialize it as nested `populate`.
49
+ return paths ? paths[0] : traversedPopulate;
50
+ })// Array of strings ['foo', 'bar.baz'] => traverse as one object, then serialize when possible
49
51
  .intercept(isStringArray, async (visitor, options, populate, { recurse })=>{
50
- const paths = await Promise.all(populate.map((subClause)=>recurse(visitor, options, subClause)));
51
- return paths.filter((item)=>!isNil(item));
52
+ const populateObject = pathsToObjectPopulate(populate);
53
+ const traversedPopulate = await recurse(visitor, options, populateObject);
54
+ const paths = objectPopulateToPaths(traversedPopulate);
55
+ // A string array cannot hold polymorphic `on` fragments. Return the sanitized object
56
+ // as a whole when one is present, so consumers receive a valid populate representation.
57
+ return paths ?? traversedPopulate;
52
58
  }).intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate)=>{
53
59
  throwQsArrayLimitPopulateError(Object.keys(populate).length);
54
60
  })// for wildcard, generate custom utilities to modify the values
@@ -196,7 +202,10 @@ isKeyword('populate'), async ({ key, visitor, path, value, schema, getModel, att
196
202
  }, {
197
203
  on: value?.on
198
204
  });
199
- set(key, newValue);
205
+ set(key, {
206
+ ...value,
207
+ ...newValue
208
+ });
200
209
  return;
201
210
  }
202
211
  const targetSchemaUID = attribute.target;
@@ -280,11 +289,17 @@ const objectPopulateToPaths = (input)=>{
280
289
  if (value === true) {
281
290
  paths.push(currentPath);
282
291
  } else {
283
- traverse(value.populate, currentPath);
292
+ const nestedPopulate = value.populate;
293
+ if (!nestedPopulate || !traverse(nestedPopulate, currentPath)) {
294
+ return false;
295
+ }
284
296
  }
285
297
  }
298
+ return true;
299
+ }
300
+ if (!traverse(input, '')) {
301
+ return undefined;
286
302
  }
287
- traverse(input, '');
288
303
  return paths;
289
304
  };
290
305
  const pathsToObjectPopulate = (input)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"query-populate.mjs","sources":["../../src/traverse/query-populate.ts"],"sourcesContent":["import {\n curry,\n isString,\n isArray,\n isEmpty,\n split,\n isObject,\n trim,\n constant,\n isNil,\n identity,\n cloneDeep,\n join,\n first,\n} from 'lodash/fp';\n\nimport traverseFactory, { type Parent } from './factory';\nimport { Attribute } from '../types';\nimport { isMorphToRelationalAttribute } from '../content-types';\nimport { ValidationError } from '../errors';\n\nconst DEFAULT_QS_ARRAY_LIMIT = 100;\n\n/**\n * Detects objects with consecutive numeric string keys and string values — the shape `qs`\n * produces when indexed array notation exceeds `arrayLimit` (see #25632).\n */\nconst isQsArrayLimitPopulateObject = (value: unknown): value is Record<string, string> => {\n if (!isObject(value) || isArray(value)) {\n return false;\n }\n\n const keys = Object.keys(value);\n\n if (keys.length === 0 || keys.length <= DEFAULT_QS_ARRAY_LIMIT) {\n return false;\n }\n\n const hasConsecutiveNumericKeys = keys.every((key, index) => key === String(index));\n\n if (!hasConsecutiveNumericKeys) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n};\n\nconst throwQsArrayLimitPopulateError = (entryCount: number) => {\n throw new ValidationError(\n `Too many populate entries (${entryCount}). The maximum number of populate entries when using array notation is ${DEFAULT_QS_ARRAY_LIMIT}. ` +\n 'Consider using object notation (populate[field]=true), nested population, or reducing the number of fields.'\n );\n};\n\nconst isKeyword = (keyword: string) => {\n return ({ key, attribute }: { key: string; attribute: Attribute }) => {\n return !attribute && keyword === key;\n };\n};\n\nconst isWildcard = (value: unknown): value is '*' => value === '*';\n\nconst isPopulateString = (value: unknown): value is string => {\n return isString(value) && !isWildcard(value);\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\nconst isObj = (value: unknown): value is Record<string, unknown> => isObject(value);\n\nconst populate = traverseFactory()\n .intercept(isPopulateString, async (visitor, options, populate, { recurse }) => {\n /**\n * Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)\n * This gives a consistent structure to track the \"parent\" node of each nested populate clause\n */\n const populateObject = pathsToObjectPopulate([populate]);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const [result] = objectPopulateToPaths(traversedPopulate);\n\n return result;\n })\n // Array of strings ['foo', 'bar.baz'] => map(recurse), then filter out empty items\n .intercept(isStringArray, async (visitor, options, populate, { recurse }) => {\n const paths = await Promise.all(\n populate.map((subClause) => recurse(visitor, options, subClause))\n );\n\n return paths.filter((item) => !isNil(item));\n })\n .intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate) => {\n throwQsArrayLimitPopulateError(Object.keys(populate).length);\n })\n // for wildcard, generate custom utilities to modify the values\n .parse(isWildcard, () => ({\n /**\n * Since value is '*', we don't need to transform it\n */\n transform: identity,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given key, it returns the data ('*')\n */\n get: (_key, data) => data,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given `key`, use `value` as the new `data`\n */\n set: (_key, value) => value,\n\n /**\n * '*' isn't a key/value structure, but we need to simulate at least one to enable\n * the data traversal. We're using '' since it represents a falsy string value\n */\n keys: constant(['']),\n\n /**\n * Removing '*' means setting it to undefined, regardless of the given key\n */\n remove: constant(undefined),\n }))\n\n // Parse string values\n .parse(isString, () => {\n const tokenize = split('.');\n const recompose = join('.');\n\n return {\n transform: trim,\n\n remove(key, data) {\n const [root] = tokenize(data);\n\n return root === key ? undefined : data;\n },\n\n set(key, value, data) {\n const [root] = tokenize(data);\n\n if (root !== key) {\n return data;\n }\n\n return isNil(value) || isEmpty(value) ? root : `${root}.${value}`;\n },\n\n keys(data) {\n const v = first(tokenize(data));\n return v ? [v] : [];\n },\n\n get(key, data) {\n const [root, ...rest] = tokenize(data);\n\n return key === root ? recompose(rest) : undefined;\n },\n };\n })\n // Parse object values\n .parse(isObj, () => ({\n transform: cloneDeep,\n\n remove(key, data) {\n // eslint-disable-next-line no-unused-vars\n const { [key]: ignored, ...rest } = data;\n\n return rest;\n },\n\n set(key, value, data) {\n return { ...data, [key]: value };\n },\n\n keys(data) {\n return Object.keys(data);\n },\n\n get(key, data) {\n return data[key];\n },\n }))\n .ignore(({ key, attribute, parent }) => {\n // We don't want to recurse using traversePopulate for query keywords.\n // Instead, the visitors handle them with the appropriate traversal (sort, filters, etc.).\n //\n // When a keyword name (e.g. 'filters') also exists as an attribute in the schema,\n // we still treat it as a keyword if we're inside a nested populate context\n // (parent is an attribute). This prevents the traverse from recursing into\n // component/relation attributes named 'filters' with query filter data,\n // which would cause \"Invalid key\" validation errors (issue #21338).\n //\n // The attribute can still be populated explicitly via `populate: { filters: true }`.\n return ['sort', 'filters', 'fields'].includes(key) && (!attribute || !!parent?.attribute);\n })\n .on(\n // Handle recursion on populate.\"populate\"\n isKeyword('populate'),\n async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse }) => {\n const parent: Parent = { key, path, schema, attribute };\n\n const newValue = await recurse(visitor, { schema, path, getModel, parent }, value);\n\n set(key, newValue);\n }\n )\n .on(\n isKeyword('on'),\n async ({ key, visitor, path, value, getModel, parent }, { set, recurse }) => {\n const newOn: Record<string, unknown> = {};\n\n if (!isObj(value)) {\n return;\n }\n\n for (const [uid, subPopulate] of Object.entries(value)) {\n const model = getModel(uid);\n const newPath = { ...path, raw: `${path.raw}[${uid}]` };\n\n newOn[uid] = await recurse(\n visitor,\n { schema: model, path: newPath, getModel, parent },\n subPopulate\n );\n }\n\n set(key, newOn);\n }\n )\n // Handle populate on relation\n .onRelation(\n async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n if (isMorphToRelationalAttribute(attribute)) {\n // Don't traverse values that cannot be parsed\n if (!isObject(value) || !('on' in value && isObject(value?.on))) {\n return;\n }\n\n // If there is a populate fragment defined, traverse it\n const newValue = await recurse(\n visitor,\n { schema, path, getModel, parent },\n { on: value?.on }\n );\n\n set(key, newValue);\n\n return;\n }\n\n const targetSchemaUID = attribute.target;\n const targetSchema = getModel(targetSchemaUID!);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on media\n .onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchemaUID = 'plugin::upload.file';\n const targetSchema = getModel(targetSchemaUID);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n })\n // Handle populate on components\n .onComponent(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchema = getModel(attribute.component);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on dynamic zones\n .onDynamicZone(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse }) => {\n if (isNil(value) || !isObject(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n // Handle fragment syntax\n if ('on' in value && value.on) {\n const newOn = await recurse(visitor, { schema, path, getModel, parent }, { on: value.on });\n\n set(key, newOn);\n }\n }\n );\n\nexport default curry(populate.traverse);\n\ntype PopulateObject = {\n [key: string]: true | { populate: PopulateObject };\n};\n\nconst objectPopulateToPaths = (input: PopulateObject): string[] => {\n const paths: string[] = [];\n\n function traverse(currentObj: PopulateObject, parentPath: string) {\n for (const [key, value] of Object.entries(currentObj)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key;\n if (value === true) {\n paths.push(currentPath);\n } else {\n traverse((value as { populate: PopulateObject }).populate, currentPath);\n }\n }\n }\n\n traverse(input, '');\n\n return paths;\n};\n\nconst pathsToObjectPopulate = (input: string[]): PopulateObject => {\n const result: PopulateObject = {};\n\n function traverse(object: PopulateObject, keys: string[]): void {\n const [first, ...rest] = keys;\n if (rest.length === 0) {\n object[first] = true;\n } else {\n if (!object[first] || typeof object[first] === 'boolean') {\n object[first] = { populate: {} };\n }\n traverse((object[first] as { populate: PopulateObject }).populate, rest);\n }\n }\n\n input.forEach((clause) => traverse(result, clause.split('.')));\n\n return result;\n};\n"],"names":["DEFAULT_QS_ARRAY_LIMIT","isQsArrayLimitPopulateObject","value","isObject","isArray","keys","Object","length","hasConsecutiveNumericKeys","every","key","index","String","values","entry","throwQsArrayLimitPopulateError","entryCount","ValidationError","isKeyword","keyword","attribute","isWildcard","isPopulateString","isString","isStringArray","isObj","populate","traverseFactory","intercept","visitor","options","recurse","populateObject","pathsToObjectPopulate","traversedPopulate","result","objectPopulateToPaths","paths","Promise","all","map","subClause","filter","item","isNil","_visitor","_options","parse","transform","identity","get","_key","data","set","constant","remove","undefined","tokenize","split","recompose","join","trim","root","isEmpty","v","first","rest","cloneDeep","ignored","ignore","parent","includes","on","path","schema","getModel","newValue","newOn","uid","subPopulate","entries","model","newPath","raw","onRelation","isMorphToRelationalAttribute","targetSchemaUID","target","targetSchema","onMedia","onComponent","component","onDynamicZone","curry","traverse","input","currentObj","parentPath","currentPath","push","object","forEach","clause"],"mappings":"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"}
1
+ {"version":3,"file":"query-populate.mjs","sources":["../../src/traverse/query-populate.ts"],"sourcesContent":["import {\n curry,\n isString,\n isArray,\n isEmpty,\n split,\n isObject,\n trim,\n constant,\n isNil,\n identity,\n cloneDeep,\n join,\n first,\n} from 'lodash/fp';\n\nimport traverseFactory, { type Parent } from './factory';\nimport { Attribute } from '../types';\nimport { isMorphToRelationalAttribute } from '../content-types';\nimport { ValidationError } from '../errors';\n\nconst DEFAULT_QS_ARRAY_LIMIT = 100;\n\n/**\n * Detects objects with consecutive numeric string keys and string values — the shape `qs`\n * produces when indexed array notation exceeds `arrayLimit` (see #25632).\n */\nconst isQsArrayLimitPopulateObject = (value: unknown): value is Record<string, string> => {\n if (!isObject(value) || isArray(value)) {\n return false;\n }\n\n const keys = Object.keys(value);\n\n if (keys.length === 0 || keys.length <= DEFAULT_QS_ARRAY_LIMIT) {\n return false;\n }\n\n const hasConsecutiveNumericKeys = keys.every((key, index) => key === String(index));\n\n if (!hasConsecutiveNumericKeys) {\n return false;\n }\n\n return Object.values(value).every((entry) => typeof entry === 'string');\n};\n\nconst throwQsArrayLimitPopulateError = (entryCount: number) => {\n throw new ValidationError(\n `Too many populate entries (${entryCount}). The maximum number of populate entries when using array notation is ${DEFAULT_QS_ARRAY_LIMIT}. ` +\n 'Consider using object notation (populate[field]=true), nested population, or reducing the number of fields.'\n );\n};\n\nconst isKeyword = (keyword: string) => {\n return ({ key, attribute }: { key: string; attribute: Attribute }) => {\n return !attribute && keyword === key;\n };\n};\n\nconst isWildcard = (value: unknown): value is '*' => value === '*';\n\nconst isPopulateString = (value: unknown): value is string => {\n return isString(value) && !isWildcard(value);\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\nconst isObj = (value: unknown): value is Record<string, unknown> => isObject(value);\n\nconst populate = traverseFactory()\n .intercept(isPopulateString, async (visitor, options, populate, { recurse }) => {\n /**\n * Ensure the populate clause its in the extended format ( { populate: { ... } }, and not just a string)\n * This gives a consistent structure to track the \"parent\" node of each nested populate clause\n */\n const populateObject = pathsToObjectPopulate([populate]);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const paths = objectPopulateToPaths(traversedPopulate);\n\n // Dot notation cannot represent polymorphic `on` fragments. Keep the object form\n // when a visitor adds one, rather than trying to serialize it as nested `populate`.\n return paths ? paths[0] : traversedPopulate;\n })\n // Array of strings ['foo', 'bar.baz'] => traverse as one object, then serialize when possible\n .intercept(isStringArray, async (visitor, options, populate, { recurse }) => {\n const populateObject = pathsToObjectPopulate(populate);\n const traversedPopulate = (await recurse(visitor, options, populateObject)) as PopulateObject;\n const paths = objectPopulateToPaths(traversedPopulate);\n\n // A string array cannot hold polymorphic `on` fragments. Return the sanitized object\n // as a whole when one is present, so consumers receive a valid populate representation.\n return paths ?? traversedPopulate;\n })\n .intercept(isQsArrayLimitPopulateObject, async (_visitor, _options, populate) => {\n throwQsArrayLimitPopulateError(Object.keys(populate).length);\n })\n // for wildcard, generate custom utilities to modify the values\n .parse(isWildcard, () => ({\n /**\n * Since value is '*', we don't need to transform it\n */\n transform: identity,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given key, it returns the data ('*')\n */\n get: (_key, data) => data,\n\n /**\n * '*' isn't a key/value structure, so regardless\n * of the given `key`, use `value` as the new `data`\n */\n set: (_key, value) => value,\n\n /**\n * '*' isn't a key/value structure, but we need to simulate at least one to enable\n * the data traversal. We're using '' since it represents a falsy string value\n */\n keys: constant(['']),\n\n /**\n * Removing '*' means setting it to undefined, regardless of the given key\n */\n remove: constant(undefined),\n }))\n\n // Parse string values\n .parse(isString, () => {\n const tokenize = split('.');\n const recompose = join('.');\n\n return {\n transform: trim,\n\n remove(key, data) {\n const [root] = tokenize(data);\n\n return root === key ? undefined : data;\n },\n\n set(key, value, data) {\n const [root] = tokenize(data);\n\n if (root !== key) {\n return data;\n }\n\n return isNil(value) || isEmpty(value) ? root : `${root}.${value}`;\n },\n\n keys(data) {\n const v = first(tokenize(data));\n return v ? [v] : [];\n },\n\n get(key, data) {\n const [root, ...rest] = tokenize(data);\n\n return key === root ? recompose(rest) : undefined;\n },\n };\n })\n // Parse object values\n .parse(isObj, () => ({\n transform: cloneDeep,\n\n remove(key, data) {\n // eslint-disable-next-line no-unused-vars\n const { [key]: ignored, ...rest } = data;\n\n return rest;\n },\n\n set(key, value, data) {\n return { ...data, [key]: value };\n },\n\n keys(data) {\n return Object.keys(data);\n },\n\n get(key, data) {\n return data[key];\n },\n }))\n .ignore(({ key, attribute, parent }) => {\n // We don't want to recurse using traversePopulate for query keywords.\n // Instead, the visitors handle them with the appropriate traversal (sort, filters, etc.).\n //\n // When a keyword name (e.g. 'filters') also exists as an attribute in the schema,\n // we still treat it as a keyword if we're inside a nested populate context\n // (parent is an attribute). This prevents the traverse from recursing into\n // component/relation attributes named 'filters' with query filter data,\n // which would cause \"Invalid key\" validation errors (issue #21338).\n //\n // The attribute can still be populated explicitly via `populate: { filters: true }`.\n return ['sort', 'filters', 'fields'].includes(key) && (!attribute || !!parent?.attribute);\n })\n .on(\n // Handle recursion on populate.\"populate\"\n isKeyword('populate'),\n async ({ key, visitor, path, value, schema, getModel, attribute }, { set, recurse }) => {\n const parent: Parent = { key, path, schema, attribute };\n\n const newValue = await recurse(visitor, { schema, path, getModel, parent }, value);\n\n set(key, newValue);\n }\n )\n .on(\n isKeyword('on'),\n async ({ key, visitor, path, value, getModel, parent }, { set, recurse }) => {\n const newOn: Record<string, unknown> = {};\n\n if (!isObj(value)) {\n return;\n }\n\n for (const [uid, subPopulate] of Object.entries(value)) {\n const model = getModel(uid);\n const newPath = { ...path, raw: `${path.raw}[${uid}]` };\n\n newOn[uid] = await recurse(\n visitor,\n { schema: model, path: newPath, getModel, parent },\n subPopulate\n );\n }\n\n set(key, newOn);\n }\n )\n // Handle populate on relation\n .onRelation(\n async ({ key, value, attribute, visitor, path, schema, getModel }, { set, recurse }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n if (isMorphToRelationalAttribute(attribute)) {\n // Don't traverse values that cannot be parsed\n if (!isObject(value) || !('on' in value && isObject(value?.on))) {\n return;\n }\n\n // If there is a populate fragment defined, traverse it\n const newValue = await recurse(\n visitor,\n { schema, path, getModel, parent },\n { on: value?.on }\n );\n\n set(key, { ...value, ...(newValue as Record<string, unknown>) });\n\n return;\n }\n\n const targetSchemaUID = attribute.target;\n const targetSchema = getModel(targetSchemaUID!);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on media\n .onMedia(async ({ key, path, schema, attribute, visitor, value, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchemaUID = 'plugin::upload.file';\n const targetSchema = getModel(targetSchemaUID);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n })\n // Handle populate on components\n .onComponent(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { recurse, set }) => {\n if (isNil(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n const targetSchema = getModel(attribute.component);\n\n const newValue = await recurse(\n visitor,\n { schema: targetSchema, path, getModel, parent },\n value\n );\n\n set(key, newValue);\n }\n )\n // Handle populate on dynamic zones\n .onDynamicZone(\n async ({ key, value, schema, visitor, path, attribute, getModel }, { set, recurse }) => {\n if (isNil(value) || !isObject(value)) {\n return;\n }\n\n const parent: Parent = { key, path, schema, attribute };\n\n // Handle fragment syntax\n if ('on' in value && value.on) {\n const newOn = await recurse(visitor, { schema, path, getModel, parent }, { on: value.on });\n\n set(key, newOn);\n }\n }\n );\n\nexport default curry(populate.traverse);\n\ntype PopulateObject = {\n [key: string]: true | { populate: PopulateObject };\n};\n\nconst objectPopulateToPaths = (input: PopulateObject): string[] | undefined => {\n const paths: string[] = [];\n\n function traverse(currentObj: PopulateObject, parentPath: string): boolean {\n for (const [key, value] of Object.entries(currentObj)) {\n const currentPath = parentPath ? `${parentPath}.${key}` : key;\n if (value === true) {\n paths.push(currentPath);\n } else {\n const nestedPopulate = (value as { populate?: PopulateObject }).populate;\n\n if (!nestedPopulate || !traverse(nestedPopulate, currentPath)) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n if (!traverse(input, '')) {\n return undefined;\n }\n\n return paths;\n};\n\nconst pathsToObjectPopulate = (input: string[]): PopulateObject => {\n const result: PopulateObject = {};\n\n function traverse(object: PopulateObject, keys: string[]): void {\n const [first, ...rest] = keys;\n if (rest.length === 0) {\n object[first] = true;\n } else {\n if (!object[first] || typeof object[first] === 'boolean') {\n object[first] = { populate: {} };\n }\n traverse((object[first] as { populate: PopulateObject }).populate, rest);\n }\n }\n\n input.forEach((clause) => traverse(result, clause.split('.')));\n\n return result;\n};\n"],"names":["DEFAULT_QS_ARRAY_LIMIT","isQsArrayLimitPopulateObject","value","isObject","isArray","keys","Object","length","hasConsecutiveNumericKeys","every","key","index","String","values","entry","throwQsArrayLimitPopulateError","entryCount","ValidationError","isKeyword","keyword","attribute","isWildcard","isPopulateString","isString","isStringArray","isObj","populate","traverseFactory","intercept","visitor","options","recurse","populateObject","pathsToObjectPopulate","traversedPopulate","paths","objectPopulateToPaths","_visitor","_options","parse","transform","identity","get","_key","data","set","constant","remove","undefined","tokenize","split","recompose","join","trim","root","isNil","isEmpty","v","first","rest","cloneDeep","ignored","ignore","parent","includes","on","path","schema","getModel","newValue","newOn","uid","subPopulate","entries","model","newPath","raw","onRelation","isMorphToRelationalAttribute","targetSchemaUID","target","targetSchema","onMedia","onComponent","component","onDynamicZone","curry","traverse","input","currentObj","parentPath","currentPath","push","nestedPopulate","result","object","forEach","clause"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,MAAM,EAAE,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,GAAI,MAAM,UAAU;;mBA8FlC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACtB,KAAK,kCAC0B,OAAO;;;;;CA+KjD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAM1C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAMvC,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,MAAM,EAAE,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACxD;AACD,MAAM,WAAW,YAAY;IAC3B,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,KAAK,EACb,OAAO,CAAC,EAAE,OAAO,KACd,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;CACpC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,QAAA,MAAM,mBAAmB,GAAI,MAAM,UAAU;;mBA8FlC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACtB,KAAK,kCAC0B,OAAO;;;;;CAsKjD,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC"}