Add schema validators for map state

This commit is contained in:
Mitchell McCaffrey 2021-07-23 12:45:07 +10:00
parent ed64294855
commit e3a2cc766c
10 changed files with 744 additions and 0 deletions

View File

@ -17,6 +17,7 @@
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^13.0.2",
"ajv": "^8.6.2",
"ammo.js": "kripken/ammo.js#aab297a4164779c3a9d8dc8d9da26958de3cb778",
"case": "^1.6.3",
"color": "^3.1.3",

26
src/validators/Color.ts Normal file
View File

@ -0,0 +1,26 @@
import Ajv, { JSONSchemaType } from "ajv";
import { Color } from "../helpers/colors";
const ajv = new Ajv();
export const ColorSchema: JSONSchemaType<Color> = {
$id: "https://www.owlbear.rodeo/schemas/color.json",
enum: [
"black",
"blue",
"darkGray",
"green",
"lightGray",
"orange",
"pink",
"primary",
"purple",
"red",
"teal",
"white",
"yellow",
],
type: "string",
};
export const isColor = ajv.compile<Color>(ColorSchema);

225
src/validators/Drawing.ts Normal file
View File

@ -0,0 +1,225 @@
import Ajv from "ajv";
import { Drawing } from "../types/Drawing";
import { ColorSchema } from "./Color";
import { Vector2Schema } from "./Vector2";
export const DrawingSchema = {
$id: "https://www.owlbear.rodeo/schemas/drawing.json",
anyOf: [
{
$ref: "#/definitions/Shape",
},
{
$ref: "#/definitions/Path",
},
],
definitions: {
PointsData: {
properties: {
points: {
items: {
$ref: "vector2.json",
},
type: "array",
},
},
required: ["points"],
type: "object",
},
RectData: {
properties: {
height: {
type: "number",
},
width: {
type: "number",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: ["height", "width", "x", "y"],
type: "object",
},
CircleData: {
properties: {
radius: {
type: "number",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: ["radius", "x", "y"],
type: "object",
},
BaseDrawing: {
properties: {
blend: {
type: "boolean",
},
color: {
$ref: "color.json",
},
id: {
type: "string",
},
strokeWidth: {
type: "number",
},
},
required: ["blend", "color", "id", "strokeWidth"],
type: "object",
},
BaseShape: {
allOf: [
{
$ref: "#/definitions/BaseDrawing",
},
{
properties: {
type: {
enum: ["shape"],
type: "string",
},
},
required: ["type"],
type: "object",
},
],
},
Line: {
allOf: [
{
$ref: "#/definitions/BaseShape",
},
{
properties: {
data: {
$ref: "#/definitions/PointsData",
},
shapeType: {
enum: ["line"],
type: "string",
},
},
required: ["data", "shapeType"],
type: "object",
},
],
},
Rectangle: {
allOf: [
{
$ref: "#/definitions/BaseShape",
},
{
properties: {
data: {
$ref: "#/definitions/RectData",
},
shapeType: {
enum: ["rectangle"],
type: "string",
},
},
required: ["data", "shapeType"],
type: "object",
},
],
},
Circle: {
allOf: [
{
$ref: "#/definitions/BaseShape",
},
{
properties: {
data: {
$ref: "#/definitions/CircleData",
},
shapeType: {
enum: ["circle"],
type: "string",
},
},
required: ["data", "shapeType"],
type: "object",
},
],
},
Triangle: {
allOf: [
{
$ref: "#/definitions/BaseShape",
},
{
properties: {
data: {
$ref: "#/definitions/PointsData",
},
shapeType: {
enum: ["triangle"],
type: "string",
},
},
required: ["data", "shapeType"],
type: "object",
},
],
},
Shape: {
anyOf: [
{
$ref: "#/definitions/Line",
},
{
$ref: "#/definitions/Rectangle",
},
{
$ref: "#/definitions/Circle",
},
{
$ref: "#/definitions/Triangle",
},
],
},
Path: {
allOf: [
{
$ref: "#/definitions/BaseDrawing",
},
{
properties: {
data: {
$ref: "#/definitions/PointsData",
},
pathType: {
enum: ["fill", "stroke"],
type: "string",
},
type: {
enum: ["path"],
type: "string",
},
},
required: ["data", "pathType", "type"],
type: "object",
},
],
},
},
};
export const ajv = new Ajv({
schemas: [DrawingSchema, ColorSchema, Vector2Schema],
});
export const isDrawing = ajv.compile<Drawing>(DrawingSchema);

59
src/validators/Fog.ts Normal file
View File

@ -0,0 +1,59 @@
import Ajv from "ajv";
import { Fog } from "../types/Fog";
import { Vector2Schema } from "./Vector2";
import { ColorSchema } from "./Color";
export const FogSchema = {
$id: "https://www.owlbear.rodeo/schemas/fog.json",
properties: {
color: {
$ref: "color.json",
},
data: {
$ref: "#/definitions/FogData",
},
id: {
type: "string",
},
strokeWidth: {
type: "number",
},
type: {
enum: ["fog"],
type: "string",
},
visible: {
type: "boolean",
},
},
required: ["color", "data", "id", "strokeWidth", "type", "visible"],
type: "object",
definitions: {
FogData: {
properties: {
holes: {
items: {
items: {
$ref: "vector2.json",
},
type: "array",
},
type: "array",
},
points: {
items: {
$ref: "vector2.json",
},
type: "array",
},
},
required: ["holes", "points"],
type: "object",
},
},
};
const ajv = new Ajv({ schemas: [FogSchema, ColorSchema, Vector2Schema] });
export const isFog = ajv.compile<Fog>(FogSchema);

104
src/validators/MapState.ts Normal file
View File

@ -0,0 +1,104 @@
import Ajv from "ajv";
import { MapState } from "../types/MapState";
import { DrawingSchema } from "./Drawing";
import { FogSchema } from "./Fog";
import { NoteSchema } from "./Note";
import { TokenStateSchema } from "./TokenState";
import { Vector2Schema } from "./Vector2";
import { ColorSchema } from "./Color";
import { OutlineSchema } from "./Outline";
export const MapStateSchema: any = {
$id: "https://www.owlbear.rodeo/schemas/map-state.json",
properties: {
tokens: {
$ref: "#/definitions/TokenStates",
},
drawShapes: {
$ref: "#/definitions/DrawingState",
},
fogShapes: {
$ref: "#/definitions/FogState",
},
editFlags: {
items: {
enum: ["drawing", "fog", "notes", "tokens"],
type: "string",
},
type: "array",
},
notes: {
$ref: "#/definitions/Notes",
},
mapId: {
type: "string",
},
},
required: [
"drawShapes",
"editFlags",
"fogShapes",
"mapId",
"notes",
"tokens",
],
type: "object",
definitions: {
TokenStates: {
propertyNames: {
type: "string",
},
additionalProperties: {
$ref: "token-state.json",
},
required: [],
type: "object",
},
DrawingState: {
propertyNames: {
type: "string",
},
additionalProperties: {
$ref: "drawing.json",
},
required: [],
type: "object",
},
FogState: {
propertyNames: {
type: "string",
},
additionalProperties: {
$ref: "fog.json",
},
required: [],
type: "object",
},
Notes: {
propertyNames: {
type: "string",
},
additionalProperties: {
$ref: "note.json",
},
required: [],
type: "object",
},
},
};
export const ajv = new Ajv({
schemas: [
MapStateSchema,
DrawingSchema,
FogSchema,
NoteSchema,
TokenStateSchema,
Vector2Schema,
ColorSchema,
OutlineSchema,
],
});
export const isMapState = ajv.compile<MapState>(MapStateSchema);

62
src/validators/Note.ts Normal file
View File

@ -0,0 +1,62 @@
import Ajv, { JSONSchemaType } from "ajv";
import { Note } from "../types/Note";
import { Vector2Schema } from "./Vector2";
import { ColorSchema } from "./Color";
export const NoteSchema: JSONSchemaType<Note> = {
$id: "https://www.owlbear.rodeo/schemas/note.json",
properties: {
color: {
$ref: "color.json",
},
id: {
type: "string",
},
lastModified: {
type: "number",
},
lastModifiedBy: {
type: "string",
},
locked: {
type: "boolean",
},
size: {
type: "number",
},
text: {
type: "string",
},
textOnly: {
type: "boolean",
},
visible: {
type: "boolean",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: [
"color",
"id",
"lastModified",
"lastModifiedBy",
"locked",
"size",
"text",
"textOnly",
"visible",
"x",
"y",
],
type: "object",
};
const ajv = new Ajv({ schemas: [NoteSchema, ColorSchema, Vector2Schema] });
export const isNote = ajv.compile<Note>(NoteSchema);

80
src/validators/Outline.ts Normal file
View File

@ -0,0 +1,80 @@
import Ajv from "ajv";
import { Outline } from "../types/Outline";
const ajv = new Ajv();
export const OutlineSchema = {
$id: "https://www.owlbear.rodeo/schemas/outline.json",
anyOf: [
{
$ref: "#/definitions/CircleOutline",
},
{
$ref: "#/definitions/RectOutline",
},
{
$ref: "#/definitions/PathOutline",
},
],
definitions: {
CircleOutline: {
properties: {
radius: {
type: "number",
},
type: {
enum: ["circle"],
type: "string",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: ["radius", "type", "x", "y"],
type: "object",
},
RectOutline: {
properties: {
height: {
type: "number",
},
type: {
enum: ["rect"],
type: "string",
},
width: {
type: "number",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: ["height", "type", "width", "x", "y"],
type: "object",
},
PathOutline: {
properties: {
points: {
items: {
type: "number",
},
type: "array",
},
type: {
enum: ["path"],
type: "string",
},
},
required: ["points", "type"],
type: "object",
},
},
};
export const isColor = ajv.compile<Outline>(OutlineSchema);

View File

@ -0,0 +1,147 @@
import Ajv from "ajv";
import { TokenState } from "../types/TokenState";
import { ColorSchema } from "./Color";
import { OutlineSchema } from "./Outline";
export const TokenStateSchema = {
$id: "https://www.owlbear.rodeo/schemas/token-state.json",
anyOf: [
{
$ref: "#/definitions/DefaultTokenState",
},
{
$ref: "#/definitions/FileTokenState",
},
],
definitions: {
TokenCategory: {
enum: ["character", "prop", "vehicle"],
type: "string",
},
BaseTokenState: {
properties: {
category: {
$ref: "#/definitions/TokenCategory",
},
height: {
type: "number",
},
id: {
type: "string",
},
label: {
type: "string",
},
lastModified: {
type: "number",
},
lastModifiedBy: {
type: "string",
},
locked: {
type: "boolean",
},
outline: {
$ref: "outline.json",
},
owner: {
type: "string",
},
rotation: {
type: "number",
},
size: {
type: "number",
},
statuses: {
items: {
$ref: "color.json",
},
type: "array",
},
tokenId: {
type: "string",
},
visible: {
type: "boolean",
},
width: {
type: "number",
},
x: {
type: "number",
},
y: {
type: "number",
},
},
required: [
"category",
"height",
"id",
"label",
"lastModified",
"lastModifiedBy",
"locked",
"outline",
"owner",
"rotation",
"size",
"statuses",
"tokenId",
"visible",
"width",
"x",
"y",
],
type: "object",
},
DefaultTokenState: {
allOf: [
{
$ref: "#/definitions/BaseTokenState",
},
{
properties: {
key: {
type: "string",
},
type: {
enum: ["default"],
type: "string",
},
},
required: ["key", "type"],
type: "object",
},
],
},
FileTokenState: {
allOf: [
{
$ref: "#/definitions/BaseTokenState",
},
{
properties: {
file: {
type: "string",
},
type: {
enum: ["file"],
type: "string",
},
},
required: ["file", "type"],
type: "object",
},
],
},
},
};
export const ajv = new Ajv({
schemas: [TokenStateSchema, ColorSchema, OutlineSchema],
});
export const isTokenState = ajv.compile<TokenState>(TokenStateSchema);

20
src/validators/Vector2.ts Normal file
View File

@ -0,0 +1,20 @@
import Ajv, { JSONSchemaType } from "ajv";
import Vector2 from "../helpers/Vector2";
const ajv = new Ajv();
export const Vector2Schema: JSONSchemaType<Vector2> = {
$id: "https://www.owlbear.rodeo/schemas/vector2.json",
properties: {
x: {
type: "number",
},
y: {
type: "number",
},
},
required: ["x", "y"],
type: "object",
};
export const isColor = ajv.compile<Vector2>(Vector2Schema);

View File

@ -3686,6 +3686,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^8.6.2:
version "8.6.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571"
integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
require-from-string "^2.0.2"
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"
@ -8663,6 +8673,11 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema-traverse@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
@ -11759,6 +11774,11 @@ require-directory@^2.1.1:
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"