updateAugmentTypes.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Adds Joystream types to /definitions/augment-types.ts allowing better api.createType TS support
  2. import common from '../common'
  3. import members from '../members'
  4. import council from '../council'
  5. import roles from '../roles'
  6. import forum from '../forum'
  7. import stake from '../stake'
  8. import mint from '../mint'
  9. import recurringRewards from '../recurring-rewards'
  10. import hiring from '../hiring'
  11. import versionedStore from '../versioned-store'
  12. import versionedStorePermissions from '../versioned-store/permissions'
  13. import contentWorkingGroup from '../content-working-group'
  14. import workingGroup from '../working-group'
  15. import discovery from '../discovery'
  16. import media from '../media'
  17. import proposals from '../proposals'
  18. import fs from 'fs'
  19. import path from 'path'
  20. const typesByModule = {
  21. 'common': common,
  22. 'members': members,
  23. 'council': council,
  24. 'roles': roles,
  25. 'forum': forum,
  26. 'stake': stake,
  27. 'mint': mint,
  28. 'recurring-rewards': recurringRewards,
  29. 'hiring': hiring,
  30. 'versioned-store': versionedStore,
  31. 'versioned-store/permissions': versionedStorePermissions,
  32. 'content-working-group': contentWorkingGroup,
  33. 'working-group': workingGroup,
  34. 'discovery': discovery,
  35. 'media': media,
  36. 'proposals': proposals,
  37. }
  38. type Imports = { [moduleName: string]: string[] }
  39. type AugmentTypes = { [typeName: string]: string }
  40. const imports: Imports = {}
  41. const augmentTypes: AugmentTypes = {}
  42. const populateFileByTemplateTag = (fileContent: string, tag: string, lines: string[]) => {
  43. const fileLines = fileContent.split('\n')
  44. const startIndex = fileLines.findIndex((line) => line.includes(`/** ${tag} **/`))
  45. const endIndex = fileLines.findIndex((line) => line.includes(`/** /${tag} **/`))
  46. if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
  47. throw new Error(`populateFileByTemplateTag: Invalid tag (${tag})`)
  48. }
  49. const whitespaceMatch = fileLines[startIndex].match(/^(\s)+/)
  50. const whitespace = whitespaceMatch ? whitespaceMatch[0] : ''
  51. fileLines.splice(startIndex + 1, endIndex - (startIndex + 1), ...lines.map((line) => `${whitespace}${line}`))
  52. return fileLines.join('\n')
  53. }
  54. const updateAugmentTypesFile = (filePath: string, imports: Imports, augmentTypes: AugmentTypes) => {
  55. let fileContent = fs.readFileSync(filePath).toString()
  56. fileContent = populateFileByTemplateTag(
  57. fileContent,
  58. 'CUSTOMIMPORTS',
  59. Object.entries(imports).map(
  60. ([moduleName, importStatements]) =>
  61. // import as to avoid namespace clashes
  62. `import { ${importStatements.join(', ')} } from '../${moduleName}'`
  63. )
  64. )
  65. fileContent = populateFileByTemplateTag(
  66. fileContent,
  67. 'CUSTOMTYPES',
  68. Object.entries(augmentTypes).map(([typeName, constructorName]) => `"${typeName}": ${constructorName};`)
  69. )
  70. fs.writeFileSync(filePath, fileContent)
  71. }
  72. const addAugmentTypes = (typeName: string, constructorName: string) => {
  73. augmentTypes[typeName] = constructorName
  74. augmentTypes[`Option<${typeName}>`] = `Option<${constructorName}>`
  75. augmentTypes[`Vec<${typeName}>`] = `Vec<${constructorName}>`
  76. }
  77. Object.entries(typesByModule).forEach(([moduleName, types]) => {
  78. Object.entries(types).forEach(([typeName, codecOrName]) => {
  79. if (typeof codecOrName === 'function') {
  80. const constructorName = codecOrName.name
  81. if (!constructorName) {
  82. throw new Error(`Codec constructor doesn't have a name: ${typeName}`)
  83. }
  84. const normalizedTypeName = typeName.replace(/[^A-Za-z0-9_]/g, '_')
  85. // Add "as" to avoid namespace clashes
  86. const importStatement = `${constructorName} as ${normalizedTypeName}`
  87. !imports[moduleName] ? (imports[moduleName] = [importStatement]) : imports[moduleName].push(importStatement)
  88. addAugmentTypes(typeName, normalizedTypeName)
  89. } else if (typeof codecOrName === 'string') {
  90. addAugmentTypes(typeName, codecOrName)
  91. }
  92. })
  93. })
  94. updateAugmentTypesFile(path.join(__dirname, '../definitions/augment-types.ts'), imports, augmentTypes)