async run()

in packages/qnamaker/src/commands/qnamaker/build.ts [45:192]


  async run() {
    try {
      const {flags}: any = this.parse(QnamakerBuild)

      // Luconfig overrides flags
      let files: string[] = []
      if (flags.qnaConfig) {
        const configFilePath = path.resolve(flags.qnaConfig)
        if (await fs.exists(configFilePath)) {
          const configObj = JSON.parse(await file.getContentFromFile(configFilePath))
          for (let prop of Object.keys(configObj)) {
            if (prop === 'models') {
              files = configObj.models.map((m: string) => path.isAbsolute(m) ? m : path.join(path.dirname(configFilePath), m))
            } else if (prop === 'out') {
              flags.out = path.isAbsolute(configObj.out) ? configObj.out : path.join(path.dirname(configFilePath), configObj.out)
            } else {
              flags[prop] = configObj[prop]
            }
          }
        }
      }

      // Flags override userConfig
      let qnamakerBuildFlags = Object.keys(QnamakerBuild.flags)

      let {inVal, subscriptionKey, botName, region, out, defaultCulture, fallbackLocale, suffix, dialog, force, log, endpoint, schema}
        = await processFlags(flags, qnamakerBuildFlags, this.config.configDir)

      flags.stdin = await this.readStdin()

      if (!flags.stdin && !inVal && files.length === 0) {
        throw new CLIError('Missing input. Please use stdin or pass a file or folder location with --in flag')
      }

      if (!subscriptionKey) {
        throw new CLIError('Missing qnamaker subscription key. Please pass subscription key with --subscriptionKey flag or specify via bf config:set:qnamaker --subscriptionKey.')
      }

      if (!botName) {
        throw new CLIError('Missing bot name. Please pass bot name with --botName flag or specify via --qnaConfig.')
      }

      if (dialog && dialog !== recognizerType.MULTILANGUAGE && dialog !== recognizerType.CROSSTRAINED) {
        throw new CLIError('Recognizer type specified by --dialog is not right. Please specify [multiLanguage|crosstrained]')
      }

      defaultCulture = defaultCulture && defaultCulture !== '' ? defaultCulture : 'en-us'
      region = region && region !== '' ? region : 'westus'
      suffix = suffix && suffix !== '' ? suffix : await username() || 'development'
      fallbackLocale = fallbackLocale && fallbackLocale !== '' ? fallbackLocale : 'en-us'

      endpoint = endpoint && endpoint !== '' ? endpoint : `https://${region}.api.cognitive.microsoft.com/qnamaker/v4.0`

      // create builder class
      const builder = new Builder((input: string) => {
        if (log) this.log(input)
      })

      let qnaContents: any[] = []
      
      if ((inVal && inVal !== '') || files.length > 0) {
        if (log) this.log('Loading files...\n')

        // get qna files from flags.in.
        if (inVal && inVal !== '') {
          const qnaFiles: string[] = await file.getLuFiles(inVal, true, fileExtEnum.QnAFile)
          files.push(...qnaFiles)
        }

        // de-dupe the files list
        files = [...new Set(files)]

        // load qna contents from qna files
        // load existing recognizers, multiRecogniers and settings or create default ones
        qnaContents = await builder.loadContents(files, {
          culture: defaultCulture,
          log: log
        })
      } else {
        // load qna content from stdin and create default recognizer, multiRecognier and settings
        if (log) this.log('Load qna content from stdin\n')
        const content = new Content(flags.stdin, new qnaOptions('stdin', true, defaultCulture, path.join(process.cwd(), 'stdin')))
        qnaContents.push(content)
      }

      // update or create and then publish qnamaker kb based on loaded resources
      if (log) this.log('Handling qnamaker knowledge bases...')
      const settingsContent = await builder.build(qnaContents, subscriptionKey, botName, {
        endpoint,
        suffix,
        region
      })

      // get endpointKeys
      const endpointKeysInfo = await builder.getEndpointKeys(subscriptionKey, endpoint)
      const endpointKeys: any = {
        "primaryEndpointKey": endpointKeysInfo.primaryEndpointKey,
        "secondaryEndpointKey": endpointKeysInfo.secondaryEndpointKey
      }

      // write dialog assets based on config
      if (out) {
        const outputFolder = path.resolve(out)
        if (dialog) {
          const dialogContents = await builder.generateDialogs(qnaContents, {
            fallbackLocale,
            schema,
            dialog
          })

          let writeDone = await builder.writeDialogAssets(dialogContents, {
            force,
            out: outputFolder
          })

          if (writeDone) {
            this.log(`Successfully wrote .dialog files to ${outputFolder}\n`)
          } else {
            this.log(`No changes to .dialog files in ${outputFolder}\n`)
          }
        }

        let writeDone = await builder.writeDialogAssets(settingsContent, {
          force,
          out: outputFolder
        })

        if (writeDone) {    
          this.log(`Successfully wrote settings file to ${outputFolder}\n`)      
          this.log('QnA knowledge base endpointKeys:')
          this.log(endpointKeys)
        } else {
          this.log(`No changes to settings file in ${outputFolder}\n`)
        }
      } else {
        this.log('The published knowledge base setting:')
        this.log(JSON.stringify(JSON.parse(settingsContent[0].content).qna, null, 4))
        this.log('\n')
        this.log('QnA knowledge base endpointKeys:')
        this.log(endpointKeys)
      }
    } catch (error) {
      if (error instanceof exception) {
        throw new CLIError(error.text)
      }
      throw error
    }
  }