sumOf customKeyword

This commit is contained in:
Yanick Champoux 2022-04-26 18:55:59 -04:00
parent a3c140fd24
commit c55abfb2df
5 changed files with 90 additions and 34 deletions

View File

@ -31,6 +31,7 @@ tasks:
--verbose \
--data \
-c ajv-keywords \
-c ./src/sumOf.cjs \
-r schemas-json/classes.json \
-s schemas-json/character.json \
-d {{.CLI_ARGS}}

View File

@ -21,6 +21,8 @@
"dependencies": {
"ajv": "^8.11.0",
"ajv-cli": "^5.0.0",
"ajv-keywords": "^5.1.0"
"ajv-keywords": "^5.1.0",
"json-pointer": "^0.6.2",
"lodash": "^4.17.21"
}
}

View File

@ -19,6 +19,11 @@
"type" : "array"
},
"max" : {
"sumOf" : {
"list" : {
"$data" : "1/log"
}
},
"type" : "number"
}
},

View File

@ -3,30 +3,30 @@ title: Hyperboria character sheet
type: object
additionalProperties: false
required:
- name
- player
- statistics
- class
- level
- health
- name
- player
- statistics
- class
- level
- health
properties:
name: &string
type: string
player: *string
class: { $ref: '/classes.json' }
statistics:
type: object
allRequired: true
properties:
strength: &stat
$ref: '#/$defs/statistic'
dexterity: *stat
constitution: *stat
intelligence: *stat
wisdom: *stat
charisma: *stat
level: { type: number, minimum: 1 }
health: { $ref: '#/$defs/health' }
name: &string
type: string
player: *string
class: { $ref: "/classes.json" }
statistics:
type: object
allRequired: true
properties:
strength: &stat
$ref: "#/$defs/statistic"
dexterity: *stat
constitution: *stat
intelligence: *stat
wisdom: *stat
charisma: *stat
level: { type: number, minimum: 1 }
health: { $ref: "#/$defs/health" }
$defs:
statistic:
type: number
@ -34,14 +34,15 @@ $defs:
maximum: 20
health:
type: object
required: [ max ]
required: [max]
properties:
max: { type: number }
current: { type: number }
log:
type: array
description: history of health rolls
items: { type: number }
minItems: { $data: /level }
maxItems: { $data: /level }
max:
type: number
sumOf: { list: { $data: 1/log } }
current: { type: number }
log:
type: array
description: history of health rolls
items: { type: number }
minItems: { $data: /level }
maxItems: { $data: /level }

47
src/sumOf.cjs Normal file
View File

@ -0,0 +1,47 @@
const _ = require("lodash");
const ptr = require("json-pointer");
function resolvePointer(data, rootPath, relativePath) {
if (relativePath[0] === "/") return ptr.get(data, relativePath);
const m = relativePath.match(/^(\d+)(.*)/);
relativePath = m[2];
for (let i = 0; i < parseInt(m[1]); i++) {
rootPath = rootPath.replace(/\/[^\/]+$/, "");
}
return ptr.get(data, rootPath + relativePath);
}
module.exports = (ajv) =>
ajv.addKeyword({
keyword: "sumOf",
validate: function validate(
{ list, map },
total,
_parent,
{ rootData, instancePath }
) {
if (list.$data) {
list = resolvePointer(rootData, instancePath, list.$data);
}
if (map) data = _.map(data, map);
if (_.sum(list) === total) return true;
validate.errors = [
{
keyword: "sumOf",
message: "should add up to sum total",
params: {
list,
},
},
];
return false;
},
$data: true,
errors: true,
});