|
|
@ -1,7 +1,7 @@ |
|
|
|
const sleep = (ms)=>{ |
|
|
|
const sleep = (ms) => { |
|
|
|
return new Promise(resolve=>{ |
|
|
|
return new Promise(resolve => { |
|
|
|
console.log(`${(ms/1000).toFixed(2)}s SHOULD WAIT`); |
|
|
|
console.log(`${(ms / 1000).toFixed(2)}s SHOULD WAIT`); |
|
|
|
setTimeout(resolve,ms); |
|
|
|
setTimeout(resolve, ms); |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
function convertStringToJson(string) { |
|
|
|
function convertStringToJson(string) { |
|
|
@ -13,6 +13,43 @@ function convertStringToJson(string) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const checkCondition = ({ data, condition }, conditionArray = new Set()) => { |
|
|
|
|
|
|
|
let ands = true; |
|
|
|
|
|
|
|
for (const key in condition) { |
|
|
|
|
|
|
|
const conditionValue = condition[key]; |
|
|
|
|
|
|
|
if (key == 'or') { |
|
|
|
|
|
|
|
let ors = false; |
|
|
|
|
|
|
|
for (const cond of conditionValue) { |
|
|
|
|
|
|
|
// const orConditionChecking = checkCondition({ data, condition: cond }, conditionArray);
|
|
|
|
|
|
|
|
// ors = ors || orConditionChecking.ok;
|
|
|
|
|
|
|
|
ors = ors || checkCondition({ data, condition: cond }); |
|
|
|
|
|
|
|
// conditionArray = new Set([...conditionArray, ...orConditionChecking.conditionArray])
|
|
|
|
|
|
|
|
if (ors) break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ands = ands && ors; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (data[key] == 'true') data[key] = true; |
|
|
|
|
|
|
|
if (data[key] == 'false') data[key] = false; |
|
|
|
|
|
|
|
switch (key) { |
|
|
|
|
|
|
|
case [Op.gt]: |
|
|
|
|
|
|
|
ands = ands && data[key] > conditionValue; |
|
|
|
|
|
|
|
// if (!conditionArray.has(key)) conditionArray.add(key);
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
ands = ands && data[key] == conditionValue; |
|
|
|
|
|
|
|
// if (!conditionArray.has(key)) conditionArray.add(key);
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!ands) { |
|
|
|
|
|
|
|
// return { ok: false, conditionArray };
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return { ok: true, conditionArray };
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
function checkingOptions({ question, answer }) { |
|
|
|
function checkingOptions({ question, answer }) { |
|
|
|
let options = convertStringToJson(question?.options) || [], |
|
|
|
let options = convertStringToJson(question?.options) || [], |
|
|
|
inputType = +question?.inputType || -1; |
|
|
|
inputType = +question?.inputType || -1; |
|
|
@ -22,35 +59,62 @@ function checkingOptions({ question, answer }) { |
|
|
|
const OptionsValidValue = options.map((option) => { |
|
|
|
const OptionsValidValue = options.map((option) => { |
|
|
|
return parseValue(option?.value); |
|
|
|
return parseValue(option?.value); |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const questionAnswer = answer[question.id]; |
|
|
|
const questionAnswer = answer[question.id]; |
|
|
|
if (questionAnswer === null || questionAnswer === undefined) return { |
|
|
|
if (questionAnswer === null || questionAnswer === undefined) return { |
|
|
|
ok: false |
|
|
|
ok: false |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let min = question?.min, |
|
|
|
|
|
|
|
max = question?.max, |
|
|
|
|
|
|
|
length = question?.length, |
|
|
|
|
|
|
|
validation = question?.validation; |
|
|
|
|
|
|
|
|
|
|
|
switch (inputType) { |
|
|
|
switch (inputType) { |
|
|
|
case 1: //TEXT
|
|
|
|
case 1: //TEXT
|
|
|
|
case 3: |
|
|
|
case 3: |
|
|
|
if (typeof questionAnswer !== "string" || questionAnswer.length == 0) { |
|
|
|
if (typeof questionAnswer !== "string") { |
|
|
|
return { |
|
|
|
return { |
|
|
|
ok: false |
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidData |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (length && isNumber(length) && questionAnswer.length > +length) { |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidTextLength(question.id, length) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (validation && isValidRegex(validation)) { |
|
|
|
|
|
|
|
let validationRegex = new RegExp(validation); |
|
|
|
|
|
|
|
if (!validationRegex.test(questionAnswer)) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidTextPattern |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
case 2: //NUMBER
|
|
|
|
case 2: //NUMBER
|
|
|
|
if (!isNumber(questionAnswer) || !OptionsValidValue.includes(questionAnswer?.toString())) { |
|
|
|
if (!isNumber(questionAnswer)) { |
|
|
|
return { |
|
|
|
return { |
|
|
|
ok: false |
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidNumber(question.id) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (min && isNumber(min) && +min > +questionAnswer) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidMinNumber(question.id, min) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (max && isNumber(max) && +max < +questionAnswer) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidMaxNumber(question.id, max) |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 4: // tak entekhab
|
|
|
|
case 4: // tak entekhab
|
|
|
|
case 6: |
|
|
|
case 6: |
|
|
|
console.log("OptionsValidValue",OptionsValidValue); |
|
|
|
|
|
|
|
console.log("questionAnswer",questionAnswer) |
|
|
|
|
|
|
|
if (!OptionsValidValue.includes(questionAnswer)) { |
|
|
|
if (!OptionsValidValue.includes(questionAnswer)) { |
|
|
|
return { |
|
|
|
return { |
|
|
|
ok: false |
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidSelectedOption(question.id) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
@ -58,70 +122,88 @@ function checkingOptions({ question, answer }) { |
|
|
|
case 7: |
|
|
|
case 7: |
|
|
|
if (Array.isArray(questionAnswer)) { |
|
|
|
if (Array.isArray(questionAnswer)) { |
|
|
|
for (let ans of questionAnswer) { |
|
|
|
for (let ans of questionAnswer) { |
|
|
|
if (!OptionsValidValue.includes(ans)) return { ok: false } |
|
|
|
if (!OptionsValidValue.includes(ans)) return { statusCode: 400, message: ErrorMessages.InvalidAdditionalData(question.id) }; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (typeof questionAnswer === "string") { |
|
|
|
} else if (typeof questionAnswer === "string") { |
|
|
|
for (let ans of questionAnswer.split(",")) { |
|
|
|
for (let ans of questionAnswer.split(",")) { |
|
|
|
if (!OptionsValidValue.includes(ans)) return { ok: false } |
|
|
|
if (!OptionsValidValue.includes(ans)) return { statusCode: 400, message: ErrorMessages.InvalidAdditionalData(question.id) }; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return { ok: false }; |
|
|
|
return { statusCode: 400, message: ErrorMessages.InvalidData(question.id) }; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 8: |
|
|
|
case 8: |
|
|
|
console.log("oomadinja"); |
|
|
|
if (!isValidDateStrict(questionAnswer)) return { statusCode: 400, message: ErrorMessages.InvalidDate(question.id) }; |
|
|
|
console.log("javabesh", questionAnswer, isValidDateStrict(questionAnswer)) |
|
|
|
const questionDate = new Date(questionAnswer); |
|
|
|
if (!isValidDateStrict(questionAnswer)) return { ok: false }; |
|
|
|
if (min) { |
|
|
|
break; |
|
|
|
if (isValidDateStrict(min)) { |
|
|
|
|
|
|
|
if (new Date(min) > questionDate) return { |
|
|
|
case 10: |
|
|
|
statusCode: 400, |
|
|
|
if (!isBoolean(questionAnswer)) return { ok: false } |
|
|
|
message: ErrorMessages.InvalidMinDate(question.id) |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
|
} else if (min === "now()") { |
|
|
|
|
|
|
|
if (new Date() > questionDate) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidMinDate(question.id) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if (min.includes("day")) { |
|
|
|
|
|
|
|
let days = min.match(/day(s)?\(([0-9]{1,2})\)/)[2]; |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
!isNaN(+days) |
|
|
|
|
|
|
|
// &&
|
|
|
|
|
|
|
|
// Date.now() < questionDate
|
|
|
|
|
|
|
|
&& |
|
|
|
|
|
|
|
Math.abs(Date.now() - questionDate.getTime()) > convertDaysToSeconds(days) |
|
|
|
|
|
|
|
) { |
|
|
|
return { |
|
|
|
return { |
|
|
|
ok: false |
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidDayMinDate(question.id, days) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (max) { |
|
|
|
|
|
|
|
if (isValidDateStrict(max)) { |
|
|
|
|
|
|
|
if (new Date(max) < questionDate) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidMaxDate(question.id) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (max === "now()") { |
|
|
|
|
|
|
|
if (new Date() < questionDate) return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidMaxDate(question.id) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else if (max.includes("day")) { |
|
|
|
|
|
|
|
let days = max.match(/day(s)?\(([0-9]{1,2})\)/)[2]; |
|
|
|
|
|
|
|
if ( |
|
|
|
|
|
|
|
!isNaN(+days) |
|
|
|
|
|
|
|
// &&
|
|
|
|
|
|
|
|
// Date.now() < questionDate
|
|
|
|
|
|
|
|
&& |
|
|
|
|
|
|
|
Math.abs(Date.now() - questionDate.getTime()) < convertDaysToSeconds(days) |
|
|
|
|
|
|
|
) { |
|
|
|
return { |
|
|
|
return { |
|
|
|
ok: true |
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidDayMaxDate(question.id, days) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const checkCondition = ({ data, condition, inputType = 2, options = null }, conditionArray = new Set()) => { |
|
|
|
|
|
|
|
let ands = true; |
|
|
|
|
|
|
|
for (const key in condition) { |
|
|
|
|
|
|
|
const conditionValue = condition[key]; |
|
|
|
|
|
|
|
if (key == 'or') { |
|
|
|
|
|
|
|
let ors = false; |
|
|
|
|
|
|
|
for (const cond of conditionValue) { |
|
|
|
|
|
|
|
const orConditionChecking = checkCondition({ data, condition: cond }, conditionArray); |
|
|
|
|
|
|
|
ors = ors || orConditionChecking.ok; |
|
|
|
|
|
|
|
conditionArray = new Set([...conditionArray, ...orConditionChecking.conditionArray]) |
|
|
|
|
|
|
|
if (ors) break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
ands = ands && ors; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (data[key] == 'true') data[key] = true; |
|
|
|
|
|
|
|
if (data[key] == 'false') data[key] = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (key) { |
|
|
|
|
|
|
|
case [Op.gt]: |
|
|
|
|
|
|
|
ands = ands && data[key] > conditionValue; |
|
|
|
|
|
|
|
if (!conditionArray.has(key)) conditionArray.add(key); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
ands = ands && data[key] == conditionValue; |
|
|
|
|
|
|
|
if (!conditionArray.has(key)) conditionArray.add(key); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!ands) { |
|
|
|
break; |
|
|
|
return { ok: false, conditionArray }; |
|
|
|
case 10: |
|
|
|
|
|
|
|
if (!isBoolean(questionAnswer)) return { statusCode: 400, message: ErrorMessages.InvalidBooleanData(question.id) } |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
statusCode: 400, |
|
|
|
|
|
|
|
message: ErrorMessages.InvalidInputType(question.id) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
return { ok: true, conditionArray }; |
|
|
|
} |
|
|
|
}; |
|
|
|
module.exports = { |
|
|
|
module.exports={ |
|
|
|
|
|
|
|
sleep, |
|
|
|
sleep, |
|
|
|
convertStringToJson |
|
|
|
convertStringToJson, |
|
|
|
|
|
|
|
checkingOptions, |
|
|
|
|
|
|
|
checkCondition |
|
|
|
} |
|
|
|
} |