swaps out ajv for joi
This commit is contained in:
@@ -1,154 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "collection.schema.json",
|
||||
"title": "Payload Collection Configuration",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"slug",
|
||||
"fields"
|
||||
],
|
||||
"properties": {
|
||||
"slug": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"singular": {
|
||||
"type": "string",
|
||||
"description": "Name used when referring to an instance of the collection"
|
||||
},
|
||||
"plural": {
|
||||
"type": "string",
|
||||
"description": "Name used when referring to set of instances for the collection"
|
||||
}
|
||||
}
|
||||
},
|
||||
"access": {
|
||||
"type": "object",
|
||||
"description": "Callable functions to determine permission access"
|
||||
},
|
||||
"auth": {
|
||||
"type": ["object", "boolean"],
|
||||
"description": "Authentication properties",
|
||||
"properties": {
|
||||
"verify": {
|
||||
"description": "Require users to verify their email before being able to login for this collection",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "Enable email verification of user accounts, set to true to enable the feature using Payload default settings"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{
|
||||
"required": [
|
||||
"generateEmailSubject"
|
||||
],
|
||||
"properties": {
|
||||
"generateEmailSubject": {
|
||||
"type": "string",
|
||||
"description": "Subject field used when sending verify email for new user accounts"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"generateEmailHTML"
|
||||
],
|
||||
"generateEmailHTML": {
|
||||
"type": "string",
|
||||
"description": "Function that returns HTML for the body of the email sent to verify user accounts"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"description": "The attributes of the collection",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The attribute key of the field used on model instances"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": ""
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "Field label for the admin panel"
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean",
|
||||
"description": "Enforce attribute has a value when saving"
|
||||
},
|
||||
"defaultValue": {
|
||||
"description": "When not present, will be saved with when not given"
|
||||
},
|
||||
"unique": {
|
||||
"description": "Enforce instances in the collection to not repeat the value",
|
||||
"type": "boolean"
|
||||
},
|
||||
"access": {
|
||||
"description": "Field level permissions",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"create": {},
|
||||
"update": {},
|
||||
"read": {}
|
||||
}
|
||||
},
|
||||
"relationTo": {
|
||||
"description": "The name of the collection being referenced",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"options": {
|
||||
"description": "Choices",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{"type": "string"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"value": {
|
||||
"description": "The data stored and returned for the selection",
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"description": "The name that identifies the value to be selected",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"timestamps": {
|
||||
"type": "boolean",
|
||||
"description": "Adds createdAt and updatedAt fields for the collection",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/collections/config/schema.ts
Normal file
7
src/collections/config/schema.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import Joi from 'joi';
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
slug: Joi.string().required(),
|
||||
}).unknown();
|
||||
|
||||
export default schema;
|
||||
@@ -11,8 +11,6 @@ const sanitizeConfig = (config: Config): Config => {
|
||||
// TODO: remove default values from sanitize in favor of assigning in the schema within validateSchema and use https://www.npmjs.com/package/ajv#coercing-data-types where needed
|
||||
if (sanitizedConfig.publicENV === undefined) sanitizedConfig.publicENV = {};
|
||||
|
||||
if (sanitizedConfig.defaultDepth === undefined) sanitizedConfig.defaultDepth = 2;
|
||||
|
||||
sanitizedConfig.collections = sanitizedConfig.collections.map((collection) => sanitizeCollection(sanitizedConfig.collections, collection));
|
||||
checkDuplicateCollections(sanitizedConfig.collections);
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "payload.schema.json",
|
||||
"title": "Payload Configuration",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"collections"
|
||||
],
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": "object",
|
||||
"description": "Admin panel configuration",
|
||||
"properties": {
|
||||
"user": {
|
||||
"type": "string",
|
||||
"description": "Collection name users designated to access the panel"
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"description": "Admin web interface configuration",
|
||||
"required": [
|
||||
"titleSuffix"
|
||||
],
|
||||
"properties": {
|
||||
"titleSuffix": {
|
||||
"type": "string",
|
||||
"description": "Text to add at the end of the page title of the admin html head"
|
||||
},
|
||||
"ogImage": {
|
||||
"type": "string",
|
||||
"description": "src url for the admin image"
|
||||
},
|
||||
"favicon": {
|
||||
"type": "string",
|
||||
"description": "Admin panel favicon file to use"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"maxDepth": {
|
||||
"type": "number",
|
||||
"description": "The maximum population depth allowed for relationship fields",
|
||||
"default": 10
|
||||
},
|
||||
"collections": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "./collection.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/config/schema.ts
Normal file
53
src/config/schema.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import Joi from 'joi';
|
||||
import collectionSchema from '../collections/config/schema';
|
||||
import globalSchema from '../globals/config/schema';
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
serverURL: Joi.string().required(),
|
||||
routes: Joi.object()
|
||||
.keys({
|
||||
admin: Joi.string()
|
||||
.default('/admin'),
|
||||
api: Joi.string()
|
||||
.default('/api'),
|
||||
graphQL: Joi.string()
|
||||
.default('/graphql'),
|
||||
graphQLPlayground: Joi.string()
|
||||
.default('/graphql-playground'),
|
||||
}).default(),
|
||||
collections: Joi.array()
|
||||
.items(collectionSchema)
|
||||
.default([]),
|
||||
globals: Joi.array()
|
||||
.items(globalSchema)
|
||||
.default([]),
|
||||
admin: Joi.object()
|
||||
.keys({
|
||||
user: Joi.string()
|
||||
.default('users'),
|
||||
meta: Joi.object()
|
||||
.keys({
|
||||
titleSuffix: Joi.string()
|
||||
.default('- Payload'),
|
||||
ogImage: Joi.string()
|
||||
.default('/static/img/find-image-here.jpg'),
|
||||
favicon: Joi.string()
|
||||
.default('/static/img/whatever.png'),
|
||||
})
|
||||
.default(),
|
||||
disable: Joi.bool()
|
||||
.default(false),
|
||||
components: Joi.object()
|
||||
.keys({}),
|
||||
}).default(),
|
||||
defaultDepth: Joi.number()
|
||||
.min(0)
|
||||
.max(30)
|
||||
.default(3),
|
||||
maxDepth: Joi.number()
|
||||
.min(0)
|
||||
.max(100)
|
||||
.default(11),
|
||||
}).unknown();
|
||||
|
||||
export default schema;
|
||||
@@ -1,20 +1,22 @@
|
||||
import Ajv from 'ajv';
|
||||
import * as configSchema from './schema.json';
|
||||
import * as collectionSchema from '../collections/config/schema.json';
|
||||
|
||||
import InvalidSchema from '../errors/InvalidSchema';
|
||||
import schema from './schema';
|
||||
import { PayloadConfig, Config } from './types';
|
||||
|
||||
const validateSchema = (config: PayloadConfig): Config => {
|
||||
const ajv = new Ajv({ useDefaults: true });
|
||||
const validate = ajv.addSchema(collectionSchema, '../collections/config/schema.json').compile(configSchema);
|
||||
const valid = validate(config);
|
||||
const result = schema.validate(config, {
|
||||
abortEarly: false,
|
||||
});
|
||||
|
||||
if (!valid) {
|
||||
throw new InvalidSchema(`Invalid payload config provided. Found ${validate.errors.length} errors`, validate.errors);
|
||||
if (result.error) {
|
||||
console.error(`There were ${result.error.details.length} errors validating your Payload config`);
|
||||
|
||||
result.error.details.forEach(({ message }, i) => {
|
||||
console.error(`${i + 1}: ${message}`);
|
||||
});
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return config as Config;
|
||||
return result.value as Config;
|
||||
};
|
||||
|
||||
export default validateSchema;
|
||||
|
||||
7
src/globals/config/schema.ts
Normal file
7
src/globals/config/schema.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import Joi from 'joi';
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
slug: Joi.string().required(),
|
||||
}).unknown();
|
||||
|
||||
export default schema;
|
||||
Reference in New Issue
Block a user