From 3472bdcfd4ea0a6145dd68972f563e483baf7e6b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 28 Nov 2017 11:16:35 -0600 Subject: Refactor docs to be more declarative, put all hard-coded doc-related data in one place so it easier to add new doc pages --- packages/website/ts/utils/constants.ts | 131 ++++++----------------------- packages/website/ts/utils/typedoc_utils.ts | 126 ++++++++++++--------------- 2 files changed, 77 insertions(+), 180 deletions(-) (limited to 'packages/website/ts/utils') diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts index 77a6e3e38..f307df929 100644 --- a/packages/website/ts/utils/constants.ts +++ b/packages/website/ts/utils/constants.ts @@ -5,12 +5,18 @@ import { ExchangeContractErrs, Networks, PublicNodeUrlsByNetworkId, - SmartContractsDocSections, WebsitePaths, - ZeroExJsDocSections, } from 'ts/types'; const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs'; +const smartContractDocSections = { + Introduction: 'Introduction', + Exchange: 'Exchange', + TokenTransferProxy: 'TokenTransferProxy', + TokenRegistry: 'TokenRegistry', + ZRXToken: 'ZRXToken', + EtherToken: 'EtherToken', +}; export const constants = { ANGELLIST_URL: 'https://angel.co/0xproject/jobs', @@ -27,7 +33,6 @@ export const constants = { FEE_RECIPIENT_ADDRESS: '0x0000000000000000000000000000000000000000', FIREFOX_U2F_ADDON: 'https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/', GITHUB_URL: 'https://github.com/0xProject', - GITHUB_0X_JS_URL: 'https://github.com/0xProject/0x.js', GITHUB_CONTRACTS_URL: 'https://github.com/0xProject/contracts', GITHUB_WIKI_URL: 'https://github.com/0xProject/wiki', HTTP_NO_CONTENT_STATUS_CODE: 204, @@ -67,8 +72,6 @@ export const constants = { REDDIT_URL: 'https://reddit.com/r/0xproject', STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md', SUCCESS_STATUS: 200, - S3_0XJS_DOCUMENTATION_JSON_ROOT: 'https://s3.amazonaws.com/0xjs-docs-jsons', - S3_SMART_CONTRACTS_DOCUMENTATION_JSON_ROOT: 'https://s3.amazonaws.com/smart-contracts-docs-json', UNAVAILABLE_STATUS: 503, TAKER_FEE: new BigNumber(0), TESTNET_NAME: 'Kovan', @@ -154,119 +157,33 @@ export const constants = { [Networks.rinkeby]: 4, [Networks.kovan]: 42, } as {[networkName: string]: number}, - // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is - // currently no way to extract the re-exported types from index.ts via TypeDoc :( - public0xjsTypes: [ - 'Order', - 'SignedOrder', - 'ECSignature', - 'ZeroExError', - 'EventCallback', - 'EventCallbackAsync', - 'EventCallbackSync', - 'ExchangeContractErrs', - 'ContractEvent', - 'Token', - 'ExchangeEvents', - 'IndexedFilterValues', - 'SubscriptionOpts', - 'BlockParam', - 'OrderFillOrKillRequest', - 'OrderCancellationRequest', - 'OrderFillRequest', - 'ContractEventEmitter', - 'Web3Provider', - 'ContractEventArgs', - 'LogCancelArgs', - 'LogFillArgs', - 'LogErrorContractEventArgs', - 'LogFillContractEventArgs', - 'LogCancelContractEventArgs', - 'TokenEvents', - 'ExchangeContractEventArgs', - 'TransferContractEventArgs', - 'ApprovalContractEventArgs', - 'TokenContractEventArgs', - 'ZeroExConfig', - 'TransactionReceiptWithDecodedLogs', - 'LogWithDecodedArgs', - 'DecodedLogArgs', - 'MethodOpts', - 'ValidateOrderFillableOpts', - 'OrderTransactionOpts', - 'ContractEventArg', - 'LogEvent', - 'LogEntry', - 'DecodedLogEvent', - ], - menuSmartContracts: { - introduction: [ - SmartContractsDocSections.Introduction, - ], - contracts: [ - SmartContractsDocSections.Exchange, - SmartContractsDocSections.TokenRegistry, - SmartContractsDocSections.ZRXToken, - SmartContractsDocSections.EtherToken, - SmartContractsDocSections.TokenTransferProxy, - ], - }, - menu0xjs: { - introduction: [ - ZeroExJsDocSections.introduction, - ], - install: [ - ZeroExJsDocSections.installation, - ], - topics: [ - ZeroExJsDocSections.async, - ZeroExJsDocSections.errors, - ZeroExJsDocSections.versioning, - ], - zeroEx: [ - ZeroExJsDocSections.zeroEx, - ], - contracts: [ - ZeroExJsDocSections.exchange, - ZeroExJsDocSections.token, - ZeroExJsDocSections.tokenRegistry, - ZeroExJsDocSections.etherToken, - ZeroExJsDocSections.proxy, - ], - types: [ - ZeroExJsDocSections.types, - ], - }, - menuSubsectionToVersionWhenIntroduced: { - [ZeroExJsDocSections.etherToken]: '0.7.1', - [ZeroExJsDocSections.proxy]: '0.8.0', - }, docToPath: { [Docs.ZeroExJs]: WebsitePaths.ZeroExJs, [Docs.SmartContracts]: WebsitePaths.SmartContracts, }, + smartContractDocSections, contractAddresses: { '1.0.0': { [Networks.mainnet]: { - [SmartContractsDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093', - [SmartContractsDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4', - [SmartContractsDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498', - [SmartContractsDocSections.EtherToken]: '0x2956356cd2a2bf3202f771f50d3d14a367b48070', - [SmartContractsDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c', + [smartContractDocSections.Exchange]: '0x12459c951127e0c374ff9105dda097662a027093', + [smartContractDocSections.TokenTransferProxy]: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4', + [smartContractDocSections.ZRXToken]: '0xe41d2489571d322189246dafa5ebde1f4699f498', + [smartContractDocSections.EtherToken]: '0x2956356cd2a2bf3202f771f50d3d14a367b48070', + [smartContractDocSections.TokenRegistry]: '0x926a74c5c36adf004c87399e65f75628b0f98d2c', }, [Networks.ropsten]: { - [SmartContractsDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac', - [SmartContractsDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6', - [SmartContractsDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d', - [SmartContractsDocSections.EtherToken]: '0xc00fd9820cd2898cc4c054b7bf142de637ad129a', - [SmartContractsDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed', + [smartContractDocSections.Exchange]: '0x479cc461fecd078f766ecc58533d6f69580cf3ac', + [smartContractDocSections.TokenTransferProxy]: '0x4e9aad8184de8833365fea970cd9149372fdf1e6', + [smartContractDocSections.ZRXToken]: '0xa8e9fa8f91e5ae138c74648c9c304f1c75003a8d', + [smartContractDocSections.EtherToken]: '0xc00fd9820cd2898cc4c054b7bf142de637ad129a', + [smartContractDocSections.TokenRegistry]: '0x6b1a50f0bb5a7995444bd3877b22dc89c62843ed', }, [Networks.kovan]: { - [SmartContractsDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364', - [SmartContractsDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4', - [SmartContractsDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570', - [SmartContractsDocSections.EtherToken]: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c', - [SmartContractsDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f', + [smartContractDocSections.Exchange]: '0x90fe2af704b34e0224bf2299c838e04d4dcf1364', + [smartContractDocSections.TokenTransferProxy]: '0x087Eed4Bc1ee3DE49BeFbd66C662B434B15d49d4', + [smartContractDocSections.ZRXToken]: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570', + [smartContractDocSections.EtherToken]: '0x05d090b51c40b020eab3bfcb6a2dff130df22e9c', + [smartContractDocSections.TokenRegistry]: '0xf18e504561f4347bea557f3d4558f559dddbae7f', }, }, } as ContractAddresses, diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts index bb2f7745a..61d9f4bf2 100644 --- a/packages/website/ts/utils/typedoc_utils.ts +++ b/packages/website/ts/utils/typedoc_utils.ts @@ -1,41 +1,27 @@ -import compareVersions = require('compare-versions'); import * as _ from 'lodash'; +import {DocsInfo} from 'ts/pages/documentation/docs_info'; import { CustomType, CustomTypeChild, DocAgnosticFormat, DocSection, + DocsMenu, IndexSignature, KindString, MenuSubsectionsBySection, Parameter, Property, + SectionsMap, Type, TypeDocNode, TypeDocType, TypeDocTypes, TypeParameter, TypescriptMethod, - ZeroExJsDocSections, } from 'ts/types'; import {constants} from 'ts/utils/constants'; import {utils} from 'ts/utils/utils'; -const TYPES_MODULE_PATH = '"src/types"'; - -export const sectionNameToPossibleModulePaths: {[name: string]: string[]} = { - [ZeroExJsDocSections.zeroEx]: ['"src/0x"'], - [ZeroExJsDocSections.exchange]: ['"src/contract_wrappers/exchange_wrapper"'], - [ZeroExJsDocSections.tokenRegistry]: ['"src/contract_wrappers/token_registry_wrapper"'], - [ZeroExJsDocSections.token]: ['"src/contract_wrappers/token_wrapper"'], - [ZeroExJsDocSections.etherToken]: ['"src/contract_wrappers/ether_token_wrapper"'], - [ZeroExJsDocSections.proxy]: [ - '"src/contract_wrappers/proxy_wrapper"', - '"src/contract_wrappers/token_transfer_proxy_wrapper"', - ], - [ZeroExJsDocSections.types]: [TYPES_MODULE_PATH], -}; - export const typeDocUtils = { isType(entity: TypeDocNode): boolean { return entity.kindString === KindString.Interface || @@ -56,35 +42,33 @@ export const typeDocUtils = { isPrivateOrProtectedProperty(propertyName: string): boolean { return _.startsWith(propertyName, '_'); }, - isPublicType(typeName: string): boolean { - return _.includes(constants.public0xjsTypes, typeName); - }, - getModuleDefinitionBySectionNameIfExists(versionDocObj: TypeDocNode, sectionName: string): + getModuleDefinitionBySectionNameIfExists(versionDocObj: TypeDocNode, modulePaths: string[]): TypeDocNode|undefined { - const possibleModulePathNames = sectionNameToPossibleModulePaths[sectionName]; const modules = versionDocObj.children; for (const mod of modules) { - if (_.includes(possibleModulePathNames, mod.name)) { + if (_.includes(modulePaths, mod.name)) { const moduleWithName = mod; return moduleWithName; } } return undefined; }, - getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection { + getMenuSubsectionsBySection( + sections: SectionsMap, docAgnosticFormat?: DocAgnosticFormat, + ): MenuSubsectionsBySection { const menuSubsectionsBySection = {} as MenuSubsectionsBySection; if (_.isUndefined(docAgnosticFormat)) { return menuSubsectionsBySection; } - const docSections = _.keys(ZeroExJsDocSections); + const docSections = _.keys(sections); _.each(docSections, sectionName => { const docSection = docAgnosticFormat[sectionName]; if (_.isUndefined(docSection)) { return; // no-op } - if (sectionName === ZeroExJsDocSections.types) { + if (!_.isUndefined(sections.types) && sectionName === sections.types) { const typeNames = _.map(docSection.types, t => t.name); menuSubsectionsBySection[sectionName] = typeNames; } else { @@ -94,27 +78,17 @@ export const typeDocUtils = { }); return menuSubsectionsBySection; }, - getFinal0xjsMenu(selectedVersion: string): {[section: string]: string[]} { - const finalMenu = _.cloneDeep(constants.menu0xjs); - finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => { - const versionIntroducedIfExists = constants.menuSubsectionToVersionWhenIntroduced[contractName]; - if (!_.isUndefined(versionIntroducedIfExists)) { - const existsInSelectedVersion = compareVersions(selectedVersion, - versionIntroducedIfExists) >= 0; - return existsInSelectedVersion; - } else { - return true; - } - }); - return finalMenu; - }, - convertToDocAgnosticFormat(typeDocJson: TypeDocNode): DocAgnosticFormat { - const subMenus = _.values(constants.menu0xjs); + convertToDocAgnosticFormat(docsInfo: DocsInfo, typeDocJson: TypeDocNode): DocAgnosticFormat { + const subMenus = _.values(docsInfo.getMenu()); const orderedSectionNames = _.flatten(subMenus); const docAgnosticFormat: DocAgnosticFormat = {}; _.each(orderedSectionNames, sectionName => { + const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName); + if (_.isUndefined(modulePathsIfExists)) { + return; // no-op + } const packageDefinitionIfExists = typeDocUtils.getModuleDefinitionBySectionNameIfExists( - typeDocJson, sectionName, + typeDocJson, modulePathsIfExists, ); if (_.isUndefined(packageDefinitionIfExists)) { return; // no-op @@ -125,7 +99,7 @@ export const typeDocUtils = { // for it. let entities; let packageComment = ''; - if (sectionName === ZeroExJsDocSections.types) { + if (sectionName === docsInfo.sections.types) { entities = packageDefinitionIfExists.children; } else { entities = packageDefinitionIfExists.children[0].children; @@ -133,13 +107,13 @@ export const typeDocUtils = { packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment; } - const docSection = typeDocUtils._convertEntitiesToDocSection(entities, sectionName); + const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName); docSection.comment = packageComment; docAgnosticFormat[sectionName] = docSection; }); return docAgnosticFormat; }, - _convertEntitiesToDocSection(entities: TypeDocNode[], sectionName: string) { + _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) { const docSection: DocSection = { comment: '', constructors: [], @@ -153,21 +127,25 @@ export const typeDocUtils = { switch (entity.kindString) { case KindString.Constructor: isConstructor = true; - const constructor = typeDocUtils._convertMethod(entity, isConstructor, sectionName); + const constructor = typeDocUtils._convertMethod( + entity, isConstructor, docsInfo.sections, sectionName, + ); docSection.constructors.push(constructor); break; case KindString.Method: if (entity.flags.isPublic) { isConstructor = false; - const method = typeDocUtils._convertMethod(entity, isConstructor, sectionName); + const method = typeDocUtils._convertMethod( + entity, isConstructor, docsInfo.sections, sectionName, + ); docSection.methods.push(method); } break; case KindString.Property: if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) { - const property = typeDocUtils._convertProperty(entity, sectionName); + const property = typeDocUtils._convertProperty(entity, docsInfo.sections, sectionName); docSection.properties.push(property); } break; @@ -177,8 +155,8 @@ export const typeDocUtils = { case KindString.Variable: case KindString.Enumeration: case KindString['Type alias']: - if (typeDocUtils.isPublicType(entity.name)) { - const customType = typeDocUtils._convertCustomType(entity, sectionName); + if (docsInfo.isPublicType(entity.name)) { + const customType = typeDocUtils._convertCustomType(entity, docsInfo.sections, sectionName); docSection.types.push(customType); } break; @@ -189,16 +167,16 @@ export const typeDocUtils = { }); return docSection; }, - _convertCustomType(entity: TypeDocNode, sectionName: string): CustomType { + _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string): CustomType { const typeIfExists = !_.isUndefined(entity.type) ? - typeDocUtils._convertType(entity.type, sectionName) : + typeDocUtils._convertType(entity.type, sections, sectionName) : undefined; const isConstructor = false; const methodIfExists = !_.isUndefined(entity.declaration) ? - typeDocUtils._convertMethod(entity.declaration, isConstructor, sectionName) : + typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName) : undefined; const indexSignatureIfExists = !_.isUndefined(entity.indexSignature) ? - typeDocUtils._convertIndexSignature(entity.indexSignature[0], sectionName) : + typeDocUtils._convertIndexSignature(entity.indexSignature[0], sections, sectionName) : undefined; const commentIfExists = !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText) ? entity.comment.shortText : @@ -207,7 +185,7 @@ export const typeDocUtils = { const childrenIfExist = !_.isUndefined(entity.children) ? _.map(entity.children, (child: TypeDocNode) => { const childTypeIfExists = !_.isUndefined(child.type) ? - typeDocUtils._convertType(child.type, sectionName) : + typeDocUtils._convertType(child.type, sections, sectionName) : undefined; const c: CustomTypeChild = { name: child.name, @@ -230,21 +208,21 @@ export const typeDocUtils = { }; return customType; }, - _convertIndexSignature(entity: TypeDocNode, sectionName: string): IndexSignature { + _convertIndexSignature(entity: TypeDocNode, sections: SectionsMap, sectionName: string): IndexSignature { const key = entity.parameters[0]; const indexSignature = { keyName: key.name, - keyType: typeDocUtils._convertType(key.type, sectionName), + keyType: typeDocUtils._convertType(key.type, sections, sectionName), valueName: entity.type.name, }; return indexSignature; }, - _convertProperty(entity: TypeDocNode, sectionName: string): Property { + _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string): Property { const source = entity.sources[0]; const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined; const property = { name: entity.name, - type: typeDocUtils._convertType(entity.type, sectionName), + type: typeDocUtils._convertType(entity.type, sections, sectionName), source: { fileName: source.fileName, line: source.line, @@ -253,7 +231,9 @@ export const typeDocUtils = { }; return property; }, - _convertMethod(entity: TypeDocNode, isConstructor: boolean, sectionName: string): TypescriptMethod { + _convertMethod( + entity: TypeDocNode, isConstructor: boolean, sections: SectionsMap, sectionName: string, + ): TypescriptMethod { const signature = entity.signatures[0]; const source = entity.sources[0]; const hasComment = !_.isUndefined(signature.comment); @@ -262,18 +242,18 @@ export const typeDocUtils = { const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.'; // HACK: we use the fact that the sectionName is the same as the property name at the top-level // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON. - let callPath = (sectionName !== ZeroExJsDocSections.zeroEx) ? + let callPath = (!_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx) ? `${topLevelInterface}${sectionName}.` : topLevelInterface; callPath = isConstructor ? '' : callPath; const parameters = _.map(signature.parameters, param => { - return typeDocUtils._convertParameter(param, sectionName); + return typeDocUtils._convertParameter(param, sections, sectionName); }); - const returnType = typeDocUtils._convertType(signature.type, sectionName); + const returnType = typeDocUtils._convertType(signature.type, sections, sectionName); const typeParameter = _.isUndefined(signature.typeParameter) ? undefined : - typeDocUtils._convertTypeParameter(signature.typeParameter[0], sectionName); + typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName); const method = { isConstructor, @@ -292,15 +272,15 @@ export const typeDocUtils = { }; return method; }, - _convertTypeParameter(entity: TypeDocNode, sectionName: string): TypeParameter { - const type = typeDocUtils._convertType(entity.type, sectionName); + _convertTypeParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string): TypeParameter { + const type = typeDocUtils._convertType(entity.type, sections, sectionName); const parameter = { name: entity.name, type, }; return parameter; }, - _convertParameter(entity: TypeDocNode, sectionName: string): Parameter { + _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string): Parameter { let comment = ''; if (entity.comment && entity.comment.shortText) { comment = entity.comment.shortText; @@ -312,7 +292,7 @@ export const typeDocUtils = { entity.flags.isOptional : false; - const type = typeDocUtils._convertType(entity.type, sectionName); + const type = typeDocUtils._convertType(entity.type, sections, sectionName); const parameter = { name: entity.name, @@ -322,17 +302,17 @@ export const typeDocUtils = { }; return parameter; }, - _convertType(entity: TypeDocType, sectionName: string): Type { + _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string): Type { const typeArguments = _.map(entity.typeArguments, typeArgument => { - return typeDocUtils._convertType(typeArgument, sectionName); + return typeDocUtils._convertType(typeArgument, sections, sectionName); }); const types = _.map(entity.types, t => { - return typeDocUtils._convertType(t, sectionName); + return typeDocUtils._convertType(t, sections, sectionName); }); const isConstructor = false; const methodIfExists = !_.isUndefined(entity.declaration) ? - typeDocUtils._convertMethod(entity.declaration, isConstructor, sectionName) : + typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName) : undefined; const elementTypeIfExists = !_.isUndefined(entity.elementType) ? -- cgit