You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm playing around with .meta in trpc-cli, and had a thought about how it might be useful to use it when creating CLIs. title and description are already used for positional parameter names and helptext. But right now, for defining shortopts users have to rely on trpc's .meta method on the procedure, which is a little awkward. This is what I'd like to do in future:
declare module '../node_modules/.pnpm/@zod+core@0.5.0/node_modules/@zod/core/dist/commonjs/registries.d.ts'{interfaceGlobalMeta{alias?: string}}test('zod4 meta',async()=>{constrouter=t.router({add: t.procedure.input(z.tuple([z.string().meta({title: 'module',description: 'The name of the module to addd',}),z.object({saveDev: z.boolean().meta({alias: 'D'}),saveExact: z.boolean().meta({alias: 'E'}),}),]),).mutation(async({input: [name,opts]})=>{returnJSON.stringify([`installing ${name} with opts:`,opts,'...'])}),})expect(awaitrun(router,['add','left-pad'])).toMatchInlineSnapshot(`"["installing left-pad with opts:",{"saveDev":false,"saveExact":false},"..."]"`,)expect(awaitrun(router,['add','left-pad','--save-dev','--save-exact'])).toMatchInlineSnapshot(`"["installing left-pad with opts:",{"saveDev":true,"saveExact":true},"..."]"`,)expect(awaitrun(router,['add','left-pad','-D','-E'])).toMatchInlineSnapshot(`"["installing left-pad with opts:",{"saveDev":true,"saveExact":true},"..."]"`,)expect(awaitrun(router,['add','left-pad','-DE'])).toMatchInlineSnapshot(`"["installing left-pad with opts:",{"saveDev":true,"saveExact":true},"..."]"`,)})
(run(...) is a helper method that roughly acts like doing node mycli.js add left-pad --save-dev --save-exact)
The zod-related part is the module augmentation that adds alias?: string to zod's GlobalMeta. I know it would be possible to use a custom registry, but it seems overkill for this - especially given this is only for type safety. Users can already do .meta({alias: 'D'}) and everything just works.
The problem with the above is the fact that GlobalMeta is part of @zod/core, not zod, so I have to use an installation-specific relative path - not very useful if I'm publishing a package. I think if GlobalMeta was part of zod I could just do:
Another problem solved by the new subpath approach! #4371
I've confirmed that you can extend this interface with a regular "zod/v4/core" import. Actually you can use "zod/v4" and "zod/v4-mini" as well because they re-export the same interface from core.
Notably, augmentations made to the interface propagate globally since they're all ultimately referencing the same interface.
import*aszfrom"zod/v4";import*aszmfrom"zod/v4-mini";declare module "zod/v4"{// or "zod/v4/core" or "zod/v4-mini"interfaceGlobalMeta{birthday: Date;}}z.string().meta({birthday: newDate(),});zm.string().register(zm.globalRegistry,{birthday: newDate(),});
Hello 👋
I'm playing around with
.meta
in trpc-cli, and had a thought about how it might be useful to use it when creating CLIs.title
anddescription
are already used for positional parameter names and helptext. But right now, for defining shortopts users have to rely on trpc's.meta
method on the procedure, which is a little awkward. This is what I'd like to do in future:(
run(...)
is a helper method that roughly acts like doingnode mycli.js add left-pad --save-dev --save-exact
)The zod-related part is the module augmentation that adds
alias?: string
to zod's GlobalMeta. I know it would be possible to use a custom registry, but it seems overkill for this - especially given this is only for type safety. Users can already do.meta({alias: 'D'})
and everything just works.The problem with the above is the fact that
GlobalMeta
is part of@zod/core
, notzod
, so I have to use an installation-specific relative path - not very useful if I'm publishing a package. I think ifGlobalMeta
was part ofzod
I could just do:I'm not sure exactly the best way to do that - is
zod
now just a thin wrapper for@zod/core
?The text was updated successfully, but these errors were encountered: