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.
Files changed (3) hide show
  1. package/index.js +7 -12
  2. package/package.json +2 -2
  3. 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
- return (data) => {
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
- const err = new Error(result.errors.map(e => e.message).join(', '))
25
- err.statusCode = 400
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.18",
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.5.1",
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()