sdj-esm
Version:
Self Described JSON - ESM
215 lines (213 loc) • 8.97 kB
JavaScript
/*
Copyright (c) 2023-2024 Will Rudolph <@willrudolph.com>
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { DEF_MAX_STR_LEN, ESDJ_TYPE, MAX_OBJ_ARY_LEN, STR_LEN_LNG, STR_LEN_SHRT } from "./statics.js";
import { each, isArray, isBoolean, isNumber, isObject, isString, isUndefined } from "lodash-es";
import { getRegEx } from "../util/regex.js";
export const validSDKey = (checkVal) => {
const regEx = getRegEx("sdKey");
return isString(checkVal) ? regEx.test(checkVal) : false;
};
export const validUtcDate = (checkVal) => Boolean(isNumber(checkVal));
export const validBoolean = (checkVal) => {
let rtnValid = false;
if (isString(checkVal)) {
// No allowed "true"/"FALSE" as strings for uniformity and by spec.
rtnValid = false;
}
else if (isBoolean(checkVal)) {
rtnValid = true;
}
return rtnValid;
};
export const getStrValidLenFunc = (maxLength) => (checkVal) => Boolean(isString(checkVal) && checkVal.length < maxLength);
export const getValidNumberFunc = (preciseType, posOnly = false) => (checkVal) => {
let rtnValid = false;
if (isNumber(checkVal)) {
rtnValid = true;
switch (preciseType) {
case "float":
rtnValid = Number.isFinite(checkVal);
break;
case "int":
rtnValid = Number.isFinite(checkVal) && Math.floor(checkVal) === checkVal;
break;
default:
// 'none' is also default
}
}
if (rtnValid && posOnly) {
rtnValid = (checkVal >= 0);
}
return rtnValid;
};
export const getValidObjFunc = (objType, itemType) => (checkVal) => {
let rtnValid = false, typeArray = ["string", "boolean", "number", "integer", "int-pos"], validFuncArray = [getStrValidLenFunc(DEF_MAX_STR_LEN), validBoolean, getValidNumberFunc("none"),
getValidNumberFunc("int"), getValidNumberFunc("int", true)], funcIdx = typeArray.indexOf(itemType), activeFunc = (funcIdx !== -1) ? validFuncArray[typeArray.indexOf(itemType)] : undefined;
if (typeArray.indexOf(itemType) === -1 || !activeFunc) {
throw new Error("--- Internal Dev error resolve missing:" + itemType);
}
// Yes, for now we will verify each array value
if (objType === "array" && isArray(checkVal)) {
// Yes, for now we will verify each key value
const len = checkVal.length;
if (len && len < MAX_OBJ_ARY_LEN) {
rtnValid = true;
each(checkVal, (idxValue) => {
if (activeFunc) {
if (!activeFunc(idxValue)) {
rtnValid = false;
return false;
}
}
return true;
});
}
}
else if (objType === "object" && isObject(checkVal)) {
const len = Object.keys(checkVal).length;
// stupid long key names are not allowed either
if (len && len < MAX_OBJ_ARY_LEN) {
rtnValid = true;
each(checkVal, (value, key) => {
if (activeFunc) {
if ((!isString(key) || key.length > DEF_MAX_STR_LEN) || !activeFunc(value)) {
rtnValid = false;
return false;
}
}
return true;
});
}
}
return rtnValid;
};
/*
Description arrays [extendIds, sdItems, parentIds, childIds]
are all limited to unique positive number arrays
validIntArray only confirms positive integer array is present, not uniqueness
*/
export const validIntArray = (checkValue) => {
const rtnBool = (checkValue && isArray(checkValue) && checkValue.length > 0);
return (rtnBool) ? getValidObjFunc("array", "int-pos")(checkValue) : false;
};
export const SdjDefaultTypes = [{
// sdKey; force close 'name' type to use sdKey
item: ESDJ_TYPE.KEY,
similarNames: ["sd-k", "sd--key", "sd_-key", "sd-_key", "s-d-k", "s-d-key", "sd-ke"],
valid: validSDKey
}, {
// sdId; force close 'name' type to use sdId
item: ESDJ_TYPE.ID,
similarNames: ["sd-id", "sd--id", "sd-_id", "sd_-id", "sd-i", "s-d-id", "s-d_id", "s_d-id"],
valid: getValidNumberFunc("int")
}, {
// standard JS number
item: ESDJ_TYPE.NUM,
similarNames: ["number", "num-b", "num-ber", "num-b"],
valid: getValidNumberFunc("none"),
}, {
// number forced/confirmed to integer
item: ESDJ_TYPE.INT,
similarNames: ["intr", "integr", "integ", "integer", "num-int", "int-num", "intnum", "numint", "numbint", "intnumb"],
valid: getValidNumberFunc("int"),
}, {
// number parsed for floating point
item: ESDJ_TYPE.FLT,
similarNames: ["flop", "float", "fltpt", "num-flt", "num-float", "floatnum", "fltnum"],
valid: getValidNumberFunc("float"),
}, {
// standard boolean
item: ESDJ_TYPE.BOOL,
similarNames: ["boolean", "bolean", "boolea", "boole", "b-oo", "bo-l"],
valid: validBoolean
}, {
// string default - max length 64 characters
item: ESDJ_TYPE.STR,
similarNames: ["string", "stringdef", "str-def", "string-def"],
valid: getStrValidLenFunc(DEF_MAX_STR_LEN),
}, {
// string large - max 1000 characters
item: ESDJ_TYPE.STRL,
similarNames: ["str-lg", "st-lg", "str-l", "string-lg", "string-l"],
valid: getStrValidLenFunc(STR_LEN_LNG)
}, {
// string short - max length 16 characters
item: ESDJ_TYPE.STRS,
similarNames: ["str-sh", "st-sm", "str-sm", "str-s", "string-sm", "string-s", "string-sh"],
valid: getStrValidLenFunc(STR_LEN_SHRT)
}, {
// UTC date format - throws out old/bad dates
item: ESDJ_TYPE.UTC,
similarNames: ["date-utc", "dateutc", "utcdate", "utc-date", "u-date", "date-u"],
valid: validUtcDate
}, {
// Array of boolean values [true,false,..]
item: ESDJ_TYPE.ARY_BOOL,
similarNames: ["ary-bol", "arraybol", "array-bol"],
valid: getValidObjFunc("array", "boolean")
}, {
// Array of number values [33, 4, 5.3, .322, 0, -2...]
item: ESDJ_TYPE.ARY_NUM,
similarNames: ["ary-num", "arraynum", "array-num"],
valid: getValidObjFunc("array", "number")
}, {
// TODO Confirm Short and long as they use the same function
// Array string Short - ["alpha", "beta", "gamma",...] - each entry max string length of 16 characters
item: ESDJ_TYPE.ARY_STR_SH,
similarNames: ["arystrsht", "arraystr", "array-str", "ary-str-s", "array-str-s"],
valid: getValidObjFunc("array", "string")
}, {
// Array string Default - ["alpha..", "beta..", "gamma...", ...] - each entry max string length of 64 characters
item: ESDJ_TYPE.ART_STR_DF,
similarNames: ["arystr", "ary-str", "array-def", "arystrdef", "array-str-d"],
valid: getValidObjFunc("array", "string"),
}, {
// Obj:key Strings - {"alpha": "text1", "beta": "text2", ...} each entry max string length of 64 characters
item: ESDJ_TYPE.OBJ_STR,
similarNames: ["obj-str", "object-str", "objectstr"],
valid: getValidObjFunc("object", "string")
}, {
// Obj:key Booleans - {"alpha": true, "beta": false, ...}
item: ESDJ_TYPE.OBJ_BOOL,
similarNames: ["obj-bool", "object-bool", "objectbool", "obj-bool"],
valid: getValidObjFunc("object", "boolean"),
}, {
// Obj:key Number(JS)s - {"alpha": 1, "beta": 2, ..}
item: ESDJ_TYPE.OBJ_NUM,
similarNames: ["obj-num", "object-num", "objectnum", "obj-number"],
valid: getValidObjFunc("object", "number"),
}, {
// SdIndex Key validator
item: ESDJ_TYPE.INDEX,
similarNames: ["sdjidx", "sdidx,", "sd-idx", "sdj-idx", "sd--idx", "sdinx", "sdjindx", "sdjindex"],
valid: getValidNumberFunc("int")
}
];
export const rtnSdjItemName = (nameStr) => {
let rtnName = undefined;
each(SdjDefaultTypes, (itemType) => {
if (itemType.item === nameStr) {
return false;
}
else {
each(itemType.similarNames, (strVal) => {
const underScoreCheck = strVal.replace("-", "_");
if (strVal === nameStr || nameStr === underScoreCheck) {
rtnName = itemType.item;
return false;
}
else {
return true;
}
});
return !!isUndefined(rtnName);
}
});
return rtnName;
};
export const validStrArray = getValidObjFunc("array", "string");
//# sourceMappingURL=sdj-types.js.map