2024-02-29 22:23:05 +08:00
|
|
|
import type { FunctionMap } from "../plug-api/types.ts";
|
2024-02-09 04:00:45 +08:00
|
|
|
import { niceDate, niceTime } from "./dates.ts";
|
2023-10-03 20:16:33 +08:00
|
|
|
|
|
|
|
export const builtinFunctions: FunctionMap = {
|
2024-03-02 18:01:52 +08:00
|
|
|
// String functions
|
|
|
|
contains(str: unknown, substr: unknown) {
|
|
|
|
if (typeof str !== "string") {
|
|
|
|
throw new Error("contains(): str is not a string");
|
|
|
|
}
|
|
|
|
if (typeof substr !== "string") {
|
|
|
|
throw new Error("contains(): substr is not a string");
|
|
|
|
}
|
|
|
|
return str.includes(substr);
|
2023-10-03 20:16:33 +08:00
|
|
|
},
|
2024-02-03 02:19:07 +08:00
|
|
|
replace(
|
2024-02-26 13:46:03 +08:00
|
|
|
str: unknown,
|
|
|
|
...replacementPairs: unknown[]
|
2024-02-03 02:19:07 +08:00
|
|
|
) {
|
2024-02-26 13:46:03 +08:00
|
|
|
if (typeof str !== "string") {
|
|
|
|
throw new Error("replace(): str is not a string");
|
|
|
|
}
|
|
|
|
|
2024-02-23 20:47:27 +08:00
|
|
|
if (replacementPairs.length % 2 !== 0) {
|
|
|
|
throw new Error(
|
2024-02-26 13:46:03 +08:00
|
|
|
"replace(): requires an even number of replacement arguments",
|
2024-02-23 20:47:27 +08:00
|
|
|
);
|
|
|
|
}
|
2024-02-26 13:46:03 +08:00
|
|
|
|
|
|
|
let ret = str;
|
2024-02-23 20:47:27 +08:00
|
|
|
for (let i = 0; i < replacementPairs.length; i += 2) {
|
2024-02-26 13:46:03 +08:00
|
|
|
let match = replacementPairs[i];
|
2024-02-23 20:47:27 +08:00
|
|
|
const replace = replacementPairs[i + 1];
|
2024-02-26 13:46:03 +08:00
|
|
|
match = Array.isArray(match)
|
|
|
|
? new RegExp(match[0], (match[1] ?? "") + "g")
|
2024-02-23 20:47:27 +08:00
|
|
|
: match;
|
2024-02-26 13:46:03 +08:00
|
|
|
|
|
|
|
if (typeof match !== "string" && (!(match instanceof RegExp))) {
|
|
|
|
throw new Error(
|
|
|
|
`replace(): match is not a string or regexp`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (typeof replace !== "string") {
|
|
|
|
throw new Error(
|
|
|
|
`replace(): replace is not a string`,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ret.replaceAll(match, replace);
|
2024-02-23 20:47:27 +08:00
|
|
|
}
|
2024-02-26 13:46:03 +08:00
|
|
|
return ret;
|
2024-01-21 02:16:07 +08:00
|
|
|
},
|
2024-02-26 13:46:03 +08:00
|
|
|
json: (v: unknown) => {
|
2024-02-03 02:19:07 +08:00
|
|
|
return JSON.stringify(v);
|
|
|
|
},
|
2024-02-26 13:46:03 +08:00
|
|
|
niceDate: (ts: unknown) => {
|
|
|
|
if (
|
|
|
|
typeof ts !== "string" && typeof ts !== "number" && !(ts instanceof Date)
|
|
|
|
) {
|
|
|
|
throw new Error("niceDate(): ts is not a valid date");
|
|
|
|
}
|
|
|
|
|
|
|
|
const date = new Date(ts);
|
|
|
|
if (isNaN(date.getTime())) {
|
|
|
|
throw new Error("niceDate(): ts is not a valid date");
|
|
|
|
}
|
|
|
|
|
|
|
|
return niceDate(new Date(ts));
|
|
|
|
},
|
|
|
|
escapeRegexp: (ts: unknown) => {
|
|
|
|
if (typeof ts !== "string") {
|
|
|
|
throw new Error("escapeRegexp(): ts is not a string");
|
|
|
|
}
|
2024-02-03 02:19:07 +08:00
|
|
|
return ts.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
|
|
},
|
|
|
|
// Legacy name: don't use
|
|
|
|
escape: (handlebarsExpr: string) => {
|
|
|
|
return `{{${handlebarsExpr}}}`;
|
|
|
|
},
|
2024-02-26 13:46:03 +08:00
|
|
|
escapeDirective: (directiveText: unknown) => {
|
2024-02-03 02:19:07 +08:00
|
|
|
return `{{${directiveText}}}`;
|
|
|
|
},
|
2024-03-02 18:01:52 +08:00
|
|
|
today() {
|
|
|
|
return niceDate(new Date());
|
|
|
|
},
|
2024-02-03 02:19:07 +08:00
|
|
|
time: () => niceTime(new Date()),
|
|
|
|
tomorrow: () => {
|
|
|
|
const tomorrow = new Date();
|
|
|
|
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
|
|
return niceDate(tomorrow);
|
|
|
|
},
|
|
|
|
yesterday: () => {
|
|
|
|
const yesterday = new Date();
|
|
|
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
|
|
return niceDate(yesterday);
|
|
|
|
},
|
|
|
|
lastWeek: () => {
|
|
|
|
const lastWeek = new Date();
|
|
|
|
lastWeek.setDate(lastWeek.getDate() - 7);
|
|
|
|
return niceDate(lastWeek);
|
|
|
|
},
|
|
|
|
nextWeek: () => {
|
|
|
|
const nextWeek = new Date();
|
|
|
|
nextWeek.setDate(nextWeek.getDate() + 7);
|
|
|
|
return niceDate(nextWeek);
|
|
|
|
},
|
|
|
|
weekStart: (startOnMonday = true) => {
|
|
|
|
const d = new Date();
|
|
|
|
const day = d.getDay();
|
|
|
|
let diff = d.getDate() - day;
|
|
|
|
if (startOnMonday) {
|
|
|
|
diff += day == 0 ? -6 : 1;
|
|
|
|
}
|
|
|
|
return niceDate(new Date(d.setDate(diff)));
|
|
|
|
},
|
|
|
|
|
|
|
|
// List functions
|
2024-02-26 13:46:03 +08:00
|
|
|
count: <T>(list: T[]) => {
|
2024-02-03 02:19:07 +08:00
|
|
|
return list.length;
|
|
|
|
},
|
2024-02-26 13:46:03 +08:00
|
|
|
at: <T>(list: T[], index: number) => {
|
2024-02-03 02:19:07 +08:00
|
|
|
return list[index];
|
2023-10-03 20:16:33 +08:00
|
|
|
},
|
|
|
|
};
|