Skip to content

Commit

Permalink
feat: add validator.toJSON method to get compiled schema and refs
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 29, 2024
1 parent 778ec59 commit 5259933
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 3 deletions.
3 changes: 2 additions & 1 deletion bin/test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { snapshot } from '@japa/snapshot'
import { Assert, assert } from '@japa/assert'
import { expectTypeOf } from '@japa/expect-type'
import { processCLIArgs, configure, run } from '@japa/runner'
Expand Down Expand Up @@ -48,7 +49,7 @@ configure({
files: ['tests/integration/**/*.spec(.js|.ts)'],
},
],
plugins: [assert(), expectTypeOf()],
plugins: [assert(), expectTypeOf(), snapshot()],
})

/*
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@japa/assert": "^2.1.0",
"@japa/expect-type": "^2.0.1",
"@japa/runner": "^3.1.1",
"@japa/snapshot": "^2.0.4",
"@swc/core": "^1.4.11",
"@types/dlv": "^1.1.4",
"@types/node": "^20.11.30",
Expand Down
25 changes: 23 additions & 2 deletions src/vine/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { Compiler, refsBuilder } from '@vinejs/compiler'
import type { MessagesProviderContact } from '@vinejs/compiler/types'
import type { MessagesProviderContact, Refs, RootNode } from '@vinejs/compiler/types'

import { messages } from '../defaults.js'
import { ITYPE, OTYPE, PARSE } from '../symbols.js'
Expand Down Expand Up @@ -41,7 +41,15 @@ export class VineValidator<
* Reference to static types
*/
declare [ITYPE]: Schema[typeof ITYPE];
declare [OTYPE]: Schema[typeof OTYPE]
declare [OTYPE]: Schema[typeof OTYPE];

Check failure on line 44 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / lint / lint

Delete `;`

Check failure on line 44 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_windows (20.10.0)

Delete `;`

Check failure on line 44 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (20.10.0)

Delete `;`

Check failure on line 44 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (21.x)

Delete `;`

/**
* Reference to the compiled schema
*/
#compiled: {
schema: RootNode,

Check failure on line 50 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / lint / lint

Delete `,`

Check failure on line 50 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_windows (20.10.0)

Delete `,`

Check failure on line 50 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (20.10.0)

Delete `,`

Check failure on line 50 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (21.x)

Delete `,`
refs: Refs,

Check failure on line 51 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / lint / lint

Delete `,`

Check failure on line 51 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_windows (20.10.0)

Delete `,`

Check failure on line 51 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (20.10.0)

Delete `,`

Check failure on line 51 in src/vine/validator.ts

View workflow job for this annotation

GitHub Actions / test / test_linux (21.x)

Delete `,`
}

/**
* Messages provider to use on the validator
Expand Down Expand Up @@ -102,6 +110,8 @@ export class VineValidator<
* Compile the schema to a re-usable function
*/
const { compilerNode, refs } = this.#parse(schema)
this.#compiled = { schema: compilerNode, refs }

const metaDataValidator = options.metaDataValidator
const validateFn = new Compiler(compilerNode, {
convertEmptyStringsToNull: options.convertEmptyStringsToNull,
Expand Down Expand Up @@ -147,4 +157,15 @@ export class VineValidator<
}
}
}

/**
* Returns the compiled schema and refs.
*/
toJSON() {
const { schema, refs } = this.#compiled
return {
schema: structuredClone(schema),
refs,
}
}
}
118 changes: 118 additions & 0 deletions tests/integration/validator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,121 @@ test.group('Validator | extend schema classes', () => {
assert.isTrue((vine as any).money())
})
})

test.group('Validator | toJSON', () => {
test('get JSON representation of the schema', async ({ assert }) => {
const author = vine.object({
name: vine.string(),
email: vine.string().email(),
role: vine.string().in((field) => {
assert.deepEqual(field.meta, { choices: ['admin', 'guest'] })
return field.meta.choices
}),
})

const validator = vine.compile(author)
assert.snapshot(validator.toJSON()).matchInline(`
{
"refs": {
"ref://1": {
"options": undefined,
"validator": [Function],
},
"ref://2": {
"options": undefined,
"validator": [Function],
},
"ref://3": {
"options": undefined,
"validator": [Function],
},
"ref://4": {
"options": undefined,
"validator": [Function],
},
"ref://5": {
"options": {
"choices": [Function],
},
"validator": [Function],
},
},
"schema": {
"schema": {
"allowNull": false,
"allowUnknownProperties": false,
"bail": true,
"fieldName": "",
"groups": [],
"isOptional": false,
"parseFnId": undefined,
"properties": [
{
"allowNull": false,
"bail": true,
"fieldName": "name",
"isOptional": false,
"parseFnId": undefined,
"propertyName": "name",
"type": "literal",
"validations": [
{
"implicit": false,
"isAsync": false,
"ruleFnId": "ref://1",
},
],
},
{
"allowNull": false,
"bail": true,
"fieldName": "email",
"isOptional": false,
"parseFnId": undefined,
"propertyName": "email",
"type": "literal",
"validations": [
{
"implicit": false,
"isAsync": false,
"ruleFnId": "ref://2",
},
{
"implicit": false,
"isAsync": false,
"ruleFnId": "ref://3",
},
],
},
{
"allowNull": false,
"bail": true,
"fieldName": "role",
"isOptional": false,
"parseFnId": undefined,
"propertyName": "role",
"type": "literal",
"validations": [
{
"implicit": false,
"isAsync": false,
"ruleFnId": "ref://4",
},
{
"implicit": false,
"isAsync": false,
"ruleFnId": "ref://5",
},
],
},
],
"propertyName": "",
"type": "object",
"validations": [],
},
"type": "root",
},
}
`)
}).pin()
})

0 comments on commit 5259933

Please sign in to comment.