How do correctly compose custom funcitons?

I read https://stack.convex.dev/custom-functions The problem that i have is that i want to access the context given by a parent custom function. Something like this:
export const authedQuery = customQuery(query, {
args: {},
input: async (ctx) => {
return { ctx: { user }, args: {} };
},
});

export const insideOrganizationQuery = customQuery(authedQuery, {
args: { organizationId: v.id("organizations") },
input: async (ctx, { organizationId }) => {
ctx.user; // TS Error: Property 'user' does not exist
return { ctx: { }, args: {} };
},
});

export const get = insideOrganizationQuery({
handler(ctx) {
ctx.organization; // Works
ctx.user; // // TS Error: Property 'user' does not exist
},
})
export const authedQuery = customQuery(query, {
args: {},
input: async (ctx) => {
return { ctx: { user }, args: {} };
},
});

export const insideOrganizationQuery = customQuery(authedQuery, {
args: { organizationId: v.id("organizations") },
input: async (ctx, { organizationId }) => {
ctx.user; // TS Error: Property 'user' does not exist
return { ctx: { }, args: {} };
},
});

export const get = insideOrganizationQuery({
handler(ctx) {
ctx.organization; // Works
ctx.user; // // TS Error: Property 'user' does not exist
},
})
My use case would benefit of 3 nested custom queries, where the last 2 have args. Is there a pattern to allow composing them correctly, allowing the use of the additional ctx/args?
4 Replies
Convex Bot
Convex Bot3mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
Mordsith
Mordsith3mo ago
In insideOrganizationQuery, you can return additional data you would need as part of the context
customCtx(async (ctx) => {
const organization = await getOrganization();

return {
...ctx,
organization,
};
}),
customCtx(async (ctx) => {
const organization = await getOrganization();

return {
...ctx,
organization,
};
}),
Benjamín Vicente 🇨🇱
I known that, the problem is that with that I will have like 2 "branches" of functions, 🔴 custom functions and 🔵 helper functions 🔵 getAuthedUser 🔴 authedQuery; calls 🔵 getAuthedUser 🔵 getOrganization 🔴 insideOrganizationQuery; calls 🔵 getAuthedUser❗and then 🔵 getOrganization getAuthedUser is needed to be called in 2 places, and the repetition increases with the amount of custom functions. The “solution” could be have getOrganization call getAuthedUser, but what would add an aditional responsavility the now named getOrganizationAndUser function. What I'm looking for is a pattern that allows composition of those "middlewares". Wait, i thing there is a problem on the helper types
Benjamín Vicente 🇨🇱
Confirmed, added tests that pass but fail typecheck https://github.com/get-convex/convex-helpers/pull/638
GitHub
Fix types on customFunctions by benjavicente · Pull Request #638 ...
Note: Currently, this PR only adds missing test that fail type checking but correctly passes tests. Custom functions are incorrectly typed because the given query/mutation/action to extend is assu...

Did you find this page helpful?