-
-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #383 from scythewyvern/valibot-adapter
Valibot Adapter
- Loading branch information
Showing
10 changed files
with
222 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# RVF Valibot | ||
|
||
The Valibot adapter for [RVF](https://github.com/airjp73/remix-validated-form). | ||
|
||
## Docs | ||
|
||
The best place to learn about RVF is the [documentation](https://rvf-js.io). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "@rvf/valibot", | ||
"version": "6.0.0", | ||
"main": "./dist/index.cjs.js", | ||
"module": "./dist/index.esm.js", | ||
"types": "./dist/index.d.ts", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/airjp73/remix-validated-form" | ||
}, | ||
"scripts": { | ||
"dev": "tsup --watch", | ||
"build": "tsup", | ||
"prepublishOnly": "npm run build", | ||
"typecheck": "tsc --noEmit" | ||
}, | ||
"peerDependencies": { | ||
"@rvf/core": ">= 0.0.0 < 7.0.0", | ||
"@rvf/set-get": ">= 0.0.0 < 1.0.0", | ||
"valibot": ">= 0.39.0" | ||
}, | ||
"devDependencies": { | ||
"@types/semver": "^7.5.0", | ||
"@rvf/core": "*", | ||
"semver": "^7.5.1", | ||
"@rvf/set-get": "*", | ||
"tsconfig": "*", | ||
"tsup-config": "*", | ||
"typescript": "^5.4.5", | ||
"valibot": "^0.39.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { type FieldErrors, type Validator, createValidator } from "@rvf/core"; | ||
import { pathArrayToString } from '@rvf/set-get'; | ||
import { | ||
type BaseIssue, | ||
type Config, | ||
type GenericSchema, | ||
type GenericSchemaAsync, | ||
type InferIssue, | ||
type InferOutput, | ||
safeParseAsync, | ||
} from "valibot"; | ||
|
||
type MaybeAsyncSchema = GenericSchema | GenericSchemaAsync | ||
|
||
function formatIssuePath(issue: BaseIssue<unknown>): string | null { | ||
if (!issue.path || issue.path.length === 0) return null; | ||
const pathArray = issue.path.map(path => path.key as string | number); | ||
|
||
return pathArrayToString(pathArray); | ||
} | ||
|
||
function parseIssues<Schema extends GenericSchema>( | ||
issues: [InferIssue<Schema>, ...InferIssue<Schema>[]] | ||
): FieldErrors { | ||
const parsedIssues: FieldErrors = {}; | ||
|
||
for (const issue of issues) { | ||
// More about unions: https://valibot.dev/guides/unions/ | ||
if (issue.type === 'union' && issue.issues) { | ||
const unionIssues = parseIssues(issue.issues); | ||
Object.assign(parsedIssues, unionIssues); | ||
} | ||
|
||
const path = formatIssuePath(issue); | ||
if (path) parsedIssues[path] = issue.message; | ||
} | ||
|
||
return parsedIssues; | ||
} | ||
|
||
export function withValibot<Schema extends MaybeAsyncSchema>( | ||
schema: Schema, | ||
config?: Config<InferIssue<Schema>>, | ||
): Validator<InferOutput<Schema>> { | ||
return createValidator({ | ||
validate: async (input) => { | ||
const result = await safeParseAsync(schema, input, config); | ||
|
||
if (result.success) return { data: result.output, error: undefined }; | ||
return { data: undefined, error: parseIssues(result.issues) }; | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import * as fs from "fs/promises"; | ||
import * as path from "path"; | ||
import * as semver from "semver"; | ||
import { anyString } from "@remix-validated-form/test-utils"; | ||
import { describe, it, expect } from "vitest"; | ||
import * as v from "valibot"; | ||
|
||
import { withValibot } from "./"; | ||
|
||
const packageDir = path.join(__dirname, ".."); | ||
const packageJsonPath = path.join(packageDir, "package.json"); | ||
const corePackageJsonPath = path.join(packageDir, "../core/package.json"); | ||
|
||
describe("withValibot", () => { | ||
it("returns coherent errors for complex schemas", async () => { | ||
const schema = v.union( [ | ||
v.object({ | ||
type: v.literal("foo"), | ||
foo: v.string(), | ||
}), | ||
v.object({ | ||
type: v.literal("bar"), | ||
bar: v.string(), | ||
}), | ||
]); | ||
const obj = { | ||
type: "foo", | ||
bar: 123, | ||
foo: 123, | ||
}; | ||
|
||
expect(await withValibot(schema).validate(obj)).toEqual({ | ||
data: undefined, | ||
error: { | ||
fieldErrors: { | ||
type: anyString, | ||
bar: anyString, | ||
foo: anyString, | ||
}, | ||
subaction: undefined, | ||
}, | ||
submittedData: obj, | ||
}); | ||
}); | ||
|
||
it("returns errors for fields that are unions", async () => { | ||
const schema = v.object({ | ||
field1: v.union([v.literal("foo"), v.literal("bar")]), | ||
field2: v.union([v.literal("foo"), v.literal("bar")]), | ||
}); | ||
const obj = { | ||
field1: "a value", | ||
// field2 missing | ||
}; | ||
|
||
const validator = withValibot(schema); | ||
expect(await validator.validate(obj)).toEqual({ | ||
data: undefined, | ||
error: { | ||
fieldErrors: { | ||
field1: anyString, | ||
field2: anyString, | ||
}, | ||
subaction: undefined, | ||
}, | ||
submittedData: obj, | ||
}); | ||
}); | ||
}); | ||
|
||
|
||
describe("peer dependecy version", () => { | ||
it("should have a peer dependency version that matches the lastet version of RVF", async () => { | ||
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8")); | ||
const peerDependencyVersion = packageJson.peerDependencies["@rvf/core"]; | ||
const rvfPackageJson = JSON.parse( | ||
await fs.readFile(corePackageJsonPath, "utf-8"), | ||
); | ||
const rvfVersion = rvfPackageJson.version; | ||
|
||
expect(semver.satisfies(rvfVersion, peerDependencyVersion)).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"extends": "tsconfig/tsconfig.json", | ||
"include": ["src/**/*.ts", "src/**/*.tsx"], | ||
"exclude": ["node_modules"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { config } from "tsup-config"; | ||
|
||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters