fastify-ata 0.2.18 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +7 -12
- package/package.json +2 -2
- package/test.js +90 -0
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const { Validator } = require('ata-validator')
|
|
|
5
5
|
|
|
6
6
|
function fastifyAta(fastify, opts, done) {
|
|
7
7
|
const cache = new WeakMap()
|
|
8
|
+
const hasCoercion = !!(opts.coerceTypes || opts.removeAdditional)
|
|
8
9
|
const validatorOpts = {
|
|
9
10
|
coerceTypes: opts.coerceTypes || false,
|
|
10
11
|
removeAdditional: opts.removeAdditional || false,
|
|
@@ -16,22 +17,16 @@ function fastifyAta(fastify, opts, done) {
|
|
|
16
17
|
validator = new Validator(schema, validatorOpts)
|
|
17
18
|
cache.set(schema, validator)
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
const validate = (data) => {
|
|
20
21
|
const result = validator.validate(data)
|
|
21
22
|
if (result.valid) {
|
|
22
|
-
return { value: data }
|
|
23
|
+
return hasCoercion ? { value: data } : true
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
err.validation = result.errors.map(e => ({
|
|
27
|
-
message: e.message,
|
|
28
|
-
instancePath: e.path || '',
|
|
29
|
-
schemaPath: '',
|
|
30
|
-
keyword: '',
|
|
31
|
-
params: {},
|
|
32
|
-
}))
|
|
33
|
-
return { error: err }
|
|
25
|
+
validate.errors = result.errors
|
|
26
|
+
return false
|
|
34
27
|
}
|
|
28
|
+
validate.errors = null
|
|
29
|
+
return validate
|
|
35
30
|
})
|
|
36
31
|
|
|
37
32
|
done()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify-ata",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"description": "Fastify plugin for ata-validator — beats ajv on every valid-path benchmark. 2.7x faster validate(obj), 151x faster compilation, simdjson + multi-core.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/ata-core/fastify-ata#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"ata-validator": "^0.
|
|
29
|
+
"ata-validator": "^0.7.3",
|
|
30
30
|
"fastify-ata": "^0.2.16",
|
|
31
31
|
"fastify-plugin": "^5.1.0",
|
|
32
32
|
"sanitize-filename": "^1.6.4"
|
package/test.js
CHANGED
|
@@ -99,6 +99,96 @@ async function run() {
|
|
|
99
99
|
const errBody = JSON.parse(r2.payload)
|
|
100
100
|
assert(errBody.message && errBody.message.length > 0, `error message present: "${errBody.message}"`)
|
|
101
101
|
|
|
102
|
+
// 9. Ajv-style error format — FST_ERR_VALIDATION and AJV message
|
|
103
|
+
const r4 = await app.inject({
|
|
104
|
+
method: 'POST',
|
|
105
|
+
url: '/user',
|
|
106
|
+
payload: { name: 123 },
|
|
107
|
+
})
|
|
108
|
+
const errBody4 = JSON.parse(r4.payload)
|
|
109
|
+
assert(r4.statusCode === 400, `ajv-style: returns 400 (got ${r4.statusCode})`)
|
|
110
|
+
assert(errBody4.message.includes('must be'), `ajv-style: AJV message format: "${errBody4.message}"`)
|
|
111
|
+
|
|
112
|
+
// 10. Coercion support
|
|
113
|
+
const app4 = fastify()
|
|
114
|
+
await app4.register(fastifyAta, { coerceTypes: true })
|
|
115
|
+
app4.post('/coerce', {
|
|
116
|
+
schema: {
|
|
117
|
+
body: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: { count: { type: 'integer' } },
|
|
120
|
+
required: ['count'],
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
}, (req, reply) => {
|
|
124
|
+
reply.send({ count: req.body.count, type: typeof req.body.count })
|
|
125
|
+
})
|
|
126
|
+
await app4.ready()
|
|
127
|
+
const r5 = await app4.inject({
|
|
128
|
+
method: 'POST',
|
|
129
|
+
url: '/coerce',
|
|
130
|
+
payload: { count: '42' },
|
|
131
|
+
})
|
|
132
|
+
assert(r5.statusCode === 200, `coercion: returns 200 (got ${r5.statusCode})`)
|
|
133
|
+
const body5 = JSON.parse(r5.payload)
|
|
134
|
+
assert(body5.count === 42, `coercion: count coerced to integer (got ${body5.count})`)
|
|
135
|
+
assert(body5.type === 'number', `coercion: type is number (got ${body5.type})`)
|
|
136
|
+
await app4.close()
|
|
137
|
+
|
|
138
|
+
// 11. removeAdditional support
|
|
139
|
+
const app5 = fastify()
|
|
140
|
+
await app5.register(fastifyAta, { removeAdditional: true })
|
|
141
|
+
app5.post('/strip', {
|
|
142
|
+
schema: {
|
|
143
|
+
body: {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: { name: { type: 'string' } },
|
|
146
|
+
additionalProperties: false,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
}, (req, reply) => {
|
|
150
|
+
reply.send(req.body)
|
|
151
|
+
})
|
|
152
|
+
await app5.ready()
|
|
153
|
+
const r6 = await app5.inject({
|
|
154
|
+
method: 'POST',
|
|
155
|
+
url: '/strip',
|
|
156
|
+
payload: { name: 'Mert', extra: 'gone' },
|
|
157
|
+
})
|
|
158
|
+
assert(r6.statusCode === 200, `removeAdditional: returns 200 (got ${r6.statusCode})`)
|
|
159
|
+
const body6 = JSON.parse(r6.payload)
|
|
160
|
+
assert(body6.name === 'Mert', `removeAdditional: name preserved`)
|
|
161
|
+
assert(body6.extra === undefined, `removeAdditional: extra stripped (got ${JSON.stringify(body6)})`)
|
|
162
|
+
await app5.close()
|
|
163
|
+
|
|
164
|
+
// 12. Nested schema validation error
|
|
165
|
+
const app6 = fastify()
|
|
166
|
+
await app6.register(fastifyAta)
|
|
167
|
+
app6.post('/nested', {
|
|
168
|
+
schema: {
|
|
169
|
+
body: {
|
|
170
|
+
type: 'object',
|
|
171
|
+
properties: {
|
|
172
|
+
user: {
|
|
173
|
+
type: 'object',
|
|
174
|
+
properties: { email: { type: 'string', format: 'email' } },
|
|
175
|
+
required: ['email'],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
}, (req, reply) => reply.send({ ok: true }))
|
|
181
|
+
await app6.ready()
|
|
182
|
+
const r7 = await app6.inject({
|
|
183
|
+
method: 'POST',
|
|
184
|
+
url: '/nested',
|
|
185
|
+
payload: { user: {} },
|
|
186
|
+
})
|
|
187
|
+
assert(r7.statusCode === 400, `nested: returns 400 (got ${r7.statusCode})`)
|
|
188
|
+
const errBody7 = JSON.parse(r7.payload)
|
|
189
|
+
assert(errBody7.message.includes('email'), `nested: message mentions email: "${errBody7.message}"`)
|
|
190
|
+
await app6.close()
|
|
191
|
+
|
|
102
192
|
await app.close()
|
|
103
193
|
await app2.close()
|
|
104
194
|
await app3.close()
|