8000 Allow module augmentation of global registry? · Issue #4328 · colinhacks/zod · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Allow module augmentation of global registry? #4328
Closed
@mmkal

Description

@mmkal

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 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' {
  interface GlobalMeta {
    alias?: string
  }
}

test('zod4 meta', async () => {
  const router = 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]}) => {
        return JSON.stringify([`installing ${name} with opts:`, opts, '...'])
      }),
  })

  expect(await run(router, ['add', 'left-pad'])).toMatchInlineSnapshot(
    `"["installing left-pad with opts:",{"saveDev":false,"saveExact":false},"..."]"`,
  )

  expect(await run(router, ['add', 'left-pad', '--save-dev', '--save-exact'])).toMatchInlineSnapshot(
    `"["installing left-pad with opts:",{"saveDev":true,"saveExact":true},"..."]"`,
  )

  expect(await run(router, ['add', 'left-pad', '-D', '-E'])).toMatchInlineSnapshot(
    `"["installing left-pad with opts:",{"saveDev":true,"saveExact":true},"..."]"`,
  )

  expect(await run(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:

declare module 'zod' {
  interface GlobalMeta {
    alias?: string
  }
}

I'm not sure exactly the best way to do that - is zod now just a thin wrapper for @zod/core?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0