Merge branch 'main' into fix/renaming-ext

This commit is contained in:
muzam1l
2022-08-19 15:14:52 +05:30
111 changed files with 5511 additions and 5967 deletions

View File

@@ -1,24 +1,20 @@
import { Spec, parse, Problem } from "comment-parser"
import { Spec, parse, Problem } from 'comment-parser'
export const getTags = (source?: string): Spec[] => {
if (!source) return []
const blocks = parse(source)
const tags = blocks.reduce(
(acc, block) => acc.concat(block.tags),
[] as Spec[]
);
return tags
if (!source) return []
const blocks = parse(source)
const tags = blocks.reduce((acc, block) => acc.concat(block.tags), [] as Spec[])
return tags
}
export const getErrors = (source?: string): Error | undefined => {
if (!source) return undefined
const blocks = parse(source)
const probs = blocks.reduce(
(acc, block) => acc.concat(block.problems),
[] as Problem[]
);
if (!probs.length) return undefined
const errors = probs.map(prob => `[${prob.code}] on line ${prob.line}: ${prob.message}`)
const error = new Error(`The following error(s) occurred while parsing JSDOC: \n${errors.join('\n')}`)
return error
}
if (!source) return undefined
const blocks = parse(source)
const probs = blocks.reduce((acc, block) => acc.concat(block.problems), [] as Problem[])
if (!probs.length) return undefined
const errors = probs.map(prob => `[${prob.code}] on line ${prob.line}: ${prob.message}`)
const error = new Error(
`The following error(s) occurred while parsing JSDOC: \n${errors.join('\n')}`
)
return error
}

View File

@@ -1,15 +1,15 @@
import { decodeRestrictedBase64ToBytes } from "./decodeRestrictedBase64ToBytes";
import { isZlibData, decompressZlib } from "./zlib";
import { fromByteArray } from "base64-js";
import { decodeRestrictedBase64ToBytes } from './decodeRestrictedBase64ToBytes'
import { isZlibData, decompressZlib } from './zlib'
import { fromByteArray } from 'base64-js'
export async function decodeBinary(input: string): Promise<ArrayBuffer> {
let data = decodeRestrictedBase64ToBytes(input);
let data = decodeRestrictedBase64ToBytes(input)
if (isZlibData(data)) {
data = await decompressZlib(data);
data = await decompressZlib(data)
}
return data.buffer as ArrayBuffer;
return data.buffer as ArrayBuffer
}
export function encodeBinary(input: ArrayBuffer): string {
return fromByteArray(new Uint8Array(input));
}
return fromByteArray(new Uint8Array(input))
}

View File

@@ -1,44 +1,119 @@
const base64DecodeMap = [ // starts at 0x2B
62, 0, 0, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
0, 0, 0, 0, 0, 0, 0, // 0x3A-0x40
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, // 0x5B-0x0x60
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51
];
const base64DecodeMap = [
// starts at 0x2B
62,
0,
0,
0,
63,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
0,
0,
0,
0,
0,
0,
0, // 0x3A-0x40
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
0,
0,
0,
0,
0,
0, // 0x5B-0x0x60
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51
]
const base64DecodeMapOffset = 0x2B;
const base64EOF = 0x3D;
const base64DecodeMapOffset = 0x2b
const base64EOF = 0x3d
export function decodeRestrictedBase64ToBytes(encoded: string) {
let ch: any;
let code: any;
let code2: any;
let ch: any
let code: any
let code2: any
const len = encoded.length;
const padding = encoded.charAt(len - 2) === "=" ? 2 : encoded.charAt(len - 1) === "=" ? 1 : 0;
const decoded = new Uint8Array((encoded.length >> 2) * 3 - padding);
const len = encoded.length
const padding = encoded.charAt(len - 2) === '=' ? 2 : encoded.charAt(len - 1) === '=' ? 1 : 0
const decoded = new Uint8Array((encoded.length >> 2) * 3 - padding)
for (let i = 0, j = 0; i < encoded.length;) {
ch = encoded.charCodeAt(i++);
code = base64DecodeMap[ch - base64DecodeMapOffset];
ch = encoded.charCodeAt(i++);
code2 = base64DecodeMap[ch - base64DecodeMapOffset];
decoded[j++] = (code << 2) | ((code2 & 0x30) >> 4);
for (let i = 0, j = 0; i < encoded.length; ) {
ch = encoded.charCodeAt(i++)
code = base64DecodeMap[ch - base64DecodeMapOffset]
ch = encoded.charCodeAt(i++)
code2 = base64DecodeMap[ch - base64DecodeMapOffset]
decoded[j++] = (code << 2) | ((code2 & 0x30) >> 4)
ch = encoded.charCodeAt(i++);
ch = encoded.charCodeAt(i++)
if (ch === base64EOF) {
return decoded;
return decoded
}
code = base64DecodeMap[ch - base64DecodeMapOffset];
decoded[j++] = ((code2 & 0x0f) << 4) | ((code & 0x3c) >> 2);
code = base64DecodeMap[ch - base64DecodeMapOffset]
decoded[j++] = ((code2 & 0x0f) << 4) | ((code & 0x3c) >> 2)
ch = encoded.charCodeAt(i++);
ch = encoded.charCodeAt(i++)
if (ch === base64EOF) {
return decoded;
return decoded
}
code2 = base64DecodeMap[ch - base64DecodeMapOffset];
decoded[j++] = ((code & 0x03) << 6) | code2;
code2 = base64DecodeMap[ch - base64DecodeMapOffset]
decoded[j++] = ((code & 0x03) << 6) | code2
}
return decoded;
}
return decoded
}

View File

@@ -1,30 +1,39 @@
import toast from 'react-hot-toast';
import { derive, sign } from "xrpl-accountlib"
import state, { IAccount } from "../state"
import toast from 'react-hot-toast'
import { derive, sign } from 'xrpl-accountlib'
import state, { IAccount } from '../state'
const estimateFee = async (tx: Record<string, unknown>, account: IAccount, opts: { silent?: boolean } = {}): Promise<null | { base_fee: string, median_fee: string; minimum_fee: string; open_ledger_fee: string; }> => {
const estimateFee = async (
tx: Record<string, unknown>,
account: IAccount,
opts: { silent?: boolean } = {}
): Promise<null | {
base_fee: string
median_fee: string
minimum_fee: string
open_ledger_fee: string
}> => {
try {
const copyTx = JSON.parse(JSON.stringify(tx))
delete copyTx['SigningPubKey']
if (!copyTx.Fee) {
copyTx.Fee = '1000'
}
const keypair = derive.familySeed(account.secret)
const { signedTransaction } = sign(copyTx, keypair);
const { signedTransaction } = sign(copyTx, keypair)
const res = await state.client?.send({ command: 'fee', tx_blob: signedTransaction })
if (res && res.drops) {
return res.drops;
return res.drops
}
return null
} catch (err) {
if (!opts.silent) {
console.error(err)
toast.error("Cannot estimate fee.") // ? Some better msg
toast.error('Cannot estimate fee.') // ? Some better msg
}
return null
}
}
export default estimateFee
export default estimateFee

View File

@@ -1,21 +1,21 @@
interface File {
name: string
name: string
}
export const guessZipFileName = (files: File[]) => {
let parts = (files.filter(f => f.name.endsWith('.c'))[0]?.name || 'hook').split('.')
parts = parts.length > 1 ? parts.slice(0, -1) : parts
return parts.join('')
let parts = (files.filter(f => f.name.endsWith('.c'))[0]?.name || 'hook').split('.')
parts = parts.length > 1 ? parts.slice(0, -1) : parts
return parts.join('')
}
export const capitalize = (value?: string) => {
if (!value) return '';
if (!value) return ''
return value[0].toLocaleUpperCase() + value.slice(1);
return value[0].toLocaleUpperCase() + value.slice(1)
}
export const getFileExtention = (filename?: string): string | undefined => {
if (!filename) return
const ext = (filename.includes('.') && filename.split('.').pop()) || undefined
return ext
}
if (!filename) return
const ext = (filename.includes('.') && filename.split('.').pop()) || undefined
return ext
}

View File

@@ -24,23 +24,22 @@ export const tts = {
ttNFTOKEN_CREATE_OFFER: 27,
ttNFTOKEN_CANCEL_OFFER: 28,
ttNFTOKEN_ACCEPT_OFFER: 29
};
export type TTS = typeof tts;
const calculateHookOn = (arr: (keyof TTS)[]) => {
let start = '0x000000003e3ff5bf';
arr.forEach(n => {
let v = BigInt(start);
v ^= (BigInt(1) << BigInt(tts[n as keyof TTS]));
let s = v.toString(16);
let l = s.length;
if (l < 16)
s = '0'.repeat(16 - l) + s;
s = '0x' + s;
start = s;
})
return start.substring(2);
}
export default calculateHookOn
export type TTS = typeof tts
const calculateHookOn = (arr: (keyof TTS)[]) => {
let start = '0x000000003e3ff5bf'
arr.forEach(n => {
let v = BigInt(start)
v ^= BigInt(1) << BigInt(tts[n as keyof TTS])
let s = v.toString(16)
let l = s.length
if (l < 16) s = '0'.repeat(16 - l) + s
s = '0x' + s
start = s
})
return start.substring(2)
}
export default calculateHookOn

View File

@@ -1,31 +1,32 @@
export const extractJSON = (str?: string) => {
if (!str) return
let firstOpen = 0, firstClose = 0, candidate = '';
firstOpen = str.indexOf('{', firstOpen + 1);
if (!str) return
let firstOpen = 0,
firstClose = 0,
candidate = ''
firstOpen = str.indexOf('{', firstOpen + 1)
do {
firstClose = str.lastIndexOf('}')
if (firstClose <= firstOpen) {
return
}
do {
firstClose = str.lastIndexOf('}');
if (firstClose <= firstOpen) {
return;
}
do {
candidate = str.substring(firstOpen, firstClose + 1);
try {
let result = JSON.parse(candidate);
return { result, start: firstOpen < 0 ? 0 : firstOpen, end: firstClose }
}
catch (e) { }
firstClose = str.substring(0, firstClose).lastIndexOf('}');
} while (firstClose > firstOpen);
firstOpen = str.indexOf('{', firstOpen + 1);
} while (firstOpen != -1);
candidate = str.substring(firstOpen, firstClose + 1)
try {
let result = JSON.parse(candidate)
return { result, start: firstOpen < 0 ? 0 : firstOpen, end: firstClose }
} catch (e) {}
firstClose = str.substring(0, firstClose).lastIndexOf('}')
} while (firstClose > firstOpen)
firstOpen = str.indexOf('{', firstOpen + 1)
} while (firstOpen != -1)
}
export const parseJSON = (str?: string | null): any | undefined => {
if (!str) return undefined
try {
const parsed = JSON.parse(str);
return typeof parsed === "object" ? parsed : undefined;
} catch (error) {
return undefined;
}
}
if (!str) return undefined
try {
const parsed = JSON.parse(str)
return typeof parsed === 'object' ? parsed : undefined
} catch (error) {
return undefined
}
}

View File

@@ -1,11 +1,16 @@
import { MessageConnection } from "@codingame/monaco-jsonrpc";
import { MonacoLanguageClient, ErrorAction, CloseAction, createConnection } from "@codingame/monaco-languageclient";
import normalizeUrl from "normalize-url";
import ReconnectingWebSocket from "reconnecting-websocket";
import { MessageConnection } from '@codingame/monaco-jsonrpc'
import {
MonacoLanguageClient,
ErrorAction,
CloseAction,
createConnection
} from '@codingame/monaco-languageclient'
import normalizeUrl from 'normalize-url'
import ReconnectingWebSocket from 'reconnecting-websocket'
export function createLanguageClient(connection: MessageConnection): MonacoLanguageClient {
return new MonacoLanguageClient({
name: "Clangd Language Client",
name: 'Clangd Language Client',
clientOptions: {
// use a language id as a document selector
documentSelector: ['c', 'h'],
@@ -15,8 +20,7 @@ export function createLanguageClient(connection: MessageConnection): MonacoLangu
closed: () => {
return CloseAction.DoNotRestart
}
},
}
},
// create a language client connection from the JSON RPC connection on demand
connectionProvider: {
@@ -24,12 +28,12 @@ export function createLanguageClient(connection: MessageConnection): MonacoLangu
return Promise.resolve(createConnection(connection, errorHandler, closeHandler))
}
}
});
})
}
export function createUrl(path: string): string {
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
return normalizeUrl(`${protocol}://${location.host}${location.pathname}${path}`);
const protocol = location.protocol === 'https:' ? 'wss' : 'ws'
return normalizeUrl(`${protocol}://${location.host}${location.pathname}${path}`)
}
export function createWebSocket(url: string) {
@@ -40,6 +44,6 @@ export function createWebSocket(url: string) {
connectionTimeout: 10000,
maxRetries: Infinity,
debug: false
};
return new ReconnectingWebSocket(url, [], socketOptions);
}
}
return new ReconnectingWebSocket(url, [], socketOptions)
}

