@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.
- package/dist/convert-query-params.d.ts.map +1 -1
- package/dist/convert-query-params.js +31 -1
- package/dist/convert-query-params.js.map +1 -1
- package/dist/convert-query-params.mjs +31 -1
- package/dist/convert-query-params.mjs.map +1 -1
- package/dist/sanitize/index.d.ts.map +1 -1
- package/dist/sanitize/index.js +3 -1
- package/dist/sanitize/index.js.map +1 -1
- package/dist/sanitize/index.mjs +3 -1
- package/dist/sanitize/index.mjs.map +1 -1
- package/dist/sanitize/visitors/remove-restricted-relations.d.ts.map +1 -1
- package/dist/sanitize/visitors/remove-restricted-relations.js +93 -20
- package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -1
- package/dist/sanitize/visitors/remove-restricted-relations.mjs +94 -21
- package/dist/sanitize/visitors/remove-restricted-relations.mjs.map +1 -1
- package/dist/traverse/query-populate.d.ts.map +1 -1
- package/dist/traverse/query-populate.js +23 -8
- package/dist/traverse/query-populate.js.map +1 -1
- package/dist/traverse/query-populate.mjs +24 -9
- package/dist/traverse/query-populate.mjs.map +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +2 -8
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/index.mjs +2 -8
- package/dist/validate/index.mjs.map +1 -1
- package/dist/validate/visitors/throw-restricted-relations.d.ts.map +1 -1
- package/dist/validate/visitors/throw-restricted-relations.js +34 -6
- package/dist/validate/visitors/throw-restricted-relations.js.map +1 -1
- package/dist/validate/visitors/throw-restricted-relations.mjs +35 -7
- package/dist/validate/visitors/throw-restricted-relations.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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 (
|
|
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
|
-
|
|
46
|
+
const options = elements.options;
|
|
47
|
+
if (options && typeof options === 'object') {
|
|
47
48
|
const filteredOptions = {};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const validator = VALID_RELATION_ORDERING_KEYS[
|
|
51
|
-
|
|
52
|
-
if (validator && validator(
|
|
53
|
-
filteredOptions[
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for (const element of
|
|
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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-populate.d.ts","sourceRoot":"","sources":["../../src/traverse/query-populate.ts"],"names":[],"mappings":";
|
|
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
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
53
|
-
|
|
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,
|
|
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
|
-
|
|
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 {
|
|
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
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
51
|
-
|
|
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,
|
|
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
|
-
|
|
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;;;;;
|
|
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"}
|