1 | 'use strict'
|
2 |
|
3 | const AjvStandaloneCompiler = require('@fastify/ajv-compiler/standalone')
|
4 | const { _ } = require('ajv')
|
5 | const fs = require('node:fs')
|
6 | const path = require('node:path')
|
7 |
|
8 | const factory = AjvStandaloneCompiler({
|
9 | readMode: false,
|
10 | storeFunction (routeOpts, schemaValidationCode) {
|
11 | const moduleCode = `// This file is autogenerated by ${__filename.replace(__dirname, 'build')}, do not edit
|
12 | /* istanbul ignore file */
|
13 | ${schemaValidationCode}
|
14 |
|
15 | module.exports.defaultInitOptions = ${JSON.stringify(defaultInitOptions)}
|
16 | `
|
17 |
|
18 | const file = path.join(__dirname, '..', 'lib', 'configValidator.js')
|
19 | fs.writeFileSync(file, moduleCode)
|
20 | console.log(`Saved ${file} file successfully`)
|
21 | }
|
22 | })
|
23 |
|
24 | const defaultInitOptions = {
|
25 | connectionTimeout: 0,
|
26 | keepAliveTimeout: 72000,
|
27 | forceCloseConnections: undefined,
|
28 | maxRequestsPerSocket: 0,
|
29 | requestTimeout: 0,
|
30 | bodyLimit: 1024 * 1024,
|
31 | caseSensitive: true,
|
32 | allowUnsafeRegex: false,
|
33 | disableRequestLogging: false,
|
34 | jsonShorthand: true,
|
35 | ignoreTrailingSlash: false,
|
36 | ignoreDuplicateSlashes: false,
|
37 | maxParamLength: 100,
|
38 | onProtoPoisoning: 'error',
|
39 | onConstructorPoisoning: 'error',
|
40 | pluginTimeout: 10000,
|
41 | requestIdHeader: 'request-id',
|
42 | requestIdLogLabel: 'reqId',
|
43 | http2SessionTimeout: 72000,
|
44 | exposeHeadRoutes: true,
|
45 | useSemicolonDelimiter: true
|
46 | }
|
47 |
|
48 | const schema = {
|
49 | type: 'object',
|
50 | additionalProperties: false,
|
51 | properties: {
|
52 | connectionTimeout: { type: 'integer', default: defaultInitOptions.connectionTimeout },
|
53 | keepAliveTimeout: { type: 'integer', default: defaultInitOptions.keepAliveTimeout },
|
54 | forceCloseConnections: {
|
55 | oneOf: [
|
56 | {
|
57 | type: 'string',
|
58 | pattern: 'idle'
|
59 | },
|
60 | {
|
61 | type: 'boolean'
|
62 | }
|
63 | ]
|
64 | },
|
65 | maxRequestsPerSocket: { type: 'integer', default: defaultInitOptions.maxRequestsPerSocket, nullable: true },
|
66 | requestTimeout: { type: 'integer', default: defaultInitOptions.requestTimeout },
|
67 | bodyLimit: { type: 'integer', default: defaultInitOptions.bodyLimit },
|
68 | caseSensitive: { type: 'boolean', default: defaultInitOptions.caseSensitive },
|
69 | allowUnsafeRegex: { type: 'boolean', default: defaultInitOptions.allowUnsafeRegex },
|
70 | http2: { type: 'boolean' },
|
71 | https: {
|
72 | if: {
|
73 | not: {
|
74 | oneOf: [
|
75 | { type: 'boolean' },
|
76 | { type: 'null' },
|
77 | {
|
78 | type: 'object',
|
79 | additionalProperties: false,
|
80 | required: ['allowHTTP1'],
|
81 | properties: {
|
82 | allowHTTP1: { type: 'boolean' }
|
83 | }
|
84 | }
|
85 | ]
|
86 | }
|
87 | },
|
88 | then: { setDefaultValue: true }
|
89 | },
|
90 | ignoreTrailingSlash: { type: 'boolean', default: defaultInitOptions.ignoreTrailingSlash },
|
91 | ignoreDuplicateSlashes: { type: 'boolean', default: defaultInitOptions.ignoreDuplicateSlashes },
|
92 | disableRequestLogging: {
|
93 | type: 'boolean',
|
94 | default: false
|
95 | },
|
96 | jsonShorthand: { type: 'boolean', default: defaultInitOptions.jsonShorthand },
|
97 | maxParamLength: { type: 'integer', default: defaultInitOptions.maxParamLength },
|
98 | onProtoPoisoning: { type: 'string', default: defaultInitOptions.onProtoPoisoning },
|
99 | onConstructorPoisoning: { type: 'string', default: defaultInitOptions.onConstructorPoisoning },
|
100 | pluginTimeout: { type: 'integer', default: defaultInitOptions.pluginTimeout },
|
101 | requestIdHeader: { anyOf: [{ enum: [false] }, { type: 'string' }], default: defaultInitOptions.requestIdHeader },
|
102 | requestIdLogLabel: { type: 'string', default: defaultInitOptions.requestIdLogLabel },
|
103 | http2SessionTimeout: { type: 'integer', default: defaultInitOptions.http2SessionTimeout },
|
104 | exposeHeadRoutes: { type: 'boolean', default: defaultInitOptions.exposeHeadRoutes },
|
105 | useSemicolonDelimiter: { type: 'boolean', default: defaultInitOptions.useSemicolonDelimiter },
|
106 |
|
107 | versioning: {
|
108 | type: 'object',
|
109 | additionalProperties: true,
|
110 | required: ['storage', 'deriveVersion'],
|
111 | properties: {
|
112 | storage: { },
|
113 | deriveVersion: { }
|
114 | }
|
115 | },
|
116 | constraints: {
|
117 | type: 'object',
|
118 | additionalProperties: {
|
119 | type: 'object',
|
120 | required: ['name', 'storage', 'validate', 'deriveConstraint'],
|
121 | additionalProperties: true,
|
122 | properties: {
|
123 | name: { type: 'string' },
|
124 | storage: { },
|
125 | validate: { },
|
126 | deriveConstraint: { }
|
127 | }
|
128 | }
|
129 | }
|
130 | }
|
131 | }
|
132 |
|
133 | const compiler = factory({}, {
|
134 | customOptions: {
|
135 | code: {
|
136 | source: true,
|
137 | lines: true,
|
138 | optimize: 3
|
139 | },
|
140 | removeAdditional: true,
|
141 | useDefaults: true,
|
142 | coerceTypes: true,
|
143 | keywords: [
|
144 | {
|
145 | keyword: 'setDefaultValue',
|
146 | $data: true,
|
147 |
|
148 | modifying: true,
|
149 | valid: true,
|
150 | code (keywordCxt) {
|
151 | const { gen, it, schemaValue } = keywordCxt
|
152 | const logicCode = gen.assign(_`${it.parentData}[${it.parentDataProperty}]`, schemaValue)
|
153 | return logicCode
|
154 | }
|
155 | }
|
156 | ]
|
157 | }
|
158 | })
|
159 |
|
160 | compiler({ schema })
|