View File

@@ -1,24 +1,21 @@
export const deepEqual = (object1: any, object2: any) => {
if (!isObject(object1) || !isObject(object2)) return object1 === object2
if (!isObject(object1) || !isObject(object2)) return object1 === object2
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
const keys1 = Object.keys(object1)
const keys2 = Object.keys(object2)
if (keys1.length !== keys2.length) {
return false
}
for (const key of keys1) {
const val1 = object1[key]
const val2 = object2[key]
const areObjects = isObject(val1) && isObject(val2)
if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {
return false
}
for (const key of keys1) {
const val1 = object1[key];
const val2 = object2[key];
const areObjects = isObject(val1) && isObject(val2);
if (
areObjects && !deepEqual(val1, val2) ||
!areObjects && val1 !== val2
) {
return false;
}
}
return true;
}
return true
}
export const isObject = (object: any) => {
return object != null && typeof object === 'object';
}
return object != null && typeof object === 'object'
}

View File

@@ -1,39 +1,34 @@
export const extractSchemaProps = <O extends object>(obj: O) =>
Object.entries(obj).reduce((prev, [key, val]) => {
const typeOf = <T>(arg: T) =>
arg instanceof Array
? "array"
: arg === null
? "undefined"
: typeof arg;
export const extractSchemaProps = <O extends object>(obj: O) =>
Object.entries(obj).reduce((prev, [key, val]) => {
const typeOf = <T>(arg: T) =>
arg instanceof Array ? 'array' : arg === null ? 'undefined' : typeof arg
const value = (typeOf(val) === "object" && '$type' in val && '$value' in val) ? val?.$value : val;
const type = typeOf(value);
const value = typeOf(val) === 'object' && '$type' in val && '$value' in val ? val?.$value : val
const type = typeOf(value)
let schema: any = {
title: key,
type,
default: value,
let schema: any = {
title: key,
type,
default: value
}
if (typeOf(value) === 'array') {
const item = value[0] // TODO merge other item schema's into one
if (typeOf(item) !== 'object') {
schema.items = {
type: 'object',
properties: extractSchemaProps(item),
default: item
}
}
// TODO support primitive-value arrays
}
if (typeOf(value) === 'array') {
const item = value[0] // TODO merge other item schema's into one
if (typeOf(item) !== 'object') {
schema.items = {
type: 'object',
properties: extractSchemaProps(item),
default: item
}
}
// TODO support primitive-value arrays
}
if (typeOf(value) === "object") {
schema.properties = extractSchemaProps(value)
}
return {
...prev,
[key]: schema,
};
}, {} as any);
if (typeOf(value) === 'object') {
schema.properties = extractSchemaProps(value)
}
return {
...prev,
[key]: schema
}
}, {} as any)

View File

@@ -1,78 +1,76 @@
import { getTags } from './comment-parser';
import { tts, TTS } from './hookOnCalculator';
import { getTags } from './comment-parser'
import { tts, TTS } from './hookOnCalculator'
export const transactionOptions = Object.keys(tts).map(key => ({
label: key,
value: key as keyof TTS,
}));
label: key,
value: key as keyof TTS
}))
export type SetHookData = {
Invoke: {
value: keyof TTS;
label: string;
}[];
Fee: string;
HookNamespace: string;
HookParameters: {
HookParameter: {
HookParameterName: string;
HookParameterValue: string;
};
$metaData?: any;
}[];
// HookGrants: {
// HookGrant: {
// Authorize: string;
// HookHash: string;
// };
// }[];
};
Invoke: {
value: keyof TTS
label: string
}[]
Fee: string
HookNamespace: string
HookParameters: {
HookParameter: {
HookParameterName: string
HookParameterValue: string
}
$metaData?: any
}[]
// HookGrants: {
// HookGrant: {
// Authorize: string;
// HookHash: string;
// };
// }[];
}
export const getParameters = (content?: string) => {
const fieldTags = ["field", "param", "arg", "argument"];
const tags = getTags(content)
.filter(tag => fieldTags.includes(tag.tag))
.filter(tag => !!tag.name);
const fieldTags = ['field', 'param', 'arg', 'argument']
const tags = getTags(content)
.filter(tag => fieldTags.includes(tag.tag))
.filter(tag => !!tag.name)
const paramters: SetHookData["HookParameters"] = tags.map(tag => ({
HookParameter: {
HookParameterName: tag.name,
HookParameterValue: tag.default || "",
},
$metaData: {
description: tag.description,
required: !tag.optional
},
}));
const paramters: SetHookData['HookParameters'] = tags.map(tag => ({
HookParameter: {
HookParameterName: tag.name,
HookParameterValue: tag.default || ''
},
$metaData: {
description: tag.description,
required: !tag.optional
}
}))
return paramters;
};
return paramters
}
export const getInvokeOptions = (content?: string) => {
const invokeTags = ["invoke", "invoke-on"];
const invokeTags = ['invoke', 'invoke-on']
const options = getTags(content)
.filter(tag => invokeTags.includes(tag.tag))
.reduce((cumm, curr) => {
const combined = curr.type || `${curr.name} ${curr.description}`
const opts = combined.split(' ')
const options = getTags(content)
.filter(tag => invokeTags.includes(tag.tag))
.reduce((cumm, curr) => {
const combined = curr.type || `${curr.name} ${curr.description}`
const opts = combined.split(' ')
return cumm.concat(opts as any)
}, [] as (keyof TTS)[])
.filter(opt => Object.keys(tts).includes(opt))
return cumm.concat(opts as any)
}, [] as (keyof TTS)[])
.filter(opt => Object.keys(tts).includes(opt))
const invokeOptions: SetHookData['Invoke'] = options.map(opt => ({
label: opt,
value: opt
}))
const invokeOptions: SetHookData['Invoke'] = options.map(opt => ({
label: opt,
value: opt
}))
// default
if (!invokeOptions.length) {
const payment = transactionOptions.find(tx => tx.value === 'ttPAYMENT')
if (payment) return [payment]
}
// default
if (!invokeOptions.length) {
const payment = transactionOptions.find(tx => tx.value === "ttPAYMENT")
if (payment) return [payment]
}
return invokeOptions;
};
return invokeOptions
}

