backend v4 half

This commit is contained in:
2025-07-18 09:20:40 +02:00
parent aba7a506ad
commit 725516ad6c
4183 changed files with 217684 additions and 75056 deletions
+5
View File
@@ -0,0 +1,5 @@
If you believe you have found a security vulnerability in this repository which can be potentially harful for the users in anyway, please do not report security vulnerabilities through public GitHub issues. Instead, please report it to us as described below.
## Security contact information
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
+11
View File
@@ -1,4 +1,15 @@
**2.1.1 / 2025-05-15**
- remove unnecessary check to remove lint error
**2.1.0 / 2025-05-01**
- fix e-notation
- to return string when invalid enotation is found. Eg `E24`
- to return valid number when only leading zero before e char is present
**2.0.5 / 2025-02-27**
- changes done in 1.1.2
**1.1.2 / 2025-02-27**
- fix skiplike for 0
+84
View File
@@ -0,0 +1,84 @@
FLOW: toNumber
input: x, options
IF not string
END x
ELSE_IF should skip
END x
ELSE_IF 0
END 0
ELSE_IF hex is supported AND x is hex
END int of x of base 16
ELSE_IF possible e notation
FOLLOW: resolve enotation (x, trimmed x, options)
ELSE
IF match numeric pattern
separate sign, leading zeros, pure number
IF x doesn't starts with "[+-]0."
END number(x)
IF leading zeros are not allowed
IF leading zeros > 1
#00.1
END x
ELSE_IF leading zeros == 1 AND decimal is not adjacent to leading zeros
#06.5
#but not 0.65, .65, 6.0
END x
ELSE_IF str has only zeros
END 0
ELSE
parse x to number
IF parsed x == 0 or -0
END parsed x
ELSE_IF parsed x is eNotation
IF conversion to enotation is allowed
END parsed x
ELSE
END x
ELSE_IF floating number
IF parsed x is 0
END parsed x
ELSE_IF parsed x == number without leading 0s
#0.456. 0.79000
END parsed x
ELSE_IF parsed x is negative AND == parsed x == number without leading 0s
END parsed x
ELSE
END x
ELSE_IF leading 0s are present
IF parsed x == x without leading 0s
END parsed x
ELSE
END x
ELSE
IF parsed x == x (consider sign)
END parsed x
ELSE
END x
ELSE
END x
FLOW: resolve enotation
input: x, trimmed x, options
IF eNotation has not to be evaluated
END x
IF match eNotation pattern
extract sign, eChar, leading zeros
find if eChar adjacent to leading zeros
IF leading zeros > 1 AND eChar adjacent to leading zeros
# 00e, -00e
END x
ELSE_IF exp is `0e`, `0.e`, `-0.e`, `-0e`
END number(x);
ELSE_IF leading zeros are allowed but eChar is not adjacent to leading zeros
# -003e2
remove leading zeros
END number(x)
ELSE
END x
ELSE
END x
+2 -1
View File
@@ -1,7 +1,8 @@
{
"name": "strnum",
"version": "1.1.2",
"version": "2.1.1",
"description": "Parse String to Number based on configuration",
"type": "module",
"main": "strnum.js",
"scripts": {
"test": "jasmine strnum.test.js"
+53 -35
View File
@@ -13,7 +13,7 @@ const consider = {
//skipLike: /regex/
};
function toNumber(str, options = {}){
export default function toNumber(str, options = {}){
options = Object.assign({}, consider, options );
if(!str || typeof str !== "string" ) return str;
@@ -25,23 +25,8 @@ function toNumber(str, options = {}){
return parse_int(trimmedStr, 16);
// }else if (options.oct && octRegex.test(str)) {
// return Number.parseInt(val, 8);
}else if (trimmedStr.search(/[eE]/)!== -1) { //eNotation
const notation = trimmedStr.match(/^([-\+])?(0*)([0-9]*(\.[0-9]*)?[eE][-\+]?[0-9]+)$/);
// +00.123 => [ , '+', '00', '.123', ..
if(notation){
// console.log(notation)
if(options.leadingZeros){ //accept with leading zeros
trimmedStr = (notation[1] || "") + notation[3];
}else{
if(notation[2] === "0" && notation[3][0]=== "."){ //valid number
}else{
return str;
}
}
return options.eNotation ? Number(trimmedStr) : str;
}else{
return str;
}
}else if (trimmedStr.search(/.+[eE].+/)!== -1) { //eNotation
return resolveEnotation(str,trimmedStr,options);
// }else if (options.parseBin && binRegex.test(str)) {
// return Number.parseInt(val, 2);
}else{
@@ -49,33 +34,42 @@ function toNumber(str, options = {}){
const match = numRegex.exec(trimmedStr);
// +00.123 => [ , '+', '00', '.123', ..
if(match){
const sign = match[1];
const sign = match[1] || "";
const leadingZeros = match[2];
let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.
str[leadingZeros.length+1] === "."
: str[leadingZeros.length] === ".";
//trim ending zeros for floating number
if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str; //-0123
else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str; //0123
else if(options.leadingZeros && leadingZeros===str) return 0; //00
if(!options.leadingZeros //leading zeros are not allowed
&& (leadingZeros.length > 1
|| (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))){
// 00, 00.3, +03.24, 03, 03.24
return str;
}
else{//no leading zeros or leading zeros are allowed
const num = Number(trimmedStr);
const numStr = "" + num;
const parsedStr = String(num);
if(numStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
if( num === 0) return num;
if(parsedStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
if(options.eNotation) return num;
else return str;
}else if(trimmedStr.indexOf(".") !== -1){ //floating number
if(numStr === "0" && (numTrimmedByZeros === "") ) return num; //0.0
else if(numStr === numTrimmedByZeros) return num; //0.456. 0.79000
else if( sign && numStr === "-"+numTrimmedByZeros) return num;
if(parsedStr === "0") return num; //0.0
else if(parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
else if( parsedStr === `${sign}${numTrimmedByZeros}`) return num;
else return str;
}
let n = leadingZeros? numTrimmedByZeros : trimmedStr;
if(leadingZeros){
return (numTrimmedByZeros === numStr) || (sign+numTrimmedByZeros === numStr) ? num : str
// -009 => -9
return (n === parsedStr) || (sign+n === parsedStr) ? num : str
}else {
return (trimmedStr === numStr) || (trimmedStr === sign+numStr) ? num : str
// +9
return (n === parsedStr) || (n === sign+parsedStr) ? num : str
}
}
}else{ //non-numeric string
@@ -84,6 +78,32 @@ function toNumber(str, options = {}){
}
}
const eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
function resolveEnotation(str,trimmedStr,options){
if(!options.eNotation) return str;
const notation = trimmedStr.match(eNotationRegx);
if(notation){
let sign = notation[1] || "";
const eChar = notation[3].indexOf("e") === -1 ? "E" : "e";
const leadingZeros = notation[2];
const eAdjacentToLeadingZeros = sign ? // 0E.
str[leadingZeros.length+1] === eChar
: str[leadingZeros.length] === eChar;
if(leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
else if(leadingZeros.length === 1
&& (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)){
return Number(trimmedStr);
}else if(options.leadingZeros && !eAdjacentToLeadingZeros){ //accept with leading zeros
//remove leading 0s
trimmedStr = (notation[1] || "") + notation[3];
return Number(trimmedStr);
}else return str;
}else{
return str;
}
}
/**
*
* @param {string} numStr without leading zeros
@@ -94,7 +114,7 @@ function trimZeros(numStr){
numStr = numStr.replace(/0+$/, ""); //remove ending zeros
if(numStr === ".") numStr = "0";
else if(numStr[0] === ".") numStr = "0"+numStr;
else if(numStr[numStr.length-1] === ".") numStr = numStr.substr(0,numStr.length-1);
else if(numStr[numStr.length-1] === ".") numStr = numStr.substring(0,numStr.length-1);
return numStr;
}
return numStr;
@@ -106,6 +126,4 @@ function parse_int(numStr, base){
else if(Number.parseInt) return Number.parseInt(numStr, base);
else if(window && window.parseInt) return window.parseInt(numStr, base);
else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")
}
module.exports = toNumber;
}
+9 -1
View File
@@ -1,4 +1,4 @@
const toNumber = require("./strnum.js");
import toNumber from "./strnum.js";
describe("Should convert all the valid numeric strings to number", () => {
it("should return undefined, null, empty string, or non-numeric as it is", () => {
@@ -95,6 +95,7 @@ describe("Should convert all the valid numeric strings to number", () => {
expect(toNumber("-.006")).toEqual(-0.006);
expect(toNumber("-6.0")).toEqual(-6);
expect(toNumber("-06.0")).toEqual(-6);
expect(toNumber("+06.0")).toEqual(6);
expect(toNumber("-0.0" , { leadingZeros : false})).toEqual(-0);
expect(toNumber("-00.00", { leadingZeros : false})).toEqual("-00.00");
@@ -137,6 +138,13 @@ describe("Should convert all the valid numeric strings to number", () => {
expect(toNumber("-1.0E2") ).toEqual(-100);
expect(toNumber("1.0E-2")).toEqual(0.01);
expect(toNumber("E-2")).toEqual("E-2");
expect(toNumber("E2")).toEqual("E2");
expect(toNumber("0E2")).toEqual(0);
expect(toNumber("-0E2")).toEqual(-0);
expect(toNumber("00E2")).toEqual("00E2");
expect(toNumber("00E2", { leadingZeros : false})).toEqual("00E2");
});
it("should skip matching pattern", () => {
+9
View File
@@ -0,0 +1,9 @@
import toNumber from "./strnum.js";
describe("Should convert all the valid numeric strings to number", () => {
it("should return undefined, null, empty string, or non-numeric as it is", () => {
// expect(toNumber("+ 90")).toEqual("+ 90");
// expect(toNumber("- 90")).toEqual("- 90");
expect(toNumber("-10E2")).toEqual(100);
});
});