Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewamp untyped into a runtime-friendly lib #101

Open
pi0 opened this issue Jul 25, 2023 · 3 comments
Open

rewamp untyped into a runtime-friendly lib #101

pi0 opened this issue Jul 25, 2023 · 3 comments

Comments

@pi0
Copy link
Member

pi0 commented Jul 25, 2023

Background

Back in time I was developing the untyped library, the idea was to make a unified (build-time) solution to merge type and runtime validation from one source with little or no extra code and use JSON Schema as a unified schema format mainly for handling nuxt config schema.

Currently untyped:

  • Is designed as a build-time utility
  • Uses a superset of JSON Schema for scheme definitions
  • Can Transform source to combine JSDocs and runtime validator into one schema
  • Can Generate TypeScript types and markdown from schema
  • Can normalize an input object with schema and defaults
  • Supports both object schema and function schema

However, it has some limitations:

  • It is not designed with minimum bundle impact to be a runtime library
  • Does not provide convenience API to define the schema (previous proposal: Add a field() helper for easier schema creation #91)
  • Cannot directly infer typescript types from schema without a build step
  • Does not provide compatibility with other schema validation libraries
  • Does not provide utils uses for validating schema

Future Vision

Untyped should:

  • Provide an (end) user-friendly DX to easily define and validate the schema
  • Be runtime-friendly with minimum bundle impact
  • Provide a way for compatibility with other schema validation libraries
  • Use a unified schema object for validation and definitions

At this point, I am not sure how to make the perfect solution to meet the above criteria. I might also end-up with making a new library if not fitting for one lib. Share the main vision and ideas publicly to gather ideas and myself taking notes.

Similar efforts

Recently I have found out about the (amazing) typeschema project which tries to almost do the same of unifying schema validation libraries. I love it but it has some implementation drawbacks that are not fully tree-shakable (it is fixable with some major changes) but also is not itself trying to make a standard schema nor provide build-time utils like currently untyped does.

There is also JsonTypeDef Standard (RFC) which could be a nice replacement for JSON Schema as a current source of trust.

Schema Validation Libs

Zod

Joi

Yup

io-ts

Runtypes

Valibot

AJV

Superstruct

OW

Typebox

Typia

Deepkit/type

Arktype

@pi0
Copy link
Member Author

pi0 commented Jul 25, 2023

Notes from @decs (author of typeschema): (unjs/h3#431 (comment))

we started with a simple logic, inspired by tRPC, but quickly noticed that it wouldn't support other libraries where the validation function lives outside of the schema object (like io-ts, ajv). so we pivoted to the adapter + optional peer dependencies model, and now we're on track to support all major libs this week. and indeed there's a tradeoff: the architecture change increased the LOC.

I can think of 2 alternatives to adding typeschema as a direct dependency, if the LOC is a concern:

  1. making it an optional peer dependency. try dynamically importing typeschema (falling back to no schema validation if not installed) and instructing users to install it on their own
  2. or supporting custom validators with this format: <T>(data: unknown): Promise<T> | T, then asking users to independently install typeschema and use createAssert(schema) (which generates a function on this format)

@stafyniaksacha
Copy link

Another option from typeschema (which I realy like) is to take inspiration from vee-validate vue validation library which support yup and zod out of the box by using abstraction and adapters package like @vee-validate/yup and @vee-validate/zod.

https://vee-validate.logaretm.com/v4/guide/composition-api/getting-started/#form-schema

The benefit would be to keep minimum dependencies, but would need to create and maintain each package.

The caveat I see with typeschema is that it has a lot of peerDependencies which can grow dependencies (recently pnpm has toggled auto-install-peers to true by default https://pnpm.io/next/npmrc#auto-install-peers)

@decs
Copy link

decs commented Aug 2, 2023

The peer dependencies on typeschema are all optional, just to ensure that you're using a version that's compatible with the adapter. Installing typeschema shouldn't install any peer dependencies.

I looked at the pnpm option you mentioned and it should skip optional peer dependencies as expected.

auto-install-peers

Default: true
Type: Boolean
When true, any missing non-optional peer dependencies are automatically installed.

I still haven't set my mind on one package vs multiple packages (one per adapter). But I currently lean towards one package to avoid users from having to manually install every adapter they care about (hopefully all). Though it's growing on me the idea of having both: scoped packages for each adapter and one main package will all automatically installed.

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

No branches or pull requests

3 participants