Skip to content

Instantly share code, notes, and snippets.

@Akryum
Last active September 16, 2022 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akryum/1a26bf4cc82b9a5cd63035aea1a374e4 to your computer and use it in GitHub Desktop.
Save Akryum/1a26bf4cc82b9a5cd63035aea1a374e4 to your computer and use it in GitHub Desktop.
Typed Meteor Methods and subscriptions
import { updateLobby, subscribeToLobby } from './lobby'
// ...
updateLobby('some-id', { title: 'Foo' })
subscribeToLobby('xxx-xxx-xxx')
import { createMethod } from './util'
export const updateLobby = createMethod('lobbies.update', z.tuple([
z.string(),
z.object({
title: z.string().min(2).max(42).optional(),
visibility: z.enum(['public', 'friends-only', 'private']).optional(),
password: z.string().optional(),
}),
]), (lobbyId, lobbyData) => {
checkLobbyRight(lobbyId)
LobbiesCollection.update(lobbyId, {
$set: lobbyData,
})
})
export const subscribeToLobby = createPublication('lobby', z.tuple([z.string()]), function (lobbyId) {
return LobbiesCollection.find(lobbyId)
})
import { Meteor } from 'meteor/meteor'
import { z } from 'zod'
export function createMethod<
TArgs extends z.ZodTuple | null,
TResult,
UnwrappedArgs extends unknown[] = TArgs extends z.ZodTuple ? z.infer<TArgs> : []
> (
name: string,
payloadSchema: TArgs,
handler: (...args: UnwrappedArgs) => TResult,
options: MethodOptions = {},
) {
Meteor.methods({
[name] (...args: unknown[]) {
if (!options.allowGuest && !Meteor.user()) {
throw new Meteor.Error('not-authorized')
}
if (payloadSchema != null) {
payloadSchema.parse(args)
} else if (args.length > 0) {
throw new Error('Unexpected arguments')
}
return handler(...args as UnwrappedArgs)
},
})
return (...args: UnwrappedArgs) => Meteor.call(name, ...args) as TResult
}
export function createPublication<
TArgs extends z.ZodTuple | null,
TResult,
UnwrappedArgs extends unknown[] = TArgs extends z.ZodTuple ? z.infer<TArgs> : []
> (
name: string,
payloadSchema: TArgs,
handler: (this: Meteor.Subscription, ...args: UnwrappedArgs) => TResult,
) {
if (Meteor.isServer) {
Meteor.publish(name, function (...args: unknown[]) {
if (payloadSchema != null) {
payloadSchema.parse(args)
} else if (args.length > 0) {
throw new Error('Unexpected arguments')
}
return handler.call(this, ...args as UnwrappedArgs)
})
}
return (...args: UnwrappedArgs) => Meteor.subscribe(name, ...args)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment