UNPKG

3.29 kBJavaScriptView Raw
1// Copyright 2017-2022 @polkadot/api authors & contributors
2// SPDX-License-Identifier: Apache-2.0
3import { lazyMethod, logger, objectClear } from '@polkadot/util';
4const l = logger('api/augment');
5
6function logLength(type, values, and = []) {
7 return values.length ? ` ${values.length} ${type}${and.length ? ' and' : ''}` : '';
8}
9
10function logValues(type, values) {
11 return values.length ? `\n\t${type.padStart(7)}: ${values.sort().join(', ')}` : '';
12} // log details to console
13
14
15function warn(prefix, type, [added, removed]) {
16 if (added.length || removed.length) {
17 l.warn(`api.${prefix}: Found${logLength('added', added, removed)}${logLength('removed', removed)} ${type}:${logValues('added', added)}${logValues('removed', removed)}`);
18 }
19}
20
21function findSectionExcludes(a, b) {
22 return a.filter(s => !b.includes(s));
23}
24
25function findSectionIncludes(a, b) {
26 return a.filter(s => b.includes(s));
27}
28
29function extractSections(src, dst) {
30 const srcSections = Object.keys(src);
31 const dstSections = Object.keys(dst);
32 return [findSectionExcludes(srcSections, dstSections), findSectionExcludes(dstSections, srcSections)];
33}
34
35function findMethodExcludes(src, dst) {
36 const srcSections = Object.keys(src);
37 const dstSections = findSectionIncludes(Object.keys(dst), srcSections);
38 const excludes = [];
39
40 for (let s = 0; s < dstSections.length; s++) {
41 const section = dstSections[s];
42 const srcMethods = Object.keys(src[section]);
43 const dstMethods = Object.keys(dst[section]);
44 excludes.push(...dstMethods.filter(m => !srcMethods.includes(m)).map(m => `${section}.${m}`));
45 }
46
47 return excludes;
48}
49
50function extractMethods(src, dst) {
51 return [findMethodExcludes(dst, src), findMethodExcludes(src, dst)];
52}
53
54function lazySection(src, dst) {
55 const creator = m => src[m];
56
57 const methods = Object.keys(src);
58
59 for (let i = 0; i < methods.length; i++) {
60 const method = methods[i]; // We use hasOwnproperty here to only check for the existence of the key,
61 // instead of reading dst[section][method] which will evaluate when already
62 // set as a lazy value previously
63
64 if (!Object.prototype.hasOwnProperty.call(dst, method)) {
65 lazyMethod(dst, method, creator);
66 }
67 }
68}
69/**
70 * @description Takes a decorated api section (e.g. api.tx) and augment it with the details. It does not override what is
71 * already available, but rather just adds new missing items into the result object.
72 * @internal
73 */
74
75
76export function augmentObject(prefix, src, dst, fromEmpty = false) {
77 fromEmpty && objectClear(dst); // NOTE: This part is slightly problematic since it will get the
78 // values for at least all the sections and the names of the methods
79 // (Since methods won't be decorated before lazy, this _may_ be ok)
80
81 if (prefix && Object.keys(dst).length) {
82 warn(prefix, 'modules', extractSections(src, dst));
83 warn(prefix, 'calls', extractMethods(src, dst));
84 }
85
86 const sections = Object.keys(src);
87
88 for (let i = 0; i < sections.length; i++) {
89 const section = sections[i]; // We don't set here with a lazy interface, we decorate based
90 // on the top-level structure (this bypasses adding lazy onto lazy)
91
92 if (!dst[section]) {
93 dst[section] = {};
94 }
95
96 lazySection(src[section], dst[section]);
97 }
98
99 return dst;
100}
\No newline at end of file