Rework sanitize aliasing (#1957)
* Rework sanitize aliasing * Allow special alias override (InherentOfflineReport)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2020 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { alias } from './sanitize';
|
||||
|
||||
describe('sanitize', (): void => {
|
||||
describe('alias', (): void => {
|
||||
const exec = alias(['String'], 'Text');
|
||||
|
||||
it('replaces all occurrences for types', (): void => {
|
||||
expect(exec('(String,Address,MasterString,String)')).toEqual(
|
||||
'(Text,Address,MasterString,Text)'
|
||||
);
|
||||
});
|
||||
|
||||
it('replaces actual types, but leaves struct names', (): void => {
|
||||
expect(exec('{"system":"String","versionString":"String"}')).toEqual(
|
||||
'{"system":"Text","versionString":"Text"}'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles the preceding correctly', (): void => {
|
||||
// NOTE This type doesn't make sense
|
||||
expect(exec('String String (String,[String;32],String)"String<String>')).toEqual(
|
||||
'Text Text (Text,[Text;32],Text)"Text<Text>'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
// Copyright 2017-2020 @polkadot/types authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
/* eslint-disable @typescript-eslint/no-use-before-define */
|
||||
|
||||
type Mapper = (value: string) => string;
|
||||
|
||||
@@ -10,38 +10,38 @@ const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fi
|
||||
|
||||
const mappings: Mapper[] = [
|
||||
// alias <T::InherentOfflineReport as InherentOfflineReport>::Inherent -> InherentOfflineReport
|
||||
_alias(['<T::InherentOfflineReport as InherentOfflineReport>::Inherent'], 'InherentOfflineReport'),
|
||||
alias(['<T::InherentOfflineReport as InherentOfflineReport>::Inherent'], 'InherentOfflineReport', false),
|
||||
// <T::Balance as HasCompact>
|
||||
_cleanupCompact(),
|
||||
cleanupCompact(),
|
||||
// Remove all the trait prefixes
|
||||
_removeTraits(),
|
||||
removeTraits(),
|
||||
// remove PairOf<T> -> (T, T)
|
||||
_removePairOf(),
|
||||
removePairOf(),
|
||||
// remove boxing, `Box<Proposal>` -> `Proposal`
|
||||
_removeWrap('Box'),
|
||||
removeWrap('Box'),
|
||||
// remove generics, `MisbehaviorReport<Hash, BlockNumber>` -> `MisbehaviorReport`
|
||||
_removeGenerics(),
|
||||
removeGenerics(),
|
||||
// alias String -> Text (compat with jsonrpc methods)
|
||||
_alias(['String'], 'Text'),
|
||||
alias(['String'], 'Text'),
|
||||
// alias Vec<u8> -> Bytes
|
||||
_alias(['Vec<u8>', '&\\[u8\\]'], 'Bytes'),
|
||||
alias(['Vec<u8>', '&\\[u8\\]'], 'Bytes'),
|
||||
// alias RawAddress -> Address
|
||||
_alias(['RawAddress'], 'Address'),
|
||||
alias(['RawAddress'], 'Address'),
|
||||
// lookups, mapped to Address/AccountId as appropriate in runtime
|
||||
_alias(['Lookup::Source'], 'LookupSource'),
|
||||
_alias(['Lookup::Target'], 'LookupTarget'),
|
||||
alias(['Lookup::Source'], 'LookupSource'),
|
||||
alias(['Lookup::Target'], 'LookupTarget'),
|
||||
// HACK duplication between contracts & primitives, however contracts prefixed with exec
|
||||
_alias(['exec::StorageKey'], 'ContractStorageKey'),
|
||||
alias(['exec::StorageKey'], 'ContractStorageKey'),
|
||||
// alias for internal module mappings
|
||||
_alias(['exec', 'grandpa', 'marker', 'session', 'slashing'].map((s) => `${s}::`), ''),
|
||||
alias(['exec', 'grandpa', 'marker', 'session', 'slashing'].map((s) => `${s}::`), ''),
|
||||
// flattens tuples with one value, `(AccountId)` -> `AccountId`
|
||||
_flattenSingleTuple(),
|
||||
flattenSingleTuple(),
|
||||
// converts ::Type to Type, <T as Trait<I>>::Proposal -> Proposal
|
||||
_removeColonPrefix()
|
||||
removeColonPrefix()
|
||||
];
|
||||
|
||||
// given a starting index, find the closing >
|
||||
function _findClosing (value: string, start: number): number {
|
||||
export function findClosing (value: string, start: number): number {
|
||||
let depth = 0;
|
||||
|
||||
for (let index = start; index < value.length; index++) {
|
||||
@@ -59,27 +59,29 @@ function _findClosing (value: string, start: number): number {
|
||||
throw new Error(`Unable to find closing matching <> on '${value}' (start ${start})`);
|
||||
}
|
||||
|
||||
function _alias (src: string[], dest: string): Mapper {
|
||||
export function alias (src: string[], dest: string, withChecks = true): Mapper {
|
||||
return (value: string): string => {
|
||||
return src.reduce((value, src): string => {
|
||||
// HACK... f-ing HACK. This needs a fix, so this is a HUGE FIXME
|
||||
// ignore versionString, the replace just does global replace, check the box aliases
|
||||
// (versionString from network alias definitions)
|
||||
return value.includes('versionString')
|
||||
? value
|
||||
: value.replace(new RegExp(src, 'g'), dest);
|
||||
return value
|
||||
.replace(
|
||||
new RegExp(`(^${src}|${BOX_PRECEDING.map((box) => `\\${box}${src}`).join('|')})`, 'g'),
|
||||
(src): string =>
|
||||
withChecks && BOX_PRECEDING.includes(src[0])
|
||||
? `${src[0]}${dest}`
|
||||
: dest
|
||||
);
|
||||
}, value);
|
||||
};
|
||||
}
|
||||
|
||||
function _cleanupCompact (): Mapper {
|
||||
export function cleanupCompact (): Mapper {
|
||||
return (value: string): string => {
|
||||
for (let index = 0; index < value.length; index++) {
|
||||
if (value[index] !== '<') {
|
||||
continue;
|
||||
}
|
||||
|
||||
const end = _findClosing(value, index + 1) - 14;
|
||||
const end = findClosing(value, index + 1) - 14;
|
||||
|
||||
if (value.substr(end, 14) === ' as HasCompact') {
|
||||
value = `Compact<${value.substr(index + 1, end - index - 1)}>`;
|
||||
@@ -90,19 +92,19 @@ function _cleanupCompact (): Mapper {
|
||||
};
|
||||
}
|
||||
|
||||
function _flattenSingleTuple (): Mapper {
|
||||
export function flattenSingleTuple (): Mapper {
|
||||
return (value: string): string => {
|
||||
return value.replace(/\(([^,]+)\)/, '$1');
|
||||
};
|
||||
}
|
||||
|
||||
function _removeColonPrefix (): Mapper {
|
||||
export function removeColonPrefix (): Mapper {
|
||||
return (value: string): string => {
|
||||
return value.replace(/^::/, '');
|
||||
};
|
||||
}
|
||||
|
||||
function _removeGenerics (): Mapper {
|
||||
export function removeGenerics (): Mapper {
|
||||
return (value: string): string => {
|
||||
for (let index = 0; index < value.length; index++) {
|
||||
if (value[index] === '<') {
|
||||
@@ -118,7 +120,7 @@ function _removeGenerics (): Mapper {
|
||||
|
||||
// we have not found anything, unwrap generic innards
|
||||
if (!box) {
|
||||
const end = _findClosing(value, index + 1);
|
||||
const end = findClosing(value, index + 1);
|
||||
|
||||
value = `${value.substr(0, index)}${value.substr(end + 1)}`;
|
||||
}
|
||||
@@ -130,12 +132,12 @@ function _removeGenerics (): Mapper {
|
||||
}
|
||||
|
||||
// remove the PairOf wrappers
|
||||
function _removePairOf (): Mapper {
|
||||
export function removePairOf (): Mapper {
|
||||
return (value: string): string => {
|
||||
for (let index = 0; index < value.length; index++) {
|
||||
if (value.substr(index, 7) === 'PairOf<') {
|
||||
const start = index + 7;
|
||||
const end = _findClosing(value, start);
|
||||
const end = findClosing(value, start);
|
||||
const type = value.substr(start, end - start);
|
||||
|
||||
value = `${value.substr(0, index)}(${type},${type})${value.substr(end + 1)}`;
|
||||
@@ -147,7 +149,7 @@ function _removePairOf (): Mapper {
|
||||
}
|
||||
|
||||
// remove the type traits
|
||||
function _removeTraits (): Mapper {
|
||||
export function removeTraits (): Mapper {
|
||||
return (value: string): string => {
|
||||
return value
|
||||
// remove all whitespaces
|
||||
@@ -168,7 +170,7 @@ function _removeTraits (): Mapper {
|
||||
}
|
||||
|
||||
// remove wrapping values, i.e. Box<Proposal> -> Proposal
|
||||
function _removeWrap (_check: string): Mapper {
|
||||
export function removeWrap (_check: string): Mapper {
|
||||
const check = `${_check}<`;
|
||||
|
||||
return (value: string): string => {
|
||||
@@ -179,7 +181,7 @@ function _removeWrap (_check: string): Mapper {
|
||||
|
||||
if (index !== -1) {
|
||||
const start = index + check.length;
|
||||
const end = _findClosing(value, start);
|
||||
const end = findClosing(value, start);
|
||||
|
||||
value = `${value.substr(0, index)}${value.substr(start, end - start)}${value.substr(end + 1)}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user