forked from seriousme/fastify-openapi-glue
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
95 lines (81 loc) · 2.45 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const fp = require("fastify-plugin");
const parser = require("./lib/parser");
function isObject(obj) {
return typeof obj === "object" && obj !== null;
}
function getObject(param) {
let data = param;
if (typeof param === "string") {
try {
data = require(param);
} catch (error) {
throw new Error(`failed to load ${param}`);
}
}
if (typeof data === "function") {
data = data();
}
return data;
}
// fastify uses the built-in AJV instance during serialization, and that
// instance does not know about int32 and int64 so remove those formats
// from the responses
const unknownFormats = { int32: true, int64: true };
function stripResponseFormats(schema) {
for (let item in schema) {
if (isObject(schema[item])) {
if (schema[item].format && unknownFormats[schema[item].format]) {
schema[item].format = undefined;
}
stripResponseFormats(schema[item]);
}
}
}
async function fastifyOpenapiGlue(instance, opts) {
const service = getObject(opts.service);
if (!isObject(service)) {
throw new Error("'service' parameter must refer to an object");
}
const config = await parser().parse(opts.specification);
const routeConf = {};
// AJV misses some validators for int32, int64 etc which ajv-oai adds
const Ajv = require("ajv-oai");
const ajv = new Ajv({
// the fastify defaults
removeAdditional: true,
useDefaults: true,
coerceTypes: true
});
instance.setSchemaCompiler(schema => ajv.compile(schema));
if (opts.prefix) {
routeConf.prefix = opts.prefix;
} else if (config.prefix) {
routeConf.prefix = config.prefix;
}
async function generateRoutes(routesInstance, opts) {
config.routes.forEach(item => {
const response = item.schema.response;
if (response) {
stripResponseFormats(response);
}
if (service[item.operationId]) {
routesInstance.log.debug("service has", item.operationId);
item.handler = service[item.operationId];
} else {
item.handler = async (request, reply) => {
throw new Error(`Operation ${item.operationId} not implemented`);
};
}
routesInstance.route(item);
});
}
instance.register(generateRoutes, routeConf);
}
module.exports = fp(fastifyOpenapiGlue, {
fastify: ">=0.39.0",
name: "fastify-openapi-glue"
});
module.exports.options = {
specification: "examples/petstore/petstore-swagger.v2.json",
service: "examples/petstore/service.js"
};