Skip to content

Commit

Permalink
Merge pull request #114 from polkadot-cloud/rb-iterate-scraper
Browse files Browse the repository at this point in the history
feat: classes in scraped results, labels generated from classes
  • Loading branch information
rossbulat authored Jun 13, 2024
2 parents eda5825 + c877eae commit 7d70c22
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 142 deletions.
93 changes: 41 additions & 52 deletions src/model/Scraper/Format/CallSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import type { AnyJson } from '@w3ux/types';
import type { PalletItemScraped } from '../types';
import { getShortLabel, verifyOption } from './Utils';

export class FormatCallSignature {
// The raw input config to format.
Expand All @@ -21,14 +22,11 @@ export class FormatCallSignature {

// Formats `rawConfig` data into a string.
format = () => {
const {
modifier,
type: { argTypes, returnType },
} = this.#rawConfig;
const { modifier, argTypes, returnType } = this.#rawConfig;

// Format arguments and return types.
const [argFormatted, returnFormatted] = [argTypes, returnType].map(
(section) => this.getTypeString(section)
const [argFormatted, returnFormatted] = [argTypes, returnType].map((arg) =>
this.getTypeString(arg)
);

// Format the call signature based on formatted types and modifier.
Expand Down Expand Up @@ -80,77 +78,86 @@ export class FormatCallSignature {

// A recursive function that formats a call signature by formatting its arguments and return
// types.
getTypeString = (section: AnyJson) => {
getTypeString = (arg: AnyJson) => {
let str = '';

switch (section?.type) {
switch (arg?.type) {
case 'array':
str = this.getTypeString(section.array.type);
str = this.getTypeString(arg.array.type);
break;

case 'compact':
str = this.getTypeString(section.sequence);
str = this.getTypeString(arg.compact);
break;

case 'composite':
str = this.getCompositeString(section);
str = this.getCompositeString(arg);
break;

case 'primitive':
str = arg.class.label();
break;

case 'bitSequence':
str = this.getShortLabel(section.label);
str = getShortLabel(arg.class.label());
break;

case 'sequence':
str = `Vec<${this.getTypeString(section.sequence)}>`;
str = `Vec<${this.getTypeString(arg.sequence)}>`;
break;

case 'tuple':
str = this.getTupleString(section);
str = this.getTupleString(arg);
break;

case 'variant':
str = this.getVariantType(section);
str = this.getVariantType(arg);
break;
}
return str;
};

// Formats a string from a composite type.
getCompositeString = ({ composite, label }: AnyJson) => {
getCompositeString = (arg: AnyJson) => {
let str = '';
const shortLabel = getShortLabel(arg.class.label());

// Expand type if short label is not defined, or if they've been defined in ignore list.
if (['', ...this.#ignoreLabels].includes(label.short)) {
str += composite.reduce((acc: string, field: AnyJson, index: number) => {
// Defensive: return if field type is missing.
if (!field?.type) {
return '';
}
acc = acc + this.getTypeString(field.type);
if (index < composite.length - 1) {
acc += ', ';
}
return acc;
}, '');
if (['', ...this.#ignoreLabels].includes(shortLabel)) {
str += arg.composite.reduce(
(acc: string, field: AnyJson, index: number) => {
// Defensive: return if field type is missing.
if (!field?.type) {
return '';
}
acc = acc + this.getTypeString(field.type);
if (index < arg.composite.length - 1) {
acc += ', ';
}
return acc;
},
''
);
} else {
str = `${label.short}`;
str = `${shortLabel}`;
}

return str;
};

// Formats a string from a variant type.
getVariantType = ({ variant, label }: AnyJson) => {
let str = `${label.short}`;
getVariantType = (arg: AnyJson) => {
const shortLabel = getShortLabel(arg.class.label());

let str = `${shortLabel}`;

// If variant is `Option`, expand signature with its `Some` type.
if (this.verifyOption(label.short, variant)) {
if (verifyOption(shortLabel, arg.variant)) {
str +=
variant[1].fields.reduce(
arg.variant[1].fields.reduce(
(acc: string, field: AnyJson, index: number) => {
acc = acc + this.getTypeString(field.type);
if (index < variant[1].fields.length - 1) {
if (index < arg.variant[1].fields.length - 1) {
acc += ', ';
}
return acc;
Expand All @@ -172,22 +179,4 @@ export class FormatCallSignature {
}
return acc;
}, '');

// ------------------------------------------------------
// Class helpers
// ------------------------------------------------------

// Gets a short label from a label input.
getShortLabel = (input: string | { long: string; short: string }) =>
typeof input === 'string' ? input : input.short;

// Gets a long label from a label input.
getLongLabel = (input: string | { long: string; short: string }) =>
typeof input === 'string' ? input : input.long;

// Verify if a variant is an Option.
verifyOption = (shortLabel: string, variant: { name?: string }[]) =>
shortLabel === 'Option' &&
variant?.[0]?.name === 'None' &&
variant?.[1]?.name === 'Some';
}
23 changes: 12 additions & 11 deletions src/model/Scraper/Format/InputFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import type { AnyJson } from '@w3ux/types';
import type { PalletItemScraped } from '../types';
import { getShortLabel } from './Utils';

export class FormatInputFields {
// The raw input config to format.
Expand All @@ -18,9 +19,7 @@ export class FormatInputFields {

// Formats `rawConfig` data into an input structure.
format = () => {
const {
type: { argTypes },
} = this.#rawConfig;
const { argTypes } = this.#rawConfig;

// if there are no arg types, (no args to format) return an empty object.
if (!argTypes) {
Expand Down Expand Up @@ -52,15 +51,15 @@ export class FormatInputFields {

case 'bitSequence':
result.bitSequence = {
label: arg.label.short,
label: getShortLabel(arg.class.label()),
// NOTE: Currently falling back to encoded hash until a custom input is created.
form: 'Hash',
};
break;

case 'compact':
result.compact = {
label: arg.compact.label,
label: getShortLabel(arg.compact.class.label()),
form: this.getTypeInput(arg.compact),
};
break;
Expand All @@ -71,7 +70,7 @@ export class FormatInputFields {

case 'primitive':
result.primitive = {
label: arg.label,
label: arg.class.label(),
// Treat unsigned integers as text inputs. NOTE: Could improve by allowing minus and
// decimal in `number` input.
form: [
Expand All @@ -87,9 +86,9 @@ export class FormatInputFields {
'u32',
'u64',
'u128',
].includes(arg.label)
].includes(arg.class.label())
? 'text'
: arg.label === 'bool'
: arg.class.label() === 'bool'
? 'checkbox'
: // Unsigned integers remain.
'number',
Expand All @@ -98,7 +97,7 @@ export class FormatInputFields {

case 'sequence':
result.sequence = {
label: arg.sequence.label,
label: getShortLabel(arg.sequence.class.label()),
form: this.getTypeInput(arg.sequence.type),
};
break;
Expand All @@ -119,8 +118,10 @@ export class FormatInputFields {

// Formats a variant form input.
getVariantInput(arg: AnyJson) {
const shortLabel = getShortLabel(arg.class.label());

return {
label: arg.label.short,
label: shortLabel,
form: 'select',
forms: arg.variant.reduce((acc: AnyJson, { name, fields }: AnyJson) => {
acc[name] = fields.map((field: AnyJson) =>
Expand All @@ -133,7 +134,7 @@ export class FormatInputFields {

// Formats a composite form input.
getCompositeInput(arg: AnyJson) {
let shortLabel = arg.label.short;
let shortLabel = getShortLabel(arg.class.label());

// If this composite is a sequence of u8s, then change the label to `Bytes`.
if (this.checkCompositeIsBytes(shortLabel, arg)) {
Expand Down
29 changes: 11 additions & 18 deletions src/routes/Chain/Utils.ts → src/model/Scraper/Format/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,18 @@
// Gets a short label from a label input.
export const getShortLabel = (
input: string | { long: string; short: string }
) => {
let output;
if (typeof input === 'string') {
output = input;
} else {
output = input.short;
}
return output;
};
) => (typeof input === 'string' ? input : input.short);

// Gets a long label from a label input.
export const getLongLabel = (
input: string | { long: string; short: string }
) => {
let output;
if (typeof input === 'string') {
output = input;
} else {
output = input.long;
}
return output;
};
) => (typeof input === 'string' ? input : input.long);

// Verify if a variant is an Option.
export const verifyOption = (
shortLabel: string,
variant: { name?: string }[]
) =>
shortLabel === 'Option' &&
variant?.[0]?.name === 'None' &&
variant?.[1]?.name === 'Some';
6 changes: 3 additions & 3 deletions src/model/Scraper/Pallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class PalletScraper extends MetadataScraper {
docs,
modifier,
fallback,
type: scrapedType,
...scrapedType,
};
}

Expand Down Expand Up @@ -264,7 +264,7 @@ export class PalletScraper extends MetadataScraper {
name: item.name,
docs: item.docs,
modifier: '',
type: scrapedType,
...scrapedType,
};

return result;
Expand Down Expand Up @@ -298,8 +298,8 @@ export class PalletScraper extends MetadataScraper {
name,
docs,
modifier: '', // NOTE: This could be `null`.
type: scrapedType,
value,
...scrapedType,
};
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/model/Scraper/Types/Array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export class ArrayType implements MetadataType {
this.array = array;
}

label() {
return '';
}

// Scrape array type. Overwrites `type` with scraped type.
scrape(scraper: MetadataScraper, trailParam: TrailParam) {
return scraper.getType(this.array.type, trailParam);
Expand Down
10 changes: 10 additions & 0 deletions src/model/Scraper/Types/BitSequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { LookupItem } from '../Lookup/types';
import type { MetadataScraper } from '..';
import type { TrailParam } from '../types';
import type { BitSequenceType, MetadataType } from './types';
import { Format } from '../Format';

// Class to hold a bit sequence type.
export class BitSequence implements MetadataType {
Expand All @@ -19,6 +20,15 @@ export class BitSequence implements MetadataType {
this.bitSequence = bitSequence;
}

// Get the labels of this bit sequence.
label() {
const { path, params } = this.lookup.type;
return {
long: Format.typeToString(path, params),
short: path[path.length - 1],
};
}

// Scrape bitSequence type. Overwrites `bitStoreType` and `bitOrderType` with scraped types.
scrape(scraper: MetadataScraper, { trailId }: TrailParam) {
return {
Expand Down
4 changes: 4 additions & 0 deletions src/model/Scraper/Types/Compact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export class Compact implements MetadataType {
this.type = compact.type;
}

label() {
return '';
}

// Scrape compact type. Overwrites `type` with scraped type.
scrape(scraper: MetadataScraper, trailParam: TrailParam) {
return scraper.getType(this.type, trailParam);
Expand Down
10 changes: 10 additions & 0 deletions src/model/Scraper/Types/Composite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { LookupItem } from '../Lookup/types';
import type { MetadataScraper } from '..';
import type { TrailParam } from '../types';
import type { CompositeField, CompositeType, MetadataType } from './types';
import { Format } from '../Format';

// Class to hold a composite type.
export class Composite implements MetadataType {
Expand All @@ -19,6 +20,15 @@ export class Composite implements MetadataType {
this.lookup = lookup;
}

// Get the labels of this composite type.
label() {
const { path, params } = this.lookup.type;
return {
long: Format.typeToString(path, params),
short: path[path.length - 1],
};
}

// Scrape composite fields. Overwrites `fields` with scraped fields.
scrape(scraper: MetadataScraper, { trailId }: TrailParam) {
return [...this.fields].map((field) => ({
Expand Down
5 changes: 5 additions & 0 deletions src/model/Scraper/Types/Primitive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export class Primitive implements MetadataType {
this.primitive = primitive;
}

// Get the label of this primitive.
label() {
return this.primitive.toLowerCase();
}

// Scrape primitive type. Simply returns the type.
scrape() {
return this.primitive;
Expand Down
Loading

0 comments on commit 7d70c22

Please sign in to comment.