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);
}
}
}
}