Skip to content

Conversation

@m1212e
Copy link

@m1212e m1212e commented Jul 6, 2025

This would allow granular imports from the specific function modules and would remove the necessity of having all three validator libraries in the dependencies.

@m1212e
Copy link
Author

m1212e commented Jul 6, 2025

I also added an export for the guard since that would make a lot of sense for checking at runtime which specific module should be applied. Unfortunately, node10 can't resolve the guard export and I have no idea why. Maybe you have an idea on this?

@m1212e
Copy link
Author

m1212e commented Jul 17, 2025

Hey, @sinclairzx81, did you maybe have time to take a look yet/do you have any questions?

@sinclairzx81
Copy link
Owner

@m1212e Hi,

Hey sorry for the delay on getting to this PR. Have been exceptionally busy with other projects of late, and have been in a state of trying to catch up on various issues and PR's. I think this PR is a good one tho, so can go ahead with it.


Exports

So, I think it should be ok to export each sub module individually, but would need to configure the build slightly differently to keep inline with the current TypeBox setup. TypeMap uses the same build setup as TypeBox, but where TypeBox exports submodules via computed named / directory paths.


TypeBox Setup

https://github.com/sinclairzx81/typebox/blob/master/task/build/package/build.ts#L33-L38

/** Builds package.json and redirect directories */
export async function build(target: string) {
  console.log('building...package.json')
  const submodules = ['compiler', 'errors', 'parser', 'syntax', 'system', 'type', 'value']
  await createPackageJsonRedirect(target, submodules)
  await createPackageJson(target, submodules)
}

TypeMap Setup

https://github.com/sinclairzx81/typemap/blob/main/task/build/package/build.ts#L32C1-L38C2

/** Builds package.json and redirect directories */
export async function build(target: string) {
  console.log('building...package.json')
  const submodules = [] as string[] // TODO <-- ['compile', 'syntax', 'typebox', 'valibot', 'zod']
  await createPackageJsonRedirect(target, submodules)
  await createPackageJson(target, submodules)
}

If you add this (and remove the explicit configurations), you can test the build with ...

$ npm run build

That should run a module resolution test (CJS, ESM) and confirm the sub modules are correctly resolvable. The submodule may need an additional index.ts just to re-export the typebox.ts, zod.ts etc. Note that index.ts is just a common requirement for any public submodule API as it centralizes exactly what the sub module is exporting, so will just want to export the exact types and functions from the submodule via index.ts


Are you able to take a quick look at this? Again, sorry for the delay here.
S

@m1212e
Copy link
Author

m1212e commented Jul 18, 2025

Absolutely no problem, you do this for free so no worries at all! I'll take a look, thanks for the response!

@m1212e m1212e marked this pull request as ready for review July 18, 2025 23:54
@sinclairzx81
Copy link
Owner

@m1212e Hi, thanks for the additional updates.

I've just made a few updates here to fix up some of the build, mostly just setting up the library submodules as proper submodules (just needed a index.ts file per submodule + explicit module pathing). Node 10, CJS 16, ESM 16 module resolution should work ok now.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   β”‚ "@sinclair/typemap" β”‚ "@sinclair/typemap/compile" β”‚ "@sinclair/typemap/guard" β”‚ "@sinclair/typemap/typebox" β”‚ "@sinclair/typemap/valibot" β”‚ "@sinclair/typemap/zod" β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node10            β”‚ 🟒                  β”‚ 🟒                         β”‚ 🟒                        β”‚ 🟒                         β”‚ 🟒                           β”‚ 🟒                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node16 (from CJS) β”‚ 🟒 (CJS)            β”‚ 🟒 (CJS)                   β”‚ 🟒 (CJS)                  β”‚ 🟒 (CJS)                   β”‚ 🟒 (CJS)                     β”‚ 🟒 (CJS)              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ node16 (from ESM) β”‚ 🟒 (ESM)            β”‚ 🟒 (ESM)                   β”‚ 🟒 (ESM)                  β”‚ 🟒 (ESM)                   β”‚ 🟒 (ESM)                     β”‚ 🟒 (ESM)              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ bundler           β”‚ 🟒                  β”‚ 🟒                         β”‚ 🟒                        β”‚ 🟒                         β”‚ 🟒                           β”‚ 🟒                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Before merging through, need to check a couple of things.


PeerDependenciesMeta

Your update removed Zod and Valibot from peerDependencies and referenced them via peerDependenciesMeta. I needed to add Zod and Valibot back as devDependencies to be able to run tests. But what does peerDependenciesMeta actually do? Does it mean the TypeMap package can install without Valibot and Zod? (where users need to install those libraries separately?)

It would be much better if users needed to explicitly install Zod and Valibot. I wasn't keen on the automatic installation of these libraries previously, so if peerDependenciesMeta allows them to be installed separately, that would be the way to go, but just need clarification of it.

  "peerDependenciesMeta": {
    "zod": {
      "optional": true
    },
    "valibot": {
      "optional": true
    }
  },

Submodule Imports

This setup should support selectively importing from the library sub modules, but are you able to run a test on your setup to make sure everything is working ok?

You should be able to create a build with:

$ npm run build

This should write a .tar.gz you can install in your remote project. Just need to make sure everything is working as expected.

import { Zod } from '@sinclair/typemap/zod'

Would be good to get some info on the above before merging.

@m1212e
Copy link
Author

m1212e commented Jul 21, 2025

Hey, thanks for your answer.

Actually, I think you cannot remove the peer dependencies completely, but you must have them in addition to the optional config. So this would be correct, as far as I know:

  "peerDependencies": {
    "@sinclair/typebox": "^0.34.30",
    "valibot": "^1.0.0",
    "zod": "^3.24.1"
  },
  "peerDependenciesMeta": {
    "zod": {
      "optional": true
    },
    "valibot": {
      "optional": true
    }
  }

this way the user can decide on whether they wanna install valibot or zod.

The generated module exports do work but are not really that useful as they are, at least not for my usecase. Since the index re-export modules use the * to re-export everything from every submodule, the "zod" import still requires valibot to be installed and vice versa:

@sinclair/typemap/typebox ->

export * from './typebox-from-syntax.mjs';
export * from './typebox-from-typebox.mjs';
#  requires valibot
export * from './typebox-from-valibot.mjs';
# requires zod
export * from './typebox-from-zod.mjs';
export * from './typebox.mjs';

So to prevent the necessity of both validators beeing installed, one would need to be able to import the actual function modules like @sinclair/typemap/typebox/typebox-from-valibot or @sinclair/typemap/typebox/typebox-from-zod.

EDIT:
For reference: https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true#optionaldependencies
I'm gonna take a look at that when I find time.

@m1212e
Copy link
Author

m1212e commented Sep 24, 2025

Ok, I think this is still the proper way to handle the dependencies: https://stackoverflow.com/a/66228639/11988368
Did you by any chance have time to take a look yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants