@pezkuwi/types-create 16.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/build/bundle.d.ts +3 -0
- package/build/create/class.d.ts +5 -0
- package/build/create/index.d.ts +2 -0
- package/build/create/type.d.ts +3 -0
- package/build/exports.d.ts +2 -0
- package/build/index.d.ts +2 -0
- package/build/packageDetect.d.ts +1 -0
- package/build/packageInfo.d.ts +6 -0
- package/build/types/augmentRegistry.d.ts +11 -0
- package/build/types/index.d.ts +4 -0
- package/build/types/lookup.d.ts +14 -0
- package/build/types/types.d.ts +43 -0
- package/build/util/encodeTypes.d.ts +11 -0
- package/build/util/getTypeDef.d.ts +8 -0
- package/build/util/index.d.ts +4 -0
- package/build/util/typeSplit.d.ts +1 -0
- package/build/util/xcm.d.ts +2 -0
- package/package.json +31 -0
- package/src/bundle.ts +9 -0
- package/src/create/class.ts +257 -0
- package/src/create/index.ts +5 -0
- package/src/create/type.ts +94 -0
- package/src/exports.ts +6 -0
- package/src/index.ts +6 -0
- package/src/mod.ts +4 -0
- package/src/packageDetect.ts +12 -0
- package/src/packageInfo.ts +6 -0
- package/src/types/augmentRegistry.ts +19 -0
- package/src/types/index.ts +11 -0
- package/src/types/lookup.ts +21 -0
- package/src/types/types.ts +47 -0
- package/src/util/encodeTypes.spec.ts +217 -0
- package/src/util/encodeTypes.ts +205 -0
- package/src/util/getTypeDef.spec.ts +704 -0
- package/src/util/getTypeDef.ts +279 -0
- package/src/util/index.ts +7 -0
- package/src/util/typeSplit.spec.ts +50 -0
- package/src/util/typeSplit.ts +56 -0
- package/src/util/xcm.ts +12 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.spec.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Codec, CodecClass, Registry } from '@pezkuwi/types-codec/types';
|
|
2
|
+
import type { TypeDef } from '../types/index.js';
|
|
3
|
+
export declare function constructTypeClass<T extends Codec = Codec>(registry: Registry, typeDef: TypeDef): CodecClass<T>;
|
|
4
|
+
export declare function getTypeClass<T extends Codec = Codec>(registry: Registry, typeDef: TypeDef): CodecClass<T>;
|
|
5
|
+
export declare function createClassUnsafe<T extends Codec = Codec, K extends string = string>(registry: Registry, type: K): CodecClass<T>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Codec, Registry } from '@pezkuwi/types-codec/types';
|
|
2
|
+
import type { CreateOptions } from '../types/index.js';
|
|
3
|
+
export declare function createTypeUnsafe<T extends Codec = Codec, K extends string = string>(registry: Registry, type: K, params?: unknown[], options?: CreateOptions): T;
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import '@pezkuwi/types-codec/types/registry';
|
|
2
|
+
import type { Codec, CodecClass, ICompact, INumber, LookupString } from '@pezkuwi/types-codec/types';
|
|
3
|
+
import type { ILookup, TypeDef } from '@pezkuwi/types-create/types';
|
|
4
|
+
declare module '@pezkuwi/types-codec/types/registry' {
|
|
5
|
+
interface Registry {
|
|
6
|
+
readonly lookup: ILookup;
|
|
7
|
+
createLookupType(lookupId: ICompact<INumber> | number): LookupString;
|
|
8
|
+
getUnsafe<T extends Codec = Codec, K extends string = string>(name: K, withUnknown?: boolean, knownTypeDef?: TypeDef): CodecClass<T> | undefined;
|
|
9
|
+
setLookup(lookup: ILookup): void;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Option, Text } from '@pezkuwi/types-codec';
|
|
2
|
+
import type { ICompact, INumber, LookupString } from '@pezkuwi/types-codec/types';
|
|
3
|
+
import type { TypeDef } from './types.js';
|
|
4
|
+
interface SiTypeBase {
|
|
5
|
+
def: {
|
|
6
|
+
asTuple: ICompact<INumber>[];
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface ILookup {
|
|
10
|
+
getSiType(lookupId: ICompact<INumber> | LookupString | number): SiTypeBase;
|
|
11
|
+
getTypeDef(lookupId: ICompact<INumber> | LookupString | number): TypeDef;
|
|
12
|
+
sanitizeField(name: Option<Text>): [string | null, string | null];
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare enum TypeDefInfo {
|
|
2
|
+
BTreeMap = 0,
|
|
3
|
+
BTreeSet = 1,
|
|
4
|
+
Compact = 2,
|
|
5
|
+
DoNotConstruct = 3,
|
|
6
|
+
Enum = 4,
|
|
7
|
+
HashMap = 5,
|
|
8
|
+
Int = 6,
|
|
9
|
+
Linkage = 7,
|
|
10
|
+
Null = 8,
|
|
11
|
+
Option = 9,
|
|
12
|
+
Plain = 10,
|
|
13
|
+
Range = 11,
|
|
14
|
+
RangeInclusive = 12,
|
|
15
|
+
Result = 13,
|
|
16
|
+
Set = 14,
|
|
17
|
+
Si = 15,
|
|
18
|
+
Struct = 16,
|
|
19
|
+
Tuple = 17,
|
|
20
|
+
UInt = 18,
|
|
21
|
+
Vec = 19,
|
|
22
|
+
VecFixed = 20,
|
|
23
|
+
WrapperKeepOpaque = 21,
|
|
24
|
+
WrapperOpaque = 22
|
|
25
|
+
}
|
|
26
|
+
export interface TypeDef {
|
|
27
|
+
alias?: Map<string, string> | undefined;
|
|
28
|
+
displayName?: string | undefined;
|
|
29
|
+
docs?: string[] | undefined;
|
|
30
|
+
fallbackType?: string | undefined;
|
|
31
|
+
info: TypeDefInfo;
|
|
32
|
+
index?: number;
|
|
33
|
+
isFromSi?: boolean;
|
|
34
|
+
length?: number;
|
|
35
|
+
lookupIndex?: number;
|
|
36
|
+
lookupName?: string | undefined;
|
|
37
|
+
lookupNameRoot?: string | undefined;
|
|
38
|
+
name?: string | undefined;
|
|
39
|
+
namespace?: string | undefined;
|
|
40
|
+
sub?: TypeDef | TypeDef[];
|
|
41
|
+
type: string;
|
|
42
|
+
typeName?: string | undefined;
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Registry } from '@pezkuwi/types-codec/types';
|
|
2
|
+
import type { TypeDef } from '@pezkuwi/types-create/types';
|
|
3
|
+
interface ToString {
|
|
4
|
+
toString: () => string;
|
|
5
|
+
}
|
|
6
|
+
export declare function paramsNotation<T extends ToString>(outer: string, inner?: T | T[], transform?: (_: T) => string): string;
|
|
7
|
+
export declare function encodeTypeDef(registry: Registry, typeDef: TypeDef): string;
|
|
8
|
+
export declare function withTypeString(registry: Registry, typeDef: Omit<TypeDef, 'type'> & {
|
|
9
|
+
type?: string;
|
|
10
|
+
}): TypeDef;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnyString } from '@pezkuwi/types-codec/types';
|
|
2
|
+
import type { TypeDef } from '@pezkuwi/types-create/types';
|
|
3
|
+
interface TypeDefOptions {
|
|
4
|
+
name?: string;
|
|
5
|
+
displayName?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function getTypeDef(_type: AnyString, { displayName, name }?: TypeDefOptions, count?: number): TypeDef;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function typeSplit(type: string): string[];
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Jaco Greeff <jacogr@gmail.com>",
|
|
3
|
+
"bugs": "https://github.com/pezkuwichain/pezkuwi-api/issues",
|
|
4
|
+
"description": "Type creator helpers",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=18"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/pezkuwichain/pezkuwi-api/tree/master/packages/types-create#readme",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"name": "@pezkuwi/types-create",
|
|
11
|
+
"repository": {
|
|
12
|
+
"directory": "packages/types-create",
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/pezkuwichain/pezkuwi-api.git"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": [
|
|
17
|
+
"./packageDetect.js",
|
|
18
|
+
"./packageDetect.cjs"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"version": "16.5.5",
|
|
22
|
+
"main": "index.js",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@pezkuwi/types-codec": "16.5.5",
|
|
25
|
+
"@pezkuwi/util": "14.0.5",
|
|
26
|
+
"tslib": "^2.8.1"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@pezkuwi/types": "16.5.5"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/bundle.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-codec authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// all named
|
|
5
|
+
export { packageInfo } from './packageInfo.js';
|
|
6
|
+
export { TypeDefInfo } from './types/index.js';
|
|
7
|
+
|
|
8
|
+
// all starred
|
|
9
|
+
export * from './exports.js';
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Codec, CodecClass, LookupString, Registry, U8aBitLength, UIntBitLength } from '@pezkuwi/types-codec/types';
|
|
5
|
+
import type { TypeDef } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
import { BTreeMap, BTreeSet, Bytes, CodecSet, Compact, DoNotConstruct, Enum, HashMap, Int, Null, Option, Range, RangeInclusive, Result, Struct, Tuple, U8aFixed, UInt, Vec, VecFixed, WrapperKeepOpaque, WrapperOpaque } from '@pezkuwi/types-codec';
|
|
8
|
+
import { isNumber, stringify } from '@pezkuwi/util';
|
|
9
|
+
|
|
10
|
+
import { TypeDefInfo } from '../types/index.js';
|
|
11
|
+
import { getTypeDef } from '../util/getTypeDef.js';
|
|
12
|
+
|
|
13
|
+
function getTypeDefType ({ lookupName, type }: TypeDef): string {
|
|
14
|
+
return lookupName || type;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getSubDefArray (value: TypeDef): TypeDef[] {
|
|
18
|
+
if (!Array.isArray(value.sub)) {
|
|
19
|
+
throw new Error(`Expected subtype as TypeDef[] in ${stringify(value)}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return value.sub;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getSubDef (value: TypeDef): TypeDef {
|
|
26
|
+
if (!value.sub || Array.isArray(value.sub)) {
|
|
27
|
+
throw new Error(`Expected subtype as TypeDef in ${stringify(value)}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return value.sub;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getSubType (value: TypeDef): string {
|
|
34
|
+
return getTypeDefType(getSubDef(value));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// create a maps of type string CodecClasss from the input
|
|
38
|
+
function getTypeClassMap (value: TypeDef): Record<string, string> {
|
|
39
|
+
const subs = getSubDefArray(value);
|
|
40
|
+
const map: Record<string, string> = {};
|
|
41
|
+
|
|
42
|
+
for (let i = 0, count = subs.length; i < count; i++) {
|
|
43
|
+
const sub = subs[i];
|
|
44
|
+
|
|
45
|
+
if (!sub.name) {
|
|
46
|
+
throw new Error(`No name found in definition ${stringify(sub)}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
map[sub.name] = getTypeDefType(sub);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return map;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// create an array of type string CodecClasss from the input
|
|
56
|
+
function getTypeClassArray (value: TypeDef): string[] {
|
|
57
|
+
return getSubDefArray(value).map(getTypeDefType);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createInt (Clazz: typeof Int | typeof UInt, { displayName, length }: TypeDef): CodecClass<Codec> {
|
|
61
|
+
if (!isNumber(length)) {
|
|
62
|
+
throw new Error(`Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return Clazz.with(length as UIntBitLength, displayName);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function createHashMap (Clazz: typeof BTreeMap | typeof HashMap, value: TypeDef): CodecClass<Codec> {
|
|
69
|
+
const [keyType, valueType] = getTypeClassArray(value);
|
|
70
|
+
|
|
71
|
+
return Clazz.with(keyType, valueType);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function createWithSub (Clazz: { with: (t: string) => CodecClass<Codec> }, value: TypeDef): CodecClass<Codec> {
|
|
75
|
+
return Clazz.with(getSubType(value));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => CodecClass<Codec>> = {
|
|
79
|
+
[TypeDefInfo.BTreeMap]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
80
|
+
createHashMap(BTreeMap, value),
|
|
81
|
+
|
|
82
|
+
[TypeDefInfo.BTreeSet]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
83
|
+
createWithSub(BTreeSet, value),
|
|
84
|
+
|
|
85
|
+
[TypeDefInfo.Compact]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
86
|
+
createWithSub(Compact, value),
|
|
87
|
+
|
|
88
|
+
[TypeDefInfo.DoNotConstruct]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
89
|
+
DoNotConstruct.with(value.displayName || value.type),
|
|
90
|
+
|
|
91
|
+
[TypeDefInfo.Enum]: (_registry: Registry, value: TypeDef): CodecClass<Codec> => {
|
|
92
|
+
const subs = getSubDefArray(value);
|
|
93
|
+
|
|
94
|
+
return Enum.with(
|
|
95
|
+
subs.every(({ type }) => type === 'Null')
|
|
96
|
+
? subs.reduce<Record<string, number>>((out, { index, name }, count) => {
|
|
97
|
+
if (!name) {
|
|
98
|
+
throw new Error('No name found in sub definition');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
out[name] = index || count;
|
|
102
|
+
|
|
103
|
+
return out;
|
|
104
|
+
}, {})
|
|
105
|
+
: getTypeClassMap(value)
|
|
106
|
+
);
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
[TypeDefInfo.HashMap]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
110
|
+
createHashMap(HashMap, value),
|
|
111
|
+
|
|
112
|
+
[TypeDefInfo.Int]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
113
|
+
createInt(Int, value),
|
|
114
|
+
|
|
115
|
+
// We have circular deps between Linkage & Struct
|
|
116
|
+
[TypeDefInfo.Linkage]: (_registry: Registry, value: TypeDef): CodecClass<Codec> => {
|
|
117
|
+
const type = `Option<${getSubType(value)}>`;
|
|
118
|
+
// eslint-disable-next-line sort-keys
|
|
119
|
+
const Clazz = Struct.with({ previous: type, next: type } as any);
|
|
120
|
+
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
122
|
+
Clazz.prototype.toRawType = function (): string {
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
|
124
|
+
return `Linkage<${this.next.toRawType(true)}>`;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return Clazz;
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
[TypeDefInfo.Null]: (_registry: Registry, _value: TypeDef): CodecClass<Codec> =>
|
|
131
|
+
Null,
|
|
132
|
+
|
|
133
|
+
[TypeDefInfo.Option]: (_registry: Registry, value: TypeDef): CodecClass<Codec> => {
|
|
134
|
+
if (!value.sub || Array.isArray(value.sub)) {
|
|
135
|
+
throw new Error('Expected type information for Option');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// NOTE This is opt-in (unhandled), not by default
|
|
139
|
+
// if (value.sub.type === 'bool') {
|
|
140
|
+
// return OptionBool;
|
|
141
|
+
// }
|
|
142
|
+
|
|
143
|
+
return createWithSub(Option, value);
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
[TypeDefInfo.Plain]: (registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
147
|
+
registry.getOrUnknown(value.type),
|
|
148
|
+
|
|
149
|
+
[TypeDefInfo.Range]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
150
|
+
createWithSub(Range, value),
|
|
151
|
+
|
|
152
|
+
[TypeDefInfo.RangeInclusive]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
153
|
+
createWithSub(RangeInclusive, value),
|
|
154
|
+
|
|
155
|
+
[TypeDefInfo.Result]: (_registry: Registry, value: TypeDef): CodecClass<Codec> => {
|
|
156
|
+
const [Ok, Err] = getTypeClassArray(value);
|
|
157
|
+
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
159
|
+
return Result.with({ Err, Ok });
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
[TypeDefInfo.Set]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
163
|
+
CodecSet.with(
|
|
164
|
+
getSubDefArray(value).reduce<Record<string, number>>((result, { index, name }) => {
|
|
165
|
+
if (!name || !isNumber(index)) {
|
|
166
|
+
throw new Error('No name found in sub definition');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
result[name] = index;
|
|
170
|
+
|
|
171
|
+
return result;
|
|
172
|
+
}, {}),
|
|
173
|
+
value.length
|
|
174
|
+
),
|
|
175
|
+
|
|
176
|
+
[TypeDefInfo.Si]: (registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
177
|
+
getTypeClass(registry, registry.lookup.getTypeDef(value.type as LookupString)),
|
|
178
|
+
|
|
179
|
+
[TypeDefInfo.Struct]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
180
|
+
Struct.with(getTypeClassMap(value), value.alias),
|
|
181
|
+
|
|
182
|
+
[TypeDefInfo.Tuple]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
183
|
+
Tuple.with(getTypeClassArray(value)),
|
|
184
|
+
|
|
185
|
+
[TypeDefInfo.UInt]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
186
|
+
createInt(UInt, value),
|
|
187
|
+
|
|
188
|
+
[TypeDefInfo.Vec]: (_registry: Registry, { sub }: TypeDef): CodecClass<Codec> => {
|
|
189
|
+
if (!sub || Array.isArray(sub)) {
|
|
190
|
+
throw new Error('Expected type information for vector');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return (
|
|
194
|
+
sub.type === 'u8'
|
|
195
|
+
? Bytes
|
|
196
|
+
: Vec.with(getTypeDefType(sub))
|
|
197
|
+
);
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
[TypeDefInfo.VecFixed]: (_registry: Registry, { displayName, length, sub }: TypeDef): CodecClass<Codec> => {
|
|
201
|
+
if (!isNumber(length) || !sub || Array.isArray(sub)) {
|
|
202
|
+
throw new Error('Expected length & type information for fixed vector');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
sub.type === 'u8'
|
|
207
|
+
? U8aFixed.with((length * 8) as U8aBitLength, displayName)
|
|
208
|
+
: VecFixed.with(getTypeDefType(sub), length)
|
|
209
|
+
);
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
[TypeDefInfo.WrapperKeepOpaque]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
213
|
+
createWithSub(WrapperKeepOpaque, value),
|
|
214
|
+
|
|
215
|
+
[TypeDefInfo.WrapperOpaque]: (_registry: Registry, value: TypeDef): CodecClass<Codec> =>
|
|
216
|
+
createWithSub(WrapperOpaque, value)
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
export function constructTypeClass<T extends Codec = Codec> (registry: Registry, typeDef: TypeDef): CodecClass<T> {
|
|
220
|
+
try {
|
|
221
|
+
const Type = infoMapping[typeDef.info](registry, typeDef);
|
|
222
|
+
|
|
223
|
+
if (!Type) {
|
|
224
|
+
throw new Error('No class created');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// don't clobber any existing
|
|
228
|
+
if (!Type.__fallbackType && typeDef.fallbackType) {
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
230
|
+
// @ts-ignore ...this is the only place we we actually assign this...
|
|
231
|
+
Type.__fallbackType = typeDef.fallbackType;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return Type as CodecClass<T>;
|
|
235
|
+
} catch (error) {
|
|
236
|
+
throw new Error(`Unable to construct class from ${stringify(typeDef)}: ${(error as Error).message}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Returns the type Class for construction
|
|
241
|
+
export function getTypeClass<T extends Codec = Codec> (registry: Registry, typeDef: TypeDef): CodecClass<T> {
|
|
242
|
+
return registry.getUnsafe(typeDef.type, false, typeDef) as unknown as CodecClass<T>;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function createClassUnsafe<T extends Codec = Codec, K extends string = string> (registry: Registry, type: K): CodecClass<T> {
|
|
246
|
+
return (
|
|
247
|
+
// just retrieve via name, no creation via typeDef
|
|
248
|
+
registry.getUnsafe(type) ||
|
|
249
|
+
// we don't have an existing type, create the class via typeDef
|
|
250
|
+
getTypeClass(
|
|
251
|
+
registry,
|
|
252
|
+
registry.isLookupType(type)
|
|
253
|
+
? registry.lookup.getTypeDef(type)
|
|
254
|
+
: getTypeDef(type)
|
|
255
|
+
)
|
|
256
|
+
);
|
|
257
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Bytes } from '@pezkuwi/types-codec';
|
|
5
|
+
import type { Codec, CodecClass, IU8a, Registry } from '@pezkuwi/types-codec/types';
|
|
6
|
+
import type { CreateOptions } from '../types/index.js';
|
|
7
|
+
|
|
8
|
+
import { Option } from '@pezkuwi/types-codec';
|
|
9
|
+
import { isHex, isU8a, u8aEq, u8aToHex, u8aToU8a } from '@pezkuwi/util';
|
|
10
|
+
|
|
11
|
+
import { createClassUnsafe } from './class.js';
|
|
12
|
+
|
|
13
|
+
// With isPedantic, actually check that the encoding matches that supplied. This
|
|
14
|
+
// is much slower, but verifies that we have the correct types defined
|
|
15
|
+
function checkInstance (created: Codec, matcher: Uint8Array): void {
|
|
16
|
+
const u8a = created.toU8a();
|
|
17
|
+
const rawType = created.toRawType();
|
|
18
|
+
const isOk = (
|
|
19
|
+
// full match, all ok
|
|
20
|
+
u8aEq(u8a, matcher) ||
|
|
21
|
+
(
|
|
22
|
+
// on a length-prefixed type, just check the actual length
|
|
23
|
+
['Bytes', 'Text', 'Type'].includes(rawType) &&
|
|
24
|
+
matcher.length === (created as unknown as Bytes).length
|
|
25
|
+
) ||
|
|
26
|
+
(
|
|
27
|
+
// when the created is empty and matcher is also empty, let it slide...
|
|
28
|
+
created.isEmpty &&
|
|
29
|
+
matcher.every((v) => !v)
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!isOk) {
|
|
34
|
+
throw new Error(`${rawType}:: Decoded input doesn't match input, received ${u8aToHex(matcher, 512)} (${matcher.length} bytes), created ${u8aToHex(u8a, 512)} (${u8a.length} bytes)`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function checkPedantic (created: Codec, [value]: unknown[]): void {
|
|
39
|
+
if (isU8a(value)) {
|
|
40
|
+
checkInstance(created, value);
|
|
41
|
+
} else if (isHex(value)) {
|
|
42
|
+
checkInstance(created, u8aToU8a(value));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Initializes a type with a value. This also checks for fallbacks and in the cases
|
|
47
|
+
// where isPedantic is specified (storage decoding), also check the format/structure
|
|
48
|
+
function initType<T extends Codec> (registry: Registry, Type: CodecClass, params: unknown[] = [], { blockHash, isFallback, isOptional, isPedantic }: CreateOptions = {}): T {
|
|
49
|
+
const created = new (
|
|
50
|
+
isOptional
|
|
51
|
+
? Option.with(Type)
|
|
52
|
+
: Type
|
|
53
|
+
)(registry, ...params);
|
|
54
|
+
|
|
55
|
+
isPedantic && checkPedantic(created, params);
|
|
56
|
+
|
|
57
|
+
if (blockHash) {
|
|
58
|
+
created.createdAtHash = createTypeUnsafe<IU8a>(registry, 'BlockHash', [blockHash]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (isFallback) {
|
|
62
|
+
created.isStorageFallback = true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return created as T;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// An unsafe version of the `createType` below. It's unsafe because the `type`
|
|
69
|
+
// argument here can be any string, which, when it cannot parse, will yield a
|
|
70
|
+
// runtime error.
|
|
71
|
+
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (registry: Registry, type: K, params: unknown[] = [], options: CreateOptions = {}): T {
|
|
72
|
+
let Clazz: CodecClass | null = null;
|
|
73
|
+
let firstError: Error | null = null;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
Clazz = createClassUnsafe(registry, type);
|
|
77
|
+
|
|
78
|
+
return initType(registry, Clazz, params, options);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
firstError = new Error(`createType(${type}):: ${(error as Error).message}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (Clazz?.__fallbackType) {
|
|
84
|
+
try {
|
|
85
|
+
Clazz = createClassUnsafe(registry, Clazz.__fallbackType as unknown as K);
|
|
86
|
+
|
|
87
|
+
return initType(registry, Clazz, params, options);
|
|
88
|
+
} catch {
|
|
89
|
+
// swallow, we will throw the first error again
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
throw firstError;
|
|
94
|
+
}
|
package/src/exports.ts
ADDED
package/src/index.ts
ADDED
package/src/mod.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Do not edit, auto-generated by @polkadot/dev
|
|
5
|
+
// (packageInfo imports will be kept as-is, user-editable)
|
|
6
|
+
|
|
7
|
+
import { packageInfo as codecInfo } from '@pezkuwi/types-codec/packageInfo';
|
|
8
|
+
import { detectPackage } from '@pezkuwi/util';
|
|
9
|
+
|
|
10
|
+
import { packageInfo } from './packageInfo.js';
|
|
11
|
+
|
|
12
|
+
detectPackage(packageInfo, null, [codecInfo]);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Do not edit, auto-generated by @polkadot/dev
|
|
5
|
+
|
|
6
|
+
export const packageInfo = { name: '@pezkuwi/types-create', path: 'auto', type: 'auto', version: '16.5.5' };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// import type lookup before we augment - in some environments
|
|
5
|
+
// this is required to allow for ambient/previous definitions
|
|
6
|
+
import '@pezkuwi/types-codec/types/registry';
|
|
7
|
+
|
|
8
|
+
import type { Codec, CodecClass, ICompact, INumber, LookupString } from '@pezkuwi/types-codec/types';
|
|
9
|
+
import type { ILookup, TypeDef } from '@pezkuwi/types-create/types';
|
|
10
|
+
|
|
11
|
+
declare module '@pezkuwi/types-codec/types/registry' {
|
|
12
|
+
interface Registry {
|
|
13
|
+
readonly lookup: ILookup;
|
|
14
|
+
|
|
15
|
+
createLookupType (lookupId: ICompact<INumber> | number): LookupString;
|
|
16
|
+
getUnsafe <T extends Codec = Codec, K extends string = string> (name: K, withUnknown?: boolean, knownTypeDef?: TypeDef): CodecClass<T> | undefined;
|
|
17
|
+
setLookup (lookup: ILookup): void;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import './augmentRegistry.js';
|
|
5
|
+
|
|
6
|
+
// all types
|
|
7
|
+
export type { CodecCreateOptions as CreateOptions } from '@pezkuwi/types-codec/types';
|
|
8
|
+
|
|
9
|
+
// all starred
|
|
10
|
+
export * from './lookup.js';
|
|
11
|
+
export * from './types.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/types-create authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Option, Text } from '@pezkuwi/types-codec';
|
|
5
|
+
import type { ICompact, INumber, LookupString } from '@pezkuwi/types-codec/types';
|
|
6
|
+
import type { TypeDef } from './types.js';
|
|
7
|
+
|
|
8
|
+
// A simplified SiType without the need for an interface import
|
|
9
|
+
// (while type interfaces are still in @polkadot/types). This provides
|
|
10
|
+
// the minimum interface allowing us to work with it here
|
|
11
|
+
interface SiTypeBase {
|
|
12
|
+
def: {
|
|
13
|
+
asTuple: ICompact<INumber>[]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ILookup {
|
|
18
|
+
getSiType (lookupId: ICompact<INumber> | LookupString | number): SiTypeBase;
|
|
19
|
+
getTypeDef (lookupId: ICompact<INumber> | LookupString | number): TypeDef;
|
|
20
|
+
sanitizeField (name: Option<Text>): [string | null, string | null];
|
|
21
|
+
}
|