apxtrib/api/models/Checkjson.js

249 lines
9.3 KiB
JavaScript
Raw Normal View History

2023-01-22 09:53:09 +00:00
/*
2023-04-13 05:46:35 +00:00
This module have to be use in back as well front
2023-01-22 09:53:09 +00:00
can be include in project with
2023-04-13 05:46:35 +00:00
- into a browser : <script src="https://townName.nationName.dns/nationchains/contracts/Checkjson.js"></script>
- into a node.js : const Checkjson = require( `../nationchains/socialworld/contracts/Checkjson.js`);
2023-01-22 09:53:09 +00:00
*/
// --##
2023-04-13 05:46:35 +00:00
const Checkjson = {};
Checkjson.schema = {};
Checkjson.schema.properties = {};
Checkjson.schema.properties.type = {};
Checkjson.schema.properties.type.string = (str) => typeof str === "string";
Checkjson.schema.properties.type.number = (n) => typeof n === "number";
Checkjson.schema.properties.type.boolean = (n) => typeof n === "boolean";
Checkjson.schema.properties.type.integer = (n) =>
2023-03-27 05:52:21 +00:00
n != "" && !isNaN(n) && Math.round(n) == n;
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.type.float = (n) =>
2023-03-27 05:52:21 +00:00
n != "" && !isNaN(n) && Math.round(n) != n; //not yet in json schema
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.minLength = (str, min) =>
2023-03-27 05:52:21 +00:00
typeof str === "string" && str.length > parseInt(min);
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.maxLength = (str, max) =>
2023-03-27 05:52:21 +00:00
typeof str === "string" && str.length < parseInt(max);
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.multipleOf = (n, val) =>
2023-03-27 05:52:21 +00:00
typeof n === "number" &&
typeof val === "number" &&
parseFloat(n) / parseFloat(val) -
Math.round(parseFloat(n) / parseFloat(val)) <
0.0000001;
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.range = (
2023-03-27 05:52:21 +00:00
n,
minimum,
exclusiveMinimum,
maximum,
exclusiveMaximum
) => {
//console.log(minimum,exclusiveMinimum,maximum, exclusiveMaximum,n)
if (typeof n !== "number") return false;
if (minimum && parseFloat(n) < parseFloat(minimum)) return false;
if (exclusiveMinimum && parseFloat(n) <= parseFloat(exclusiveMinimum))
return false;
if (maximum && parseFloat(n) > parseFloat(maximum)) return false;
if (exclusiveMaximum && parseFloat(n) >= parseFloat(exclusiveMaximum))
return false;
return true;
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.pattern = (str, pattern) => {
2023-03-27 05:52:21 +00:00
try {
new RegExp(pattern);
} catch (e) {
return false;
}
return pattern.test(str);
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.enum = (str, enumvalues) =>
2023-03-27 05:52:21 +00:00
typeof str === "string" && enumvalues.includes(str);
// see format https://json-schema.org/understanding-json-schema/reference/string.html#format
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.format = {
2023-03-27 05:52:21 +00:00
"date-time": / /,
2023-04-13 05:46:35 +00:00
stringalphaonly:/^[A-Za-z0-9]{3,}$/,
2023-03-27 05:52:21 +00:00
time: / /,
date: / /,
duration: / /,
email:
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
"idn-email": / /,
uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,
uri: / /,
"uri-reference": / /,
iri: / /,
hostname: / /,
"idn-hostname": / /,
ipv4: /^([09]{1,3}.){3}.([09]{1,3})$/,
ipv6: /^((([09A-Fa-f]{1,4}:){7}[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){6}:[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){5}:([09A-Fa-f]{1,4}:)?[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){4}:([09A-Fa-f]{1,4}:){0,2}[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){3}:([09A-Fa-f]{1,4}:){0,3}[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){2}:([09A-Fa-f]{1,4}:){0,4}[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){6}((b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b).){3}(b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b))|(([09A-Fa-f]{1,4}:){0,5}:((b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b).){3}(b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b))|(::([09A-Fa-f]{1,4}:){0,5}((b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b).){3}(b((25[05])|(1d{2})|(2[04]d)|(d{1,2}))b))|([09A-Fa-f]{1,4}::([09A-Fa-f]{1,4}:){0,5}[09A-Fa-f]{1,4})|(::([09A-Fa-f]{1,4}:){0,6}[09A-Fa-f]{1,4})|(([09A-Fa-f]{1,4}:){1,7}:))$/,
telephonefr: /^0[1-9][0-9]{9}$/,
telephoneinter: /^\+*(\d{3})*[0-9,\-]{8,}/,
password:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/,
postalcodefr: /(^\d{5}$)|(^\d{5}-\d{4}$)/,
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.default
Checkjson.schema.validation = (schema) => {
2023-03-27 05:52:21 +00:00
/*validate a schema structure*/
const res = { status: 200, err: [] };
if (schema.properties) {
Object.keys(schema.properties).forEach((p) => {
const properties = schema.properties;
if (
properties[p].type &&
typeof properties[p].type === "string" &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.type[properties[p].type]
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|typedoesnotexistinschema",
2023-03-27 05:52:21 +00:00
moreinfo: ` ${properties[p].type}`,
});
}
if (
properties[p].type &&
typeof properties[p].type === "object" &&
Array.isArray(properties[p].type)
) {
properties[p].type.forEach((tp) => {
2023-04-13 05:46:35 +00:00
if (!Checkjson.schema.properties.type[tp])
2023-03-27 05:52:21 +00:00
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|typedoesnotexistinschema",
2023-03-27 05:52:21 +00:00
moreinfo: `${tp} of ${properties[p].type}`,
});
});
}
if (
properties[p].format &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.format[properties[p].format]
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|formatdoesnotexistinschema",
2023-03-27 05:52:21 +00:00
moreinfo: ` ${properties[p].format}`,
});
}
if (properties[p].enum && !Array.isArray(properties[p].enum)) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|enumisnotarrayinschema",
2023-03-27 05:52:21 +00:00
moreinfo: ` ${properties[p].enum}`,
});
}
});
}
// 406 means not acceptable
if (res.err.length > 0) res.status = 406;
return res;
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
Checkjson.schema.data = (schema, data, withschemacheck) => {
2023-03-27 05:52:21 +00:00
/* validate a data set with a schema in a context ctx */
/*
console.log('#################')
console.log(schema);
console.log('---------')
console.log(data)
*/
2023-04-13 05:46:35 +00:00
if (withschemacheck) {
const validschema = Checkjson.schema.validation(schema);
if (validschema.status != 200) return validschema;
}
2023-03-27 05:52:21 +00:00
const res = { status: 200, err: [] };
if (schema.properties) {
const properties = schema.properties;
Object.keys(properties).forEach((p) => {
//type is mandatory in a propertie
if (data[p]) {
const typlist =
properties[p].type && typeof properties[p].type === "string"
? [properties[p].type]
: properties[p].type;
let valid = false;
typlist.forEach((typ) => {
// at least one test have to be ok
2023-04-13 05:46:35 +00:00
if (Checkjson.schema.properties.type[typ](data[p])) valid = true;
2023-03-27 05:52:21 +00:00
});
if (!valid)
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]}`,
});
if (
properties[p].minLength &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.minLength(data[p], properties[p].minLength)
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} minLength:${properties[p].minLength}`,
});
}
if (
properties[p].maxLength &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.maxLength(data[p], properties[p].maxLength)
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} maxLength:${properties[p].maxLength}`,
});
}
if (
properties[p].multipleOf &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.multipleOf(data[p], properties[p].multipleOf)
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} not a multipleOf:${properties[p].multipleOf}`,
});
}
if (
properties[p].minimum ||
properties[p].maximum ||
properties[p].exclusiveMinimum ||
properties[p].exclusiveMaximum
) {
// test range
if (
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.range(
2023-03-27 05:52:21 +00:00
data[p],
properties[p].minimum,
properties[p].exclusiveMinimum,
properties[p].maximum,
properties[p].exclusiveMaximum
)
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} not in range ${properties[p].minimum} exclu: ${properties[p].exclusiveMinimum} and ${properties[p].maximum} exclu: ${properties[p].exclusiveMaximum}`,
});
}
}
if (
properties[p].enum &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.enum(data[p], properties[p].enum)
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} not in enum list :${properties[p].enum}`,
});
}
if (properties[p].format) {
properties[p].pattern =
2023-04-13 05:46:35 +00:00
Checkjson.schema.properties.format[properties[p].format];
2023-03-27 05:52:21 +00:00
}
if (
properties[p].pattern &&
2023-04-13 05:46:35 +00:00
!Checkjson.schema.properties.pattern(data[p], properties[p].pattern)
2023-03-27 05:52:21 +00:00
) {
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertie",
2023-03-27 05:52:21 +00:00
moreinfo: `${p} : ${data[p]} problem pattern or format ${properties[p].pattern}`,
});
}
2023-04-13 05:46:35 +00:00
} else if (schema.required && schema.required.includes(p)) {
2023-03-27 05:52:21 +00:00
res.err.push({
2023-04-13 05:46:35 +00:00
info: "|Checkjson|dataerrpropertiesrequired",
2023-03-27 05:52:21 +00:00
moreinfo: `${p}`,
});
}
});
}
if (res.err.length > 0) res.status = 417;
return res;
2023-01-22 09:53:09 +00:00
};
2023-04-13 05:46:35 +00:00
if (typeof module !== "undefined") module.exports = Checkjson;