feat: recursive saveToJWT field support (#3130)

This commit is contained in:
Dan Ribbens
2023-08-08 12:38:44 -04:00
committed by GitHub
parent 8e188cfe61
commit c6e0908076
6 changed files with 261 additions and 25 deletions

View File

@@ -1,7 +1,99 @@
/* eslint-disable no-param-reassign */
import { User } from '..';
import { CollectionConfig } from '../../collections/config/types';
import { Field, fieldAffectsData, fieldHasSubFields } from '../../fields/config/types';
import { Field, fieldAffectsData, TabAsField, tabHasName } from '../../fields/config/types';
type TraverseFieldsArgs = {
fields: (Field | TabAsField)[]
data: Record<string, unknown>
result: Record<string, unknown>
}
const traverseFields = ({
// parent,
fields,
data,
result,
}: TraverseFieldsArgs) => {
fields.forEach((field) => {
switch (field.type) {
case 'row':
case 'collapsible': {
traverseFields({
fields: field.fields,
data,
result,
});
break;
}
case 'group': {
let targetResult;
if (typeof field.saveToJWT === 'string') {
targetResult = field.saveToJWT;
result[field.saveToJWT] = data[field.name];
} else if (field.saveToJWT) {
targetResult = field.name;
result[field.name] = data[field.name];
}
const groupData: Record<string, unknown> = data[field.name] as Record<string, unknown>;
const groupResult = (targetResult ? result[targetResult] : result) as Record<string, unknown>;
traverseFields({
fields: field.fields,
data: groupData,
result: groupResult,
});
break;
}
case 'tabs': {
traverseFields({
fields: field.tabs.map((tab) => ({ ...tab, type: 'tab' })),
data,
result,
});
break;
}
case 'tab': {
if (tabHasName(field)) {
let targetResult;
if (typeof field.saveToJWT === 'string') {
targetResult = field.saveToJWT;
result[field.saveToJWT] = data[field.name];
} else if (field.saveToJWT) {
targetResult = field.name;
result[field.name] = data[field.name];
}
const tabData: Record<string, unknown> = data[field.name] as Record<string, unknown>;
const tabResult = (targetResult ? result[targetResult] : result) as Record<string, unknown>;
traverseFields({
fields: field.fields,
data: tabData,
result: tabResult,
});
} else {
traverseFields({
fields: field.fields,
data,
result,
});
}
break;
}
default:
if (fieldAffectsData(field)) {
if (field.saveToJWT) {
if (typeof field.saveToJWT === 'string') {
result[field.saveToJWT] = data[field.name];
delete result[field.name];
} else {
result[field.name] = data[field.name] as Record<string, unknown>;
}
} else if (field.saveToJWT === false) {
delete result[field.name];
}
}
}
});
return result;
};
export const getFieldsToSign = (args: {
collectionConfig: CollectionConfig,
user: User
@@ -13,28 +105,17 @@ export const getFieldsToSign = (args: {
email,
} = args;
return collectionConfig.fields.reduce((signedFields, field: Field) => {
const result = {
...signedFields,
};
// get subfields from non-named fields like rows
if (!fieldAffectsData(field) && fieldHasSubFields(field)) {
field.fields.forEach((subField) => {
if (fieldAffectsData(subField) && subField.saveToJWT) {
result[typeof subField.saveToJWT === 'string' ? subField.saveToJWT : subField.name] = user[subField.name];
}
});
}
if (fieldAffectsData(field) && field.saveToJWT) {
result[typeof field.saveToJWT === 'string' ? field.saveToJWT : field.name] = user[field.name];
}
return result;
}, {
const result: Record<string, unknown> = {
email,
id: user.id,
collection: collectionConfig.slug,
};
traverseFields({
fields: collectionConfig.fields,
data: user,
result,
});
return result;
};

View File

@@ -228,6 +228,10 @@ const tab = baseField.keys({
.when('localized', { is: joi.exist(), then: joi.required() }),
localized: joi.boolean(),
interfaceName: joi.string().when('name', { not: joi.exist(), then: joi.forbidden() }),
saveToJWT: joi.alternatives().try(
joi.boolean(),
joi.string(),
),
label: joi.alternatives().try(
joi.string(),
joi.object().pattern(joi.string(), [joi.string()]),

View File

@@ -234,6 +234,7 @@ export type TabsAdmin = Omit<Admin, 'description'>;
type TabBase = Omit<FieldBase, 'required' | 'validation'> & {
fields: Field[]
saveToJWT?: boolean | string
description?: Description
interfaceName?: string
}
@@ -256,7 +257,7 @@ export type UnnamedTab = Omit<TabBase, 'name'> & {
export type Tab = NamedTab | UnnamedTab
export type TabsField = Omit<FieldBase, 'admin' | 'name' | 'localized'> & {
export type TabsField = Omit<FieldBase, 'admin' | 'name' | 'localized' | 'saveToJWT'> & {
type: 'tabs';
tabs: Tab[]
admin?: TabsAdmin