Update Issue Path to use Standard Schema Array Convention (#36)
* Fix issue path to follow standard schema spec * Refactor into different file
This commit is contained in:
41
src/compile/path.ts
Normal file
41
src/compile/path.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Converts a json pointer path (https://datatracker.ietf.org/doc/html/rfc6901)
|
||||
* to a format which is followed by standard-schema and zod
|
||||
*/
|
||||
export function ZodPathFromJsonPointer(jsonPointer: string): PropertyKey[] {
|
||||
if (jsonPointer === '') return []
|
||||
if (jsonPointer === '/') return ['']
|
||||
return jsonPointer
|
||||
.substring(1)
|
||||
.split('/')
|
||||
.map((segment) => segment.replace(/~1/g, '/').replace(/~0/g, '~'))
|
||||
.map((segment) => (isNaN(segment as any) ? segment : parseInt(segment)))
|
||||
}
|
||||
@@ -29,6 +29,7 @@ THE SOFTWARE.
|
||||
import { TypeCheck, ValueErrorIterator } from '@sinclair/typebox/compiler'
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import { ZodPathFromJsonPointer } from './path'
|
||||
import * as s from './standard'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
@@ -65,7 +66,7 @@ export class StandardSchemaProps<Type extends t.TSchema, Static = t.Static<Type>
|
||||
// ----------------------------------------------------------------
|
||||
private __createIssues(value: unknown) {
|
||||
const errors = [...Value.Errors(this.__check.Schema(), value)]
|
||||
const issues: s.StandardSchemaV1.Issue[] = errors.map((error) => ({ ...error, path: [error.path] }))
|
||||
const issues: s.StandardSchemaV1.Issue[] = errors.map((error) => ({ ...error, path: ZodPathFromJsonPointer(error.path) }))
|
||||
return { issues }
|
||||
}
|
||||
private __createValue(value: unknown) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Assert } from './assert'
|
||||
import { TypeBox, Valibot, Zod, Compile } from '@sinclair/typemap'
|
||||
import { ZodPathFromJsonPointer } from 'src/compile/path'
|
||||
|
||||
describe('Compile', () => {
|
||||
// ----------------------------------------------------------------
|
||||
@@ -53,3 +54,38 @@ describe('Compile', () => {
|
||||
Assert.IsTrue(R.issues!.length > 0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('ZodPathFromJsonPointer', () => {
|
||||
it('Should convert empty string', () => {
|
||||
const jsonPointer = ''
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), [])
|
||||
})
|
||||
it('Should convert whole object path', () => {
|
||||
const jsonPointer = '/'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), [''])
|
||||
})
|
||||
it('Should convert nested object path', () => {
|
||||
const jsonPointer = '/a/b'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['a', 'b'])
|
||||
})
|
||||
it('Should convert array path', () => {
|
||||
const jsonPointer = '/a/0'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['a', 0])
|
||||
})
|
||||
it('Should convert keys which looks like array index', () => {
|
||||
const jsonPointer = '/a/"0"'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['a', '"0"'])
|
||||
})
|
||||
it('Should convert keys with / escape', () => {
|
||||
const jsonPointer = '/a~1b'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['a/b'])
|
||||
})
|
||||
it('Should convert keys with ~ escape', () => {
|
||||
const jsonPointer = '/m~0n'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['m~n'])
|
||||
})
|
||||
it('Should convert keys with ~ and / escape', () => {
|
||||
const jsonPointer = '/m~01n'
|
||||
Assert.IsEqual(ZodPathFromJsonPointer(jsonPointer), ['m~1n'])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user