import * as ko from "knockout"; import template from "./api-details.html"; import { Component, OnMounted, RuntimeComponent, OnDestroyed, Param } from "@paperbits/common/ko/decorators"; import { Router } from "@paperbits/common/routing"; import { ApiService } from "../../../../../services/apiService"; import { Api } from "../../../../../models/api"; import { RouteHelper } from "../../../../../routing/routeHelper"; @RuntimeComponent({ selector: "api-details" }) @Component({ selector: "api-details", template: template }) export class ApiDetails { public readonly api: ko.Observable; public readonly selectedApiName: ko.Observable; public readonly currentApiVersion: ko.Observable; public readonly versionApis: ko.ObservableArray; public readonly working: ko.Observable; public readonly downloadSelected: ko.Observable; constructor( private readonly apiService: ApiService, private readonly routeHelper: RouteHelper, private readonly router: Router, ) { this.changeLogPageUrl = ko.observable(); this.api = ko.observable(); this.selectedApiName = ko.observable(); this.versionApis = ko.observableArray([]); this.working = ko.observable(false); this.currentApiVersion = ko.observable(); this.downloadSelected = ko.observable(""); this.loadApi = this.loadApi.bind(this); } @Param() public changeLogPageUrl: ko.Observable; @OnMounted() public async initialize(): Promise { const apiName = this.routeHelper.getApiName(); if (!apiName) { return; } this.selectedApiName(apiName); await this.loadApi(apiName); this.router.addRouteChangeListener(this.onRouteChange); this.currentApiVersion.subscribe(this.onVersionChange); this.downloadSelected.subscribe(this.onDownloadChange); } private async onRouteChange(): Promise { const apiName = this.routeHelper.getApiName(); if (!apiName || apiName === this.selectedApiName()) { return; } this.selectedApiName(apiName); await this.loadApi(apiName); } public async loadApi(apiName: string): Promise { if (!apiName) { this.api(null); return; } this.working(true); const api = await this.apiService.getApi(`apis/${apiName}`); if (api.apiVersionSet && api.apiVersionSet.id) { const apis = await this.apiService.getApisInVersionSet(api.apiVersionSet.id); apis.forEach(x => x.apiVersion = x.apiVersion || "Original"); this.versionApis(apis || []); } else { this.versionApis([]); } this.currentApiVersion(api.name); this.api(api); this.working(false); } public async onDownloadChange(): Promise { const definitionType = this.downloadSelected(); if (!definitionType) { return; } if (this.api() && this.api().id) { let exportObject = await this.apiService.exportApi(this.api().id, definitionType); let fileName = this.api().name; let fileType = "application/json"; switch (definitionType) { case "wsdl": case "wadl": fileType = "text/xml"; fileName = `${fileName}.${definitionType}.xml`; break; case "openapi": // yaml 3.0 fileName = `${fileName}.yaml`; break; default: fileName = `${fileName}.json`; exportObject = JSON.stringify(exportObject, null, 4); break; } this.download(exportObject, fileName, fileType); } setTimeout(() => this.downloadSelected(""), 100); } private download(data: string, filename: string, type: string): void { const file = new Blob([data], { type: type }); if (window.navigator.msSaveOrOpenBlob) { // IE10+ window.navigator.msSaveOrOpenBlob(file, filename); } else { // Others const a = document.createElement("a"), url = URL.createObjectURL(file); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); setTimeout(() => { document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 0); } } private onVersionChange(selectedApiName: string): void { const apiName = this.routeHelper.getApiName(); if(apiName !== selectedApiName) { const apiUrl = this.routeHelper.getApiReferenceUrl(selectedApiName); this.router.navigateTo(apiUrl); } } public getChangeLogUrl(): string { return this.routeHelper.getApiReferenceUrl(this.selectedApiName(), this.changeLogPageUrl()); } @OnDestroyed() public dispose(): void { this.router.removeRouteChangeListener(this.onRouteChange); } }