payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
170 lines (169 loc) • 8.07 kB
JavaScript
// @ts-strict-ignore
import { fieldShouldBeLocalized } from '../fields/config/types.js';
export function getLocalizedPaths({ collectionSlug, fields, globalSlug, incomingPath, locale, overrideAccess = false, parentIsLocalized, payload }) {
const pathSegments = incomingPath.split('.');
const localizationConfig = payload.config.localization;
let paths = [
{
collectionSlug,
complete: false,
field: undefined,
fields,
globalSlug,
invalid: false,
parentIsLocalized,
path: ''
}
];
for(let i = 0; i < pathSegments.length; i += 1){
const segment = pathSegments[i];
const lastIncompletePath = paths.find(({ complete })=>!complete);
if (lastIncompletePath) {
const { path } = lastIncompletePath;
let currentPath = path ? `${path}.${segment}` : segment;
let fieldsToSearch;
let _parentIsLocalized = parentIsLocalized;
let matchedField;
if (lastIncompletePath?.field?.type === 'blocks') {
if (segment === 'blockType') {
matchedField = {
name: 'blockType',
type: 'text'
};
} else {
for (const _block of lastIncompletePath.field.blockReferences ?? lastIncompletePath.field.blocks){
let block;
if (typeof _block === 'string') {
block = payload?.blocks[_block];
} else {
block = _block;
}
matchedField = block.flattenedFields.find((field)=>field.name === segment);
if (matchedField) {
break;
}
}
}
} else {
if (lastIncompletePath?.field && 'flattenedFields' in lastIncompletePath.field) {
fieldsToSearch = lastIncompletePath.field.flattenedFields;
} else {
fieldsToSearch = lastIncompletePath.fields;
}
_parentIsLocalized = parentIsLocalized || lastIncompletePath.field?.localized;
matchedField = fieldsToSearch.find((field)=>field.name === segment);
}
lastIncompletePath.field = matchedField;
if (currentPath === 'globalType' && globalSlug) {
lastIncompletePath.path = currentPath;
lastIncompletePath.complete = true;
lastIncompletePath.field = {
name: 'globalType',
type: 'text'
};
return paths;
}
if (currentPath === 'relationTo') {
lastIncompletePath.path = currentPath;
lastIncompletePath.complete = true;
lastIncompletePath.field = {
name: 'relationTo',
type: 'select',
options: Object.keys(payload.collections)
};
return paths;
}
if (!matchedField && currentPath === 'id' && i === pathSegments.length - 1) {
lastIncompletePath.path = currentPath;
const idField = {
name: 'id',
type: payload.db.defaultIDType
};
lastIncompletePath.field = idField;
lastIncompletePath.complete = true;
return paths;
}
if (matchedField) {
if ('hidden' in matchedField && matchedField.hidden && !overrideAccess) {
lastIncompletePath.invalid = true;
}
const nextSegment = pathSegments[i + 1];
const nextSegmentIsLocale = localizationConfig && localizationConfig.localeCodes.includes(nextSegment);
if (nextSegmentIsLocale) {
// Skip the next iteration, because it's a locale
i += 1;
currentPath = `${currentPath}.${nextSegment}`;
} else if (localizationConfig && fieldShouldBeLocalized({
field: matchedField,
parentIsLocalized: _parentIsLocalized
})) {
currentPath = `${currentPath}.${locale}`;
}
switch(matchedField.type){
case 'json':
case 'richText':
{
const upcomingSegments = pathSegments.slice(i + 1).join('.');
lastIncompletePath.complete = true;
lastIncompletePath.path = upcomingSegments ? `${currentPath}.${upcomingSegments}` : currentPath;
return paths;
}
case 'relationship':
case 'upload':
{
// If this is a polymorphic relation,
// We only support querying directly (no nested querying)
if (typeof matchedField.relationTo !== 'string') {
const lastSegmentIsValid = [
'relationTo',
'value'
].includes(pathSegments[pathSegments.length - 1]) || pathSegments.length === 1 || pathSegments.length === 2 && pathSegments[0] === 'version';
lastIncompletePath.path = pathSegments.join('.');
if (lastSegmentIsValid) {
lastIncompletePath.complete = true;
} else {
lastIncompletePath.invalid = true;
return paths;
}
} else {
lastIncompletePath.complete = true;
lastIncompletePath.path = currentPath;
const nestedPathToQuery = pathSegments.slice(nextSegmentIsLocale ? i + 2 : i + 1).join('.');
if (nestedPathToQuery) {
const relatedCollection = payload.collections[matchedField.relationTo].config;
const remainingPaths = getLocalizedPaths({
collectionSlug: relatedCollection.slug,
fields: relatedCollection.flattenedFields,
globalSlug,
incomingPath: nestedPathToQuery,
locale,
parentIsLocalized: false,
payload
});
paths = [
...paths,
...remainingPaths
];
}
return paths;
}
break;
}
default:
{
if (i + 1 === pathSegments.length) {
lastIncompletePath.complete = true;
}
lastIncompletePath.path = currentPath;
}
}
} else {
lastIncompletePath.invalid = true;
lastIncompletePath.path = currentPath;
return paths;
}
}
}
return paths;
}
//# sourceMappingURL=getLocalizedPaths.js.map