mirror of
https://github.com/urbit/shrub.git
synced 2024-12-24 20:47:27 +03:00
212 lines
5.0 KiB
TypeScript
212 lines
5.0 KiB
TypeScript
import _ from "lodash";
|
|
import f from "lodash/fp";
|
|
import bigInt, { BigInteger } from "big-integer";
|
|
import { Resource } from "../groups/index.d";
|
|
|
|
const DA_UNIX_EPOCH = bigInt("170141184475152167957503069145530368000"); // `@ud` ~1970.1.1
|
|
|
|
const DA_SECOND = bigInt("18446744073709551616"); // `@ud` ~s1
|
|
|
|
/**
|
|
* Returns true if an app uses a graph backend
|
|
*
|
|
* @param {string} app The name of the app
|
|
*
|
|
* @return {boolean} Whether or not it uses a graph backend
|
|
*/
|
|
export function appIsGraph(app: string): boolean {
|
|
return app === 'publish' || app == 'link';
|
|
}
|
|
|
|
/**
|
|
* Given a bigint representing an urbit date, returns a unix timestamp.
|
|
*
|
|
* @param {BigInteger} da The urbit date
|
|
*
|
|
* @return {number} The unix timestamp
|
|
*/
|
|
export function daToUnix(da: BigInteger): number {
|
|
// ported from +time:enjs:format in hoon.hoon
|
|
const offset = DA_SECOND.divide(bigInt(2000));
|
|
const epochAdjusted = offset.add(da.subtract(DA_UNIX_EPOCH));
|
|
|
|
return Math.round(
|
|
epochAdjusted.multiply(bigInt(1000)).divide(DA_SECOND).toJSNumber()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Given a unix timestamp, returns a bigint representing an urbit date
|
|
*
|
|
* @param {number} unix The unix timestamp
|
|
*
|
|
* @return {BigInteger} The urbit date
|
|
*/
|
|
export function unixToDa(unix: number): BigInteger {
|
|
const timeSinceEpoch = bigInt(unix).multiply(DA_SECOND).divide(bigInt(1000));
|
|
return DA_UNIX_EPOCH.add(timeSinceEpoch);
|
|
}
|
|
|
|
|
|
export function makePatDa(patda: string): BigInteger {
|
|
return bigInt(udToDec(patda));
|
|
}
|
|
|
|
export function udToDec(ud: string): string {
|
|
return ud.replace(/\./g, "");
|
|
}
|
|
|
|
export function decToUd(str: string): string {
|
|
return _.trimStart(
|
|
f.flow(
|
|
f.split(""),
|
|
f.reverse,
|
|
f.chunk(3),
|
|
f.map(f.flow(f.reverse, f.join(""))),
|
|
f.reverse,
|
|
f.join(".")
|
|
)(str),
|
|
"0."
|
|
);
|
|
}
|
|
|
|
export function resourceAsPath(resource: Resource): string {
|
|
const { name, ship } = resource;
|
|
return `/ship/~${ship}/${name}`;
|
|
}
|
|
|
|
export function uuid(): string {
|
|
let str = "0v";
|
|
str += Math.ceil(Math.random() * 8) + ".";
|
|
for (let i = 0; i < 5; i++) {
|
|
let _str = Math.ceil(Math.random() * 10000000).toString(32);
|
|
_str = ("00000" + _str).substr(-5, 5);
|
|
str += _str + ".";
|
|
}
|
|
|
|
return str.slice(0, -1);
|
|
}
|
|
|
|
/*
|
|
Goes from:
|
|
~2018.7.17..23.15.09..5be5 // urbit @da
|
|
To:
|
|
(javascript Date object)
|
|
*/
|
|
export function daToDate(st: string): Date {
|
|
const dub = function (n: string) {
|
|
return parseInt(n) < 10 ? "0" + parseInt(n) : n.toString();
|
|
};
|
|
const da = st.split("..");
|
|
const bigEnd = da[0].split(".");
|
|
const lilEnd = da[1].split(".");
|
|
const ds = `${bigEnd[0].slice(1)}-${dub(bigEnd[1])}-${dub(bigEnd[2])}T${dub(
|
|
lilEnd[0]
|
|
)}:${dub(lilEnd[1])}:${dub(lilEnd[2])}Z`;
|
|
return new Date(ds);
|
|
}
|
|
|
|
/*
|
|
Goes from:
|
|
(javascript Date object)
|
|
To:
|
|
~2018.7.17..23.15.09..5be5 // urbit @da
|
|
*/
|
|
|
|
export function dateToDa(d: Date, mil: boolean = false): string {
|
|
const fil = function (n: number) {
|
|
return n >= 10 ? n : "0" + n;
|
|
};
|
|
return (
|
|
`~${d.getUTCFullYear()}.` +
|
|
`${d.getUTCMonth() + 1}.` +
|
|
`${fil(d.getUTCDate())}..` +
|
|
`${fil(d.getUTCHours())}.` +
|
|
`${fil(d.getUTCMinutes())}.` +
|
|
`${fil(d.getUTCSeconds())}` +
|
|
`${mil ? "..0000" : ""}`
|
|
);
|
|
}
|
|
|
|
export function deSig(ship: string): string | null {
|
|
if (!ship) {
|
|
return null;
|
|
}
|
|
return ship.replace("~", "");
|
|
}
|
|
|
|
// trim patps to match dojo, chat-cli
|
|
export function cite(ship: string): string {
|
|
let patp = ship,
|
|
shortened = "";
|
|
if (patp === null || patp === "") {
|
|
return "";
|
|
}
|
|
if (patp.startsWith("~")) {
|
|
patp = patp.substr(1);
|
|
}
|
|
// comet
|
|
if (patp.length === 56) {
|
|
shortened = "~" + patp.slice(0, 6) + "_" + patp.slice(50, 56);
|
|
return shortened;
|
|
}
|
|
// moon
|
|
if (patp.length === 27) {
|
|
shortened = "~" + patp.slice(14, 20) + "^" + patp.slice(21, 27);
|
|
return shortened;
|
|
}
|
|
return `~${patp}`;
|
|
}
|
|
|
|
// encode the string into @ta-safe format, using logic from +wood.
|
|
// for example, 'some Chars!' becomes '~.some.~43.hars~21.'
|
|
//
|
|
export function stringToTa(str: string): string {
|
|
let out = "";
|
|
for (let i = 0; i < str.length; i++) {
|
|
const char = str[i];
|
|
let add = "";
|
|
switch (char) {
|
|
case " ":
|
|
add = ".";
|
|
break;
|
|
case ".":
|
|
add = "~.";
|
|
break;
|
|
case "~":
|
|
add = "~~";
|
|
break;
|
|
default:
|
|
const charCode = str.charCodeAt(i);
|
|
if (
|
|
(charCode >= 97 && charCode <= 122) || // a-z
|
|
(charCode >= 48 && charCode <= 57) || // 0-9
|
|
char === "-"
|
|
) {
|
|
add = char;
|
|
} else {
|
|
// TODO behavior for unicode doesn't match +wood's,
|
|
// but we can probably get away with that for now.
|
|
add = "~" + charCode.toString(16) + ".";
|
|
}
|
|
}
|
|
out = out + add;
|
|
}
|
|
return "~." + out;
|
|
}
|
|
|
|
|
|
/**
|
|
* Formats a numbers as a `@ud` inserting dot where needed
|
|
*/
|
|
export function numToUd(num: number): string {
|
|
return f.flow(
|
|
f.split(''),
|
|
f.reverse,
|
|
f.chunk(3),
|
|
f.reverse,
|
|
f.map(s => s.join('')),
|
|
f.join('.')
|
|
)(num.toString())
|
|
}
|