import { WebResource } from '@azure/ms-rest-js' ; import * as fse from 'fs-extra' ; import { OpenDialogOptions , ProgressLocation , Uri , window , workspace } from "vscode" ; import { IActionContext } from 'vscode-azureextensionui' ; import { ApisTreeItem , IApiTreeItemContext } from "../explorer/ApisTreeItem" ; import { ServiceTreeItem } from '../explorer/ServiceTreeItem' ; import { ext } from "../extensionVariables" ; import { localize } from "../localize" ; import { IOpenApiImportObject } from "../openApi/OpenApiImportObject" ; import { OpenApiParser } from '../openApi/OpenApiParser' ; import { apiUtil } from '../utils/apiUtil' ; import { processError } from '../utils/errorUtil' ; import { sendRequest } from '../utils/requestUtil' ; export async function importOpenApi ( context , node ? , importUsingLink = false ) { if ( ! node ) { const serviceNode = < ServiceTreeItem > await ext . tree . showTreeItemPicker ( ServiceTreeItem . contextValue , context ) ; node = serviceNode . apisTreeItem ; } let documentString ; if ( ! importUsingLink ) { const uris = await askDocument ( ) ; const uri = uris [ 0 ] ; const fileContent = await fse . readFile ( uri . fsPath ) ; documentString = fileContent . toString ( ) ; } else { const openApiLink = await askLink ( ) ; const webResource = new WebResource ( ) ; webResource . url = openApiLink ; webResource . method = "GET" ; documentString = await sendRequest ( webResource ) ; } if ( documentString !== undefined && documentString . trim ( ) !== "" ) { const documentJson = JSON . parse ( documentString ) ; const document = await parseDocument ( documentJson ) ; const apiName = await apiUtil . askApiName ( ) ; context . apiName = apiName ; context . document = document ; window . withProgress ( { location : ProgressLocation . Notification , title : localize ( "importingApi" , `Importing API '${ apiName }' to API Management service ${ node . root . serviceName } ...` ) , cancellable : false } , async ( ) => { return node ! . createChild ( context ) ; } ) . then ( async ( ) => { await node ! . refresh ( context ) ; window . showInformationMessage ( localize ( "importedApi" , `Imported API '${ apiName }' to API Management succesfully.` ) ) ; } ) ; } } async function askDocument ( ) { const openDialogOptions = { canSelectFiles : true , canSelectFolders : false , canSelectMany : false , openLabel : "Import" , filters : { JSON : [ "json" ] } } ; const rootPath = workspace . rootPath ; if ( rootPath ) { openDialogOptions . defaultUri = Uri . file ( rootPath ) ; } return await ext . ui . showOpenDialog ( openDialogOptions ) ; } async function askLink ( ) { const promptStr = localize ( 'apiLinkPrompt' , 'Specify a OpenAPI 2.0 or 3.0 link.' ) ; return ( await ext . ui . showInputBox ( { prompt : promptStr , placeHolder : 'https://' , validateInput : async ( value ) : Promise < string | undefined > => { value = value ? value . trim ( ) : '' ; const regexp = /http(s?):\/\/[\d\w][\d\w]*(\.[\d\w][\d\w-]*)*(:\d+)?(\/[\d\w-\.\?,'/\\\+&amp;=:%\$#_]*)?/ ; const isUrlValid = regexp . test ( value ) ; if ( ! isUrlValid ) { return localize ( "invalidOpenApiLink" , "Provide a valid link. example - https://petstore.swagger.io/v2/swagger.json" ) ; } else { return undefined ; } } } ) ) . trim ( ) ; } async function parseDocument ( documentJson ) { try { return await new OpenApiParser ( ) . parse ( documentJson ) ; } catch ( error ) { throw new Error ( processError ( error , localize ( "openApiJsonParseError" , "Could not parse the provided OpenAPI document." ) ) ) ; } }