-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
I tried to get this working but couldn't get it.
import { z as zod, ZodTypeAny, ZodObject, ZodRawShape } from 'zod';
import {
initTRPC,
inferRouterInputs,
inferRouterOutputs,
procedure as TRPCProcedure,
ProcedureBuilder,
} from '@trpc/server';
import { customErrorFormatter, hasRole } from '../../util/rpc';
import { dateFromString } from '../../util/zod';
import type { RouterContext } from '../../types';
import { Query, getQueryInput, inferRouterOutputs } from '../../schema';
// Define available entity names (capitalize first letter as used in dynamic names)
type EntityName = keyof typeof Entities;
type CapitalizedEntityName = Capitalize<EntityName>;
// Define possible service method names based on the entity name
type ServiceMethods<N extends string> = `get${N}` | `get${N}s` | `create${N}` | `update${N}`;
// Define the service type
type CoreService = {
[K in ServiceMethods<CapitalizedEntityName>]: (input: any, ctx: RouterContext) => any;
};
// Utility type for ensuring the return type matches a ProcedureBuilder
type ProcedureType = ProcedureBuilder<RouterContext, object, object, any, any, any, any, boolean>;
// Define a type for entity procedures using template literal types
type EntityProcedures<N extends CapitalizedEntityName> = {
[K in ServiceMethods<N>]: ProcedureType;
};
// Utility function to create standard procedures for an entity
function createEntityProcedures<N extends CapitalizedEntityName>(
entity: ZodObject<ZodRawShape>,
entityName: N
): EntityProcedures<N> {
return {
[`get${entityName}`]: procedure
.use(hasRole('guest', t))
.use(customErrorFormatter(t))
.input(getQueryInput(entity))
.output(entity)
.query(({ input, ctx }) => (ctx.app.service.Core[`get${entityName}` as keyof CoreService] as any)(input, ctx)),
[`get${entityName}s`]: procedure
.use(hasRole('guest', t))
.use(customErrorFormatter(t))
.input(getQueryInput(entity))
.output(entity.array())
.query(({ input, ctx }) => (ctx.app.service.Core[`get${entityName}s` as keyof CoreService] as any)(input, ctx)),
[`create${entityName}`]: procedure
.use(hasRole('admin', t))
.use(customErrorFormatter(t))
.input(getQueryInput(entity))
.output(entity.pick({ id: true }))
.mutation(({ input, ctx }) =>
(ctx.app.service.Core[`create${entityName}` as keyof CoreService] as any)(input, ctx)
),
[`update${entityName}`]: procedure
.use(hasRole('admin', t))
.use(customErrorFormatter(t))
.input(getQueryInput(entity))
.output(entity.pick({ id: true }))
.mutation(({ input, ctx }) =>
(ctx.app.service.Core[`update${entityName}` as keyof CoreService] as any)(input, ctx)
),
} as EntityProcedures<N>;
}
// Dynamically create all procedures using the utility function
const entityProcedures = Object.keys(Entities).reduce((acc, entityName) => {
const entitySchema = Entities[entityName as keyof typeof Entities];
if (!entitySchema || !(entitySchema instanceof z.ZodObject)) return acc; // Ensure the schema is a ZodObject
const capitalizedEntityName = (entityName.charAt(0).toUpperCase() + entityName.slice(1)) as CapitalizedEntityName;
return { ...acc, ...createEntityProcedures(entitySchema, capitalizedEntityName) };
}, {} as Record<string, ProcedureType>);
export const createRouter = () =>
router({
...entityProcedures
})
Metadata
Metadata
Assignees
Labels
No labels