sumOf customKeyword

main
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 \ --verbose \
--data \ --data \
-c ajv-keywords \ -c ajv-keywords \
-c ./src/sumOf.cjs \
-r schemas-json/classes.json \ -r schemas-json/classes.json \
-s schemas-json/character.json \ -s schemas-json/character.json \
-d {{.CLI_ARGS}} -d {{.CLI_ARGS}}

View File

@ -21,6 +21,8 @@
"dependencies": { "dependencies": {
"ajv": "^8.11.0", "ajv": "^8.11.0",
"ajv-cli": "^5.0.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" "type" : "array"
}, },
"max" : { "max" : {
"sumOf" : {
"list" : {
"$data" : "1/log"
}
},
"type" : "number" "type" : "number"
} }
}, },

View File

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