Adjustments for getTypeDef (#4944)
* Adjustments for getTypeDef * Cleanup unneeded + * Adjust sanitize replacers * Ordering * Adjust sanitize
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Copyright 2017-2022 @polkadot/types-create authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { AnyString } from '@polkadot/types-codec/types';
|
||||
import type { TypeDef } from '@polkadot/types-create/types';
|
||||
|
||||
import { sanitize } from '@polkadot/types-codec';
|
||||
@@ -15,6 +16,8 @@ interface TypeDefOptions {
|
||||
}
|
||||
|
||||
const MAX_NESTED = 64;
|
||||
const MAX_FIX_LEN = 2048;
|
||||
const MAX_BIT_LEN = 8192;
|
||||
const KNOWN_INTERNALS = ['_alias', '_fallback'];
|
||||
|
||||
function getTypeString (typeOrObj: any): string {
|
||||
@@ -132,8 +135,7 @@ function _decodeFixedVec (value: TypeDef, type: string, _: string, count: number
|
||||
const [strLength, displayName] = type.substring(index + 1, max).split(';');
|
||||
const length = parseInt(strLength.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(length <= 256, () => `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
assert(length <= MAX_FIX_LEN, () => `${type}: Only support for [Type; <length>], where length <= ${MAX_FIX_LEN}`);
|
||||
|
||||
value.displayName = displayName;
|
||||
value.length = length;
|
||||
@@ -157,8 +159,7 @@ function _decodeAnyInt (value: TypeDef, type: string, _: string, clazz: 'Int' |
|
||||
const [strLength, displayName] = type.substring(clazz.length + 1, type.length - 1).split(',');
|
||||
const length = parseInt(strLength.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(length <= 8192 && (length % 8) === 0, () => `${type}: Only support for ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
|
||||
assert(length <= MAX_BIT_LEN && (length % 8) === 0, () => `${type}: Only support for ${clazz}<bitLength>, where length <= ${MAX_BIT_LEN} and a power of 8, found ${length}`);
|
||||
|
||||
value.displayName = displayName;
|
||||
value.length = length;
|
||||
@@ -216,8 +217,7 @@ function extractSubType (type: string, [start, end]: [string, string, TypeDefInf
|
||||
return type.substring(start.length, type.length - end.length);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function getTypeDef (_type: String | string, { displayName, name }: TypeDefOptions = {}, count = 0): TypeDef {
|
||||
export function getTypeDef (_type: AnyString, { displayName, name }: TypeDefOptions = {}, count = 0): TypeDef {
|
||||
// create the type via Type, allowing types to be sanitized
|
||||
const type = sanitize(_type);
|
||||
const value: TypeDef = { displayName, info: TypeDefInfo.Plain, name, type };
|
||||
|
||||
@@ -36,13 +36,13 @@ describe('typeSplit', (): void => {
|
||||
|
||||
it('checks for unclosed vec', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, Vec<u64')
|
||||
() => typeSplit('Text, Vec<u64')
|
||||
).toThrow(/Invalid definition/);
|
||||
});
|
||||
|
||||
it('checks for unclosed tuple', (): void => {
|
||||
expect(
|
||||
(): string[] => typeSplit('Text, (u64, u32')
|
||||
() => typeSplit('Text, (u64, u32')
|
||||
).toThrow(/Invalid definition/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,46 +3,51 @@
|
||||
|
||||
import { assert } from '@polkadot/util';
|
||||
|
||||
function isNotNested (...counters: number[]): boolean {
|
||||
return !counters.some((counter): boolean => counter !== 0);
|
||||
}
|
||||
|
||||
// safely split a string on ', ' while taking care of any nested occurences
|
||||
export function typeSplit (type: string): string[] {
|
||||
let [cDepth, fDepth, sDepth, tDepth, start] = [0, 0, 0, 0, 0];
|
||||
const result = [];
|
||||
const result: string[] = [];
|
||||
|
||||
const extract = (index: number): void => {
|
||||
if (isNotNested(cDepth, fDepth, sDepth, tDepth)) {
|
||||
result.push(type.substring(start, index).trim());
|
||||
start = index + 1;
|
||||
}
|
||||
};
|
||||
// these are the depths of the various tokens: <, [, {, (
|
||||
let c = 0;
|
||||
let f = 0;
|
||||
let s = 0;
|
||||
let t = 0;
|
||||
|
||||
for (let index = 0; index < type.length; index++) {
|
||||
switch (type[index]) {
|
||||
// current start position
|
||||
let start = 0;
|
||||
|
||||
for (let i = 0; i < type.length; i++) {
|
||||
switch (type[i]) {
|
||||
// if we are not nested, add the type
|
||||
case ',': extract(index); break;
|
||||
case ',': {
|
||||
if (!(c || f || s || t)) {
|
||||
result.push(type.substring(start, i).trim());
|
||||
start = i + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// adjust compact/vec (and friends) depth
|
||||
case '<': cDepth++; break;
|
||||
case '>': cDepth--; break;
|
||||
case '<': c++; break;
|
||||
case '>': c--; break;
|
||||
|
||||
// adjust fixed vec depths
|
||||
case '[': fDepth++; break;
|
||||
case ']': fDepth--; break;
|
||||
case '[': f++; break;
|
||||
case ']': f--; break;
|
||||
|
||||
// adjust struct depth
|
||||
case '{': sDepth++; break;
|
||||
case '}': sDepth--; break;
|
||||
case '{': s++; break;
|
||||
case '}': s--; break;
|
||||
|
||||
// adjust tuple depth
|
||||
case '(': tDepth++; break;
|
||||
case ')': tDepth--; break;
|
||||
case '(': t++; break;
|
||||
case ')': t--; break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(isNotNested(cDepth, fDepth, sDepth, tDepth), () => `Invalid definition (missing terminators) found in ${type}`);
|
||||
// ensure we have all the terminators taken care of
|
||||
assert(!(c || f || s || t), () => `Invalid definition (missing terminators) found in ${type}`);
|
||||
|
||||
// the final leg of the journey
|
||||
result.push(type.substring(start, type.length).trim());
|
||||
|
||||
Reference in New Issue
Block a user