refactor: migrate monorepo from pnpm to Bun runtime and workspaces
- root: bun workspaces via package.json, packageManager bun@1.4.0, scripts use bun --filter - backend: Bun.serve, bun test (vitest removed), bun --watch dev script, tsconfig types bun - tests: migrate 6 test files from vitest to bun:test (mock.module) - validate: replace @hono/zod-validator with hono validator + zod safeParse (fixes TS2589) - lockfile: bunfig.toml saveTextLockfile, regenerated bun.lock (text) for turbo - docs: AGENTS.md, README.md, stack.md updated to Bun stack
This commit is contained in:
@@ -1,57 +1,62 @@
|
||||
import { zValidator } from '@hono/zod-validator';
|
||||
import type { Context } from 'hono';
|
||||
import type { ZodIssue, ZodSchema } from 'zod';
|
||||
import type { Context, MiddlewareHandler } from 'hono';
|
||||
import { validator } from 'hono/validator';
|
||||
import type { ZodTypeAny, z } from 'zod';
|
||||
import { validationProblem } from './problem-builders';
|
||||
import { zodIssuesToRecord } from './zod-issues';
|
||||
|
||||
type ValidationTarget = 'json' | 'query' | 'param' | 'header' | 'form';
|
||||
|
||||
function makeValidator(target: ValidationTarget, schema: ZodSchema) {
|
||||
return zValidator(
|
||||
target,
|
||||
schema,
|
||||
(result: { success: boolean; error?: { issues: ZodIssue[] } }, c: Context) => {
|
||||
if (result.success) {
|
||||
return;
|
||||
}
|
||||
type ValidationInput<S extends ZodTypeAny, T extends ValidationTarget> = {
|
||||
out: { [K in T]: z.output<S> };
|
||||
};
|
||||
|
||||
const requestId = c.get('requestId');
|
||||
const instance = requestId ? `/requests/${requestId}` : undefined;
|
||||
const issues = result.error?.issues ?? [];
|
||||
function makeValidator<S extends ZodTypeAny, T extends ValidationTarget>(
|
||||
target: T,
|
||||
schema: S,
|
||||
): MiddlewareHandler<{}, string, ValidationInput<S, T>> {
|
||||
const middleware = validator(target, (value: unknown, c: Context) => {
|
||||
const result = schema.safeParse(value);
|
||||
|
||||
return c.json(
|
||||
validationProblem({
|
||||
detail: `Invalid ${target} data`,
|
||||
instance,
|
||||
errors: zodIssuesToRecord(issues),
|
||||
}),
|
||||
400,
|
||||
{
|
||||
'Content-Type': 'application/problem+json',
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
if (result.success) {
|
||||
return result.data;
|
||||
}
|
||||
|
||||
const requestId = c.get('requestId');
|
||||
const instance = requestId ? `/requests/${requestId}` : undefined;
|
||||
|
||||
return c.json(
|
||||
validationProblem({
|
||||
detail: `Invalid ${target} data`,
|
||||
instance,
|
||||
errors: zodIssuesToRecord(result.error.issues),
|
||||
}),
|
||||
400,
|
||||
{
|
||||
'Content-Type': 'application/problem+json',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
return middleware as unknown as MiddlewareHandler<{}, string, ValidationInput<S, T>>;
|
||||
}
|
||||
|
||||
export const validate = {
|
||||
json(schema: ZodSchema) {
|
||||
json<S extends ZodTypeAny>(schema: S) {
|
||||
return makeValidator('json', schema);
|
||||
},
|
||||
|
||||
query(schema: ZodSchema) {
|
||||
query<S extends ZodTypeAny>(schema: S) {
|
||||
return makeValidator('query', schema);
|
||||
},
|
||||
|
||||
param(schema: ZodSchema) {
|
||||
param<S extends ZodTypeAny>(schema: S) {
|
||||
return makeValidator('param', schema);
|
||||
},
|
||||
|
||||
header(schema: ZodSchema) {
|
||||
header<S extends ZodTypeAny>(schema: S) {
|
||||
return makeValidator('header', schema);
|
||||
},
|
||||
|
||||
form(schema: ZodSchema) {
|
||||
form<S extends ZodTypeAny>(schema: S) {
|
||||
return makeValidator('form', schema);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user