@hono/typebox-validator
Advanced tools
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/index.ts | ||
| var index_exports = {}; | ||
| __export(index_exports, { | ||
| tbValidator: () => tbValidator | ||
| }); | ||
| module.exports = __toCommonJS(index_exports); | ||
| var import_typebox = require("@sinclair/typebox"); | ||
| var import_value = require("@sinclair/typebox/value"); | ||
| var import_validator = require("hono/validator"); | ||
| var IsObject = import_typebox.ValueGuard.IsObject; | ||
| var IsArray = import_typebox.ValueGuard.IsArray; | ||
| function tbValidator(target, schema, hook, stripNonSchemaItems) { | ||
| return (0, import_validator.validator)(target, (unprocessedData, c) => { | ||
| const data = stripNonSchemaItems ? removeNonSchemaItems(schema, unprocessedData) : unprocessedData; | ||
| if (import_value.Value.Check(schema, data)) { | ||
| if (hook) { | ||
| const hookResult = hook({ success: true, data }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return data; | ||
| } | ||
| const errors = Array.from(import_value.Value.Errors(schema, data)); | ||
| if (hook) { | ||
| const hookResult = hook({ success: false, errors }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return c.json({ success: false, errors }, 400); | ||
| }); | ||
| } | ||
| function removeNonSchemaItems(schema, obj) { | ||
| if (typeof obj !== "object" || obj === null) { | ||
| return obj; | ||
| } | ||
| if (Array.isArray(obj)) { | ||
| return obj.map((item) => removeNonSchemaItems(schema.items, item)); | ||
| } | ||
| const result = {}; | ||
| for (const key in schema.properties) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| const propertySchema = schema.properties[key]; | ||
| if (IsObject(propertySchema) && !IsArray(propertySchema)) { | ||
| result[key] = removeNonSchemaItems(propertySchema, obj[key]); | ||
| } else { | ||
| result[key] = obj[key]; | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| tbValidator | ||
| }); |
| import { TSchema, Static } from '@sinclair/typebox'; | ||
| import { ValueError } from '@sinclair/typebox/value'; | ||
| import { Env, Context, ValidationTargets, TypedResponse, MiddlewareHandler } from 'hono'; | ||
| type Hook<T, E extends Env, P extends string> = (result: { | ||
| success: true; | ||
| data: T; | ||
| } | { | ||
| success: false; | ||
| errors: ValueError[]; | ||
| }, c: Context<E, P>) => Response | Promise<Response> | void; | ||
| /** | ||
| * Hono middleware that validates incoming data via a [TypeBox](https://github.com/sinclairzx81/typebox) schema. | ||
| * | ||
| * --- | ||
| * | ||
| * No Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * const route = app.post('/user', tbValidator('json', schema), (c) => { | ||
| * const user = c.req.valid('json') | ||
| * return c.json({ success: true, message: `${user.name} is ${user.age}` }) | ||
| * }) | ||
| * ``` | ||
| * | ||
| * --- | ||
| * Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * app.post( | ||
| * '/user', | ||
| * tbValidator('json', schema, (result, c) => { | ||
| * if (!result.success) { | ||
| * return c.text('Invalid!', 400) | ||
| * } | ||
| * }) | ||
| * //... | ||
| * ) | ||
| * ``` | ||
| */ | ||
| type ExcludeResponseType<T> = T extends Response & TypedResponse<any> ? never : T; | ||
| declare function tbValidator<T extends TSchema, Target extends keyof ValidationTargets, E extends Env, P extends string, V extends { | ||
| in: { | ||
| [K in Target]: Static<T>; | ||
| }; | ||
| out: { | ||
| [K in Target]: ExcludeResponseType<Static<T>>; | ||
| }; | ||
| }>(target: Target, schema: T, hook?: Hook<Static<T>, E, P>, stripNonSchemaItems?: boolean): MiddlewareHandler<E, P, V>; | ||
| export { type Hook, tbValidator }; |
| import { TSchema, Static } from '@sinclair/typebox'; | ||
| import { ValueError } from '@sinclair/typebox/value'; | ||
| import { Env, Context, ValidationTargets, TypedResponse, MiddlewareHandler } from 'hono'; | ||
| type Hook<T, E extends Env, P extends string> = (result: { | ||
| success: true; | ||
| data: T; | ||
| } | { | ||
| success: false; | ||
| errors: ValueError[]; | ||
| }, c: Context<E, P>) => Response | Promise<Response> | void; | ||
| /** | ||
| * Hono middleware that validates incoming data via a [TypeBox](https://github.com/sinclairzx81/typebox) schema. | ||
| * | ||
| * --- | ||
| * | ||
| * No Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * const route = app.post('/user', tbValidator('json', schema), (c) => { | ||
| * const user = c.req.valid('json') | ||
| * return c.json({ success: true, message: `${user.name} is ${user.age}` }) | ||
| * }) | ||
| * ``` | ||
| * | ||
| * --- | ||
| * Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * app.post( | ||
| * '/user', | ||
| * tbValidator('json', schema, (result, c) => { | ||
| * if (!result.success) { | ||
| * return c.text('Invalid!', 400) | ||
| * } | ||
| * }) | ||
| * //... | ||
| * ) | ||
| * ``` | ||
| */ | ||
| type ExcludeResponseType<T> = T extends Response & TypedResponse<any> ? never : T; | ||
| declare function tbValidator<T extends TSchema, Target extends keyof ValidationTargets, E extends Env, P extends string, V extends { | ||
| in: { | ||
| [K in Target]: Static<T>; | ||
| }; | ||
| out: { | ||
| [K in Target]: ExcludeResponseType<Static<T>>; | ||
| }; | ||
| }>(target: Target, schema: T, hook?: Hook<Static<T>, E, P>, stripNonSchemaItems?: boolean): MiddlewareHandler<E, P, V>; | ||
| export { type Hook, tbValidator }; |
| // src/index.ts | ||
| import { ValueGuard } from "@sinclair/typebox"; | ||
| import { Value } from "@sinclair/typebox/value"; | ||
| import { validator } from "hono/validator"; | ||
| var IsObject = ValueGuard.IsObject; | ||
| var IsArray = ValueGuard.IsArray; | ||
| function tbValidator(target, schema, hook, stripNonSchemaItems) { | ||
| return validator(target, (unprocessedData, c) => { | ||
| const data = stripNonSchemaItems ? removeNonSchemaItems(schema, unprocessedData) : unprocessedData; | ||
| if (Value.Check(schema, data)) { | ||
| if (hook) { | ||
| const hookResult = hook({ success: true, data }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return data; | ||
| } | ||
| const errors = Array.from(Value.Errors(schema, data)); | ||
| if (hook) { | ||
| const hookResult = hook({ success: false, errors }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return c.json({ success: false, errors }, 400); | ||
| }); | ||
| } | ||
| function removeNonSchemaItems(schema, obj) { | ||
| if (typeof obj !== "object" || obj === null) { | ||
| return obj; | ||
| } | ||
| if (Array.isArray(obj)) { | ||
| return obj.map((item) => removeNonSchemaItems(schema.items, item)); | ||
| } | ||
| const result = {}; | ||
| for (const key in schema.properties) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| const propertySchema = schema.properties[key]; | ||
| if (IsObject(propertySchema) && !IsArray(propertySchema)) { | ||
| result[key] = removeNonSchemaItems(propertySchema, obj[key]); | ||
| } else { | ||
| result[key] = obj[key]; | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| export { | ||
| tbValidator | ||
| }; |
+24
-14
| { | ||
| "name": "@hono/typebox-validator", | ||
| "version": "0.3.2", | ||
| "version": "0.3.3", | ||
| "description": "Validator middleware using TypeBox", | ||
| "types": "dist/esm/index.d.ts", | ||
| "type": "module", | ||
| "module": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "exports": { | ||
| "import": "./dist/esm/index.js", | ||
| "require": "./dist/cjs/index.js", | ||
| "types": "./dist/esm/index.d.ts" | ||
| ".": { | ||
| "import": { | ||
| "types": "./dist/index.d.ts", | ||
| "default": "./dist/index.js" | ||
| }, | ||
| "require": { | ||
| "types": "./dist/index.d.cts", | ||
| "default": "./dist/index.cjs" | ||
| } | ||
| } | ||
| }, | ||
@@ -15,8 +24,6 @@ "files": [ | ||
| "scripts": { | ||
| "test": "jest", | ||
| "build:cjs": "tsc -p tsconfig.cjs.json", | ||
| "build:esm": "tsc -p tsconfig.esm.json && echo '{\"type\": \"module\"}' > dist/esm/package.json", | ||
| "build": "rimraf dist && yarn build:cjs && yarn build:esm", | ||
| "prerelease": "yarn build && yarn test", | ||
| "release": "yarn publish" | ||
| "build": "tsup ./src/index.ts", | ||
| "prepack": "yarn build", | ||
| "publint": "attw --pack && publint", | ||
| "test": "vitest" | ||
| }, | ||
@@ -30,3 +37,4 @@ "license": "MIT", | ||
| "type": "git", | ||
| "url": "https://github.com/honojs/middleware.git" | ||
| "url": "git+https://github.com/honojs/middleware.git", | ||
| "directory": "packages/typebox-validator" | ||
| }, | ||
@@ -39,7 +47,9 @@ "homepage": "https://github.com/honojs/middleware", | ||
| "devDependencies": { | ||
| "@arethetypeswrong/cli": "^0.17.4", | ||
| "@sinclair/typebox": "^0.31.15", | ||
| "hono": "^3.11.7", | ||
| "jest": "^29.7.0", | ||
| "rimraf": "^5.0.5" | ||
| "publint": "^0.3.9", | ||
| "tsup": "^8.4.0", | ||
| "vitest": "^3.0.8" | ||
| } | ||
| } |
+2
-0
| # TypeBox validator middleware for Hono | ||
| [](https://codecov.io/github/honojs/middleware) | ||
| Validator middleware using [TypeBox](https://github.com/sinclairzx81/typebox) for [Hono](https://honojs.dev) applications. | ||
@@ -4,0 +6,0 @@ Define your schema with TypeBox and validate incoming requests. |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.tbValidator = void 0; | ||
| const typebox_1 = require("@sinclair/typebox"); | ||
| const value_1 = require("@sinclair/typebox/value"); | ||
| const validator_1 = require("hono/validator"); | ||
| var IsObject = typebox_1.ValueGuard.IsObject; | ||
| var IsArray = typebox_1.ValueGuard.IsArray; | ||
| /** | ||
| * Hono middleware that validates incoming data via a [TypeBox](https://github.com/sinclairzx81/typebox) schema. | ||
| * | ||
| * --- | ||
| * | ||
| * No Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * const route = app.post('/user', tbValidator('json', schema), (c) => { | ||
| * const user = c.req.valid('json') | ||
| * return c.json({ success: true, message: `${user.name} is ${user.age}` }) | ||
| * }) | ||
| * ``` | ||
| * | ||
| * --- | ||
| * Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * app.post( | ||
| * '/user', | ||
| * tbValidator('json', schema, (result, c) => { | ||
| * if (!result.success) { | ||
| * return c.text('Invalid!', 400) | ||
| * } | ||
| * }) | ||
| * //... | ||
| * ) | ||
| * ``` | ||
| */ | ||
| function tbValidator(target, schema, hook, stripNonSchemaItems) { | ||
| // Compile the provided schema once rather than per validation. This could be optimized further using a shared schema | ||
| // compilation pool similar to the Fastify implementation. | ||
| return (0, validator_1.validator)(target, (unprocessedData, c) => { | ||
| const data = stripNonSchemaItems | ||
| ? removeNonSchemaItems(schema, unprocessedData) | ||
| : unprocessedData; | ||
| if (value_1.Value.Check(schema, data)) { | ||
| if (hook) { | ||
| const hookResult = hook({ success: true, data }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return data; | ||
| } | ||
| const errors = Array.from(value_1.Value.Errors(schema, data)); | ||
| if (hook) { | ||
| const hookResult = hook({ success: false, errors }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return c.json({ success: false, errors }, 400); | ||
| }); | ||
| } | ||
| exports.tbValidator = tbValidator; | ||
| function removeNonSchemaItems(schema, obj) { | ||
| if (typeof obj !== 'object' || obj === null) { | ||
| return obj; | ||
| } | ||
| if (Array.isArray(obj)) { | ||
| return obj.map((item) => removeNonSchemaItems(schema.items, item)); | ||
| } | ||
| const result = {}; | ||
| for (const key in schema.properties) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| const propertySchema = schema.properties[key]; | ||
| if (IsObject(propertySchema) && !IsArray(propertySchema)) { | ||
| result[key] = removeNonSchemaItems(propertySchema, obj[key]); | ||
| } | ||
| else { | ||
| result[key] = obj[key]; | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| } |
| import type { TSchema, Static } from '@sinclair/typebox'; | ||
| import type { ValueError } from '@sinclair/typebox/value'; | ||
| import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono'; | ||
| export type Hook<T, E extends Env, P extends string> = (result: { | ||
| success: true; | ||
| data: T; | ||
| } | { | ||
| success: false; | ||
| errors: ValueError[]; | ||
| }, c: Context<E, P>) => Response | Promise<Response> | void; | ||
| /** | ||
| * Hono middleware that validates incoming data via a [TypeBox](https://github.com/sinclairzx81/typebox) schema. | ||
| * | ||
| * --- | ||
| * | ||
| * No Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * const route = app.post('/user', tbValidator('json', schema), (c) => { | ||
| * const user = c.req.valid('json') | ||
| * return c.json({ success: true, message: `${user.name} is ${user.age}` }) | ||
| * }) | ||
| * ``` | ||
| * | ||
| * --- | ||
| * Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * app.post( | ||
| * '/user', | ||
| * tbValidator('json', schema, (result, c) => { | ||
| * if (!result.success) { | ||
| * return c.text('Invalid!', 400) | ||
| * } | ||
| * }) | ||
| * //... | ||
| * ) | ||
| * ``` | ||
| */ | ||
| export declare function tbValidator<T extends TSchema, Target extends keyof ValidationTargets, E extends Env, P extends string, V extends { | ||
| in: { | ||
| [K in Target]: Static<T>; | ||
| }; | ||
| out: { | ||
| [K in Target]: Static<T>; | ||
| }; | ||
| }>(target: Target, schema: T, hook?: Hook<Static<T>, E, P>, stripNonSchemaItems?: boolean): MiddlewareHandler<E, P, V>; |
| import { ValueGuard } from '@sinclair/typebox'; | ||
| import { Value } from '@sinclair/typebox/value'; | ||
| import { validator } from 'hono/validator'; | ||
| var IsObject = ValueGuard.IsObject; | ||
| var IsArray = ValueGuard.IsArray; | ||
| /** | ||
| * Hono middleware that validates incoming data via a [TypeBox](https://github.com/sinclairzx81/typebox) schema. | ||
| * | ||
| * --- | ||
| * | ||
| * No Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * const route = app.post('/user', tbValidator('json', schema), (c) => { | ||
| * const user = c.req.valid('json') | ||
| * return c.json({ success: true, message: `${user.name} is ${user.age}` }) | ||
| * }) | ||
| * ``` | ||
| * | ||
| * --- | ||
| * Hook | ||
| * | ||
| * ```ts | ||
| * import { tbValidator } from '@hono/typebox-validator' | ||
| * import { Type as T } from '@sinclair/typebox' | ||
| * | ||
| * const schema = T.Object({ | ||
| * name: T.String(), | ||
| * age: T.Number(), | ||
| * }) | ||
| * | ||
| * app.post( | ||
| * '/user', | ||
| * tbValidator('json', schema, (result, c) => { | ||
| * if (!result.success) { | ||
| * return c.text('Invalid!', 400) | ||
| * } | ||
| * }) | ||
| * //... | ||
| * ) | ||
| * ``` | ||
| */ | ||
| export function tbValidator(target, schema, hook, stripNonSchemaItems) { | ||
| // Compile the provided schema once rather than per validation. This could be optimized further using a shared schema | ||
| // compilation pool similar to the Fastify implementation. | ||
| return validator(target, (unprocessedData, c) => { | ||
| const data = stripNonSchemaItems | ||
| ? removeNonSchemaItems(schema, unprocessedData) | ||
| : unprocessedData; | ||
| if (Value.Check(schema, data)) { | ||
| if (hook) { | ||
| const hookResult = hook({ success: true, data }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return data; | ||
| } | ||
| const errors = Array.from(Value.Errors(schema, data)); | ||
| if (hook) { | ||
| const hookResult = hook({ success: false, errors }, c); | ||
| if (hookResult instanceof Response || hookResult instanceof Promise) { | ||
| return hookResult; | ||
| } | ||
| } | ||
| return c.json({ success: false, errors }, 400); | ||
| }); | ||
| } | ||
| function removeNonSchemaItems(schema, obj) { | ||
| if (typeof obj !== 'object' || obj === null) { | ||
| return obj; | ||
| } | ||
| if (Array.isArray(obj)) { | ||
| return obj.map((item) => removeNonSchemaItems(schema.items, item)); | ||
| } | ||
| const result = {}; | ||
| for (const key in schema.properties) { | ||
| if (Object.prototype.hasOwnProperty.call(obj, key)) { | ||
| const propertySchema = schema.properties[key]; | ||
| if (IsObject(propertySchema) && !IsArray(propertySchema)) { | ||
| result[key] = removeNonSchemaItems(propertySchema, obj[key]); | ||
| } | ||
| else { | ||
| result[key] = obj[key]; | ||
| } | ||
| } | ||
| } | ||
| return result; | ||
| } |
| {"type": "module"} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
10548
4.47%56
3.7%Yes
NaN6
50%191
-26.82%1
Infinity%