Skip to content

Commit

Permalink
Merge pull request #531 from zeeshanakram3/fix-typegen-for-deprecated…
Browse files Browse the repository at this point in the history
…-events

Fix `hydra-typegen` to properly generate types for deprecated/deleted events & extrinsics
  • Loading branch information
mnaamani authored Sep 26, 2023
2 parents af4fbc8 + c495259 commit a70c88e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 38 deletions.
69 changes: 55 additions & 14 deletions packages/hydra-typegen/src/commands/typegen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,33 +137,74 @@ types don't much the metadata definiton`,
} as IConfig
}

async buildGeneratorConfigs(config: IConfig): Promise<GeneratorConfig[]> {
async buildGeneratorConfigs(config: IConfig): Promise<{
configs: GeneratorConfig[]
allMissingEvents: string[][]
allMissingCalls: string[][]
}> {
const { outDir } = config

const specsMetadata = await getAllMetadata(config.metadata)

return Promise.all(
const results = await Promise.all(
specsMetadata.map(async ([originalMetadata, chainSpec]) => {
const modules = await extractMeta(config, originalMetadata)
const { extracted, missingEvents, missingCalls } = await extractMeta(
config,
originalMetadata
)

return {
importsRegistry: buildImportsRegistry(),
modules,
validateArgs: config.strict || false, // do not enforce validation by default
dest: path.resolve(
path.join(outDir, chainSpec.specVersion.toString())
),
originalMetadata,
specVersion: chainSpec.specVersion,
config: {
importsRegistry: buildImportsRegistry(),
modules: extracted,
validateArgs: config.strict || false,
dest: path.resolve(
path.join(outDir, chainSpec.specVersion.toString())
),
originalMetadata,
specVersion: chainSpec.specVersion,
},
missingEvents,
missingCalls,
}
})
)

const generatorConfigs = results.map((r) => r.config)
const allMissingEvents = results.map((r) => r.missingEvents)
const allMissingCalls = results.map((r) => r.missingCalls)

return { configs: generatorConfigs, allMissingEvents, allMissingCalls }
}

async generate(config: IConfig): Promise<void> {
const generatorConfigs = await this.buildGeneratorConfigs(config)
const { configs, allMissingEvents, allMissingCalls } =
await this.buildGeneratorConfigs(config)

const globalMissingEvents = config.events.filter(
(event) =>
!allMissingEvents.some(
(missingEvents) => !missingEvents.includes(event)
)
)

const globalMissingCalls = config.calls.filter(
(call) =>
!allMissingCalls.some((missingCalls) => !missingCalls.includes(call))
)

if (globalMissingEvents.length > 0) {
throw new Error(
`No metadata found for the events: ${globalMissingEvents.join(', ')}`
)
}
if (globalMissingCalls.length > 0) {
throw new Error(
`No metadata found for the calls: ${globalMissingCalls.join(', ')}`
)
}

for (const generatorConfig of generatorConfigs) {
for (const generatorConfig of configs) {
const { dest } = generatorConfig

debug(`Output dir: ${dest}`)
Expand All @@ -175,6 +216,6 @@ types don't much the metadata definiton`,
generateModuleTypes(generatorConfig)
}

generateRootIndex(config, generatorConfigs)
generateRootIndex(config, configs)
}
}
65 changes: 41 additions & 24 deletions packages/hydra-typegen/src/metadata/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,72 @@ import { TypeDef } from '@polkadot/types/types'
import { uniq } from 'lodash'
import { IConfig } from '../commands/typegen'
import { pushToDictionary } from '../util'
import { ExtractedModuleMeta, ExtractedVaraintData, weakEquals } from './types'
import { ExtractedVaraintData, MetaExtractionResult, weakEquals } from './types'

const debug = require('debug')('hydra-typegen:extract')

export async function extractMeta(
{ events, calls }: IConfig,
originalMetadata: Metadata
): Promise<ExtractedModuleMeta[]> {
): Promise<MetaExtractionResult> {
const modules: Record<string, PalletMetadataLatest> = {}
const moduleEvents: Record<string, ExtractedVaraintData[]> = {}
const moduleCalls: Record<string, ExtractedVaraintData[]> = {}
const moduleTypes: Record<string, string[]> = {}

const metadata = originalMetadata.asLatest

const missingEvents: string[] = []
const missingCalls: string[] = []

for (const e of events) {
const [module, event, types] = extractEvent(metadata, e)
const name = module.name.toString()
modules[name] = module
pushToDictionary(moduleEvents, name, event)
pushToDictionary(moduleTypes, name, ...types)
const extractedEvent = extractEvent(metadata, e)
if (extractedEvent) {
const [module, event, types] = extractedEvent
const name = module.name.toString()
modules[name] = module
pushToDictionary(moduleEvents, name, event)
pushToDictionary(moduleTypes, name, ...types)
} else {
missingEvents.push(e)
}
}

for (const c of calls) {
const [module, call, types] = extractCall(metadata, c)
const name = module.name.toString()
modules[name] = module
pushToDictionary(moduleCalls, name, call)
pushToDictionary(moduleTypes, name, ...types)
const extractedCall = extractCall(metadata, c)
if (extractedCall) {
const [module, call, types] = extractedCall
const name = module.name.toString()
modules[name] = module
pushToDictionary(moduleCalls, name, call)
pushToDictionary(moduleTypes, name, ...types)
} else {
missingCalls.push(c)
}
}

return Object.keys(modules).map((name) => ({
module: modules[name],
events: moduleEvents[name],
calls: moduleCalls[name],
types: moduleTypes[name],
}))
return {
extracted: Object.keys(modules).map((name) => ({
module: modules[name],
events: moduleEvents[name],
calls: moduleCalls[name],
types: moduleTypes[name],
})),
missingEvents,
missingCalls,
}
}

function extractCall(
meta: MetadataLatest,
callName: string
): [PalletMetadataLatest, ExtractedVaraintData, string[]] {
): [PalletMetadataLatest, ExtractedVaraintData, string[]] | undefined {
const [moduleName, method] = callName.split('.')

const module = meta.pallets.find((v) => weakEquals(v.name, moduleName))

if (module === undefined || module.calls === undefined) {
throw new Error(`No metadata found for module ${moduleName}`)
return undefined // extrinsic module not found
}

let callVariant: Si1Variant | undefined
Expand All @@ -69,7 +86,7 @@ function extractCall(
}

if (callVariant === undefined) {
throw new Error(`No metadata found for the call ${callName}`)
return undefined // extrinsic call not found
}

return [
Expand All @@ -82,13 +99,13 @@ function extractCall(
function extractEvent(
meta: MetadataLatest,
eventName: string
): [PalletMetadataLatest, ExtractedVaraintData, string[]] {
): [PalletMetadataLatest, ExtractedVaraintData, string[]] | undefined {
const [moduleName, method] = eventName.split('.')

const module = meta.pallets.find((v) => weakEquals(v.name, moduleName))

if (module === undefined || module.events === undefined) {
throw new Error(`No metadata found for module ${moduleName}`)
return undefined // Event module not found
}

let eventVaraint: Si1Variant | undefined
Expand All @@ -101,7 +118,7 @@ function extractEvent(
}

if (eventVaraint === undefined) {
throw new Error(`No metadata found for the event ${eventName}`)
return undefined // Event variant not found
}

return [
Expand Down
6 changes: 6 additions & 0 deletions packages/hydra-typegen/src/metadata/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ export type ExtractedModuleMeta = {
types: string[]
}

export type MetaExtractionResult = {
extracted: ExtractedModuleMeta[]
missingEvents: string[]
missingCalls: string[]
}

export function weakEquals(s1: string | Text, s2: string | Text): boolean {
if (s1 === undefined || s2 === undefined) {
return false
Expand Down

0 comments on commit a70c88e

Please sign in to comment.