decs / typeschema

🛵 Universal adapter for TypeScript schema validation.
https://typeschema.com
MIT License
368 stars 11 forks source link

TypeBox Adapter does not respect global settings (e.g. FormatRegistry) #65

Open NiklasPor opened 3 weeks ago

NiklasPor commented 3 weeks ago

It seems like the TypeBox adapter is not respecting global settings. In my example I've got a simple email validator:

import { FormatRegistry } from "@sinclair/typebox";
FormatRegistry.Set("demo", () => true);

Now if you try to use it via TypeBox wrap:

import { Type } from "@sinclair/typebox";
import { wrap } from "@typeschema/typebox";

const schema = Type.String({ format: "demo" });
const wrapped = wrap(schema);
const result = wrapped.validate("test_string");

// Throws: "Unknown format 'email'"

My first suspicion would be that the dynamic import inside @typeschema/typebox conflicts with the global module configuration in my node application:

const importValidationModule = memoize(async () => {
  const {TypeCompiler} = await import('@sinclair/typebox/compiler');
  return {TypeCompiler};
});

Versions:

Node: 20
"@sinclair/typebox": "0.33.7",
"@typeschema/typebox": "0.13.4"

Upvote & Fund

Fund with Polar

NiklasPor commented 3 weeks ago

I can confirm that this is due to the dynamic module loading of @sinclair/typebox/compiler. I just monkey patched my package.

Before:

// File node_modules/@typeschema/typebox/dist/index.js

// src/validation.ts
var import_core = require("@typeschema/core");
var importValidationModule = (0, import_core.memoize)(async () => {
  try {
    var dynamicallyImportedModule = await import(
      /* webpackIgnore: true */
      "@sinclair/typebox/compiler"
    );
  } catch (moduleImportError) {
    throw moduleImportError;
  }
  const { TypeCompiler } = dynamicallyImportedModule;
  return { TypeCompiler };
});
var validationAdapter = async (schema) => {
  const { TypeCompiler } = await importValidationModule();

After:

// File node_modules/@typeschema/typebox/dist/index.js

// src/validation.ts
const { TypeCompiler } = require("@sinclair/typebox/compiler");

var validationAdapter = async (schema) => {
  const result = TypeCompiler.Compile(schema);

As I'm using the package anyway it's not a problem for me to load it statically. It would be nice if we could find a better fix 👍