async function exportBot()

in packages/MSBot/src/msbot-export-services.ts [102:312]


async function exportBot(config: BotConfiguration, folder: string, exportOptions?: Partial<ExportOptions>): Promise<BotRecipe> {
    let options = Object.assign({ download: true }, exportOptions);

    let recipe = new BotRecipe();

    await fsx.ensureDir(folder);

    let index = 0;
    for (let service of config.services) {
        index++;

        switch (service.type) {
            case ServiceTypes.Dispatch:
                {
                    await exportLuisService(service);

                    let dispatchResource: IDispatchResource = {
                        type: service.type,
                        id: service.id,
                        name: service.name,
                        serviceIds: (<IDispatchService>service).serviceIds
                    };
                    recipe.resources.push(dispatchResource);
                }
                break;
            case ServiceTypes.Luis:
                {
                    await exportLuisService(service);

                    let resource: IResource = {
                        type: service.type,
                        id: service.id,
                        name: service.name
                    };
                    recipe.resources.push(resource);
                }
                break;

            case ServiceTypes.QnA:
                {
                    let qnaService = <IQnAService>service;
                    if (options.download) {
                        let command = `qnamaker export kb --kbId ${qnaService.kbId} --environment prod --subscriptionKey ${qnaService.subscriptionKey} --hostname ${qnaService.hostname} --endpointKey ${qnaService.endpointKey}`;
                        if (options.progress) {
                            options.progress(service, command, index, config.services.length);
                        }
                        let json = '';
                        await spawnAsync(command, (stdout) => json += stdout, (stderr) => console.error(stderr));
                        // make sure it's json
                        JSON.parse(json);
                        await fsx.writeFile(folder + `/${qnaService.id}.qna`, json, { encoding: 'utf8' });
                    }
                    else {
                        if (options.progress) {
                            options.progress(service, '', index, config.services.length);
                        }
                    }

                    let resource: IResource = {
                        type: service.type,
                        id: service.id,
                        name: service.name
                    };
                    recipe.resources.push(resource);
                }
                break;

            case ServiceTypes.Endpoint:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    let endpointResource: IUrlResource = {
                        type: ServiceTypes.Endpoint,
                        id: service.id,
                        name: service.name,
                        url: (<IEndpointService>service).endpoint
                    };
                    recipe.resources.push(endpointResource);
                }
                break;

            case ServiceTypes.BlobStorage:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    let blobResource: IBlobResource = {
                        type: ServiceTypes.BlobStorage,
                        id: service.id,
                        name: service.name,
                        container: (<IBlobStorageService>service).container || ''
                    };
                    recipe.resources.push(blobResource);
                }
                break;

            case ServiceTypes.CosmosDB:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    let cosmosDBResource: ICosmosDBResource = {
                        type: ServiceTypes.CosmosDB,
                        id: service.id,
                        name: service.name,
                        database: (<ICosmosDBService>service).database,
                        collection: (<ICosmosDBService>service).collection,
                    };
                    recipe.resources.push(cosmosDBResource);
                }
                break;

            case ServiceTypes.File:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    let fileResource: IFileResource = {
                        type: ServiceTypes.File,
                        id: service.id,
                        name: service.name,
                        path: (<IFileService>service).path,
                    };
                    recipe.resources.push(fileResource);
                }
                break;

            case ServiceTypes.Generic:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    console.warn(`WARNING: Generic services cannot be cloned and all configuration data will be passed unchanged and unencrypted `);
                    let genericService = <IGenericService>service;
                    let genericResource: IGenericResource = {
                        type: ServiceTypes.Generic,
                        id: service.id,
                        name: service.name,
                        url: genericService.url,
                        configuration: genericService.configuration,
                    };
                    recipe.resources.push(genericResource);
                }
                break;

            case ServiceTypes.Bot:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }

                    let resource: IResource = {
                        type: service.type,
                        id: service.id,
                        name: service.name
                    };
                    recipe.resources.push(resource);
                }
                break;

            case ServiceTypes.AppInsights:
                {
                    if (options.progress) {
                        options.progress(service, '', index, config.services.length);
                    }
                    let resource: IResource = {
                        type: service.type,
                        id: service.id,
                        name: service.name
                    };
                    recipe.resources.push(resource);
                }
                break;

            default:
                if (options.progress) {
                    options.progress(service, '', index, config.services.length);
                }
                console.warn(`WARNING: Unknown service type [${service.type}].  This service will not be exported.`);
                break;
        }
    }
    await fsx.writeFile(folder + `/bot.recipe`, JSON.stringify(recipe, null, 2), { encoding: 'utf8' });
    return recipe;

    async function exportLuisService(service: IConnectedService) {
        let luisService = <ILuisService>service;
        if (options.download) {
            const luisAuthoringRegion = regionToLuisAuthoringRegionMap[luisService.region];
            let command = `luis export version --region ${luisAuthoringRegion} --appId ${luisService.appId} --authoringKey ${luisService.authoringKey} --versionId "${luisService.version}"`;
            if (options.progress) {
                options.progress(service, command, index, config.services.length);
            }
            let json = '';
            await spawnAsync(command, (stdout) => json += stdout, (stderr) => console.error(stderr));
            // make sure it's json
            try {
                JSON.parse(json);
            } catch(err) {
                throw new Error(`${err.message || err}\n${json}`);
            }
            await fsx.writeFile(folder + `/${luisService.id}.luis`, json, { encoding: 'utf8' });
        }
        else {
            if (options.progress) {
                options.progress(service, '', index, config.services.length);
            }
        }
    }
}