diff --git a/convex/_generated/api.d.ts b/convex/_generated/api.d.ts index ec93670..93e8a3e 100644 --- a/convex/_generated/api.d.ts +++ b/convex/_generated/api.d.ts @@ -20,6 +20,7 @@ import type * as functions from "../functions.js"; import type * as games from "../games.js"; import type * as lib_functions from "../lib/functions.js"; import type * as lib_middlewareUtils from "../lib/middlewareUtils.js"; +import type * as lib_validators from "../lib/validators.js"; import type * as message from "../message.js"; import type * as model_cards from "../model/cards.js"; import type * as model_game from "../model/game.js"; @@ -49,6 +50,7 @@ declare const fullApi: ApiFromModules<{ games: typeof games; "lib/functions": typeof lib_functions; "lib/middlewareUtils": typeof lib_middlewareUtils; + "lib/validators": typeof lib_validators; message: typeof message; "model/cards": typeof model_cards; "model/game": typeof model_game; diff --git a/convex/dealCards.ts b/convex/dealCards.ts index d556505..e735672 100644 --- a/convex/dealCards.ts +++ b/convex/dealCards.ts @@ -2,26 +2,12 @@ import { PaginationResult, paginationOptsValidator } from 'convex/server' import { v } from 'convex/values' import { Doc } from './_generated/dataModel' import { queryWithEnt } from './lib/functions' +import { betterV } from './lib/validators' export default queryWithEnt({ args: { gameId: v.id('Games'), paginationOpts: paginationOptsValidator }, returns: v.object({ - page: v.array( - v.object({ - GameId: v.id('Games'), - blue: v.boolean(), - green: v.boolean(), - orange: v.boolean(), - proset: v.union(v.null(), v.id('Prosets')), - purple: v.boolean(), - rank: v.float64(), - red: v.boolean(), - selectedBy: v.union(v.null(), v.id('Players')), - yellow: v.boolean(), - _id: v.id('PlayingCards'), - _creationTime: v.number(), - }) - ), + page: v.array(betterV.doc('PlayingCards')), isDone: v.boolean(), continueCursor: v.string(), splitCursor: v.optional(v.union(v.string(), v.null())), diff --git a/convex/games.ts b/convex/games.ts index c9e50b2..8f62659 100644 --- a/convex/games.ts +++ b/convex/games.ts @@ -5,6 +5,7 @@ import { mutationWithGame, queryWithGame, } from './lib/functions' +import { betterV } from './lib/validators' import * as Games from './model/game' import * as Players from './model/player' import * as User from './model/user' @@ -75,23 +76,15 @@ const playerFields = { export const getInfo = queryWithGame({ args: {}, returns: v.object({ - game: v.object({ - name: v.string(), - selectingPlayer: v.union(v.null(), v.id('Players')), - selectionStartTime: v.union(v.null(), v.number()), - inProgress: v.boolean(), - isPublic: v.optional(v.boolean()), - // system fields - _id: v.id('Games'), - _creationTime: v.number(), - // fields added by ents - }), - currentPlayer: v.object({ - ...playerFields, - isGuest: v.boolean(), - showOnboarding: v.boolean(), - }), - otherPlayers: v.array(v.object(playerFields)), + game: betterV.doc('Games'), + currentPlayer: betterV.mergeObjects( + betterV.doc('Players'), + v.object({ + isGuest: v.boolean(), + showOnboarding: v.boolean(), + }) + ), + otherPlayers: v.array(betterV.doc('Players')), // record playerToProsets: v.any(), }), diff --git a/convex/lib/validators.ts b/convex/lib/validators.ts new file mode 100644 index 0000000..2e80bb0 --- /dev/null +++ b/convex/lib/validators.ts @@ -0,0 +1,37 @@ +import { Validator, v } from 'convex/values' +import { Doc, TableNames } from '../_generated/dataModel' +import schema from '../schema' + +export const betterV = { + id: (tableName: T) => { + return v.id(tableName) + }, + doc: (tableName: T): Validator, false, any> => { + const validator = v.object( + (schema.tables[tableName] as any).documentSchema + ) as Validator + if (validator?.kind !== 'object') { + throw new Error(`Not an object validator`) + } + return v.object({ + ...validator.fields, + _id: v.id(tableName), + _creationTime: v.number(), + }) + }, + mergeObjects: < + O1 extends Record, + O2 extends Record + >( + validator1: Validator, + validator2: Validator + ): Validator & O2, false, any> => { + if (validator1.kind !== 'object' || validator2.kind !== 'object') { + throw new Error('Not object validators') + } + return v.object({ + ...validator1.fields, + ...validator2.fields, + }) as any + }, +} diff --git a/convex/message.ts b/convex/message.ts index d716ea0..73741c8 100644 --- a/convex/message.ts +++ b/convex/message.ts @@ -2,6 +2,7 @@ import { v } from 'convex/values' import { Doc } from './_generated/dataModel' import { internalMutation } from './_generated/server' import { mutationWithGame, queryWithGame } from './lib/functions' +import { betterV } from './lib/validators' import * as Message from './model/message' export const send = mutationWithGame({ @@ -28,15 +29,7 @@ export const remove = internalMutation({ export const list = queryWithGame({ args: {}, - returns: v.array( - v.object({ - content: v.string(), - player: v.union(v.null(), v.string()), - GameId: v.id('Games'), - _id: v.id('Messages'), - _creationTime: v.number(), - }) - ), + returns: v.array(betterV.doc('Messages')), handler: async (ctx): Promise>> => { const messages = await ctx.game.edge('Messages') return messages.filter( diff --git a/convex/users.ts b/convex/users.ts index 8358fcc..73432b5 100644 --- a/convex/users.ts +++ b/convex/users.ts @@ -1,5 +1,6 @@ import { v } from 'convex/values' import { mutationWithEnt, queryWithEnt } from './lib/functions' +import { betterV } from './lib/validators' import * as User from './model/user' export const getOrCreate = mutationWithEnt({ @@ -13,21 +14,7 @@ export const getOrCreate = mutationWithEnt({ export const getOrNull = queryWithEnt({ args: { sessionId: v.string() }, - returns: v.union( - v.null(), - v.object({ - // system fields - _id: v.id('Users'), - _creationTime: v.number(), - // fields I copied from my schema - name: v.string(), - showOnboarding: v.boolean(), - isGuest: v.boolean(), - // field with a unique constraint - identifier: v.string(), - // ent fields that I had to kinda guess and check - }) - ), + returns: v.union(v.null(), betterV.doc('Users')), handler: async (ctx, { sessionId }) => { const userOrNull = await User.getOrNull(ctx, { sessionId }) if (userOrNull !== null) { diff --git a/package-lock.json b/package-lock.json index 2ef3a26..6fc0341 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@mui/material": "^5.12.1", "@types/react-transition-group": "^4.4.5", "canvas-confetti": "^1.6.0", - "convex": "file:../convex-helpers/convex-1.12.1.tgz", + "convex": "file:../convex/npm-packages/convex/convex-1.12.1.tgz", "convex-ents": "^0.7.6", "convex-helpers": "file:../convex-helpers/packages/convex-helpers/convex-helpers-0.1.41.tgz", "itertools": "^1.7.1", @@ -2148,8 +2148,8 @@ }, "node_modules/convex": { "version": "1.12.1", - "resolved": "file:../convex-helpers/convex-1.12.1.tgz", - "integrity": "sha512-A0syb8XPaeHzyVj0340L7zBiTWbwQcXDkSFRdyRoS2TeQ0vVemHSrHQj5uqmdnlxMuTctwMKAi+zLoftuU6IAg==", + "resolved": "file:../convex/npm-packages/convex/convex-1.12.1.tgz", + "integrity": "sha512-6G6DOivON75Ts8oMTwGfldWIlZmnIBT+fL0UdoQuwVXLmfQMTKoerfpC+ZwTMlr5mtDzxn9sQTjf9+q5zOgPoA==", "license": "Apache-2.0", "dependencies": { "esbuild": "^0.17.5", @@ -7261,8 +7261,8 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "convex": { - "version": "file:../convex-helpers/convex-1.12.1.tgz", - "integrity": "sha512-A0syb8XPaeHzyVj0340L7zBiTWbwQcXDkSFRdyRoS2TeQ0vVemHSrHQj5uqmdnlxMuTctwMKAi+zLoftuU6IAg==", + "version": "file:../convex/npm-packages/convex/convex-1.12.1.tgz", + "integrity": "sha512-6G6DOivON75Ts8oMTwGfldWIlZmnIBT+fL0UdoQuwVXLmfQMTKoerfpC+ZwTMlr5mtDzxn9sQTjf9+q5zOgPoA==", "requires": { "esbuild": "^0.17.5", "jwt-decode": "^3.1.2", diff --git a/package.json b/package.json index b72eaa4..68ec88e 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@mui/material": "^5.12.1", "@types/react-transition-group": "^4.4.5", "canvas-confetti": "^1.6.0", - "convex": "file:../convex-helpers/convex-1.12.1.tgz", + "convex": "file:../convex/npm-packages/convex/convex-1.12.1.tgz", "convex-ents": "^0.7.6", "convex-helpers": "file:../convex-helpers/packages/convex-helpers/convex-helpers-0.1.41.tgz", "itertools": "^1.7.1",