View File

@@ -1,8 +1,8 @@
const truncate = (str: string, max: number = 8) => {
const array = str.trim().split('');
const ellipsis = array.length > max ? '...' : '';
const array = str.trim().split('')
const ellipsis = array.length > max ? '...' : ''
return array.slice(0, max).join('') + ellipsis;
};
return array.slice(0, max).join('') + ellipsis
}
export default truncate
export default truncate

File diff suppressed because it is too large Load Diff

View File

@@ -2,31 +2,27 @@ import JSZip, { JSZipFileOptions } from 'jszip'
import { saveAs } from 'file-saver'
interface File {
name: string
content: any
options?: JSZipFileOptions
name: string
content: any
options?: JSZipFileOptions
}
interface Zipped {
saveFile: (filename: string) => void
data: Blob
saveFile: (filename: string) => void
data: Blob
}
export const createZip = async (files: File[]): Promise<Zipped> => {
const zip = new JSZip()
const zip = new JSZip()
files.forEach(({ name, content, options }) => {
zip.file(name, content, options)
})
files.forEach(({ name, content, options }) => {
zip.file(name, content, options)
})
const data = await zip.generateAsync({ type: "blob" })
const data = await zip.generateAsync({ type: 'blob' })
return {
saveFile: (filename: string) =>
saveAs(data, filename),
data
}
return {
saveFile: (filename: string) => saveAs(data, filename),
data
}
}

View File

@@ -1,10 +1,10 @@
export function isZlibData(data: Uint8Array): boolean {
// @ts-expect-error
const [firstByte, secondByte] = data;
return firstByte === 0x78 && (secondByte === 0x01 || secondByte === 0x9C || secondByte === 0xDA);
const [firstByte, secondByte] = data
return firstByte === 0x78 && (secondByte === 0x01 || secondByte === 0x9c || secondByte === 0xda)
}
export async function decompressZlib(data: Uint8Array): Promise<Uint8Array> {
const { inflate } = await import("pako");
return inflate(data);
const { inflate } = await import('pako')
return inflate(data)
}