169 lines
6.6 KiB
TypeScript
169 lines
6.6 KiB
TypeScript
import * as _ from 'lodash';
|
|
import {
|
|
AbiTypes,
|
|
DocAgnosticFormat,
|
|
DocSection,
|
|
DoxityAbiDoc,
|
|
DoxityContractObj,
|
|
DoxityDocObj,
|
|
DoxityInput,
|
|
EventArg,
|
|
Parameter,
|
|
Property,
|
|
SolidityMethod,
|
|
Type,
|
|
TypeDocTypes,
|
|
} from 'ts/types';
|
|
|
|
export const doxityUtils = {
|
|
convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
|
|
const docAgnosticFormat: DocAgnosticFormat = {};
|
|
_.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
|
|
const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
|
|
return abiDoc.type === AbiTypes.Constructor;
|
|
});
|
|
const constructors = [];
|
|
if (!_.isUndefined(doxityConstructor)) {
|
|
const constructor = {
|
|
isConstructor: true,
|
|
name: doxityContractObj.name,
|
|
comment: doxityConstructor.details,
|
|
returnComment: doxityConstructor.return,
|
|
callPath: '',
|
|
parameters: this._convertParameters(doxityConstructor.inputs),
|
|
returnType: this._convertType(doxityContractObj.name),
|
|
};
|
|
constructors.push(constructor);
|
|
}
|
|
|
|
const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
|
|
doxityContractObj.abiDocs,
|
|
(abiDoc: DoxityAbiDoc) => {
|
|
return this._isMethod(abiDoc);
|
|
},
|
|
);
|
|
const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
|
|
doxityMethods,
|
|
(doxityMethod: DoxityAbiDoc) => {
|
|
// We assume that none of our functions returns more then a single value
|
|
const outputIfExists = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs[0] : undefined;
|
|
const returnTypeIfExists = !_.isUndefined(outputIfExists)
|
|
? this._convertType(outputIfExists.type)
|
|
: undefined;
|
|
// For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
|
|
const callPath =
|
|
contractName !== 'ZRXToken'
|
|
? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
|
|
: `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
|
|
const method = {
|
|
isConstructor: false,
|
|
isConstant: doxityMethod.constant,
|
|
isPayable: doxityMethod.payable,
|
|
name: doxityMethod.name,
|
|
comment: doxityMethod.details,
|
|
returnComment: doxityMethod.return,
|
|
callPath,
|
|
parameters: this._convertParameters(doxityMethod.inputs),
|
|
returnType: returnTypeIfExists,
|
|
};
|
|
return method;
|
|
},
|
|
);
|
|
|
|
const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
|
|
doxityContractObj.abiDocs,
|
|
(abiDoc: DoxityAbiDoc) => {
|
|
return this._isProperty(abiDoc);
|
|
},
|
|
);
|
|
const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
|
|
// We assume that none of our functions return more then a single return value
|
|
let typeName = doxityProperty.outputs[0].type;
|
|
if (!_.isEmpty(doxityProperty.inputs)) {
|
|
// Properties never have more then a single input
|
|
typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
|
|
}
|
|
const property = {
|
|
name: doxityProperty.name,
|
|
type: this._convertType(typeName),
|
|
comment: doxityProperty.details,
|
|
};
|
|
return property;
|
|
});
|
|
|
|
const doxityEvents = _.filter(
|
|
doxityContractObj.abiDocs,
|
|
(abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
|
|
);
|
|
const events = _.map(doxityEvents, doxityEvent => {
|
|
const event = {
|
|
name: doxityEvent.name,
|
|
eventArgs: this._convertEventArgs(doxityEvent.inputs),
|
|
};
|
|
return event;
|
|
});
|
|
|
|
const docSection: DocSection = {
|
|
comment: doxityContractObj.title,
|
|
constructors,
|
|
methods,
|
|
properties,
|
|
types: [],
|
|
events,
|
|
};
|
|
docAgnosticFormat[contractName] = docSection;
|
|
});
|
|
return docAgnosticFormat;
|
|
},
|
|
_convertParameters(inputs: DoxityInput[]): Parameter[] {
|
|
const parameters = _.map(inputs, input => {
|
|
const parameter = {
|
|
name: input.name,
|
|
comment: input.description,
|
|
isOptional: false,
|
|
type: this._convertType(input.type),
|
|
};
|
|
return parameter;
|
|
});
|
|
return parameters;
|
|
},
|
|
_convertType(typeName: string): Type {
|
|
const type = {
|
|
name: typeName,
|
|
typeDocType: TypeDocTypes.Intrinsic,
|
|
};
|
|
return type;
|
|
},
|
|
_isMethod(abiDoc: DoxityAbiDoc) {
|
|
if (abiDoc.type !== AbiTypes.Function) {
|
|
return false;
|
|
}
|
|
const hasInputs = !_.isEmpty(abiDoc.inputs);
|
|
const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
|
|
const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
|
|
const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
|
|
return isMethod;
|
|
},
|
|
_isProperty(abiDoc: DoxityAbiDoc) {
|
|
if (abiDoc.type !== AbiTypes.Function) {
|
|
return false;
|
|
}
|
|
const hasInputs = !_.isEmpty(abiDoc.inputs);
|
|
const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
|
|
const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
|
|
const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
|
|
return isProperty;
|
|
},
|
|
_convertEventArgs(inputs: DoxityInput[]): EventArg[] {
|
|
const eventArgs = _.map(inputs, input => {
|
|
const eventArg = {
|
|
isIndexed: input.indexed,
|
|
name: input.name,
|
|
type: this._convertType(input.type),
|
|
};
|
|
return eventArg;
|
|
});
|
|
return eventArgs;
|
|
},
|
|
};
|