BREAKING CHANGE: document contracts from sol-doc
Change website to accept smart contract documentation in the format generated by sol-doc rather than that generated by Doxity.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
#### WARNING: Alpha software. Expect things to break when trying to use.
|
||||
|
||||
A full-page React component for rendering beautiful documentation for Solidity and Typescript code generated with [TypeDoc](http://typedoc.org/) or [Doxity](https://github.com/0xproject/doxity).
|
||||
A full-page React component for rendering beautiful documentation for Solidity and Typescript code generated with [TypeDoc](http://typedoc.org/) or [sol-doc](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-doc).
|
||||
|
||||
<div style="text-align: center;">
|
||||
<img src="https://s3.eu-west-2.amazonaws.com/0x-wiki-images/screenshot.png" style="padding-bottom: 20px; padding-top: 20px;" width="80%" />
|
||||
@@ -47,7 +47,7 @@ Feel free to contribute to these improvements!
|
||||
|
||||
* Allow user to pass in styling for all major elements similar to [Material-UI](http://www.material-ui.com/).
|
||||
* Allow user to define an alternative font and have it change everywhere.
|
||||
* Add source links to Solidity docs (currently unsupported by Doxity).
|
||||
* Add source links to Solidity docs (currently unsupported by solc, which underlies sol-doc).
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
"description": "React documentation component for rendering TypeDoc & Doxity generated JSON",
|
||||
"description": "React documentation component for rendering TypeDoc & sol-doc generated JSON",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"scripts": {
|
||||
|
||||
@@ -329,7 +329,7 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
|
||||
return <div>{externalExports}</div>;
|
||||
}
|
||||
private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode {
|
||||
if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
|
||||
if (this.props.docsInfo.type !== SupportedDocJson.Solidity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import { MenuSubsectionsBySection } from '@0xproject/react-shared';
|
||||
import { DocAgnosticFormat, GeneratedDocJson, TypeDefinitionByName } from '@0xproject/types';
|
||||
import { DocAgnosticFormat, TypeDefinitionByName } from '@0xproject/types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
ContractsByVersionByNetworkId,
|
||||
DocsInfoConfig,
|
||||
DocsMenu,
|
||||
DoxityDocObj,
|
||||
SectionNameToMarkdownByVersion,
|
||||
SectionsMap,
|
||||
SupportedDocJson,
|
||||
} from './types';
|
||||
import { doxityUtils } from './utils/doxity_utils';
|
||||
import { TypeDocUtils } from './utils/typedoc_utils';
|
||||
|
||||
export class DocsInfo {
|
||||
public id: string;
|
||||
@@ -93,12 +90,4 @@ export class DocsInfo {
|
||||
const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name') as any;
|
||||
return typeDefinitionByName;
|
||||
}
|
||||
public convertToDocAgnosticFormat(docObj: DoxityDocObj | GeneratedDocJson): DocAgnosticFormat {
|
||||
if (this.type === SupportedDocJson.Doxity) {
|
||||
return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
|
||||
} else {
|
||||
const typeDocUtils = new TypeDocUtils(docObj as GeneratedDocJson, this);
|
||||
return typeDocUtils.convertToDocAgnosticFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@ export { Signature } from './components/signature';
|
||||
export { SourceLink } from './components/source_link';
|
||||
export { TypeDefinition } from './components/type_definition';
|
||||
export { Type } from './components/type';
|
||||
export { TypeDocUtils } from './utils/typedoc_utils';
|
||||
|
||||
export { DocsInfo } from './docs_info';
|
||||
|
||||
export { DocsInfoConfig, DoxityDocObj, DocsMenu, SupportedDocJson } from './types';
|
||||
export { DocsInfoConfig, DocsMenu, SupportedDocJson } from './types';
|
||||
|
||||
export { constants } from './utils/constants';
|
||||
|
||||
@@ -38,7 +38,7 @@ export enum KindString {
|
||||
}
|
||||
|
||||
export enum SupportedDocJson {
|
||||
Doxity = 'DOXITY',
|
||||
Solidity = 'SOLIDITY',
|
||||
TypeDoc = 'TYPEDOC',
|
||||
}
|
||||
|
||||
@@ -50,40 +50,6 @@ export interface ContractsByVersionByNetworkId {
|
||||
};
|
||||
}
|
||||
|
||||
export interface DoxityDocObj {
|
||||
[contractName: string]: DoxityContractObj;
|
||||
}
|
||||
|
||||
export interface DoxityContractObj {
|
||||
title: string;
|
||||
fileName: string;
|
||||
name: string;
|
||||
abiDocs: DoxityAbiDoc[];
|
||||
}
|
||||
|
||||
export interface DoxityAbiDoc {
|
||||
constant: boolean;
|
||||
inputs: DoxityInput[];
|
||||
name: string;
|
||||
outputs: DoxityOutput[];
|
||||
payable: boolean;
|
||||
type: string;
|
||||
details?: string;
|
||||
return?: string;
|
||||
}
|
||||
|
||||
export interface DoxityOutput {
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface DoxityInput {
|
||||
name: string;
|
||||
type: string;
|
||||
description: string;
|
||||
indexed?: boolean;
|
||||
}
|
||||
|
||||
export interface AddressByContractName {
|
||||
[contractName: string]: string;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export const constants = {
|
||||
TYPES_SECTION_NAME: 'types',
|
||||
EXTERNAL_EXPORTS_SECTION_NAME: 'external exports',
|
||||
TYPE_TO_SYNTAX: {
|
||||
[SupportedDocJson.Doxity]: 'solidity',
|
||||
[SupportedDocJson.Solidity]: 'solidity',
|
||||
[SupportedDocJson.TypeDoc]: 'typescript',
|
||||
} as { [supportedDocType: string]: string },
|
||||
};
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {
|
||||
DocAgnosticFormat,
|
||||
DocSection,
|
||||
EventArg,
|
||||
Parameter,
|
||||
Property,
|
||||
SolidityMethod,
|
||||
Type,
|
||||
TypeDocTypes,
|
||||
} from '@0xproject/types';
|
||||
|
||||
import { AbiTypes, DoxityAbiDoc, DoxityContractObj, DoxityDocObj, DoxityInput } from '../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: doxityUtils._convertParameters(doxityConstructor.inputs),
|
||||
returnType: doxityUtils._convertType(doxityContractObj.name),
|
||||
};
|
||||
constructors.push(constructor);
|
||||
}
|
||||
|
||||
const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
|
||||
doxityContractObj.abiDocs,
|
||||
(abiDoc: DoxityAbiDoc) => {
|
||||
return doxityUtils._isMethod(abiDoc);
|
||||
},
|
||||
);
|
||||
const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
|
||||
doxityMethods,
|
||||
(doxityMethod: DoxityAbiDoc) => {
|
||||
const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
|
||||
let returnTypeIfExists: Type;
|
||||
if (outputs.length === 0) {
|
||||
// no-op. It's already undefined
|
||||
} else if (outputs.length === 1) {
|
||||
const outputsType = outputs[0].type;
|
||||
returnTypeIfExists = doxityUtils._convertType(outputsType);
|
||||
} else {
|
||||
const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
|
||||
returnTypeIfExists = doxityUtils._convertType(outputsType);
|
||||
}
|
||||
// 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: doxityUtils._convertParameters(doxityMethod.inputs),
|
||||
returnType: returnTypeIfExists,
|
||||
};
|
||||
return method;
|
||||
},
|
||||
);
|
||||
|
||||
const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
|
||||
doxityContractObj.abiDocs,
|
||||
(abiDoc: DoxityAbiDoc) => {
|
||||
return doxityUtils._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: doxityUtils._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: doxityUtils._convertEventArgs(doxityEvent.inputs),
|
||||
};
|
||||
return event;
|
||||
});
|
||||
|
||||
const docSection: DocSection = {
|
||||
comment: doxityContractObj.title,
|
||||
constructors,
|
||||
methods,
|
||||
properties,
|
||||
types: [],
|
||||
functions: [],
|
||||
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: doxityUtils._convertType(input.type),
|
||||
};
|
||||
return parameter;
|
||||
});
|
||||
return parameters;
|
||||
},
|
||||
_convertType(typeName: string): Type {
|
||||
const type = {
|
||||
name: typeName,
|
||||
typeDocType: TypeDocTypes.Intrinsic,
|
||||
};
|
||||
return type;
|
||||
},
|
||||
_isMethod(abiDoc: DoxityAbiDoc): boolean {
|
||||
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): boolean {
|
||||
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: doxityUtils._convertType(input.type),
|
||||
};
|
||||
return eventArg;
|
||||
});
|
||||
return eventArgs;
|
||||
},
|
||||
};
|
||||
8
packages/website/md/docs/smart_contracts/2.0.0/introduction.md
vendored
Normal file
8
packages/website/md/docs/smart_contracts/2.0.0/introduction.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
Welcome to the [0x smart contracts](https://github.com/0xProject/contracts) documentation! This documentation is intended for dApp developers who want to integrate 0x exchange functionality directly into their own smart contracts.
|
||||
|
||||
### Helpful wiki articles:
|
||||
|
||||
* [Overview of 0x protocol architecture](https://0xproject.com/wiki#Architecture)
|
||||
* [0x smart contract interactions](https://0xproject.com/wiki#Contract-Interactions)
|
||||
* [Deployed smart contract addresses](https://0xproject.com/wiki#Deployed-Addresses)
|
||||
* [0x protocol message format](https://0xproject.com/wiki#Message-Format)
|
||||
@@ -11,29 +11,28 @@ import { Translate } from 'ts/utils/translate';
|
||||
|
||||
/* tslint:disable:no-var-requires */
|
||||
const IntroMarkdownV1 = require('md/docs/smart_contracts/1.0.0/introduction');
|
||||
const IntroMarkdownV2 = require('md/docs/smart_contracts/2.0.0/introduction');
|
||||
/* tslint:enable:no-var-requires */
|
||||
|
||||
const docsInfoConfig: DocsInfoConfig = {
|
||||
id: DocPackages.SmartContracts,
|
||||
packageName: 'contracts',
|
||||
type: SupportedDocJson.Doxity,
|
||||
type: SupportedDocJson.Solidity,
|
||||
displayName: '0x Smart Contracts',
|
||||
packageUrl: 'https://github.com/0xProject/contracts',
|
||||
markdownMenu: {
|
||||
introduction: [Sections.Introduction],
|
||||
contracts: [Sections.Exchange, Sections.TokenRegistry, Sections.ZRXToken, Sections.TokenTransferProxy],
|
||||
},
|
||||
sectionNameToMarkdownByVersion: {
|
||||
'0.0.1': {
|
||||
[Sections.Introduction]: IntroMarkdownV1,
|
||||
},
|
||||
'2.0.0': {
|
||||
[Sections.Introduction]: IntroMarkdownV2,
|
||||
},
|
||||
},
|
||||
markdownSections: {
|
||||
Introduction: Sections.Introduction,
|
||||
Exchange: Sections.Exchange,
|
||||
TokenTransferProxy: Sections.TokenTransferProxy,
|
||||
TokenRegistry: Sections.TokenRegistry,
|
||||
ZRXToken: Sections.ZRXToken,
|
||||
},
|
||||
contractsByVersionByNetworkId: {
|
||||
'1.0.0': {
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { DocAgnosticFormat, DocsInfo, Documentation } from '@0xproject/react-docs';
|
||||
import {
|
||||
DocAgnosticFormat,
|
||||
DocsInfo,
|
||||
Documentation,
|
||||
GeneratedDocJson,
|
||||
SupportedDocJson,
|
||||
TypeDocUtils,
|
||||
} from '@0xproject/react-docs';
|
||||
import findVersions = require('find-versions');
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
@@ -128,7 +135,22 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> {
|
||||
|
||||
const versionFilePathToFetch = versionToFilePath[versionToFetch];
|
||||
const versionDocObj = await docUtils.getJSONDocFileAsync(versionFilePathToFetch, docBucketRoot);
|
||||
const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj);
|
||||
let docAgnosticFormat;
|
||||
if (this.props.docsInfo.type === SupportedDocJson.TypeDoc) {
|
||||
docAgnosticFormat = new TypeDocUtils(
|
||||
versionDocObj as GeneratedDocJson,
|
||||
this.props.docsInfo,
|
||||
).convertToDocAgnosticFormat();
|
||||
} else if (this.props.docsInfo.type === SupportedDocJson.Solidity) {
|
||||
// documenting solidity.
|
||||
docAgnosticFormat = versionDocObj as DocAgnosticFormat;
|
||||
// need to modify docsInfo like convertToDocAgnosticFormat() would do
|
||||
this.props.docsInfo.menu.Contracts = [];
|
||||
_.each(docAgnosticFormat, (docObj, contractName) => {
|
||||
this.props.docsInfo.sections[contractName] = contractName;
|
||||
this.props.docsInfo.menu.Contracts.push(contractName);
|
||||
});
|
||||
}
|
||||
|
||||
if (!this._isUnmounted) {
|
||||
this.setState({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DoxityDocObj, GeneratedDocJson } from '@0xproject/react-docs';
|
||||
import { DocAgnosticFormat, GeneratedDocJson } from '@0xproject/react-docs';
|
||||
import { fetchAsync, logUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import { S3FileObject, VersionToFilePath } from 'ts/types';
|
||||
@@ -70,7 +70,7 @@ export const docUtils = {
|
||||
});
|
||||
return versionFilePaths;
|
||||
},
|
||||
async getJSONDocFileAsync(filePath: string, s3DocJsonRoot: string): Promise<GeneratedDocJson | DoxityDocObj> {
|
||||
async getJSONDocFileAsync(filePath: string, s3DocJsonRoot: string): Promise<GeneratedDocJson | DocAgnosticFormat> {
|
||||
const endpoint = `${s3DocJsonRoot}/${filePath}`;
|
||||
const response = await fetchAsync(endpoint);
|
||||
if (response.status !== 200) {
|
||||
|
||||
Reference in New Issue
Block a user