Implement config validation

This commit is contained in:
LordMathis 2020-05-09 14:37:48 +02:00
parent 663f4d86fb
commit 70e7ec8e5d
5 changed files with 159 additions and 1 deletions

View File

@ -17,6 +17,7 @@
"author": "Matúš Námešný",
"license": "MIT",
"dependencies": {
"ajv": "^6.12.2",
"async": "^3.1.0",
"axios": "^0.19.1",
"chokidar": "^3.3.0",

View File

@ -9,6 +9,7 @@ import { ServerRenderer } from './utils/serverRender'
import { Scanner } from './utils/scanner'
import { FileStorage } from './utils/storage/file'
import { MongoStorage } from './utils/storage/mongo'
import { Config } from './utils/config'
import { Api } from './utils/api'
const configPath = process.argv[2] || path.join(process.cwd(), 'config/config.json')
@ -16,7 +17,7 @@ const configPath = process.argv[2] || path.join(process.cwd(), 'config/config.js
const app = express()
app.set('trust proxy', true)
const config = jsonfile.readFileSync(configPath)
const config = new Config(jsonfile.readFileSync(configPath))
if (config == null) {
throw new Error('Config file not found!')
}

25
src/utils/config.js Normal file
View File

@ -0,0 +1,25 @@
import Ajv from 'ajv'
import configSchema from './configSchema.json'
export class Config {
constructor (configFile) {
const ajv = new Ajv()
var valid = ajv.validate(configSchema, configFile)
if (!valid) {
throw ajv.errors
}
this.title = configFile.title
this.name = configFile.name
this.email = configFile.email || ''
this.social = configFile.social || []
this.baseUrl = configFile.baseUrl || 'localhost'
this.contentPath = configFile.contentPath || './content'
this.storage = configFile.storage || 'file'
if (this.storage === 'mongo') {
this.mongoUrl = configFile.mongoUrl
}
this.specialFiles = configFile.specialFiles || ['about.md']
}
}

121
src/utils/configSchema.json Normal file
View File

@ -0,0 +1,121 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"title": "The root schema",
"description": "The root schema comprises the entire JSON document.",
"default": {},
"required": [
"title",
"name",
"baseUrl"
],
"additionalProperties": true,
"properties": {
"title": {
"$id": "#/properties/title",
"type": "string",
"title": "The title schema",
"description": "The title of the website"
},
"name": {
"$id": "#/properties/name",
"type": "string",
"title": "The name schema",
"description": "Your name",
"examples": [
"John Doe"
]
},
"email": {
"$id": "#/properties/email",
"type": "string",
"title": "The email schema",
"description": "Your email",
"default": "",
"examples": [
"john.doe@example.com"
]
},
"social": {
"$id": "#/properties/social",
"type": "object",
"title": "The social schema",
"description": "Links to your social accounts",
"default": {},
"examples": [
{
"linkedin": "https://www.linkedin.com/in/johndoe/",
"codepen": "https://codepen.io/johndoe/",
"github": "https://github.com/johndoe"
}
],
"additionalProperties": true
},
"baseUrl": {
"$id": "#/properties/baseUrl",
"type": "string",
"title": "The baseUrl schema",
"description": "Base URL of your website",
"examples": [
"example.com"
]
},
"storage": {
"$id": "#/properties/storage",
"type": "string",
"enum": ["mongo", "file"],
"title": "The storage schema",
"description": "The content storage configuration",
"default": "file"
},
"mongourl": {
"$id": "#/properties/mongourl",
"type": "string",
"title": "The mongourl schema",
"description": "Sets MongoDb url if mongo is specified as a storage option.",
"examples": [
"mongodb://localhost:27017"
]
},
"contentPath": {
"$id": "#/properties/contentPath",
"type": "string",
"title": "The contentPath schema",
"description": "The path to your content.",
"examples": [
"./content"
]
},
"specialFiles": {
"$id": "#/properties/specialFiles",
"type": "array",
"title": "The specialFiles schema",
"description": "Files that are not normal blog posts.",
"default": [],
"examples": [
[
"about.md",
"resume.md"
]
],
"additionalItems": true,
"items": {
"$id": "#/properties/specialFiles/items",
"anyOf": [
{
"$id": "#/properties/specialFiles/items/anyOf/0",
"type": "string",
"title": "The first anyOf schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
"about.md",
"resume.md"
]
}
]
}
}
}
}

View File

@ -1116,6 +1116,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^6.12.2:
version "6.12.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
alphanum-sort@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"