Štosdenfer
Štosdenfer2w ago

Issues with multiple repo api generation

I'm having issues generating an API to use in another repository. It is too late for me now to switch to monorepo, that's maybe something for the future, but right now launch is near and I would like to get it working with how it is. The generated API file gives a lot of "any" errors. I don't mind fixing this manually, but I would need some guidance because I can't figure out what's supposed to go where. Here are some snippets
// part of generated api file
export type PublicApiType = {
priceHistory: {
addPrice: FunctionReference<
"mutation",
"public",
{ price: number; setBy: string },
any
>;
getLatestPrice: FunctionReference<"query", "public", any, any>;
};
}
// part of generated api file
export type PublicApiType = {
priceHistory: {
addPrice: FunctionReference<
"mutation",
"public",
{ price: number; setBy: string },
any
>;
getLatestPrice: FunctionReference<"query", "public", any, any>;
};
}
// priceHistory.ts
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";

export const addPrice = mutation({
args: {
price: v.number(),
setBy: v.string(),
},
handler: async (ctx, args) => {
// check auth
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Not authenticated");
}

await ctx.db.insert("price_history", {
...args,
});
},
});

export const getLatestPrice = query({
handler: async (ctx) => {
return await ctx.db.query("price_history").order("desc").first();
},
});
// priceHistory.ts
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";

export const addPrice = mutation({
args: {
price: v.number(),
setBy: v.string(),
},
handler: async (ctx, args) => {
// check auth
const identity = await ctx.auth.getUserIdentity();
if (identity === null) {
throw new Error("Not authenticated");
}

await ctx.db.insert("price_history", {
...args,
});
},
});

export const getLatestPrice = query({
handler: async (ctx) => {
return await ctx.db.query("price_history").order("desc").first();
},
});
// part of schema
export default defineSchema({
price_history: defineTable({
price: v.number(),
setBy: v.string(),
}),
)}
// part of schema
export default defineSchema({
price_history: defineTable({
price: v.number(),
setBy: v.string(),
}),
)}
7 Replies
Convex Bot
Convex Bot2w 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!
Štosdenfer
ŠtosdenferOP2w ago
Yeah I just can't get it to work. I'm thinking of just copy pasteing the functions files between folders to keep them the same... I actually managed to manually fix most of the any errors, but I got an error somehwere that the call is missing a lot of elements like pick, omit... so I figured it's a deeper issue or I did something wrong I guess that's why it's in beta or I'm doing something wrong I dont know...
Clever Tagline
Can you share more details about the errors you're seeing? You say that they're "any" errors, but that's pretty vague. More details about your project stack would also be helpful: version numbers, framework, etc. (see #⚠️ PLEASE READ BEFORE POSTING ⚠️ ) You also said "I guess that's why it's in beta." What was that in reference to?
deen
deen7d ago
you need to add return validators to your functions. the return types you can normally use are inferred by typescript. they don't have like a "physical" source or definition. but your functions args and and table data do - the args validators and table validators. you can't materialize the inferred types into a portable form. therefore your functions return any. this is frustrating at first, but clever reuse of your existing validators makes it easier - especially with the new pick/omit/nullable helpers built in.
Štosdenfer
ŠtosdenferOP6d ago
I was gonna reply to this after the launch and deal with it, but @deen I think hit the nail on the head. I'm going to try what deen said and come back. Sorry if my initial issue didn't have enough info, I'll do better on next ones. And the beta comment was too much on my end, I didn't mean no harm @deen is there no better way to validate return values of objects from databse than manually adding the system fields?
export const getLatestPrice = query({
returns: v.union(
v.object({
_id: v.id("price_history"),
_creationTime: v.number(),
price: v.number(),
setBy: v.string(),
}),
v.null(),
),
handler: async (ctx) => {
return await ctx.db.query("price_history").order("desc").first();
},
});
export const getLatestPrice = query({
returns: v.union(
v.object({
_id: v.id("price_history"),
_creationTime: v.number(),
price: v.number(),
setBy: v.string(),
}),
v.null(),
),
handler: async (ctx) => {
return await ctx.db.query("price_history").order("desc").first();
},
});
// schema
export default defineSchema({
price_history: defineTable({
price: v.number(),
setBy: v.string(),
}),
});
// schema
export default defineSchema({
price_history: defineTable({
price: v.number(),
setBy: v.string(),
}),
});
Also, I'm noticing that internal actions don't get typed to this api. It's just an empty object being any. I think for this a monorepo is probably a better solution. Seems like to me at least Maybe I'm wrong
deen
deen6d ago
do it once, and share the validator. something like vPriceHistoryReturn. the non system fields can be retrieve from your schema object, from something like schema.tables.price_history.validator, or you could define the table validator separately. there's also a nullable( ) convex helper that is very useful for return types. i'm not sure about that one, it should work? although i haven't used one there in a while. i would favour a monorepo over doing this personally, but it's up to you. it sonuds like you could make the process a bit more efficient still
Štosdenfer
ŠtosdenferOP5d ago
thank you for the help! I'll try and refactor both projects to a monorepo never done a monorepo before so should be fun

Did you find this page helpful?