Skip to content

Commit

Permalink
handle nested object in sourceArgs map (#5730)
Browse files Browse the repository at this point in the history
* handle nested object in sourceArgs map

* run prettier

* changeset
  • Loading branch information
EmrysMyrddin authored Jul 25, 2023
1 parent 1c808b3 commit d1310cd
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 151 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-comics-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-mesh/utils': patch
---

Allow nested objects as `sourceArgs` argument of `@resolveTo` and `additionalResolvers`
170 changes: 19 additions & 151 deletions packages/utils/src/resolve-additional-resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,16 +264,14 @@ export function resolveAdditionalResolversWithoutImport(
}
const resolverData = { root, args, context, info, env: process.env };
const targetArgs: any = {};
for (const argPath in additionalResolver.sourceArgs) {
dset(
targetArgs,
argPath,
stringInterpolator.parse(
additionalResolver.sourceArgs[argPath].toString(),
resolverData,
),
);
}

deeplySetArgs(
resolverData,
{ targetArgs },
'targetArgs',
additionalResolver.sourceArgs,
);

const options: any = {
...baseOptions,
root,
Expand Down Expand Up @@ -321,148 +319,18 @@ export function resolveAdditionalResolvers(

return resolvers;
} else {
const baseOptions: any = {};
if (additionalResolver.result) {
baseOptions.valuesFromResults = generateValuesFromResults(additionalResolver.result);
}
if ('pubsubTopic' in additionalResolver) {
return {
[additionalResolver.targetTypeName]: {
[additionalResolver.targetFieldName]: {
subscribe: withFilter(
(root, args, context, info) => {
const resolverData = { root, args, context, info, env: process.env };
const topic = stringInterpolator.parse(
additionalResolver.pubsubTopic,
resolverData,
);
return pubsub.asyncIterator(topic) as AsyncIterableIterator<any>;
},
(root, args, context, info) => {
return additionalResolver.filterBy
? // eslint-disable-next-line no-new-func
new Function(`return ${additionalResolver.filterBy}`)()
: true;
},
),
resolve: (payload: any) => {
if (baseOptions.valuesFromResults) {
return baseOptions.valuesFromResults(payload);
}
return payload;
},
},
},
};
} else if ('keysArg' in additionalResolver) {
return {
[additionalResolver.targetTypeName]: {
[additionalResolver.targetFieldName]: {
selectionSet:
additionalResolver.requiredSelectionSet || `{ ${additionalResolver.keyField} }`,
resolve: async (root: any, args: any, context: any, info: any) => {
if (!baseOptions.selectionSet) {
baseOptions.selectionSet = generateSelectionSetFactory(
info.schema,
additionalResolver,
);
}
const resolverData = { root, args, context, info, env: process.env };
const targetArgs: any = {};
for (const argPath in additionalResolver.additionalArgs || {}) {
dset(
targetArgs,
argPath,
stringInterpolator.parse(
additionalResolver.additionalArgs[argPath],
resolverData,
),
);
}
const options: any = {
...baseOptions,
root,
context,
info,
argsFromKeys: (keys: string[]) => {
const args: any = {};
dset(args, additionalResolver.keysArg, keys);
Object.assign(args, targetArgs);
return args;
},
key: lodashGet(root, additionalResolver.keyField),
};
return context[additionalResolver.sourceName][additionalResolver.sourceTypeName][
additionalResolver.sourceFieldName
](options);
},
},
},
};
} else if ('targetTypeName' in additionalResolver) {
return {
[additionalResolver.targetTypeName]: {
[additionalResolver.targetFieldName]: {
selectionSet: additionalResolver.requiredSelectionSet,
resolve: (root: any, args: any, context: any, info: GraphQLResolveInfo) => {
// Assert source exists
if (!context[additionalResolver.sourceName]) {
throw new Error(`No source found named "${additionalResolver.sourceName}"`);
}
if (!context[additionalResolver.sourceName][additionalResolver.sourceTypeName]) {
throw new Error(
`No root type found named "${additionalResolver.sourceTypeName}" exists in the source ${additionalResolver.sourceName}\n` +
`It should be one of the following; ${Object.keys(
context[additionalResolver.sourceName],
).join(',')})}}`,
);
}
if (
!context[additionalResolver.sourceName][additionalResolver.sourceTypeName][
additionalResolver.sourceFieldName
]
) {
throw new Error(
`No field named "${additionalResolver.sourceFieldName}" exists in the type ${additionalResolver.sourceTypeName} from the source ${additionalResolver.sourceName}`,
);
}

if (!baseOptions.selectionSet) {
baseOptions.selectionSet = generateSelectionSetFactory(
info.schema,
additionalResolver,
);
}
const resolverData = { root, args, context, info, env: process.env };
const targetArgs: any = {};
for (const argPath in additionalResolver.sourceArgs) {
dset(
targetArgs,
argPath,
stringInterpolator.parse(
additionalResolver.sourceArgs[argPath].toString(),
resolverData,
),
);
}
const options: any = {
...baseOptions,
root,
args: targetArgs,
context,
info,
};
return context[additionalResolver.sourceName][additionalResolver.sourceTypeName][
additionalResolver.sourceFieldName
](options);
},
},
},
};
} else {
return additionalResolver;
}
return resolveAdditionalResolversWithoutImport(additionalResolver, pubsub);
}
}),
);
}

function deeplySetArgs(resolverData: any, args: object, path: string, value: any) {
if (typeof value === 'string') {
dset(args, path, stringInterpolator.parse(value.toString(), resolverData));
} else {
for (const key in value) {
deeplySetArgs(resolverData, args, `${path}.${key}`, value[key]);
}
}
}

0 comments on commit d1310cd

Please sign in to comment.