Skip to content

Instantly share code, notes, and snippets.

@izakfilmalter
Last active January 7, 2024 14:39
Show Gist options
  • Save izakfilmalter/0a7e6d902e0260deea0a705da30461de to your computer and use it in GitHub Desktop.
Save izakfilmalter/0a7e6d902e0260deea0a705da30461de to your computer and use it in GitHub Desktop.
Type safe trigger client
import { triggerRouter } from './trigger'
triggerClient.defineJob({
id: 'some-event',
name: 'Some event.',
version: '0.0.1',
trigger: eventTrigger(triggerRouter.someEvent),
run: async (payload, io) => {
await sendTriggerIOEvent(
io.sendEvent,
'someEventAgain',
'someEvent',
{
userId: payload.userId
},
)
}
)
import { TriggerClient } from '@trigger.dev/sdk'
import { buildTriggerClient, triggerRouter } from './triggerTypes'
export const runtime = 'node'
export const triggerClient = new TriggerClient({
})
export const sendTriggerEvent = buildTriggerClient(
triggerRouter,
// eslint-disable-next-line @typescript-eslint/unbound-method
triggerClient.sendEvent,
)
export const sendTriggerIOEvent = buildTriggerIO(triggerRouter)
import type { DeserializedJson } from '@trigger.dev/core'
import type { TriggerClient } from '@trigger.dev/sdk'
import { z } from 'zod'
type JsonZod = z.ZodString | z.ZodNumber | z.ZodBoolean
type SafeZodObject = z.ZodObject<Record<string, JsonZod>>
type Input<TShape extends SafeZodObject> = {
name: string
schema: TShape
}
const fn: <TShape extends SafeZodObject>(
input: Input<TShape>,
ingestFunc: (input: z.infer<TShape>) => void,
) => Input<TShape> = (i) => i
const router: <T>(input: T) => T = (i) => i
const trigger = { fn, router }
const buildClientHelper: <
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TRouter extends Record<string, Input<any>>,
TKey extends keyof TRouter,
>(
router: TRouter,
sendEvent: TriggerClient['sendEvent'],
) => (
event: TKey,
input: z.infer<TRouter[TKey]['schema']>,
) => Promise<{
id: string
name: string
payload:
| ((
| string
| number
| boolean
| Record<string, DeserializedJson>
| Array<DeserializedJson>
) &
(
| string
| number
| boolean
| Record<string, DeserializedJson>
| Array<DeserializedJson>
| undefined
))
| null
timestamp: Date
context?: DeserializedJson | undefined
deliverAt?: Date | null | undefined
deliveredAt?: Date | null | undefined
cancelledAt?: Date | null | undefined
}> = (_, sendEvent) => (event, input) =>
sendEvent({ name: event as string, payload: input })
const buildIOClientHelper: <
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TRouter extends Record<string, Input<any>>,
TKey extends keyof TRouter,
>(
router: TRouter,
) => (
sendEvent: IO['sendEvent'],
key: string,
event: TKey,
input: z.infer<TRouter[TKey]['schema']>,
) => Promise<{
id: string
name: string
payload:
| ((
| string
| number
| boolean
| Record<string, _trigger_dev_core.DeserializedJson>
| Array<_trigger_dev_core.DeserializedJson>
) &
(
| string
| number
| boolean
| Record<string, _trigger_dev_core.DeserializedJson>
| Array<_trigger_dev_core.DeserializedJson>
| undefined
))
| null
timestamp: Date
context?: _trigger_dev_core.DeserializedJson | undefined
deliverAt?: Date | null | undefined
deliveredAt?: Date | null | undefined
cancelledAt?: Date | null | undefined
}> = () => (sendEvent, key, event, input) =>
sendEvent(key, { name: event as string, payload: input })
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const buildTriggerClient = <TRouter extends Record<string, Input<any>>>(
passedRouter: TRouter,
sendEvent: TriggerClient['sendEvent'],
) => buildClientHelper<TRouter, keyof TRouter>(passedRouter, sendEvent)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const buildTriggerIO = <TRouter extends Record<string, Input<any>>>(
passedRouter: TRouter,
) => buildIOClientHelper<TRouter, keyof TRouter>(passedRouter)
export const triggerRouter = trigger.router({
someEvent: {
name: 'someEvent',
schema: z.object({
userId: z.string(),
}),
},
})
import { sendTriggerEvent } from './trigger'
const test = async () => {
await sendTriggerEvent('someEvent', {
userId: 'My User Id',
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment