jsfast
Version:
Fastjs(jsfast) is a useful, lightweight JavaScript library for any types of project.
1,491 lines (1,466 loc) • 58.7 kB
JavaScript
function browserCheck(module) {
const isBrowser = typeof window !== "undefined";
if (!isBrowser) {
throw error(`${module}/browserCheck`, "This module is only available in browser environments.");
}
}
function getStyle(key) {
const style = {
"fastjs.bold": "\u001b[1m",
"fastjs.reverse": "\u001b[7m",
"fastjs.red": "\u001b[31m",
"fastjs.green": "\u001b[32m",
"fastjs.yellow": "\u001b[33m",
"fastjs.blue": "\u001b[34m",
"fastjs.magenta": "\u001b[35m",
"fastjs.cyan": "\u001b[36m",
"fastjs.white": "\u001b[37m",
"fastjs.gray": "\u001b[90m",
"fastjs.bgRed": "\u001b[41m",
"fastjs.bgGreen": "\u001b[42m",
"fastjs.bgYellow": "\u001b[43m",
"fastjs.bgBlue": "\u001b[44m",
"fastjs.bgMagenta": "\u001b[45m",
"fastjs.bgCyan": "\u001b[46m",
"fastjs.bgWhite": "\u001b[47m",
"fastjs.bgGray": "\u001b[100m",
"fastjs.wrong": "\u001b[41m\u001b[37m\u001b[1m",
"fastjs.right": "\u001b[42m\u001b[37m\u001b[1m",
"fastjs.warn": "\u001b[43m\u001b[90m\u001b[1m"
};
if (!key)
return "";
if (Array.isArray(key)) {
return key.map((e) => style[e]).join("");
}
return style[key] || "";
}
function warn(module, message, args = [], styleArgs = []) {
args = args.filter((arg) => arg !== "");
args = args.map((arg, k) => typeof arg === "string" &&
arg[0] !== "&" &&
args[k - 1]?.[args[k - 1].length - 1] !== "&"
? "\n > " + arg
: arg);
args = args.map((arg) => {
if (typeof arg !== "string")
return arg;
if (arg[0] === "&")
arg = ` ${arg.slice(1)} `;
if (arg[arg.length - 1] === "&")
arg = `${arg.slice(0, -1)} `;
return arg;
});
let styleKey = 0;
let outputMessage = "";
let outputObjects = [];
styleArgs.length
? getStyle(styleArgs[styleArgs.length - 1])
: "";
args.unshift(`[Fastjs warn] ${module}: ${message}`);
args.forEach((arg) => {
if (typeof arg !== "string") {
outputMessage += "%o";
outputObjects.push(arg);
return;
}
if (arg.includes("> *") && !arg.includes("> **")) {
let style = styleArgs[styleKey];
arg = arg.replace("*", "");
arg = arg.replace(" >", getStyle(style) + "-->\u001b[0m");
styleKey++;
}
if (arg.includes("***")) {
let style = styleArgs[styleKey];
arg = arg.replace("***", "");
arg =
arg.split("> ")[0] +
"> " +
getStyle(style) +
arg.split("> ").slice(1).join("> ") +
"\u001b[0m";
styleKey++;
}
while (arg.includes(`**`)) {
let style = styleArgs[styleKey];
arg = arg.replace(`**`, getStyle(style));
arg = arg.replace(`**`, "\u001b[0m");
styleKey++;
}
outputMessage += arg;
});
console.warn(outputMessage, ...outputObjects);
}
function error(module, message, args = [], styleArgs = []) {
const eid = Math.floor(Math.random() * (1e8 - 1e7) + 1e7);
args.push(`Trace: ${eid}`);
warn(module, message, args, styleArgs);
return new Error(`[Fastjs error] ${module}: ${message.replace(/[*&]/g, "")}\n > Trace: ${eid}`);
}
function experimentFeatureWarning(id, name, call) {
warn("fastjs/experiment-feature-" + id, `${name} is an experimental feature, it may be removed or changed in the future.`, [`call: `, call], ["fastjs.warn"]);
}
var _dev = {
browserCheck,
experimentFeatureWarning,
warn,
error
};
function _selector(selector, parent = document) {
if (!!(process.env.NODE_ENV !== 'production'))
_dev.browserCheck("fastjs/dom/selector");
const specialStatements = ["body", "head"];
const result = [];
// @ts-ignore
if (parent?.construct === "FastjsDom")
parent = parent._el;
// @ts-ignore
if (parent?.construct === "FastjsDomList")
parent = parent._list;
function select(el, selector) {
if (el.set)
return el.get("querySelectorAll")(selector);
return el.querySelectorAll(selector);
}
Array.isArray(parent)
? parent.forEach((e) => {
result.push(...queryResultToArray(select(e, selector)));
})
: result.push(...queryResultToArray(select(parent, selector)));
if (result.length === 0)
return null;
if ((result[0].id && selector.includes(`#${result[0].id}`)) ||
specialStatements.includes(selector))
return result[0];
const list = [];
result.forEach((e) => {
list.push(e);
});
return list;
function queryResultToArray(queryResult) {
const result = [];
queryResult.forEach((e) => {
result.push(e);
});
return result;
}
}
function isUndefined(value) {
return value === undefined;
}
function isDom(value) {
return value.construct === "FastjsDom";
}
function createMethods$4(list) {
return {
add(el) {
list.push(el);
return list;
},
delete(key, deleteDom = true) {
if (deleteDom)
list[key].remove();
list.splice(key, 1);
return list;
},
each(callback) {
list.forEach((el, i) => callback(el, el.el(), i));
return list;
},
el(key = 0) {
return list[key].el();
},
getElement(key = 0) {
return this.el(key);
},
getDom(key = 0) {
return list[key];
},
next(el = "*") {
const result = _selector(el, this.toElArray());
if (Array.isArray(result))
return createFastjsDomList(result);
if (result === null)
return null;
return createFastjsDom(result);
},
toArray() {
return list;
},
toElArray() {
return list.map((e) => e.el());
}
};
}
function createFastjsDomList(list) {
const domList = [];
for (const el of list) {
if (el === null || el === undefined)
continue;
if (isDom(el))
domList.push(el);
else if (Array.isArray(el))
domList.push(...el);
else
domList.push(createFastjsDom(el));
}
const _atom = setupAtom(domList);
const moduleAtom = new Proxy(_atom, {
get(target, key) {
if (key in target)
return target[key];
if (key in target._list)
return target._list[key];
if (key in target._list[0]) {
const val = target._list[0][key];
if (typeof val === "function") {
return function () {
for (const dom of target._list) {
const proto = dom[key];
if (typeof proto === "function") {
const res = proto.bind(dom, ...arguments)();
if (!isUndefined(res) && res.construct !== "FastjsDom")
return res;
}
}
return target;
};
}
else
return val;
}
return target[key];
},
set(target, key, value) {
target[key] = value;
if (Number.isInteger(Number(key))) {
_atom._list[key] = value;
target[key] = value;
}
return true;
}
});
moduleAtom._list = new Proxy(domList, {
set(target, key, value) {
target[Number(key)] = value;
_atom[Number(key)] = value;
return true;
}
});
domList.forEach((e, i) => {
moduleAtom[i] = e;
});
return Object.assign(moduleAtom, createMethods$4(moduleAtom));
}
function setupAtom(list) {
return {
construct: "FastjsDomList",
get length() {
return list.length;
},
set length(value) {
list.length = value;
}
};
}
async function callUntilEnd(func, timeout, immediate = false, continueEvenError = false) {
return new Promise((resolve, reject) => {
let end = false;
const endFunc = () => end;
setTimeout(callFunc, immediate ? 0 : timeout);
async function callFunc() {
try {
let res = func(endFunc);
if (res instanceof Promise) {
res = await res;
}
if (end || !res) {
setTimeout(callFunc, timeout);
}
else
resolve();
}
catch (error) {
if (!!(process.env.NODE_ENV !== 'production')) {
_dev.warn("fastjs/utils/doUntilEnd", "An error occurred while executing the function", [error.toString()]);
}
if (continueEvenError) {
setTimeout(callFunc, timeout);
console.error(error);
}
else {
reject(error);
end = true;
}
}
}
});
}
function catchError(func, onError) {
const err = (error) => {
if (!!(process.env.NODE_ENV !== 'production')) {
_dev.warn("fastjs/utils/catchError", "An error occurred while executing the function", [error.toString()]);
}
if (onError)
onError(error);
else
console.error(error);
return error;
};
try {
const res = func();
if (res instanceof Promise) {
return res.then((res) => res).catch(err);
}
return res;
}
catch (error) {
return err(error);
}
}
function secureCall(func) {
try {
const res = func();
if (res instanceof Promise) {
return new Promise((resolve, reject) => {
res
.then((res) => resolve([res, null]))
.catch((error) => resolve([undefined, error]));
});
}
return [res, null];
}
catch (error) {
return [undefined, error];
}
}
var basic = /*#__PURE__*/Object.freeze({
__proto__: null,
callUntilEnd: callUntilEnd,
catchError: catchError,
secureCall: secureCall
});
async function copy(text) {
try {
const input = await createDomElement(text);
const selection = selectText(input);
copyToClipboard(selection);
input.remove();
}
catch (error) {
if (!!(process.env.NODE_ENV !== 'production')) {
_dev.warn("fastjs/utils/copy", "An error occurred while copying text to clipboard", error);
}
}
async function createDomElement(text) {
const { createFastjsDom } = await Promise.resolve().then(function () { return dom$2; });
let input = createFastjsDom("span");
input
.html(replaceNewLinesAndSpaces(text))
.push(document.body, "lastElementChild");
return input.el();
function replaceNewLinesAndSpaces(text) {
return text.replace(/\n/g, "<br>").replace(/ /g, " ");
}
}
function selectText(element) {
const range = document.createRange();
range.setStart(element, 0);
range.setEnd(element, element.childNodes.length);
const selection = window.getSelection();
if (!selection)
return null;
selection.removeAllRanges();
selection.addRange(range);
return selection;
}
function copyToClipboard(selection) {
if (!selection) {
if (!!(process.env.NODE_ENV !== 'production')) {
_dev.warn("fastjs/utils/copy", "selection is null");
}
return;
}
document.execCommand("copy");
}
}
var dom$3 = /*#__PURE__*/Object.freeze({
__proto__: null,
copy: copy
});
function rand(min, max, decimal = 0) {
if (!!(process.env.NODE_ENV !== 'production')) {
if (min > max) {
_dev.warn("fastjs/utils/rand", "min is greater than max, this may cause unexpected results", [`*min: ${min}`, `*max: ${max}`, `decimal: ${decimal}`]);
}
if (decimal < 0) {
_dev.warn("fastjs/utils/rand", "decimal is less than 0, this may cause unexpected results", [`min: ${min}`, `max: ${max}`, `*decimal: ${decimal}`]);
}
}
const prefix = decimal * 10 || 1;
[min, max] = [min * prefix, max * prefix];
let num = (Math.floor(Math.pow(10, 14) * Math.random() * Math.random()) %
(max - min + 1)) +
min;
return num / prefix;
}
function randString(length, options = {}) {
const letters = "abcdefghijklmnopqrstuvwxyz";
let choices = "";
if (options.number)
choices += "0123456789";
if (options.letter !== false) {
if (options.upper)
choices += letters.toUpperCase();
if (options.lower !== false)
choices += letters;
}
if (Array.isArray(options.custom))
choices += options.custom.join("");
else if (options?.custom)
choices += options.custom;
if (options.max)
length = rand(length, options.max);
let result = "";
for (let i = 0; i < length; i++) {
result += choices.charAt(rand(0, choices.length - 1));
}
return result;
}
function uuid() {
const s = (len) => randString(len, { number: true });
return `${s(8)}-${s(4)}-4${s(3)}-${s(4)}-${s(12)}`;
}
var rand$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
rand: rand,
randString: randString,
uuid: uuid
});
var index$3 = {
...basic,
...dom$3,
...rand$1
};
function createMethods$3(dom) {
function get(key) {
return dom._el[key];
}
function set(key, val) {
if (findPropInChain(dom._el?.constructor.prototype, key)
?.writable ||
findPropInChain(dom._el?.constructor.prototype, key)?.set) {
dom._el[key] = val;
}
else if (!!(process.env.NODE_ENV !== 'production'))
_dev.warn("fastjs/dom/set", `key **${key}** is not writable`, [
"*key: " + key,
"set<T extends keyof BasicElement>(**key: T**, val: HTMLElement[T]): Dom",
"super: ",
dom
], ["fastjs.warn"]);
return dom;
function findPropInChain(obj, prop) {
while (obj !== null) {
const desc = Object.getOwnPropertyDescriptor(obj, prop);
if (desc)
return desc;
obj = Object.getPrototypeOf(obj);
}
return null;
}
}
function text(val) {
if (val === undefined)
return dom._el.textContent || "";
dom._el.textContent = val;
return dom;
}
function html(val) {
if (val === undefined)
return dom._el.innerHTML;
dom._el.innerHTML = val;
return dom;
}
function val(val) {
const key = (dom._el.tagName === "TEXTAREA" ? "textContent" : "value");
if (val === undefined)
return dom._el[key];
set(key, val);
return dom;
}
const el = () => dom._el;
const remove = () => {
dom._el.remove();
return dom;
};
const focus = () => {
dom._el.focus();
return dom;
};
const first = () => dom._el.firstElementChild
? createFastjsDom(dom._el.firstElementChild)
: null;
const last = () => dom._el.lastElementChild ? createFastjsDom(dom._el.lastElementChild) : null;
const father = () => {
const father = dom._el.parentElement;
return father ? createFastjsDom(father) : null;
};
const children = () => createFastjsDomList([...dom._el.children]);
const next = (selector = "*") => {
const result = _selector(selector, dom._el);
if (Array.isArray(result))
return createFastjsDomList(result);
if (result === null)
return null;
return createFastjsDom(result);
};
const each = (callback, deep = false) => {
const children = [...dom._el.children];
children.forEach((v, i) => {
callback(createFastjsDom(v), v, i);
if (deep)
createFastjsDom(v).each(callback, deep);
});
return dom;
};
function addEvent(event, callback) {
let eventTrig = (event) => callback(dom, event);
dom._events.push({
type: event,
callback: callback,
trigger: eventTrig,
remove: () => {
dom.removeEvent(callback);
}
});
dom._el.addEventListener(event, eventTrig);
return dom;
}
function removeEvent(typeOrCallback, key) {
const attrs = {
type: typeof typeOrCallback === "string" ? typeOrCallback : undefined,
callback: typeof typeOrCallback === "function" ? typeOrCallback : undefined,
key
};
if (attrs.callback) {
dom._events.forEach((v, i) => {
if (v.callback === attrs.callback) {
dom._el.removeEventListener(v.type, v.trigger);
dom._events.splice(i, 1);
}
});
}
else if (attrs.type) {
if (attrs.key !== undefined) {
dom._el.removeEventListener(dom._events[attrs.key].type, dom._events[attrs.key].trigger);
dom._events.splice(attrs.key, 1);
}
else {
dom._events.forEach((v) => {
if (v.type === attrs.type) {
dom._el.removeEventListener(v.type, v.trigger);
dom._events.splice(dom._events.indexOf(v), 1);
}
});
}
}
return dom;
}
function getStyle(keyOrCallback) {
const getStyleProxy = () => {
return new Proxy(styles, {
get: (target, key) => {
return (target.getPropertyValue(key) ||
target[key] ||
null);
},
set: (target, key, value) => {
dom.setStyle(key, value);
return Reflect.set(target, key, value);
}
});
};
const computedStyle = window.getComputedStyle(dom._el);
const styles = Object.assign(computedStyle, dom._el.style);
if (typeof keyOrCallback === "string")
return styles.getPropertyValue(keyOrCallback.replace(/[A-Z]/g, (v) => "-" + v.toLowerCase()));
else if (typeof keyOrCallback === "function")
keyOrCallback(getStyleProxy(), dom);
else
return getStyleProxy();
return dom;
}
function setStyle(strOrObj, val, important) {
if (val)
dom._el.style.setProperty(strOrObj.replace(/[A-Z]/g, (v) => "-" + v.toLowerCase()), val, important ? "important" : "");
else if (typeof strOrObj === "string")
dom._el.style.cssText = strOrObj;
else {
let key;
for (key in strOrObj) {
dom.setStyle(key, strOrObj[key]);
}
}
return dom;
}
function getClass(callback) {
const arr = [...dom._el.classList];
if (callback)
callback(arr);
else
return arr;
}
function setClass(nameOrObj, value = true) {
if (typeof nameOrObj === "string")
dom._el.classList[value ? "add" : "remove"](nameOrObj);
else {
for (const key in nameOrObj) {
dom.setClass(key, nameOrObj[key]);
}
}
return dom;
}
const classOp = (name, op) => {
name.forEach((v) => {
v.split(" ").forEach((v) => {
dom.setClass(v, op);
});
});
};
function addClass(className) {
if (typeof className === "string")
classOp([...arguments], true);
else
className.forEach((v) => dom.addClass(v));
return dom;
}
function removeClass(className) {
if (typeof className === "string")
classOp([...arguments], false);
else
className.forEach((v) => dom.removeClass(v));
return dom;
}
const clearClass = () => {
dom._el.className = "";
return dom;
};
function getAttr(param) {
const getAttrProxy = () => {
const arr = [...dom._el.attributes];
const obj = {};
arr.forEach((v) => {
obj[v.name] = v.value;
});
return new Proxy(obj, {
set: (target, key, value) => {
dom.setAttr(key, value);
return Reflect.set(target, key, value);
}
});
};
switch (typeof param) {
case "string":
return dom._el.getAttribute(param);
case "function":
param(getAttrProxy(), dom);
return dom;
default:
return getAttrProxy();
}
}
function setAttr(keyOrAttr, val) {
const setAttr = (key, val) => {
if (val === null)
dom._el.removeAttribute(key);
else
dom._el.setAttribute(key, val);
};
if (typeof keyOrAttr === "string")
setAttr(keyOrAttr, val);
else {
for (const key in keyOrAttr) {
setAttr(key, keyOrAttr[key]);
}
}
return dom;
}
function push(el = document.body, target = "lastElementChild", clone) {
// @ts-expect-error Check if el is FastjsDom | FastjsDomList
el = el.tagName ? el : el.el();
const isReplace = (target === "replaceElement");
const newElement = createFastjsDom(clone ? dom._el.cloneNode(true) : dom._el);
if (isReplace) {
const father = createFastjsDom(dom._el.parentElement);
if (father === null) {
if (!!(process.env.NODE_ENV !== 'production')) {
throw _dev.error("fastjs/dom/push", "father is null", [
"*el: ",
el,
"target: ",
target,
"push<T extends PushTarget>(**el?: HTMLElement | FastjsDomList | FastjsDom**, target?: T, clone?: boolean): PushReturn<T>"
], ["fastjs.wrong"]);
}
throw new Error("father is null");
}
father._el.replaceChild(newElement._el, dom._el);
}
else if (typeof target === "number") {
if (!!(process.env.NODE_ENV !== 'production')) {
if (target > dom._el.children.length) {
throw _dev.error("fastjs/dom/push", "target is out of range", [
"*dom(container): ",
dom,
"target: ",
target,
"push<T extends PushTarget>(**el?: HTMLElement | FastjsDomList | FastjsDom**, target?: T, clone?: boolean): PushReturn<T>"
], ["fastjs.wrong"]);
}
}
dom._el.insertBefore(newElement._el, dom._el.children[target]);
}
else {
const event = {
firstElementChild: () => el.prepend(newElement._el),
lastElementChild: () => el.append(newElement._el),
randomElementChild,
beforeElement: () => el.before(newElement._el),
afterElement: () => el.after(newElement._el)
};
event[target]();
}
return {
isReplace,
newElement: (isReplace && newElement),
oldElement: isReplace && dom,
index: [...el.children].indexOf(newElement._el),
el: newElement,
origin: dom,
father: newElement.father()
};
function randomElementChild() {
const children = [...el.children];
if (children.length === 0)
el.appendChild(dom._el);
else {
const pos = rand(0, children.length);
if (pos === children.length)
el.appendChild(dom._el);
else
el.insertBefore(dom._el, children[rand(0, children.length - 1)]);
}
}
}
function insert(el, target = "last", clone) {
// @ts-expect-error Check if el is FastjsDom | FastjsDomList
el = el.tagName ? el : el.el();
const newElement = createFastjsDom(clone ? el.cloneNode(true) : el);
if (typeof target === "number") {
if (!!(process.env.NODE_ENV !== 'production')) {
if (target > el.children.length) {
throw _dev.error("fastjs/dom/insert", "target is **out of range**", [
"*el(container): ",
el,
"target: ",
target,
"insert<T extends InsertTarget>(**el: HTMLElement | FastjsDomList | FastjsDom**, target: T, clone?: boolean): InsertReturn"
], ["fastjs.wrong"]);
}
}
el.insertBefore(newElement._el, dom._el.children[target]);
}
else {
const event = {
first: () => dom._el.prepend(newElement._el),
last: () => dom._el.append(newElement._el),
random: randomElementChild,
before: () => dom._el.before(newElement._el),
after: () => dom._el.after(newElement._el)
};
event[target]();
}
return {
index: Array.from(el.children).indexOf(newElement._el),
added: newElement,
origin: dom
};
function randomElementChild() {
const children = [...dom._el.children];
if (children.length === 0)
dom._el.appendChild(newElement._el);
else
dom._el.insertBefore(newElement._el, children[rand(0, children.length - 1)]);
}
}
return {
get,
set,
text,
html,
val,
el,
remove,
focus,
first,
last,
father,
children,
next,
each,
addEvent,
removeEvent,
getStyle,
setStyle,
getClass,
setClass,
addClass,
removeClass,
clearClass,
getAttr,
setAttr,
push,
insert
};
}
function createModule(module) {
return {
...module(),
setCustomProp(name, value) {
this[String(name)] = value;
return this;
},
setCustomProps(props) {
for (const key in props) {
this[key] = props[key];
}
return this;
},
getCustomProp(name) {
return this[String(name)];
},
setCustomEvent(name, func, setup = false) {
this[name] = func;
if (setup)
func(this, this);
return this;
},
callCustomEvent(name, ...args) {
this[name](this, ...args);
return this;
},
then(func, time = 0) {
if (!!(process.env.NODE_ENV !== 'production')) {
if (typeof func !== "function") {
throw _dev.error("fastjs/base/FastjsBaseModule", "Invalid function, **a function is required**.", [
`***func: ${func}`,
`time: ${time}`,
"then(**func: (e: T) => void**, time: number = 0): T",
"FastjsBaseModule.then"
], ["fastjs.wrong"]);
}
if (typeof time !== "number") {
_dev.warn("fastjs/base/FastjsBaseModule", "Invalid time, **a number is required**.", [
`func: ${func}`,
`***time: ${time}`,
"then(func: (e: T) => void, **time: number = 0**): T",
"FastjsBaseModule.then"
], ["fastjs.warn"]);
}
}
const callback = () => func(this);
time === 0 ? callback() : setTimeout(callback, time);
return this;
}
};
}
function createFastjsDom(el = document.body, props) {
if (typeof el === "string")
el = document.createElement(el);
else if ("construct" in el && el.construct === "FastjsDom")
el = el._el;
const moduleAtom = createModule(() => ({
construct: "FastjsDom",
_events: [],
_el: el
}));
const module = Object.assign(moduleAtom, createMethods$3(moduleAtom));
if (props)
mergeProps(module, props);
return module;
}
function mergeProps(el, props) {
let key;
for (key in props) {
if (key === "html")
el.html(props.html);
else if (key === "text")
el.text(props.text);
else if (key === "css")
el.setStyle(props.css);
else if (key === "class")
el.addClass(props.class);
else if (key === "attr")
el.setAttr(props.attr);
else if (key === "val")
el.val(props.val);
else if (key in el._el)
el.set(key, props[key]);
}
}
var dom$2 = /*#__PURE__*/Object.freeze({
__proto__: null,
createFastjsDom: createFastjsDom
});
function selector(target = "body", parent = document) {
const result = _selector(target, parent);
if (Array.isArray(result))
return createFastjsDomList(result);
if (result === null)
return null;
return createFastjsDom(result);
}
const dom = function (target = "body", parent = document) {
return selector(target, parent);
};
dom.select = selector;
dom.newEl = createFastjsDom;
dom.newElList = createFastjsDomList;
var dom$1 = dom;
function extractIgnoreTokens(formatString) {
const ignoreTokens = [];
let processedString = "";
let tokenBuffer = "";
let depth = 0;
for (const char of formatString) {
if (char === "<") {
if (++depth === 1)
continue;
}
else if (char === ">") {
depth--;
if (depth === 0) {
ignoreTokens.push(tokenBuffer);
processedString += `{{*${ignoreTokens.length - 1}}}`;
tokenBuffer = "";
continue;
}
}
if (depth > 0)
tokenBuffer += char;
else
processedString += char;
}
if (depth > 0)
processedString += `<${tokenBuffer}`;
return [processedString, ignoreTokens];
}
function getReplacement(date = new Date()) {
const replacement = [
["Y", date.getFullYear()],
["M", date.getMonth() + 1],
["D", date.getDate()],
["H", date.getHours() % 12],
["hh", date.getHours()],
["h", date.getHours()],
["mm", date.getMinutes()],
["m", date.getMinutes()],
["ss", date.getSeconds()],
["s", date.getSeconds()],
["S", date.getMilliseconds()],
// A and a should be the last one because it will affect the result of replacement
["A", date.getHours() >= 12 ? "PM" : "AM"],
["a", date.getHours() >= 12 ? "pm" : "am"]
];
return replacement.map((replacement) => replacement[0].length === 1 && typeof replacement[1] === "number"
? [replacement[0], padZero(replacement[1])]
: replacement);
function padZero(number) {
return number < 10 ? "0" + number : number.toString();
}
}
function createMethods$2(date) {
function changeDate(time) {
if (typeof time === "string") {
time = parseFormatString(date.format, time);
}
date._date = time;
date._createAt = Date.now();
return date;
}
const changeFormat = (format) => {
date.format = format;
return date;
};
const setZone = (zone) => {
date.timezoneDiff = zone * 3600 * 1000;
return date;
};
const refresh = () => {
date._createAt = Date.now();
return date;
};
const toNumber = (utc = true) => utc ? date._date : date._date - date.timezoneDiff;
const toActiveNumber = (utc = true) => toNumber(utc) + Date.now() - date._createAt;
function toString(showOrFormat, format) {
const attrs = {
format
};
if (!showOrFormat)
attrs.show = "utc";
else if (typeof showOrFormat === "number" ||
["utc", "local"].includes(showOrFormat))
attrs.show = showOrFormat;
else
attrs.format = showOrFormat;
const [formatString, ignoreTokens] = extractIgnoreTokens(attrs.format || date.format);
let t = date._date;
if (typeof attrs.show === "number")
t -= attrs.show * 3600 * 1000;
else if (attrs.show === "local")
t -= date.timezoneDiff;
let result = formatString;
for (const replace of getReplacement(new Date(t))) {
const format = replace[0];
const replacement = replace[1];
result = result.replace(new RegExp(format, "g"), String(replacement));
}
ignoreTokens.forEach((token, index) => {
result = result.replace(`{{*${index}}}`, `${token}`);
});
return result;
}
function toActiveString(showOrFormat, format) {
if (typeof showOrFormat === "string" &&
!["utc", "local"].includes(showOrFormat)) {
format = showOrFormat;
}
return createFastjsDate(format || date.format, toActiveNumber()).toString();
}
return {
changeDate,
changeFormat,
setZone,
refresh,
toNumber,
toActiveNumber,
toString,
toActiveString
};
}
function parseFormatString(formatString, dateString) {
let isInIgnoreToken = false;
let parsedDate = new Date();
parsedDate.setMilliseconds(0);
let is12Hour = "";
let isAm = null;
let isToken = false;
let dateStringPointer = -1;
const allTokens = getReplacement().map((replacement) => replacement[0]);
for (let i = 0; i < formatString.length; i++) {
dateStringPointer++;
const char = formatString[i];
if (char === "<" || char === ">") {
isInIgnoreToken = char === "<";
isToken = false;
dateStringPointer--;
continue;
}
if (isInIgnoreToken) {
continue;
}
if (allTokens.includes(char)) {
if (isToken) {
if (!!(process.env.NODE_ENV !== 'production')) {
throw _dev.error("fastjs/date/FastjsDate", "Invalid format string, token cannot be adjacent, did you using the chars like 'hh', 'mm'?", [
"***formatString: " + formatString,
"***dateString: " + dateString,
"private parseFormatString(formatString: string, dateString: string): number"
], ["fastjs.wrong"]);
}
throw "fg3j";
}
switch (char) {
case "Y":
parsedDate.setFullYear(Number(dateString.slice(dateStringPointer, dateStringPointer + 4)));
dateStringPointer += 3;
break;
case "M":
parsedDate.setMonth(Number(dateString.slice(dateStringPointer, dateStringPointer + 2)) -
1);
dateStringPointer += 1;
break;
case "D":
parsedDate.setDate(Number(dateString.slice(dateStringPointer, dateStringPointer + 2)));
dateStringPointer += 1;
break;
case "H":
is12Hour = dateString.slice(dateStringPointer, dateStringPointer + 2);
dateStringPointer += 1;
break;
case "A":
isAm =
dateString.slice(dateStringPointer, dateStringPointer + 2) === "AM";
dateStringPointer += 1;
break;
case "a":
isAm =
dateString.slice(dateStringPointer, dateStringPointer + 2) === "am";
dateStringPointer += 1;
break;
case "h":
parsedDate.setHours(Number(dateString.slice(dateStringPointer, dateStringPointer + 2)));
dateStringPointer += 1;
break;
case "m":
parsedDate.setMinutes(Number(dateString.slice(dateStringPointer, dateStringPointer + 2)));
dateStringPointer += 1;
break;
case "s":
parsedDate.setSeconds(Number(dateString.slice(dateStringPointer, dateStringPointer + 2)));
dateStringPointer += 1;
break;
case "S":
parsedDate.setMilliseconds(Number(dateString.slice(dateStringPointer, dateStringPointer + 3)));
dateStringPointer += 2;
break;
}
isToken = true;
}
else {
isToken = false;
}
}
if (is12Hour) {
if (isAm === null) {
if (!!(process.env.NODE_ENV !== 'production')) {
throw _dev.error("fastjs/date/FastjsDate", "Invalid format string, using 12 hours format but missing AM/PM token", [
"***formatString: " + formatString,
"***dateString: " + dateString,
"private parseFormatString(formatString: string, dateString: string): number"
], ["fastjs.wrong"]);
}
throw "2b5s";
}
if (isAm) {
parsedDate.setHours(Number(is12Hour));
}
else {
parsedDate.setHours(Number(is12Hour) + 12);
}
}
return parsedDate.getTime();
}
function createFastjsDate(format = "Y-M-D h:m:s", date = Date.now(), local = false) {
if (typeof date === "string")
date = parseFormatString(format, date);
else if (date instanceof Date)
date = date.getTime();
const moduleAtom = createModule(() => ({
construct: "FastjsDate",
format,
_date: date,
_createAt: Date.now(),
timezoneDiff: new Date().getTimezoneOffset() * 60 * 1000
}));
if (local)
moduleAtom._date += moduleAtom.timezoneDiff;
const module = Object.assign(moduleAtom, createMethods$2(moduleAtom));
return module;
}
/**
* @description
* Parse a date string or timestamp into a parseReturn object
*/
const parse$1 = (time, format = "Y-M-D h:m:s") => {
const fastjsDateObject = createFastjsDate(format, time);
const dateString = fastjsDateObject.toString();
const timestamp = fastjsDateObject.toNumber();
const utc = timestamp + new Date().getTimezoneOffset() * 60 * 1000;
return {
format,
date: new Date(timestamp),
string: dateString,
dateString,
timestamp,
utcDate: new Date(utc),
utcTimestamp: utc,
utcDateString: createFastjsDate(format, utc).toString()
};
};
/**
* @description
* Get a parseReturn object of timestamp or now
*/
const parseTime = (time, format) => parse$1(time, format);
/**
* @description
* Get a parseReturn object of string or now
*/
const parseDate = (date, format) => parse$1(date, format);
/**
* @description
* Get a string of timestamp or now
* - For string input, use parse(t, f?) or parseDate(t, f?) instead
* - For string to string(reformat), use reformat(t, f, nf?) instead
* - For other output, use parse(t, f?) instead
*/
// const string = (format: string, date: number = Date.now()): string => parse(date, format).string;
const string = (format, date = Date.now()) => parse$1(date, format).string;
/**
* @description
* Reformat a date string into another format
* - For other output, use parse(rf(), f?) instead
*/
const reformat = (format, date, newFormat = "Y-M-D h:m:s") => createFastjsDate(format, date).toString(newFormat);
/**
* @description
* Get a parseReturn object of now
*/
const now = (format) => parse$1(Date.now(), format);
/**
* @description
* Create a FastjsDate instance
*/
var index$2 = {
parse: parse$1,
parseTime,
parseDate,
string,
reformat,
now,
create: createFastjsDate
};
const globalConfig = {
timeout: 5000,
hooks: {
runAll: false
},
handler: {
handleResponse: async (response, request) => {
if (response.headers.get("Content-Type")?.includes("application/json"))
return await response.json();
return await response.text();
},
responseCode: (code) => {
return code >= 200 && code < 300;
}
},
check: {
ignoreFormatWarning: false,
stringBodyWarning: true,
unrecommendedMethodWarning: true
}
};
function createConfig(config = {}) {
return {
timeout: config.timeout || globalConfig.timeout,
headers: config.headers || {},
wait: config.wait || 0,
failed: config.failed || (() => 0),
callback: config.callback || (() => 0),
query: config.query || null,
body: config.body || null,
hooks: generateHooks()
};
function generateHooks() {
const requestHooks = {
before: [],
init: [],
success: [],
failed: []
};
let key;
for (key in requestHooks) {
const addHooks = (hooks) => {
if (!hooks)
return;
requestHooks[key].push(
// @ts-ignore
...(Array.isArray(hooks)
? hooks
: [hooks]));
};
if (config.hooks?.[key])
addHooks(config.hooks[key]);
if (globalConfig.hooks[key])
addHooks(globalConfig.hooks[key]);
}
return Object.assign(requestHooks, {
runAll: config.hooks?.runAll || globalConfig.hooks.runAll
});
}
}
function addQuery(url, query) {
if (!query || Object.keys(query).length === 0)
return url;
const urlSearchParams = queryToUrlParams(query);
if (urlSearchParams.size > 0)
url = url + (url.includes("?") ? "&" : "?") + urlSearchParams.toString();
return url;
}
function queryToUrlParams(query) {
if (typeof query !== "string")
return new URLSearchParams(query);
if (query[0] === "?") {
query = query.slice(1);
}
const urlSearchParams = new URLSearchParams();
query.split("&").forEach((query) => {
const [key, value] = query.split("=");
urlSearchParams.set(key, value);
});
return urlSearchParams;
}
function transformPathParams(url, query) {
const urlComponents = url.split("/");
const pathReg = /^:/;
const matchs = [];
return [
urlComponents
.map((component) => {
const key = component.replace(":", "");
if (pathReg.test(component) && query[key]) {
matchs.push(key);
const data = query[key];
delete query[key];
return data;
}
return component;
})
.join("/"),
matchs
];
}
function parse(data) {
try {
return JSON.parse(data);
}
catch (error) {
return data;
}
}
function sendRequest(request, method, url = request.url) {
if (!!(process.env.NODE_ENV !== 'production')) {
if (["GET", "HEAD", "OPTIONS"].includes(method) && request.config.body) {
_dev.warn("fastjs/request", `Body is not allowed in ${method} request, use POST instead. (HTTP 1.1)`, [
`url: ${url || request.url}`,
`*method: ${method}`,
`*body: `,
request.body,
"super: ",
request
], ["fastjs.warn"]);
}
}
if (!url)
url = request.url;
if (!url) {
if (!!(process.env.NODE_ENV !== 'production')) {
throw _dev.error("fastjs/request", "A correct url is **required**.", [
`*url: **undefined**`,
"data: ",
request.data,
"config: ",
request.config,
"super: ",
request
], ["fastjs.wrong", "fastjs.wrong", "fastjs.wrong"]);
}
throw new Error("A correct url is required.");
}
const data = {
body: isBodyAllowed(method) ? request.data : null,
query: (isBodyAllowed(method) ? null : request.data) || request.config.query
};
if (request.config.wait) {
if (request.wait)
clearTimeout(request.wait);
request.wait = setTimeout(() => {
passthrough();
request.wait = null;
}, request.config.wait);
}
else
passthrough();
return request;
function isBodyAllowed(method) {
return !["GET", "HEAD", "OPTIONS"].includes(method);
}
async function passthrough() {
const hooks = request.config.hooks;
if (!(await runHooks(hooks.before, [request])))
return hookFailed("before", request, null);
let pathParamMatches = [];
[url, pathParamMatches] = transformPathParams(url, request.data);
for (const match of pathParamMatches) {
delete request.data[match];
}
if (typeof data.body === "object") {
request.config.headers["Content-Type"] = "application/json";
}
request.request = new Request(addQuery(url, data.query), {
method,
headers: request.config.headers,
body: data.body ? JSON.stringify(data.body) : undefined
});
if (!(await runHooks(hooks.init, [request])))
return hookFailed("init", request, null);
const signal = request.config.timeout
? AbortSignal.timeout(request.config.timeout)
: null;
if (!!(process.env.NODE_ENV !== 'production') && request.config.timeout && request.config.timeout <= 1000) {
_dev.warn("fastjs/request", "Timeout is too short, it may cause the request to be interrupted.", [
`url: ${url}`,
`method: ${method}`,
"body: ",
request.body,
`*timeout: ${request.config.timeout}`,
"super: ",
request
], ["fastjs.warn"]);
}
fetch(request.request, { signal })
.then(async (response) => {
const data = await globalConfig.handler.handleResponse(response, request);
const headers = response.headers;
headers.toArray = () => [...response.headers.entries()];
headers.toObject = () => Object.fromEntries(response.headers.entries());
const returnData = parse(data);
const requestReturn = {
headers,
response,
data: returnData,
status: response.status,
request,
resend: () => sendRequest(request, method)
};
const proto = Object.create(Object.getPrototypeOf(returnData));
proto.getFullReturn = () => requestReturn;
Object.setPrototypeOf(returnData, proto);
if (!globalConfig.handler.responseCode(response.status, request))
return await handleBadResponse(requestReturn, request);
if (!(await runHooks(hooks.success, [requestReturn, request])))
return hookFailed("success", request, requestReturn);
matchCallback(request.callback.success, [data, requestReturn], method);
matchCallback(request.callback.finally, [request], method);
})
.catch(async (error) => {
if (!!(process.env.NODE_ENV !== 'production')) {
if (error.message === "signal timed out") {
_dev.warn("fastjs/request", `${method} Request timed out.`, [
`url: ${url}`,
"body: ",
request.body,
`*timeout: ${request.config.timeout}`,
"super: ",
request
], ["fastjs.warn"]);
}
}
else {
_dev.warn("fastjs/request", "Failed to send request.", [
`url: ${url}`,
`method: ${method}`,
`body: `,