Skip to content

Commit

Permalink
Merge pull request #20 from dylibso/type-format-properties
Browse files Browse the repository at this point in the history
feat: make sure users can define exports/imports/schemas/properties named `format`/`type`
  • Loading branch information
mhmd-azeez authored Nov 4, 2024
2 parents 38dea85 + 7fb2672 commit ac0419e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.0.0-rc.13",
"version": "1.0.0-rc.14",
"name": "@dylibso/xtp-bindgen",
"description": "XTP bindgen helper library",
"main": "dist/index.js",
Expand Down
12 changes: 12 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ export class ValidationError {
this.path = path
}
}

declare global {
interface Array<T> {
none(predicate: (item: T) => boolean): boolean;
}
}

if (!Array.prototype.none) {
Array.prototype.none = function<T>(predicate: (item: T) => boolean): boolean {
return !this.some(predicate);
}
}
18 changes: 15 additions & 3 deletions src/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,27 @@ export function parseAndNormalizeJson(encoded: string): XtpSchema {
const { doc, errors } = parser.parseAny(JSON.parse(encoded))

if (errors && errors.length > 0) {
console.log(JSON.stringify(errors))
throw Error(`Invalid document`)
if (errors.length === 1) {
throw new NormalizeError(errors[0].message, errors)
} else {
throw new NormalizeError(`${errors[0].message} (and ${errors.length - 1} other error(s))`, errors)
}
}

if (parser.isV0Schema(doc)) {
return normalizeV0Schema(doc)
} else if (parser.isV1Schema(doc)) {
return normalizeV1Schema(doc)
} else {
throw new Error("Could not normalize unknown version of schema");
throw new NormalizeError("Could not normalize unknown version of schema", [{
message: "Could not normalize unknown version of schema",
path: '#/version',
}])
}
}

export class NormalizeError extends Error {
constructor(msg: string, public errors: ValidationError[]) {
super(msg)
}
}
29 changes: 26 additions & 3 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,21 @@ class V1Validator {
* This saves us a lot of code but might be a little bit slower.
*/
validateNode(node: any) {
this.validateTypedInterface(node)
const currentPath = this.getLocation()

// allow defining properties/exports/imports/schemas named `type` or `format`
const skipPatterns = [
/^#\/components\/schemas\/[^/]+\/properties$/,
/^#\/components\/schemas$/,
/^#\/components$/,
/^#\/exports$/,
/^#\/imports$/
]

const shouldValidate = skipPatterns.none(pattern => pattern.test(currentPath))
if (shouldValidate) {
this.validateTypedInterface(node)
}

if (node && typeof node === 'object') {
// i don't think we need to validate array children
Expand Down Expand Up @@ -104,7 +118,7 @@ class V1Validator {

const validTypes = ['string', 'number', 'integer', 'boolean', 'object', 'array', 'buffer'];
if (prop.type && !validTypes.includes(prop.type)) {
this.recordError(`Invalid type '${prop.type}'. Options are: ${validTypes.map(t => `'${t}'`).join(', ')}`)
this.recordError(`Invalid type '${stringify(prop.type)}'. Options are: ${validTypes.map(t => `'${t}'`).join(', ')}`)
}

if (prop.format) {
Expand All @@ -118,7 +132,7 @@ class V1Validator {
}

if (!validFormats.includes(prop.format)) {
this.recordError(`Invalid format ${prop.format} for type ${prop.type}. Valid formats are: ${validFormats.join(', ')}`)
this.recordError(`Invalid format ${stringify(prop.format)} for type ${stringify(prop.type)}. Valid formats are: ${validFormats.join(', ')}`)
}
}

Expand All @@ -132,6 +146,15 @@ class V1Validator {
}


function stringify(typ: any): string {
if (typeof typ === 'object') {
return JSON.stringify(typ)
}

return `${typ}`
}


// Main Schema export interface
export interface V0Schema {
version: Version;
Expand Down
8 changes: 8 additions & 0 deletions tests/schemas/v1-valid-doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ components:
anUntypedObject:
description: An untyped object with no properties
type: object
type:
type: string
description: An enum prop
enum: [complex, simple]
format:
type: string
description: An enum prop
enum: [json, xml]
MyInt:
description: an int as a schema
type: integer
Expand Down

0 comments on commit ac0419e

Please sign in to comment.