Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# @brainylab/resolver-validators

## 0.8.5

### Patch Changes

- [`f9d8661`](https://github.com/brainylab/resolver-validators/commit/f9d86616340db6dc776d837b40a7e78dc65f22f4) Thanks [@andrefelipeschulle](https://github.com/andrefelipeschulle)! - fix build typebox-deprecated

## 0.8.4

### Patch Changes

- [`03a372b`](https://github.com/brainylab/resolver-validators/commit/03a372bb7b6287453965d559367cc6e82b34025e) Thanks [@andrefelipeschulle](https://github.com/andrefelipeschulle)! - add deprecated version from typebox, compatible from elysia

## 0.8.3

### Patch Changes
Expand Down
5 changes: 5 additions & 0 deletions clean-package.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"import": "./dist/resolvers/typebox.js",
"default": "./dist/resolvers/typebox.js"
},
"./typebox-deprecated": {
"types": "./dist/resolvers/typebox-deprecated.d.ts",
"import": "./dist/resolvers/typebox-deprecated.js",
"default": "./dist/resolvers/typebox-deprecated.js"
},
"./zod": {
"types": "./dist/resolvers/zod.d.ts",
"import": "./dist/resolvers/zod.js",
Expand Down
8 changes: 3 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@brainylab/resolver-validators",
"version": "0.8.3",
"version": "0.8.5",
"description": "",
"keywords": [],
"bugs": {
Expand All @@ -20,10 +20,7 @@
],
"type": "module",
"scripts": {
"build": "pnpm build:core && pnpm build:resolvers:typebox && pnpm build:resolvers:zod",
"build:core": "pnpm tsup ./src/index.ts --clean",
"build:resolvers:typebox": "pnpm tsup ./src/resolvers/typebox.ts --out-dir dist/resolvers --clean",
"build:resolvers:zod": "pnpm tsup ./src/resolvers/zod.ts --out-dir dist/resolvers",
"build": "pnpm tsup --clean",
"commit": "pnpm commit:add && pnpm commit:detail && pnpm commit:push",
"commit:add": "git add .",
"commit:detail": "cz",
Expand All @@ -45,6 +42,7 @@
"@changesets/cli": "2.29.8",
"@changesets/get-release-plan": "4.0.14",
"@changesets/types": "6.1.0",
"@sinclair/typebox": "0.34.41",
"@types/node": "^22.7.4",
"@vitest/coverage-v8": "2.1.2",
"@vitest/ui": "2.1.2",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions src/resolvers/typebox-deprecated.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Type } from "@sinclair/typebox";
import { describe, expect, it } from "vitest";

import { rv } from "../index";
import { resolver } from "./typebox-deprecated";

describe("TypeBox Deprecated Resolver", () => {
it("resolver core schema to typebox validator", () => {
const coreSchema = rv.object({
name: rv.string({ description: "description test" }),
age: rv.optional(rv.number()),
isActive: rv.boolean(),
description: rv.nullable(rv.string()),
other: rv.object({
name: rv.string(),
age: rv.number(),
}),
hobbies: rv.array(rv.string()),
cities: rv.tuple([rv.string(), rv.number()]),
date: rv.or(rv.date(), rv.string()),
});

const typeBoxSchema = Type.Object({
name: Type.String({ description: "description test" }),
age: Type.Optional(Type.Number()),
isActive: Type.Boolean(),
description: Type.Null(Type.String()),
other: Type.Object({
name: Type.String(),
age: Type.Number(),
}),
hobbies: Type.Array(Type.String()),
cities: Type.Tuple([Type.String(), Type.Number()]),
date: Type.Union([Type.Date(), Type.String()]),
});

const resolvedTypeBox = resolver(coreSchema);

expect(resolvedTypeBox).toEqual(typeBoxSchema);
});
});
205 changes: 205 additions & 0 deletions src/resolvers/typebox-deprecated.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import {
type NumberOptions,
type StringOptions,
type TArray,
type TBoolean,
type TDate,
type TNull,
type TNumber,
type TObject,
type TSchema,
type TString,
type TTuple,
type TUnion,
Type,
} from "@sinclair/typebox";

import { isObject } from "@/utils";

import type {
RVNumberParams,
RVParams,
RVSchema,
RVStringParams,
RVTypes,
} from "@/types";

// import { TBOptional } from "./optional";
// import { TBRequired } from "./required";

function TBString(params?: RVStringParams): TString {
const typeBoxParams: StringOptions = {};

const keys: { [key in keyof RVStringParams]: string } = {
min: "minLength",
max: "maxLength",
format: "format",
pattern: "pattern",
description: "description",
};

if (params) {
for (const key in keys) {
const mappedKey = keys[key as keyof typeof keys] as keyof RVStringParams;
if (params[key as keyof RVStringParams] !== undefined) {
typeBoxParams[mappedKey] = params[key as keyof RVStringParams];
}
}
}

return Type.String(typeBoxParams);
}

function TBTuple(schemas: TSchema[]): TTuple {
return Type.Tuple(schemas);
}

function TBUnion(schemas: TSchema[]): TUnion<TSchema[]> {
return Type.Union(schemas);
}

function TBArray(schema: TArray): TArray {
return Type.Array(schema);
}

function TBBoolean(): TBoolean {
return Type.Boolean();
}

function TBDate(): TDate {
return Type.Date();
}

function TBNullable(schema: TSchema): TNull {
return Type.Null(schema);
}

function TBOptional(schema: TSchema): TSchema {
return Type.Optional(schema as unknown as TSchema);
}

function TBNumber(params?: RVNumberParams): TNumber {
const typeBoxParams: NumberOptions = {};

const keys: { [key in keyof RVNumberParams]: string } = {
min: "minLength",
max: "maxLength",
description: "description",
};

if (params) {
for (const key in keys) {
const mappedKey = keys[key as keyof typeof keys] as keyof RVNumberParams;
if (params[key as keyof RVNumberParams] !== undefined) {
typeBoxParams[mappedKey] = params[key as keyof RVNumberParams];
}
}
}

return Type.Number(typeBoxParams);
}

function TBObject(schema: TObject): TObject {
return Type.Object(schema);
}

type PrimitiveSchema = {
type: RVTypes;
schema?: RVSchema;
schemas?: RVSchema[];
params?: RVParams;
optional?: boolean;
};

type ResolverObjectSchema = {
type: "object";
schema: { [key: string]: PrimitiveSchema };
};

function resolverPrimitiveSchema(
options: PrimitiveSchema,
): TSchema | undefined {
if (options.type === "string") {
return TBString(options.params);
}

if (options.type === "number") {
return TBNumber(options.params);
}

if (options.type === "boolean") {
return TBBoolean();
}

if (options.type === "date") {
return TBDate();
}

if (options.type === "array") {
return TBArray(
resolverPrimitiveSchema(options.schema as PrimitiveSchema) as TArray,
);
}

if (options.type === "tuple") {
const tuplePrimitiveResolved = options.schemas?.map((schema) =>
resolverPrimitiveSchema(schema as PrimitiveSchema),
);
return TBTuple(tuplePrimitiveResolved as TSchema[]);
}

if (options.type === "object") {
return resolverObjectSchema(
options as unknown as ResolverObjectSchema,
) as TObject;
}

if (options.type === "optional") {
return TBOptional(
resolverPrimitiveSchema(options.schema as PrimitiveSchema) as TSchema,
);
}

if (options.type === "nullable") {
return TBNullable(
resolverPrimitiveSchema(options.schema as PrimitiveSchema) as TSchema,
);
}

if (options.type === "or") {
return TBUnion(
options.schemas?.map(
(item) => resolverPrimitiveSchema(item as PrimitiveSchema) as TSchema,
) as TSchema[],
);
}
}

function resolverObjectSchema(schema: ResolverObjectSchema) {
if (schema.type === "object") {
const resolvedTypeBox = {} as TObject;

const primitiveSchema = schema.schema;

for (const key in primitiveSchema) {
const value = primitiveSchema[key];

if (value.type === "optional") {
resolvedTypeBox[key] = resolverPrimitiveSchema(value);
continue;
}

resolvedTypeBox[key] = resolverPrimitiveSchema(value);
}

return TBObject(resolvedTypeBox);
}
}

export function resolver(schema: RVSchema) {
if (isObject(schema)) {
return resolverObjectSchema(schema as ResolverObjectSchema);
}

return resolverPrimitiveSchema(schema as PrimitiveSchema);
}
6 changes: 3 additions & 3 deletions tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["!./src/**/*.spec.ts"],
entry: ["src", "!./src/**/*.spec.ts"],
target: "es2022",
format: ["esm"],
splitting: false,
bundle: true,
bundle: false,
dts: true,
external: ["typebox", "zod"],
external: ["typebox", "zod", "@sinclair/typebox"],
});