* Prepares query args for extended result fields (recursive): * - Strips ext result field names from `select` and `omit` * - Injects `needs` fields into `select` when ext result fields are explicitly selected * - Recurses into `include` and `select` for nested relation fields
(args: unknown, model: string, schema: SchemaDef, plugins: AnyPlugin[])
| 973 | * - Recurses into `include` and `select` for nested relation fields |
| 974 | */ |
| 975 | function prepareArgsForExtResult(args: unknown, model: string, schema: SchemaDef, plugins: AnyPlugin[]): unknown { |
| 976 | if (!args || typeof args !== 'object') { |
| 977 | return args; |
| 978 | } |
| 979 | |
| 980 | const extResultDefs = collectExtResultFieldDefs(model, schema, plugins); |
| 981 | const typedArgs = args as Record<string, unknown>; |
| 982 | let result = typedArgs; |
| 983 | let changed = false; |
| 984 | |
| 985 | const select = typedArgs['select'] as Record<string, unknown> | undefined; |
| 986 | const omit = typedArgs['omit'] as Record<string, unknown> | undefined; |
| 987 | const include = typedArgs['include'] as Record<string, unknown> | undefined; |
| 988 | |
| 989 | if (select && extResultDefs.size > 0) { |
| 990 | const newSelect = { ...select }; |
| 991 | for (const [fieldName, fieldDef] of extResultDefs) { |
| 992 | if (newSelect[fieldName]) { |
| 993 | delete newSelect[fieldName]; |
| 994 | // inject needs fields |
| 995 | for (const needField of Object.keys(fieldDef.needs)) { |
| 996 | if (!newSelect[needField]) { |
| 997 | newSelect[needField] = true; |
| 998 | } |
| 999 | } |
| 1000 | } |
| 1001 | } |
| 1002 | result = { ...result, select: newSelect }; |
| 1003 | changed = true; |
| 1004 | } |
| 1005 | |
| 1006 | if (omit && extResultDefs.size > 0) { |
| 1007 | const newOmit = { ...omit }; |
| 1008 | for (const [fieldName, fieldDef] of extResultDefs) { |
| 1009 | if (newOmit[fieldName]) { |
| 1010 | // strip ext result field names from omit (they don't exist in the DB) |
| 1011 | delete newOmit[fieldName]; |
| 1012 | } else { |
| 1013 | // this ext result field is active — ensure its needs are not omitted |
| 1014 | for (const needField of Object.keys(fieldDef.needs)) { |
| 1015 | if (newOmit[needField]) { |
| 1016 | delete newOmit[needField]; |
| 1017 | } |
| 1018 | } |
| 1019 | } |
| 1020 | } |
| 1021 | result = { ...result, omit: newOmit }; |
| 1022 | changed = true; |
| 1023 | } |
| 1024 | |
| 1025 | // Recurse into nested relations in `include` |
| 1026 | if (include) { |
| 1027 | const newInclude = { ...include }; |
| 1028 | let includeChanged = false; |
| 1029 | for (const [field, value] of Object.entries(newInclude)) { |
| 1030 | if (value && typeof value === 'object') { |
| 1031 | const fieldDef = getField(schema, model, field); |
| 1032 | if (fieldDef?.relation) { |
no test coverage detected