azure-devops-extension-sdk
Version:
Azure DevOps web extension JavaScript library.
300 lines (296 loc) • 11.3 kB
JavaScript
define(['exports', 'tslib', './XDM'], (function (exports, tslib, XDM) { 'use strict';
/**
* Web SDK version number. Can be specified in an extension's set of demands like: vss-sdk-version/3.0
*/
var sdkVersion = 4.0;
var global = window;
if (global._AzureDevOpsSDKVersion) {
console.error("The AzureDevOps SDK is already loaded. Only one version of this module can be loaded in a given document.");
}
global._AzureDevOpsSDKVersion = sdkVersion;
/**
* DevOps host level
*/
exports.HostType = void 0;
(function (HostType) {
HostType[HostType["Unknown"] = 0] = "Unknown";
/**
* The Deployment host
*/
HostType[HostType["Deployment"] = 1] = "Deployment";
/**
* The Enterprise host
*/
HostType[HostType["Enterprise"] = 2] = "Enterprise";
/**
* The organization host
*/
HostType[HostType["Organization"] = 4] = "Organization";
})(exports.HostType || (exports.HostType = {}));
var hostControlId = "DevOps.HostControl";
var serviceManagerId = "DevOps.ServiceManager";
var parentChannel = XDM.channelManager.addChannel(window.parent);
var teamContext;
var webContext;
var hostPageContext;
var extensionContext;
var initialConfiguration;
var initialContributionId;
var userContext;
var hostContext;
var themeElement;
var resolveReady;
var readyPromise = new Promise(function (resolve) {
resolveReady = resolve;
});
/**
* Register a method so that the host frame can invoke events
*/
function dispatchEvent(eventName, params) {
var global = window;
var evt;
if (typeof global.CustomEvent === "function") {
evt = new global.CustomEvent(eventName, params);
}
else {
params = params || { bubbles: false, cancelable: false };
evt = document.createEvent('CustomEvent');
evt.initCustomEvent(eventName, params.bubbles, params.cancelable, params.detail);
}
window.dispatchEvent(evt);
}
parentChannel.getObjectRegistry().register("DevOps.SdkClient", {
dispatchEvent: dispatchEvent
});
/**
* Initiates the handshake with the host window.
*
* @param options - Initialization options for the extension.
*/
function init(options) {
return new Promise(function (resolve) {
var initOptions = tslib.__assign(tslib.__assign({}, options), { sdkVersion: sdkVersion });
parentChannel.invokeRemoteMethod("initialHandshake", hostControlId, [initOptions]).then(function (handshakeData) {
var context = handshakeData.context;
hostPageContext = context.pageContext;
webContext = hostPageContext ? hostPageContext.webContext : undefined;
teamContext = webContext ? webContext.team : undefined;
initialConfiguration = handshakeData.initialConfig || {};
initialContributionId = handshakeData.contributionId;
extensionContext = context.extension;
userContext = context.user;
hostContext = context.host;
if (handshakeData.themeData) {
applyTheme(handshakeData.themeData);
window.addEventListener("themeChanged", function (ev) {
applyTheme(ev.detail.data);
});
}
resolveReady();
resolve();
});
});
}
/**
* Register a callback that gets called once the initial setup/handshake has completed.
* If the initial setup is already completed, the callback is invoked at the end of the current call stack.
*/
function ready() {
return tslib.__awaiter(this, void 0, void 0, function () {
return tslib.__generator(this, function (_a) {
return [2 /*return*/, readyPromise];
});
});
}
/**
* Notifies the host that the extension successfully loaded (stop showing the loading indicator)
*/
function notifyLoadSucceeded() {
return parentChannel.invokeRemoteMethod("notifyLoadSucceeded", hostControlId);
}
/**
* Notifies the host that the extension failed to load
*/
function notifyLoadFailed(e) {
return parentChannel.invokeRemoteMethod("notifyLoadFailed", hostControlId, [e]);
}
function getWaitForReadyError(method) {
return "Attempted to call ".concat(method, "() before init() was complete. Wait for init to complete or place within a ready() callback.");
}
/**
* Get the configuration data passed in the initial handshake from the parent frame
*/
function getConfiguration() {
if (!initialConfiguration) {
throw new Error(getWaitForReadyError("getConfiguration"));
}
return initialConfiguration;
}
/**
* Gets the information about the contribution that first caused this extension to load.
*/
function getContributionId() {
if (!initialContributionId) {
throw new Error(getWaitForReadyError("getContributionId"));
}
return initialContributionId;
}
/**
* Gets information about the current user
*/
function getUser() {
if (!userContext) {
throw new Error(getWaitForReadyError("getUser"));
}
return userContext;
}
/**
* Gets information about the host (i.e. an Azure DevOps organization) that the page is targeting
*/
function getHost() {
if (!hostContext) {
throw new Error(getWaitForReadyError("getHost"));
}
return hostContext;
}
/**
* Get the context about the extension that owns the content that is being hosted
*/
function getExtensionContext() {
if (!extensionContext) {
throw new Error(getWaitForReadyError("getExtensionContext"));
}
return extensionContext;
}
/**
* Gets information about the team that the page is targeting
*/
function getTeamContext() {
if (!teamContext) {
throw new Error(getWaitForReadyError("getTeamContext"));
}
return teamContext;
}
/**
* Get the context about the host page
*/
function getPageContext() {
if (!hostPageContext) {
throw new Error(getWaitForReadyError("getPageContext"));
}
return hostPageContext;
}
/**
* Get the context about the web
*/
function getWebContext() {
if (!webContext) {
throw new Error(getWaitForReadyError("getWebContext"));
}
return webContext;
}
/**
* Get the contribution with the given contribution id. The returned contribution has a method to get a registered object within that contribution.
*
* @param contributionId - Id of the contribution to get
*/
function getService(contributionId) {
return tslib.__awaiter(this, void 0, void 0, function () {
return tslib.__generator(this, function (_a) {
return [2 /*return*/, ready().then(function () {
return parentChannel.invokeRemoteMethod("getService", serviceManagerId, [contributionId]);
})];
});
});
}
/**
* Register an object (instance or factory method) that this extension exposes to the host frame.
*
* @param instanceId - unique id of the registered object
* @param instance - Either: (1) an object instance, or (2) a function that takes optional context data and returns an object instance.
*/
function register(instanceId, instance) {
parentChannel.getObjectRegistry().register(instanceId, instance);
}
/**
* Removes an object that this extension exposed to the host frame.
*
* @param instanceId - unique id of the registered object
*/
function unregister(instanceId) {
parentChannel.getObjectRegistry().unregister(instanceId);
}
/**
* Fetch an access token which will allow calls to be made to other DevOps services
*/
function getAccessToken() {
return tslib.__awaiter(this, void 0, void 0, function () {
return tslib.__generator(this, function (_a) {
return [2 /*return*/, parentChannel.invokeRemoteMethod("getAccessToken", hostControlId).then(function (tokenObj) { return tokenObj.token; })];
});
});
}
/**
* Fetch an token which can be used to identify the current user
*/
function getAppToken() {
return tslib.__awaiter(this, void 0, void 0, function () {
return tslib.__generator(this, function (_a) {
return [2 /*return*/, parentChannel.invokeRemoteMethod("getAppToken", hostControlId).then(function (tokenObj) { return tokenObj.token; })];
});
});
}
/**
* Requests the parent window to resize the container for this extension based on the current extension size.
*
* @param width - Optional width, defaults to scrollWidth
* @param height - Optional height, defaults to scrollHeight
*/
function resize(width, height) {
var body = document.body;
if (body) {
var newWidth = typeof width === "number" ? width : (body ? body.scrollWidth : undefined);
var newHeight = typeof height === "number" ? height : (body ? body.scrollHeight : undefined);
parentChannel.invokeRemoteMethod("resize", hostControlId, [newWidth, newHeight]);
}
}
/**
* Applies theme variables to the current document
*/
function applyTheme(themeData) {
if (!themeElement) {
themeElement = document.createElement("style");
themeElement.type = "text/css";
document.head.appendChild(themeElement);
}
var cssVariables = [];
if (themeData) {
for (var varName in themeData) {
cssVariables.push("--" + varName + ": " + themeData[varName]);
}
}
themeElement.innerText = ":root { " + cssVariables.join("; ") + " } body { color: var(--text-primary-color) }";
dispatchEvent("themeApplied", { detail: themeData });
}
exports.applyTheme = applyTheme;
exports.getAccessToken = getAccessToken;
exports.getAppToken = getAppToken;
exports.getConfiguration = getConfiguration;
exports.getContributionId = getContributionId;
exports.getExtensionContext = getExtensionContext;
exports.getHost = getHost;
exports.getPageContext = getPageContext;
exports.getService = getService;
exports.getTeamContext = getTeamContext;
exports.getUser = getUser;
exports.getWebContext = getWebContext;
exports.init = init;
exports.notifyLoadFailed = notifyLoadFailed;
exports.notifyLoadSucceeded = notifyLoadSucceeded;
exports.ready = ready;
exports.register = register;
exports.resize = resize;
exports.sdkVersion = sdkVersion;
exports.unregister = unregister;
}));
//# sourceMappingURL=SDK.js.map