createChannel.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
  2. import ChannelEntitySchema from '@joystream/cd-schemas/schemas/entities/ChannelEntity.schema.json'
  3. import { ChannelEntity } from '@joystream/cd-schemas/types/entities/ChannelEntity'
  4. import { InputParser } from '@joystream/cd-schemas'
  5. import { IOFlags, getInputJson, saveOutputJson } from '../../helpers/InputOutput'
  6. import { JSONSchema } from '@apidevtools/json-schema-ref-parser'
  7. import { JsonSchemaCustomPrompts, JsonSchemaPrompter } from '../../helpers/JsonSchemaPrompt'
  8. import { cli } from 'cli-ux'
  9. import { flags } from '@oclif/command'
  10. import _ from 'lodash'
  11. export default class CreateChannelCommand extends ContentDirectoryCommandBase {
  12. static description = 'Create a new channel on Joystream (requires a membership).'
  13. static flags = {
  14. ...IOFlags,
  15. confirm: flags.boolean({ char: 'y', name: 'confirm', required: false, description: 'Confirm the provided input' }),
  16. }
  17. async getExistingChannelHandles(): Promise<string[]> {
  18. cli.action.start('Fetching chain data...')
  19. const result = await Promise.all(
  20. (await this.entitiesByClassAndOwner('Channel'))
  21. .filter(([, c]) => c.supported_schemas.toArray().length)
  22. .map(async ([, channel]) => {
  23. const { handle } = await this.parseToEntityJson<ChannelEntity>(channel)
  24. return handle
  25. })
  26. )
  27. cli.action.stop()
  28. return result
  29. }
  30. async run() {
  31. const account = await this.getRequiredSelectedAccount()
  32. const memberId = await this.getRequiredMemberId()
  33. const actor = { Member: memberId }
  34. await this.requestAccountDecoding(account)
  35. const channelJsonSchema = (ChannelEntitySchema as unknown) as JSONSchema
  36. const { input, output, confirm } = this.parse(CreateChannelCommand).flags
  37. // Can potentially slow things down quite a bit
  38. const existingHandles = await this.getExistingChannelHandles()
  39. let inputJson = await getInputJson<ChannelEntity>(input, channelJsonSchema)
  40. if (!inputJson) {
  41. const customPrompts: JsonSchemaCustomPrompts = [
  42. [
  43. 'handle',
  44. { validate: (h) => (existingHandles.includes(h) ? 'Channel with such handle already exists' : true) },
  45. ],
  46. ['language', () => this.promptForEntityId('Choose channel language', 'Language', 'name')],
  47. ['isCensored', 'skip'],
  48. ]
  49. const prompter = new JsonSchemaPrompter<ChannelEntity>(channelJsonSchema, undefined, customPrompts)
  50. inputJson = await prompter.promptAll()
  51. }
  52. this.jsonPrettyPrint(JSON.stringify(inputJson))
  53. const confirmed =
  54. confirm || (await this.simplePrompt({ type: 'confirm', message: 'Do you confirm the provided input?' }))
  55. if (confirmed) {
  56. saveOutputJson(output, `${_.startCase(inputJson.handle)}Channel.json`, inputJson)
  57. const inputParser = InputParser.createWithKnownSchemas(this.getOriginalApi(), [
  58. {
  59. className: 'Channel',
  60. entries: [inputJson],
  61. },
  62. ])
  63. const operations = await inputParser.getEntityBatchOperations()
  64. await this.sendAndFollowNamedTx(account, 'contentDirectory', 'transaction', [actor, operations])
  65. }
  66. }
  67. }