Skip to content

Commit 4e474bd

Browse files
author
Sako K
committed
[NEW] - Add option excludeOnFalseSchema + Test
1 parent 9f78301 commit 4e474bd

File tree

4 files changed

+135
-5
lines changed

4 files changed

+135
-5
lines changed

index.d.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ enum SchemaTypes {
2323
Params = "params",
2424
}
2525

26-
declare namespace fasticyEnforceSchema {
26+
declare namespace fastifyEnforceSchema {
2727
export type OriginFunction = (
2828
origin: string,
2929
callback: OriginCallback
@@ -35,6 +35,22 @@ declare namespace fasticyEnforceSchema {
3535
* A list of endpoints to exclude by the route path
3636
*/
3737
exclude: string[];
38+
/**
39+
* If true, the plugin will not throw an error if the schema or schema types is equal to false
40+
* @default false
41+
* @example
42+
* fastify.register(fastifyEnforceSchema, { excludeOnFalseSchema: true })
43+
*
44+
* fastify.get('/', { schema: false }, (req, reply) => {
45+
* reply.send({ hello: 'world' })
46+
* })
47+
* // or
48+
* fastify.get('/test', { schema: { body: false } }, (req, reply) => {
49+
* reply.send({ hello: 'world' })
50+
* })
51+
* // no error will be thrown
52+
*/
53+
excludeOnFalseSchema: boolean;
3854
}
3955

4056
export interface FastifyEnforceSchemaOptionsDelegateCallback {

index.js

+32-3
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,43 @@ function FastifyEnforceSchema(fastify, opts, done) {
2121
opts.exclude = [];
2222
}
2323

24-
const { required, exclude } = opts;
24+
if (!Object.prototype.hasOwnProperty.call(opts, 'excludeOnFalseSchema')) {
25+
opts.excludeOnFalseSchema = false;
26+
}
27+
28+
const { required, exclude, excludeOnFalseSchema } = opts;
2529

26-
fastify.addHook("onRoute", routeOptions => {
27-
if (routeOptions.path === "*" || !routeOptions.path) {
30+
fastify.addHook("onRoute", (routeOptions) => {
31+
if (
32+
routeOptions.path === "*" ||
33+
!routeOptions.path ||
34+
(excludeOnFalseSchema && routeOptions.schema === false)
35+
) {
2836
done();
2937
return;
3038
}
3139

40+
if (excludeOnFalseSchema && typeof routeOptions.schema === "object") {
41+
const excludedEntity = exclude.find(
42+
({ url }) => url === routeOptions.path
43+
);
44+
const excludedSchemas = [];
45+
46+
Object.entries(routeOptions.schema).forEach(([key, value]) => {
47+
if (value === false) {
48+
excludedSchemas.push(key);
49+
}
50+
});
51+
52+
if (excludedEntity) {
53+
excludedEntity.excludedSchemas = [
54+
...new Set([...excludedEntity.excludedSchemas, ...excludedSchemas]),
55+
];
56+
} else {
57+
exclude.push({ url: routeOptions.path, excludedSchemas });
58+
}
59+
}
60+
3261
const excludedEntity = [...initialExcludes, ...exclude].find(
3362
({ url }) => url === routeOptions.path
3463
);

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "fastify-enforce-schema",
33
"url": "",
44
"author": "Aleksandar Grbic - (https://programmer.network)",
5-
"version": "1.0.4",
5+
"version": "1.0.5",
66
"description": "Enforce AJV schemas across your endpoints.",
77
"repository": {
88
"type": "git",

test/enforce-schema.test.js

+85
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,52 @@ test("enforce should be disabled for excluded paths without excludedSchemas prop
243243
t.equal(res.payload, "exclude works");
244244
});
245245

246+
test("enforce should be disabled for excluded paths via excludeOnFalseSchema option directly on schema", async (t) => {
247+
t.plan(2);
248+
249+
const fastify = Fastify();
250+
251+
await fastify.register(enforceSchema, {
252+
required: ["response"],
253+
excludeOnFalseSchema: true,
254+
});
255+
256+
fastify.get("/foo", { schema: false }, (req, reply) => {
257+
reply.code(200).send("exclude works");
258+
});
259+
260+
const res = await fastify.inject({
261+
method: "GET",
262+
url: "/foo",
263+
});
264+
265+
t.equal(res.statusCode, 200);
266+
t.equal(res.payload, "exclude works");
267+
});
268+
269+
test("enforce should be disabled for excluded paths via excludeOnFalseSchema option directly on schema.response", async (t) => {
270+
t.plan(2);
271+
272+
const fastify = Fastify();
273+
274+
await fastify.register(enforceSchema, {
275+
required: ["response"],
276+
excludeOnFalseSchema: true,
277+
});
278+
279+
fastify.get("/foo", { schema: { response: false } }, (req, reply) => {
280+
reply.code(200).send("exclude works");
281+
});
282+
283+
const res = await fastify.inject({
284+
method: "GET",
285+
url: "/foo",
286+
});
287+
288+
t.equal(res.statusCode, 200);
289+
t.equal(res.payload, "exclude works");
290+
});
291+
246292
test("enforce should be disabled at the body schema", async t => {
247293
t.plan(2);
248294

@@ -273,3 +319,42 @@ test("enforce should be disabled at the body schema", async t => {
273319
t.equal(res.statusCode, 200);
274320
t.equal(res.payload, "body schema excluded for /foo");
275321
});
322+
323+
test("No http status codes set in schema for required schema type", async (t) => {
324+
t.plan(1);
325+
326+
const fastify = Fastify();
327+
328+
await fastify.register(enforceSchema, {
329+
required: ["response"],
330+
});
331+
332+
try {
333+
fastify.get("/foo", { schema: { response: {} } }, (req, reply) => {
334+
reply.code(200).send("exclude works");
335+
});
336+
} catch (err) {
337+
t.equal(
338+
err.message,
339+
"No HTTP status codes provided in the response schema"
340+
);
341+
}
342+
});
343+
344+
test("Http status code outside support set in schema for required schema type", async (t) => {
345+
t.plan(1);
346+
347+
const fastify = Fastify();
348+
349+
await fastify.register(enforceSchema, {
350+
required: ["response"],
351+
});
352+
353+
try {
354+
fastify.get("/foo", { schema: { response: { 600: {} } } }, (req, reply) => {
355+
reply.code(200).send("exclude works");
356+
});
357+
} catch (err) {
358+
t.equal(err.message, "HTTP status codes from 100 - 599 supported");
359+
}
360+
});

0 commit comments

Comments
 (0)