1export async function formulaEndpoint(req) {
2 if (req.method !== "GET") {
3 return new Response("Method Not Allowed", { status: 405 });
28
29 // the params contain either numbers or strings, depending on the method passed.
30 // methods/functions include: add, subtract, multiply, mod, pow, divide, equal, =/=, >, <, >=, <=, and, or, not, xor, nand, nor, xnor, true, false, if_empty, length, contains, test, match, replace, replaceAll, lowercase, uppercase, repeat(#), strip_formatting, min, max, absolute, round, ceiling, floor, squareroot, cuberoot, exponent, ln, log10, log2, now, minute, hour, day, date, week, month, year, dateAdd, dateSubtract, dateBetween, timestamp, fromTimeStamptoDate, formatDate, parseDate, at, first, last, slice, concat, sort, reverse, join, split, unique, includes, find, findIndex, filter, some, every, map, flatten
31 // variable types include: number, string, boolean, date, array, object, null, undefined
32 // the return type is always a string.
35 let result = null;
36
37 // DICTIONARY OF ALL FUNCTIONS, MAX NUMBER OF PARAMETERS, AND ACCEPTED TYPE
38 const functions = {
39 "add": ["infinite", "number"],
40 "subtract": ["infinite", "number"],
119 };
120
121 // CHECK IF METHOD EXISTS AGAINST FUNCTIONS DICTIONARY
122 if (functions[method] === undefined) {
123 return new Response("Method not found", { status: 404 });
124 }
125
126 function extractAndParseDate(dateString) {
127 const match = dateString.match(/\[\[date:(\d{4}-\d{2}-\d{2})\]\]/);
128 if (!match) {
137 }
138
139 // CREATE FUNCTIONS
140 function add(vars) {
141 let result = 0;
142 for (const [key, value] of Object.entries(vars)) {
145 return result;
146 }
147 function subtract(vars) {
148 let result = parseFloat(vars[Object.keys(vars)[0]]);
149 for (const [key, value] of Object.entries(vars)) {
154 return result;
155 }
156 function multiply(vars) {
157 let result = 1;
158 for (const [key, value] of Object.entries(vars)) {
161 return result;
162 }
163 function mod(vars) {
164 let result = parseFloat(vars[Object.keys(vars)[0]]);
165 for (const [key, value] of Object.entries(vars)) {
170 return result;
171 }
172 function pow(vars) {
173 let result = parseFloat(vars[Object.keys(vars)[0]]);
174 for (const [key, value] of Object.entries(vars)) {
179 return result;
180 }
181 function divide(vars) {
182 let result = parseFloat(vars[Object.keys(vars)[0]]);
183 for (const [key, value] of Object.entries(vars)) {
188 return result;
189 }
190 function equal(vars) {
191 let result = vars[Object.keys(vars)[0]];
192 for (const [key, value] of Object.entries(vars)) {
199 return true;
200 }
201 function notEqual(vars) {
202 let result = vars[Object.keys(vars)[0]];
203 for (const [key, value] of Object.entries(vars)) {
210 return true;
211 }
212 function greaterThan(vars) {
213 let result = parseFloat(vars[Object.keys(vars)[0]]);
214 for (const [key, value] of Object.entries(vars)) {
221 return true;
222 }
223 function lessThan(vars) {
224 let result = parseFloat(vars[Object.keys(vars)[0]]);
225 for (const [key, value] of Object.entries(vars)) {
232 return true;
233 }
234 function greaterThanOrEqual(vars) {
235 let result = parseFloat(vars[Object.keys(vars)[0]]);
236 for (const [key, value] of Object.entries(vars)) {
243 return true;
244 }
245 function lessThanOrEqual(vars) {
246 let result = parseFloat(vars[Object.keys(vars)[0]]);
247 for (const [key, value] of Object.entries(vars)) {
254 return true;
255 }
256 function and(vars) {
257 let result = vars[Object.keys(vars)[0]];
258 for (const [key, value] of Object.entries(vars)) {
263 return result;
264 }
265 function or(vars) {
266 let result = vars[Object.keys(vars)[0]];
267 for (const [key, value] of Object.entries(vars)) {
272 return result;
273 }
274 function not(vars) {
275 let result = vars[Object.keys(vars)[0]];
276 return !result;
277 }
278 function xor(vars) {
279 let result = vars[Object.keys(vars)[0]];
280 for (const [key, value] of Object.entries(vars)) {
285 return result;
286 }
287 function nand(vars) {
288 let result = vars[Object.keys(vars)[0]];
289 for (const [key, value] of Object.entries(vars)) {
294 return result;
295 }
296 function nor(vars) {
297 let result = vars[Object.keys(vars)[0]];
298 for (const [key, value] of Object.entries(vars)) {
303 return result;
304 }
305 function xnor(vars) {
306 let result = vars[Object.keys(vars)[0]];
307 for (const [key, value] of Object.entries(vars)) {
312 return result;
313 }
314 function trueFunction(vars) {
315 // if first var is true, return second var, else return third var
316 if (vars[Object.keys(vars)[0]] === "true") {
321 }
322 }
323 function falseFunction(vars) {
324 // if first var is false, return second var, else return third var
325 if (vars[Object.keys(vars)[0]] === "false") {
330 }
331 }
332 function ifEmpty(vars) {
333 // if var is empty, return string "True", else return "False"
334 if (vars[Object.keys(vars)[0]] === "") {
339 }
340 }
341 function length(vars) {
342 return vars[Object.keys(vars)[0]].length;
343 }
344 function contains(vars) {
345 return vars[Object.keys(vars)[0]].includes(vars[Object.keys(vars)[1]]);
346 }
347 function test(vars) {
348 // test whether first var contains second var
349 // second var can be a regular expression
351 return regex.test(vars[Object.keys(vars)[0]]);
352 }
353 function match(vars) {
354 // match first var to second var
355 // second var can be a regular expression
357 return vars[Object.keys(vars)[0]].match(regex);
358 }
359 function replace(vars) {
360 // replace second var in first var with third var
361 // second var can be a regular expression
363 return vars[Object.keys(vars)[0]].replace(regex, vars[Object.keys(vars)[2]]);
364 }
365 function replaceAll(vars) {
366 // replace all instances of second var in first var with third var
367 // second var can be a regular expression
369 return vars[Object.keys(vars)[0]].replace(regex, vars[Object.keys(vars)[2]]);
370 }
371 function lowercase(vars) {
372 return vars[Object.keys(vars)[0]].toLowerCase();
373 }
374 function uppercase(vars) {
375 return vars[Object.keys(vars)[0]].toUpperCase();
376 }
377 function repeat(vars) {
378 // repeats a string a given number of times
379 let result = "";
383 return result;
384 }
385 function stripFormatting(vars) {
386 // removes all formatting from a string
387 return vars[Object.keys(vars)[0]].replace(/(<([^>]+)>)/gi, "");
388 }
389 function min(vars) {
390 let result = parseFloat(vars[Object.keys(vars)[0]]);
391 for (const [key, value] of Object.entries(vars)) {
394 return result;
395 }
396 function max(vars) {
397 let result = parseFloat(vars[Object.keys(vars)[0]]);
398 for (const [key, value] of Object.entries(vars)) {
401 return result;
402 }
403 function absolute(vars) {
404 return Math.abs(parseFloat(vars[Object.keys(vars)[0]]));
405 }
406 function round(vars) {
407 return Math.round(parseFloat(vars[Object.keys(vars)[0]]));
408 }
409 function ceiling(vars) {
410 return Math.ceil(parseFloat(vars[Object.keys(vars)[0]]));
411 }
412 function floor(vars) {
413 return Math.floor(parseFloat(vars[Object.keys(vars)[0]]));
414 }
415 function squareroot(vars) {
416 return Math.sqrt(parseFloat(vars[Object.keys(vars)[0]]));
417 }
418 function cuberoot(vars) {
419 return Math.cbrt(parseFloat(vars[Object.keys(vars)[0]]));
420 }
421 function exponent(vars) {
422 return Math.pow(parseFloat(vars[Object.keys(vars)[0]]), parseFloat(vars[Object.keys(vars)[1]]));
423 }
424 function ln(vars) {
425 return Math.log(parseFloat(vars[Object.keys(vars)[0]]));
426 }
427 function log10(vars) {
428 return Math.log10(parseFloat(vars[Object.keys(vars)[0]]));
429 }
430 function log2(vars) {
431 return Math.log2(parseFloat(vars[Object.keys(vars)[0]]));
432 }
433 function now(vars) {
434 // returns current time adjusted to provided UTC offset
435 const date = new Date();
439 return date.toISOString().slice(0, 10);
440 }
441 function minute(vars) {
442 // from a given date, returns an integer between 0 and 59 corresponding to the minute of its date argument
443 const dateString = vars[Object.keys(vars)[0]];
445 return date.getMinutes();
446 }
447 function hour(vars) {
448 // from a given date, returns an integer between 0 and 23 corresponding to the hour of its date argument
449 const dateString = vars[Object.keys(vars)[0]];
451 return date.getHours();
452 }
453 function day(vars) {
454 // from a given date, returns an integer between 1 and 31 corresponding to the day of its date
455 const dateString = vars[Object.keys(vars)[0]];
457 return date.getDate();
458 }
459 function date(vars) {
460 // from a given date, returns an integer between 1 and 31 corresponding to the day of its date argument
461 const dateString = vars[Object.keys(vars)[0]];
463 return date.getDate();
464 }
465 function week(vars) {
466 // from a given date, returns an integer between 0 and 53 corresponding to the week of its date argument
467 const dateString = vars[Object.keys(vars)[0]];
469 return date.getWeek();
470 }
471 function month(vars) {
472 // from a given date, returns an integer between 0 and 11 corresponding to the month of its date argument
473 const dateString = vars[Object.keys(vars)[0]];
475 return date.getMonth();
476 }
477 function year(vars) {
478 // from a given date, returns an integer between 0 and 9999 corresponding to the year of its date argument
479 const dateString = vars[Object.keys(vars)[0]];
481 return date.getFullYear();
482 }
483 function dateAdd(vars) {
484 // accepts date var and adds to it, returning new date, requiring three arguments: date, number, unit (can be years, quarters, months, weeks, days, hours, minutes, seconds, milliseconds)
485 const dateString = vars[Object.keys(vars)[0]];
516 return date.toISOString.slice(0, 10)();
517 }
518 function dateSubtract(vars) {
519 // accepts date var and subtracts from it, returning new date, requiring three arguments: date, number, unit (can be years, quarters, months, weeks, days, hours, minutes, seconds, milliseconds)
520 const dateString = vars[Object.keys(vars)[0]];
551 return date.toISOString.slice(0, 10)();
552 }
553 function dateBetween(vars) {
554 // accepts two dates and returns the difference between them, requiring three arguments: date1, date2, unit (can be years, quarters, months, weeks, days, hours, minutes, seconds, milliseconds)
555
588 }
589 }
590 function timestamp(vars) {
591 // converts received var to Unix timestamp
592 const dateString = vars[Object.keys(vars)[0]];
594 return Date.parse(date);
595 }
596 function fromTimestamp(vars) {
597 // converts Unix timestamp into date
598 const dateString = vars[Object.keys(vars)[0]];
600 return date.toISOString.slice(0, 10)();
601 }
602 function formatDate(vars) {
603 // formats date according to provided string format (e.g. "MMMM DD YYYY", "dddd, MMMM DD, YYYY hh:mm A zz", "[Month of] MMMM, YYYY")
604 const dateString = vars[Object.keys(vars)[0]];
607 return date.format(format);
608 }
609 function parseDate(vars) {
610 // takes ISO 1860-formatted string and converts into date object
611 const dateString = vars[Object.keys(vars)[0]];
613 return date.toISOString.slice(0, 10)();
614 }
615 function at(vars) {
616 // returns the value at a given index of an array
617 const index = parseInt(vars[Object.keys(vars)[1]]);
618 return vars[Object.keys(vars)[0]][index];
619 }
620 function first(vars) {
621 // returns the first value of an array
622 return vars[Object.keys(vars)[0]][0];
623 }
624 function last(vars) {
625 // returns the last value of an array
626 return vars[Object.keys(vars)[0]][vars[Object.keys(vars)[0]].length - 1];
627 }
628 function slice(vars) {
629 // returns a portion of an array
630 const start = parseInt(vars[Object.keys(vars)[1]]);
632 return vars[Object.keys(vars)[0]].slice(start, end);
633 }
634 function concat(vars) {
635 // can receive infinite number of strings or arrays and concatenate them into a single string
636 let result = "";
640 return result;
641 }
642 function sort(vars) {
643 // sorts an array
644 return vars[Object.keys(vars)[0]].sort();
645 }
646 function reverse(vars) {
647 // reverses an array
648 return vars[Object.keys(vars)[0]].reverse();
649 }
650 function join(vars) {
651 // combines the array in the first var into a string, separated by the second var
652 return vars[Object.keys(vars)[0]].join(vars[Object.keys(vars)[1]]);
653 }
654 function split(vars) {
655 // splits a string into an array, separated by the second var
656 return vars[Object.keys(vars)[0]].split(vars[Object.keys(vars)[1]]);
657 }
658 function unique(vars) {
659 // returns an array containing only unique values
660 return [...new Set(vars[Object.keys(vars)[0]])];
661 }
662 function includes(vars) {
663 // returns true if second var is found in first var
664 return vars[Object.keys(vars)[0]].includes(vars[Object.keys(vars)[1]]);
665 }
666 function find(vars) {
667 // returns the index of the second var in the first var
668 return vars[Object.keys(vars)[0]].findIndex(vars[Object.keys(vars)[1]]);
669 }
670 function findIndex(vars) {
671 // returns the index of the second var in the first var
672 return vars[Object.keys(vars)[0]].findIndex(vars[Object.keys(vars)[1]]);
673 }
674 function filter(vars) {
675 // returns a new array containing only the values that pass the test
676 return vars[Object.keys(vars)[0]].filter(vars[Object.keys(vars)[1]]);
677 }
678 function some(vars) {
679 // returns true if at least one value passes the test
680 return vars[Object.keys(vars)[0]].some(vars[Object.keys(vars)[1]]);
681 }
682 function every(vars) {
683 // returns true if all values pass the test
684 return vars[Object.keys(vars)[0]].every(vars[Object.keys(vars)[1]]);
685 }
686 function map(vars) {
687 // returns a new array containing the results of the function applied to each value
688 return vars[Object.keys(vars)[0]].map(vars[Object.keys(vars)[1]]);
689 }
690 function flatten(vars) {
691 // receives infinite number of arrays, which are combined into a single array
692 let result = [];
697 }
698
699 // EXECUTE FUNCTION
700 switch (method) {
701 case "add":
757 break;
758 case "true":
759 result = trueFunction(vars);
760 break;
761 case "false":
762 result = falseFunction(vars);
763 break;
764 case "if_empty":