%PDF- %PDF-
Direktori : /proc/985914/root/data/old/home/stash/stash/atlassian-stash/static/stash/api/util/ |
Current File : //proc/985914/root/data/old/home/stash/stash/atlassian-stash/static/stash/api/util/navbuilder.js |
/** * The basic idea of the nav builder is to support a chain of method calls that roughly map to the structure and categorisation * of parts of Stash. This is referred to as the "Builder API" of navbuilder. * * E.g. `nav.project('foo').repo('bar').permissions()` will return a builder that can build the URL for the permissions page * of the repository with slug 'bar' of the project with key 'foo', while just `nav.project('foo')` will return a builder for a URL to * the project page for project 'foo'. * * At each point in the method chain, the returned object will support methods that return a builder * that maps to a concept at a lower level. * At most points, `.build()` may be called to build the URL to be used. There are a few places where no URL makes sense. * * The "Classes" listed in this module describe the methods that can be called from each step in the chain. E.g. * * ```javascript * var adminBuilder = navbuilder.admin(); // adminBuilder will be a {@linkcode stash/api/util/navbuilder.AdminBuilder} * var groupsBuilder = adminBuilder.groups(); // groupsBuilder will be a {@linkcode stash/api/util/navbuilder.GroupsBuilder} * ``` * * **Web Resource:** com.atlassian.stash.stash-web-api:navbuilder * * @example * require([ * 'stash/api/util/navbuilder', * 'stash/api/util/server' * ], function (navbuilder, server) { * server.rest({ * url: navbuilder.rest().projects().build() * }).then(doSomethingWithProjects); * }); * * @namespace stash/api/util/navbuilder */ define('stash/api/util/navbuilder', [ 'aui', 'jquery', 'lib/jsuri', 'underscore', 'util/deprecation', 'model/page-state', 'exports' ], /** * @exports stash/api/util/navbuilder */ function ( AJS, $, Uri, _, deprecate, pageState, exports ) { 'use strict'; /** * Encapsulates a URI path and params that make up a query string. * This class is immutable - all mutating operations return a new instance. * * NOTE: The PathAndQuery constructor is not exposed. * * @private * @class PathAndQuery * @memberof stash/api/util/navbuilder */ function PathAndQuery(components, params, anchor) { this.components = (_.isString(components) ? [components] : components) || []; this.params = params || {}; this.anchor = anchor || undefined; } /** * Returns the described URL as a string. The returned URL is relative to the Stash application's * context path root. E.g. If Stash is running at example.com/stash, the URL example.com/stash/a/b/c * will be returned as /a/b/c. * In client-side code, this version of the URL is rarely useful. stash/api/util/navbuilder.PathAndQuery.buildRelative is * likely to be what you want to use. * * @name stash/api/util/navbuilder.PathAndQuery#buildRelNoContext * @returns {string} */ PathAndQuery.prototype.buildRelNoContext = function() { var path = '/' + _.map(this.components, encodeURIComponent).join('/'); var params = _.reduce(this.params, function(memo, values, key) { if (!(_.isArray(values))) { values = [values]; } _.forEach(values, function(value) { memo.push({ key : key, value : value }); }); return memo; }, []); var query = _.map(params, function (param) { var encodedValue = encodeURIComponent(param.value); return encodeURIComponent(param.key) + (encodedValue ? '=' + encodedValue : ''); }).join("&"); return path + (query ? '?' + query : '') + (this.anchor ? '#' + this.anchor : ''); }; /** * Returns the described URL as a string. The returned URL is relative to the server root. E.g. * If Stash is running at example.com/stash, the URL example.com/stash/a/b/c * will be returned as /stash/a/b/c. * * stash/api/util/navbuilder.PathAndQuery.buildRelative * @returns {string} */ PathAndQuery.prototype.buildRelative = function () { return AJS.contextPath() + this.buildRelNoContext(); }; /** * Returns the described URL as a string. The returned URL is absolute. E.g. * If Stash is running at example.com/stash, the URL example.com/stash/a/b/c * will be returned as http://example.com/stash/a/b/c. * * stash/api/util/navbuilder.PathAndQuery.buildAbsolute * @returns {string} */ PathAndQuery.prototype.buildAbsolute = function () { return location.protocol + "//" + location.hostname + (location.port ? ':' + location.port : '') + this.buildRelative(); }; PathAndQuery.prototype.toString = function() { return this.buildRelative(); }; /** * Adds query parameters. If a map (object) is supplied, its properties are added to the parameters. * If a single string is supplied, it is added as a query parameter with no value. * * @name stash/api/util/navbuilder.PathAndQuery#addParams * @returns a new PathAndQuery object with the updated query params */ PathAndQuery.prototype.addParams = function (params) { var path = new PathAndQuery(this.components, _.extend({}, this.params)); if (_.isString(params)) { path.params[params] = ''; } else { if (params.hasOwnProperty("queryParams")) { path.params = _.extend(path.params, params.queryParams); } else if (!params.hasOwnProperty("urlMode")) { path.params = _.extend(path.params, params); }// todo - implement urlMode } return path; }; /** * Sets the document hash. If a hash has been set previously, it is overwritten * * @name stash/api/util/navbuilder.PathAndQuery#withFragment * @return a new PathAndQuery object with unchanged path and query string params, but with a new anchor */ PathAndQuery.prototype.withFragment = function (anchor) { return new PathAndQuery(this.components, this.params, anchor); }; /** * Pushes a new path component onto the list of path components. * * @name stash/api/util/navbuilder.PathAndQuery#pushComponents * @returns a new PathAndQuery object with the updated query params */ PathAndQuery.prototype.pushComponents = function() { var path = new PathAndQuery(this.components.slice(0), this.params); _.each(_.toArray(arguments).slice(0), function (component) { if (component !== '') { path.components.push(component); } }); return path; }; /** * A Builder of URLs. All methods in the Builder API will return a subclass of this and will include these methods. * * * NOTE: The Builder constructor is not exposed. A new Builder can be created through * {@linkcode stash/api/util/navbuilder.newBuilder}. * * @class Builder * @memberof stash/api/util/navbuilder */ /** * Returns a new builder for the current path with the properties supported by otherMethods. * Used after each call in the method chain to construct the next object in the chain and specify * exactly which calls are acceptable. * * @name stash/api/util/navbuilder.PathAndQuery#makeBuilder * @returns {stash/api/util/navbuilder.Builder} a new builder */ PathAndQuery.prototype.makeBuilder = function (otherMethods) { var path = this; return _.extend( /** @lends stash/api/util/navbuilder.Builder.prototype */ { /** * @private */ _path: function() { return path; }, /** * @returns {string} relative URL. See stash/api/util/navbuilder.PathAndQuery.buildRelative */ build: function() { return path.buildRelative(); }, /** * @returns {string} absolute URL. See stash/api/util/navbuilder.PathAndQuery.buildAbsolute */ buildAbsolute: function() { return path.buildAbsolute(); }, /** * @returns {stash/api/util/navbuilder.Uri} URI object formed by the builder. */ parse : function() { return parse(this.build()); }, /** * Sets query string parameters for the output URL of this builder. * @param {Object} params - A map of parameter name to value. Previous params with the same names will be overwritten. * @returns {stash/api/util/navbuilder.Builder} */ withParams: function(params) { //return a new builder with the same methods as the current builder but with added query parameters return path.addParams(params).makeBuilder(otherMethods); }, /** * Sets the hash (#) portion of the output URL for this builder. * @param {string} anchor - The hash portion of the URL. * @returns {stash/api/util/navbuilder.Builder} */ withFragment: function (anchor) { return path.withFragment(anchor).makeBuilder(otherMethods); }, /** * Return a new builder with more path components appended to the URL. * @param {...string} component - A path component to append. * @returns {stash/api/util/navbuilder.Builder} */ addPathComponents: function() { //return a new builder with the same methods as the current builder but with an augmented (new) path return path.pushComponents.apply(path, arguments).makeBuilder(otherMethods); } }, otherMethods); }; // id/slug/key helpers // If the input is a string, it's the key/slug/id. // Otherwise, if it exists, assume it's a project/repo/PR // Otherwise, use this pageState's project/repo/PR. /** * @private */ function getProjectKey(projectOrKey) { if (typeof(projectOrKey) === 'string') { return projectOrKey; } else if (!projectOrKey) { throw new Error(AJS.I18n.getText('stash.web.error.no.project')); } return projectOrKey.getKey ? projectOrKey.getKey() : projectOrKey.key; } /** * @private */ function getCurrentProject() { if (pageState.getProject()) { return pageState.getProject(); } throw new Error(AJS.I18n.getText('stash.web.error.no.project.context')); } /** * @private */ function getRepoSlug(repoOrSlug) { if (typeof(repoOrSlug) === 'string') { return repoOrSlug; } else if (!repoOrSlug) { throw new Error(AJS.I18n.getText('stash.web.error.no.repo')); } return repoOrSlug.getSlug ? repoOrSlug.getSlug() : repoOrSlug.slug; } /** * @private */ function getHookKey(hookOrKey) { if (typeof(hookOrKey) === 'string') { return hookOrKey; } else if (!hookOrKey) { throw new Error(AJS.I18n.getText('stash.web.error.no.hook.key')); } return hookOrKey.getDetails().getKey(); } /** * @private */ function getCurrentRepository() { if (pageState.getRepository()) { return pageState.getRepository(); } throw new Error(AJS.I18n.getText('stash.web.error.no.repo.context')); } /** * @private */ function getPullRequestId(prOrId) { if (prOrId !== 0 && !prOrId) { throw new Error(AJS.I18n.getText('stash.web.error.no.pull-request.id')); } if (typeof prOrId in {"string":1, "number": 1}) { return prOrId; } return prOrId.getId ? prOrId.getId() : prOrId.id; } /** * @private */ function getCurrentPullRequest() { if (pageState.getPullRequest()) { return pageState.getPullRequest(); } throw new Error(AJS.I18n.getText('stash.web.error.no.pull-request.context')); } /** * If the project is a personal project, use the /users/slug form otherwise go with /projects/KEY form * @private */ function maybeResolveAsUserPath(path) { var projectKey = path.components[1]; var userSlugPattern = /~(.*)/; var result = userSlugPattern.exec(projectKey); if (result) { return new PathAndQuery(['users', result[1].toLowerCase()]); } else { return path; } } /** * pull path components from an arguments object. We all .path('a', 'b') and .path(['a', 'b']) both. * @param {Array<string>} args * @private */ function componentsFromArguments(args) { //accept multiple args or accept a single arg that's an array to support .path('a', 'b') and .path(['a', 'b']) if (args.length === 1) { if (args[0] && args[0].getComponents) { // accept a Path object return args[0].getComponents(); } else if (args[0] && args[0].components) { // accept a JSON.PathJSON return args[0].components; } else if ($.isArray(args[0])) { return args[0]; } } return _.toArray(args); } //---------------------------------------- //Start of Builder API method chains //---------------------------------------- //--- Methods at the root of the chain --- /** * login-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class LoginBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.LoginBuilder} */ function login() { return new PathAndQuery('login').makeBuilder( /** * @lends stash/api/util/navbuilder.LoginBuilder.prototype */ { /** * @param {string} url - next URL to navigate to after login. * @returns {stash/api/util/navbuilder.Builder} */ next : _nextUrl }); } /** * @private */ function _nextUrl(url) { if (typeof url !== 'string') { var contextPath = AJS.contextPath(); var currentPath = location.pathname; //Make current path relative if context path exist if (contextPath.length > 0) { currentPath = currentPath.substring(currentPath.indexOf(contextPath) + contextPath.length); } url = currentPath + location.search + location.hash; } return this._path().addParams({ next: url }).makeBuilder(); } /** * Temporary resource-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class TmpBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.TmpBuilder} */ function tmp() { return new PathAndQuery('tmp').makeBuilder(/** * @lends stash/api/util/navbuilder.TmpBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ avatars: function tmpAvatars(){ return this._path().pushComponents('avatars').makeBuilder(); } }); } /** * Welcome page {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class WelcomeBuilder * @memberof stash/api/util/navbuilder * @deprecated */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.WelcomeBuilder} */ function welcome() { return gettingStarted(); } /** * Getting Started page {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class GettingStartedBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.GettingStartedBuilder} */ function gettingStarted() { return new PathAndQuery('getting-started').makeBuilder(/** * @lends stash/api/util/navbuilder.GettingStartedBuilder.prototype */ { /** * @param {string} url - next URL to navigate to after login. * @returns {stash/api/util/navbuilder.Builder} */ next : _nextUrl }); } /** * Admin-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class AdminBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.AdminBuilder} */ function admin() { return new PathAndQuery('admin').makeBuilder(/** * @lends stash/api/util/navbuilder.AdminBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.PermissionsBuilder} */ permissions: permissions, /** * @method * @returns {stash/api/util/navbuilder.AdminUsersBuilder} */ users: adminUsers, /** * @method * @returns {stash/api/util/navbuilder.GroupsBuilder} */ groups: groups, /** * @method * @returns {stash/api/util/navbuilder.LicenseBuilder} */ licensing: function licensing() { /** * License-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class LicenseBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('license').makeBuilder( /** * @lends stash/api/util/navbuilder.LicenseBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ edit: function editLicense() { return this._path().addParams({edit: ''}).makeBuilder(); } }); }, /** * @returns {stash/api/util/navbuilder.Builder} */ mailServer: function mailServer() { return this._path().pushComponents('mail-server').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ db : function adminDb() { return this._path().pushComponents('db').makeBuilder(); } }); } /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.Builder} */ function allProjects() { return new PathAndQuery('projects').makeBuilder(); } /** * {@linkcode stash/api/util/navbuilder.Builder} for the Stash-wide repository list. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class GlobalRepoBuilder * @memberof stash/api/util/navbuilder */ /** * @name allRepos * @method * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.GlobalRepoBuilder} */ function globalAllRepos() { return new PathAndQuery('repos').makeBuilder( /** * @lends stash/api/util/navbuilder.GlobalRepoBuilder */ { /** * @param {string} visibility - A filter to the shown list of repositories: "public" or "private". * @returns {stash/api/util/navbuilder.Builder} */ visibility: function allReposWithVisibility(visibility) { return this._path().addParams({'visibility': visibility}).makeBuilder(); } }); } /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.Builder} */ function captcha() { //Add a changing query param to ensure all browsers reload the image when refreshing it - some don't respect the HTTP headers return new PathAndQuery('captcha').addParams({'ts' : new Date().getTime().toString()}).makeBuilder(); } /** * Project-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class ProjectBuilder * @memberof stash/api/util/navbuilder */ /** * @param {string} projectKey - The key of the project to return a builder for. * @returns {stash/api/util/navbuilder.ProjectBuilder} */ function project(projectOrKey) { var path = new PathAndQuery(['projects', getProjectKey(projectOrKey)]); return maybeResolveAsUserPath(path).makeBuilder( /** * @lends stash/api/util/navbuilder.ProjectBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.Builder} */ allRepos: allRepos, /** * @method * @param {string} slug - The slug of the repository to return a builder for. * @returns {stash/api/util/navbuilder.RepositoryBuilder} */ repo: repo, /** * @returns {stash/api/util/navbuilder.Builder} */ createRepo: function createRepo() { return maybeResolveAsUserPath(this._path()).pushComponents('repos').addParams('create').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ settings: function projSettings() { return this._path().pushComponents('settings').makeBuilder(); }, /** * @method * @returns {stash/api/util/navbuilder.PermissionsBuilder} */ permissions: permissions, /** * @returns {stash/api/util/navbuilder.Builder} */ remove: function projDelete() { return this._path().makeBuilder(); }, /** * @method * @returns {stash/api/util/navbuilder.AdminUsersBuilder} */ users: adminUsers, /** * @method * @returns {stash/api/util/navbuilder.GroupsBuilder} */ groups: groups, /** * @param {number} [size] - A pixel value for the height and width of the avatar. Please use only pixel sizes referenced by the ADG at http://developer.atlassian.com/design. * @returns {stash/api/util/navbuilder.Builder} */ avatar: function projAvatar(size) { var builder = this._path().pushComponents('avatar.png'); if (size) { builder = builder.addParams({s: size}); } return builder.makeBuilder(); } }); } /** * Returns the project builder for the current page's project, if there is one. * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.ProjectBuilder} */ function currentProject() { return project(getCurrentProject()); } /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.Builder} */ function createProject() { return new PathAndQuery('projects').addParams('create').makeBuilder(); } /** * REST URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.RestBuilder} */ function rest(resourcePath) { resourcePath = resourcePath ? resourcePath : 'api'; return new PathAndQuery(['rest', resourcePath, 'latest']).makeBuilder( /** * @lends stash/api/util/navbuilder.RestBuilder.prototype */ { /** * @method * @param {string} key - The key of the project to form URLs for. * @returns {stash/api/util/navbuilder.RestProjectBuilder} */ project: restProj, /** * @method * @returns {stash/api/util/navbuilder.RestProjectBuilder} */ currentProject : restCurrentProject, /** * @method * @returns {stash/api/util/navbuilder.RestRepositoryBuilder} */ currentRepo: restCurrentRepo, /** * @method * @returns {stash/api/util/navbuilder.RestPullRequestBuilder} */ currentPullRequest: restCurrentPullRequest, /** * @returns {stash/api/util/navbuilder.RestMarkupBuilder} */ markup: function restMarkup() { /** * REST markup URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestMarkupBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('markup').makeBuilder( /** * @lends stash/api/util/navbuilder.RestMarkupBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ preview: function restMarkupPreview() { return this._path().pushComponents('preview').makeBuilder(); } }); }, /** * @returns {stash/api/util/navbuilder.RestProfileBuilder} */ profile: function restProfile() { /** * REST profile URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestProfileBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('profile').makeBuilder( /** * @lends stash/api/util/navbuilder.RestProfileBuilder.prototype */ { /** * REST recently viewed URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRecentlyViewedBuilder * @memberof stash/api/util/navbuilder */ /** * @returns {stash/api/util/navbuilder.RestRecentlyViewedBuilder} */ recent: function restProfileRecent() { return this._path().pushComponents('recent').makeBuilder( /** * @lends stash/api/util/navbuilder.RestRecentlyViewedBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ repos: function restProfileRecentRepos() { return this._path().pushComponents('repos').makeBuilder(); } }); } }); }, /** * @param {string} [userSlug] - If provided, a RestUserBuilder will be returned. Otherwise, a regular builder is returned. * @returns {stash/api/util/navbuilder.Builder|stash/api/util/navbuilder.RestUserBuilder} */ users: function restUsers(userSlug) { var builder = this._path().pushComponents('users'); if (userSlug) { /** * {@linkcode stash/api/util/navbuilder.Builder} for REST user URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestUserBuilder * @memberof stash/api/util/navbuilder */ return builder.pushComponents(userSlug).makeBuilder( /** * @lends stash/api/util/navbuilder.RestUserBuilder.prototype */ { /** * @method * @param {number} [size] - A pixel value for the height and width of the avatar. Please use only pixel sizes referenced by the ADG at http://developer.atlassian.com/design. * @returns {stash/api/util/navbuilder.Builder} */ avatar: userAvatar }); } return builder.makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ groups: function restGroups() { return this._path().pushComponents('groups').makeBuilder(); }, /** * @method * @returns {stash/api/util/navbuilder.RestHookPluginsBuilder} */ hooks: restHookPlugins, /** * @method * @returns {stash/api/util/navbuilder.Builder} */ allRepos: allRepos, /** * @returns {stash/api/util/navbuilder.RestAdminBuilder} */ admin: function restAdmin() { /** * Admin REST URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestAdminBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('admin').makeBuilder( /** * @lends stash/api/util/navbuilder.RestAdminBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ users: function restAdminUsers() { return this._path().pushComponents('users').makeBuilder(); } }); } }); } /** * Add-on-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class AddonBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.AddonBuilder} */ function addons() { return new PathAndQuery(['plugins', 'servlet', 'upm']).makeBuilder( /** * @lends stash/api/util/navbuilder.AddonBuilder.prototype */ { /** * Add-on-requests-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class AddonRequestsBuilder * @memberof stash/api/util/navbuilder */ /** * @returns {stash/api/util/navbuilder.AddonRequestsBuilder} */ requests: function addonsRequests() { return this._path().pushComponents('requests', 'popular').makeBuilder( /** * @lends stash/api/util/navbuilder.AddonRequestsBuilder.prototype */ { /** * @param {string} category - The category of requests to filter by. * @returns {stash/api/util/navbuilder.Builder} */ category: function(category) { return this._path().addParams({category: category}).makeBuilder(); } }); } }); } /** * {@linkcode stash/api/util/navbuilder.Builder} for creating plugin servlet URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PluginServletsBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.PluginServletsBuilder} */ function pluginServlets() { return new PathAndQuery(['plugins', 'servlet']).makeBuilder( /** * @lends stash/api/util/navbuilder.PluginServletsBuilder.prototype */ { /** * @param {...string} component - A path component under the servlet. * @returns {stash/api/util/navbuilder.Builder} */ path: function servletPath() { var path = this._path(); return path.pushComponents.apply(path, componentsFromArguments(arguments)).makeBuilder(); } }); } /** * permissions-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PermissionsBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function permissions() { return this._path().pushComponents('permissions').makeBuilder( /** * @lends stash/api/util/navbuilder.PermissionsBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.PermissionBuilder} */ permission: permission, /** * @method * @returns {stash/api/util/navbuilder.AdminUsersBuilder} */ users: adminUsers, /** * @method * @returns {stash/api/util/navbuilder.GroupsBuilder} */ groups: groups }); } /** * permission-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PermissionBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function permission(name) { return this._path().pushComponents(name).makeBuilder( /** * @lends stash/api/util/navbuilder.PermissionBuilder.prototype */ { /** * @returns stash/api/util/navbuilder.Builder */ users: function usersPerm() { return this._path().pushComponents('users').makeBuilder(); }, /** * @returns stash/api/util/navbuilder.Builder */ groups: function groupsPerm() { return this._path().pushComponents('groups').makeBuilder(); }, /** * @returns stash/api/util/navbuilder.Builder */ all: function allPerm() { return this._path().pushComponents('all').makeBuilder(); } }); } /** * Admin user-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class AdminUsersBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function adminUsers() { return this._path().pushComponents('users').makeBuilder( /** * @lends stash/api/util/navbuilder.AdminUsersBuilder.prototype */ { /** * @method * @returns stash/api/util/navbuilder.Builder */ create: createEntity, /** * @method * @param {string} name - The username of the user to delete. * @returns {stash/api/util/navbuilder.Builder} */ deleteUser: deleteEntity, /** * @param {string} name - The username of the user to read/write captcha info for. * @returns {stash/api/util/navbuilder.Builder} */ captcha: function adminCaptcha(name) { return this._path().pushComponents('captcha').addParams({name: name}).makeBuilder(); }, /** * @method * @param {string} name - The username of the user to view. * @returns {stash/api/util/navbuilder.Builder} */ view: viewEntity, /** * @method * @param {string} filter - A search string to filter by. * @returns {stash/api/util/navbuilder.Builder} */ filter: filterEntity, /** * @private * @param {string} deletedUser - The user who was just deleted. * @returns {stash/api/util/navbuilder.Builder} */ deleteSuccess: deleteSuccess, /** * @method * @returns {stash/api/util/navbuilder.PermissionsBuilder} */ permissions: permissions, /** * @method * @returns {stash/api/util/navbuilder.Builder} */ none: nonePerm }); } /** * Group-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class GroupsBuilder * @memberof stash/api/util/navbuilder */ /** * @private */ function groups() { return this._path().pushComponents('groups').makeBuilder( /** * @lends stash/api/util/navbuilder.GroupsBuilder.prototype */ { /** * @method * @returns stash/api/util/navbuilder.Builder */ create: createEntity, /** * @method * @param {string} name - The name of the group to delete. * @returns {stash/api/util/navbuilder.Builder} */ deleteGroup: deleteEntity, /** * @method * @param {string} name - The name of the group to view. * @returns {stash/api/util/navbuilder.Builder} */ view: viewEntity, /** * @method * @param {string} filter - A search string to filter by. * @returns {stash/api/util/navbuilder.Builder} */ filter: filterEntity, /** * @private * @param {string} deletedUser - The user who was just deleted. * @returns {stash/api/util/navbuilder.Builder} */ deleteSuccess: deleteSuccess, /** * @method * @returns {stash/api/util/navbuilder.PermissionsBuilder} */ permissions: permissions, /** * @method * @returns {stash/api/util/navbuilder.Builder} */ none: nonePerm }); } //--- Methods further down the chain --- /** * Documented at parent builders * @private */ function nonePerm() { return this._path().pushComponents('none').makeBuilder(); } /** * Documented at parent builders * @private */ function allRepos() { return maybeResolveAsUserPath(this._path()).pushComponents('repos').makeBuilder(); } /** * User-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class UserBuilder * @memberof stash/api/util/navbuilder */ /** * @memberof stash/api/util/navbuilder * @param {string} userSlug - The URL-safe slug for a user. * @returns {stash/api/util/navbuilder.UserBuilder} */ function user(userSlug) { return new PathAndQuery(['users', userSlug]).makeBuilder( /** * @lends stash/api/util/navbuilder.UserBuilder.prototype */ { /** * @method * @param {number} [size] - A pixel value for the height and width of the avatar. Please use only pixel sizes referenced by the ADG at http://developer.atlassian.com/design. * @returns {stash/api/util/navbuilder.Builder} */ avatar: userAvatar }); } /** * Documented at parent builders * @private */ function createEntity() { return this._path().addParams({create: ''}).makeBuilder(); } /** * Documented at parent builders * @private */ function deleteEntity(name) { // delete is a reserved keyword return this._path().addParams({name: name}).makeBuilder(); } /** * Documented at parent builds * @private */ function viewEntity(name) { return this._path().pushComponents('view').addParams({name: name}).makeBuilder(); } /** * Documented at parent builds * @private */ function filterEntity(filterValue) { return this._path().addParams({filter: filterValue}).makeBuilder(); } /** * Documented at parent builds * @private */ function deleteSuccess(name) { return this._path().addParams({deleted: name}).makeBuilder(); } /** * Repository-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RepositoryBuilder * @memberof stash/api/util/navbuilder */ /** * @param {string} slug - The slug of the repository to return a builder for. * @returns {stash/api/util/navbuilder.RepositoryBuilder} */ function repo(repoOrSlug) { return maybeResolveAsUserPath(this._path()).pushComponents('repos', getRepoSlug(repoOrSlug)).makeBuilder( /** * @lends stash/api/util/navbuilder.RepositoryBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.RepoBrowseBuilder} */ browse: function repoBrowse() { return this._path().pushComponents('browse').makeBuilder(RepoBrowseBuilderMethods); }, /** * @method * @param {string|JSON.FileChangeJSON} pathOrFileChange - A string to use as the file path to diff, or a FileChangeJSON to specify the revisions and paths together. * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ diff : repoDiff, /** * @returns {stash/api/util/navbuilder.CommitsBuilder} */ commits: function repoCommits() { /** * Commits list-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class CommitsBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('commits').makeBuilder( /** * @lends stash/api/util/navbuilder.CommitsBuilder.prototype */ { /** * @param {string} [until] - The ID of the ref to use as the tip of the commit list. Omit to use the default branch's HEAD. * @returns {stash/api/util/navbuilder.Builder} */ until: function repoCommitsUntil(until) { var builder = this._path(); if (until && !until.isDefault) { if (typeof until !== 'string') { until = until.displayId || until; } builder = builder.addParams({ until: until }); } return builder.makeBuilder(); } }); }, /** * @param {string} [baseRef] - The ID of the ref to use as the base branch for comparisons. * @returns {stash/api/util/navbuilder.Builder} */ branches: function repoBranches(baseRef) { var builder = this._path().pushComponents('branches'); if (baseRef && !baseRef.isDefault) { if (typeof baseRef !== 'string') { baseRef = baseRef.displayId || baseRef.id || baseRef; } builder = builder.addParams({ base: baseRef }); } return builder.makeBuilder(); }, /** * @method * @param {string} commitId - The ID of the commit to form URLs for. * @returns {stash/api/util/navbuilder.CommitBuilder} */ changeset: repoCommit, /** * @method * @param {string} commitId - The ID of the commit to form URLs for. * @returns {stash/api/util/navbuilder.CommitBuilder} */ commit: repoCommit, /** * {@linkcode stash/api/util/navbuilder.Builder} for branch comparison URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class BranchCompareBuilder * @extends stash/api/util/navbuilder.SourceTargetBuilder * @memberof stash/api/util/navbuilder */ /** * @returns {stash/api/util/navbuilder.BranchCompareBuilder} */ compare: function repoCompare() { function comparePath(path) { return function() { //noinspection JSPotentiallyInvalidUsageOfThis return this._path().pushComponents(path).makeBuilder(secondBranchParamBuilders); }; } return this._path().pushComponents('compare').makeBuilder(_.extend( /** * @lends stash/api/util/navbuilder.BranchCompareBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ commits : comparePath('commits'), /** * @method * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ diff: comparePath('diff') }, compareDefaultBranchParamBuilders)); }, /** * @returns {stash/api/util/navbuilder.Builder} */ settings: function repoSettings() { return this._path().pushComponents('settings').makeBuilder(); }, /** * @method * @returns {stash/api/util/navbuilder.PermissionsBuilder} */ permissions: permissions, /** * @method * @returns {stash/api/util/navbuilder.Builder} */ hooks: repoHooks, /** * @param {string} scm - The kind of SCM (e.g. git) for this repo. * @returns {stash/api/util/navbuilder.Builder} */ clone: function repoClone(scm) { var path = this._path(), projectKey = path.components[1].toLowerCase(), repoSlug = path.components[3].toLowerCase(); if (path.components[0] === 'users') { projectKey = "~" + projectKey; } return new PathAndQuery(['scm', projectKey, repoSlug + '.' + scm], path.params).makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ fork: function repoFork() { return this._path().addParams('fork').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ allPullRequests: function allPullRequests() { return this._path().pushComponents('pull-requests').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ createPullRequest: function createPullRequest() { return this._path().pushComponents('pull-requests').addParams('create').makeBuilder(secondBranchParamBuilders); }, /** * @method * @param {number} pullRequestId - The ID of a pull request to build URLs for. * @returns {stash/api/util/navbuilder.PullRequestBuilder} */ pullRequest: pullRequest, /** * @returns {stash/api/util/navbuilder.Builder} */ attachments: function repoAttachments() { return this._path().pushComponents('attachments').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ sizes : function repoSizes() { return this._path().pushComponents('sizes').makeBuilder(); }, /** * Documented under Builder * @private */ build: function () { return this._path().pushComponents('browse').toString(); //the stem /projects/PROJ/repos is different to the path needed if build() is called } }); } /** * Returns the builder for the current page's repository, if there is one. * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.RepositoryBuilder} */ function currentRepo() { return currentProject().repo(pageState.getRepository()); } /** * {@linkcode stash/api/util/navbuilder.Builder} to select which commits are involved and whether to retrieve the * "raw" version when browsing files within Stash. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RevisionSpecifyingBuilder * @memberof stash/api/util/navbuilder */ var RevisionRangeSpecifyingBuilderMethods = /** * @lends stash/api/util/navbuilder.RevisionSpecifyingBuilder.prototype */ { /** * Set the "at" revision for browsing. This revision describes the branch head whose history is being viewed. * This is _not_ the actual revision at which to view the file (but it is used as fallback for that purpose). * The main purpose of this parameter is to determine which branch to use as "current" in the page layout. * * @param {string} refId - The ID of a ref or commit in the SCM whose history to browse. * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ at : function repoBrowsePathAt(refId) { var builder = this._path(); if (refId) { if (typeof refId !== 'string') { refId = refId.displayId || refId; } builder = builder.addParams({ at: refId }); } return builder.makeBuilder(RevisionRangeSpecifyingBuilderMethods); }, /** * Set the "until" commit for browsing. This commit describes the actual revision at which you want to view file content. * @param {string} commitId - The ID of a commit in the SCM at which to browse. * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ until : function repoBrowsePathUntil(commitId) { return this._path().addParams({until: commitId}).makeBuilder(RevisionRangeSpecifyingBuilderMethods); }, /** * Describes that you want to view the "raw"/downloadable version of the file, not the HTML version * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ raw : function repoBrowsePathRaw() { return this._path().addParams({raw: ''}).makeBuilder(RevisionRangeSpecifyingBuilderMethods); } }; /** * {@linkcode stash/api/util/navbuilder.Builder} to select where to browse files. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RepoBrowseBuilder * @memberof stash/api/util/navbuilder */ var RepoBrowseBuilderMethods = /** * @lends stash/api/util/navbuilder.RepoBrowseBuilder.prototype */ { /** * @param {...string} components - path components for the file/directory at which to browse. * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ path : function repoBrowsePath() { var path = this._path(); return path.pushComponents.apply(path, componentsFromArguments(arguments)).makeBuilder(RevisionRangeSpecifyingBuilderMethods); }, /** * Set the "at" revision for browsing. This revision describes the branch head whose history is being viewed. * This is _not_ the actual revision at which to view the file (but it is used as fallback for that purpose). * The main purpose of this parameter is to determine which branch to use as "current" in the page layout. * * @method * @param {string} refId - The ID of a ref or commit in the SCM whose history to browse. * @returns {stash/api/util/navbuilder.RevisionSpecifyingBuilder} */ at : RevisionRangeSpecifyingBuilderMethods.at }; /** * Documented at parent builders * @private */ function repoDiff(fileChangeOrPath) { var builder = this._path(), path; // Duck-type as adding FileChange as a dependency on navbuilder causes too much recursion in dependency stack var isFileChange = ( fileChangeOrPath.getCommitRange && fileChangeOrPath.getPath && fileChangeOrPath.getSrcPath ); var isFileChangeJSON = ( fileChangeOrPath.commitRange && fileChangeOrPath.path && fileChangeOrPath.srcPath ); var fileChangeJSON; if (isFileChange || isFileChangeJSON) { fileChangeJSON = fileChangeOrPath.toJSON ? fileChangeOrPath.toJSON() : fileChangeOrPath; } if (fileChangeJSON) { var commitRangeJSON = fileChangeJSON.commitRange; path = fileChangeJSON.path; if (commitRangeJSON.pullRequest) { builder = builder.pushComponents('pull-requests', commitRangeJSON.pullRequest.id); } else { // Use of extend will root out undefined props builder = builder.addParams($.extend({}, { until: commitRangeJSON.untilRevision && commitRangeJSON.untilRevision.id || undefined, since: commitRangeJSON.sinceRevision && commitRangeJSON.sinceRevision.id || undefined })); } } else { path = fileChangeOrPath; } builder = builder.pushComponents('diff'); // need to do this separately otherwise we don't have the correct context for the next apply invocation. builder = builder.pushComponents.apply(builder, path && componentsFromArguments([path])); builder = builder.addParams($.extend({}, { // extend removes undefined properties srcPath: fileChangeJSON && fileChangeJSON.srcPath || undefined })); return builder.makeBuilder(RevisionRangeSpecifyingBuilderMethods); } /** * {@linkcode stash/api/util/navbuilder.Builder} for commit-related URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class CommitBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function repoCommit(commitId) { // commitId must be SHA1 hash return this._path().pushComponents('commits', commitId).makeBuilder( /** * @lends stash/api/util/navbuilder.CommitBuilder.prototype */ { /** * @param {number} commentId - The commit comment to form URLs for. * @returns {stash/api/util/navbuilder.Builder} */ comment: function repoCommitComment(commentId) { return this._path().addParams({ commentId: commentId }).makeBuilder(); } }); } /** * Documented at parent builders * @private */ function repoHooks() { return this._path().pushComponents('settings', 'hooks').makeBuilder(); } //--- Pull Request Methods --- /** * {@linkcode stash/api/util/navbuilder.Builder} for URLs that have a source and target branch. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class SourceTargetBuilder * @memberof stash/api/util/navbuilder */ var secondBranchParamBuilders = /** * @lends stash/api/util/navbuilder.SourceTargetBuilder.prototype */ { /** * The builder that will be returned from branch setter methods * @private */ _builder: null, /** * @param {string} sourceBranchRefId - The refId for the source branch. * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ sourceBranch: function sourceBranch(sourceBranchRefId) { return this._path().addParams({sourceBranch: sourceBranchRefId}).makeBuilder(this._builder); }, /** * @param {string} targetBranchRefId - The refId for the target branch. * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ targetBranch: function targetBranch(targetBranchRefId) { return this._path().addParams({targetBranch: targetBranchRefId}).makeBuilder(this._builder); }, /** * @param {string} id - The ID (not slug) for the target repository (containing the target branch). * @returns {stash/api/util/navbuilder.SourceTargetBuilder} */ targetRepo: function targetRepo(id) { return this._path().addParams({targetRepoId: id}).makeBuilder(this._builder); } }; // set the builder secondBranchParamBuilders._builder = secondBranchParamBuilders; var compareDefaultBranchParamBuilders = _.extend({ /** * Documented under Builder * @private */ build: function () { return this._path().pushComponents('commits').toString(); //the stem /projects/PROJ/repos is different to the path needed if build() is called } }, secondBranchParamBuilders); // set the builder compareDefaultBranchParamBuilders._builder = compareDefaultBranchParamBuilders; /** * Pull request-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PullRequestBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builder * @private */ function pullRequest(prOrId) { return this._path().pushComponents('pull-requests', getPullRequestId(prOrId)).makeBuilder( /** * @lends stash/api/util/navbuilder.PullRequestBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ unwatch: function pullRequestUnwatch() { return this._path().pushComponents('unwatch').makeBuilder(); }, /** * @param {string} [commitId] - The ID of a commit in the pull request. * @returns {stash/api/util/navbuilder.Builder} */ changeset: function pullRequestChangeset(commitId) { //Unlike repository changesets, ref names like "master" are not supported here. As a result, there is //no need to do all the path gyrations repoChangeset does return this._path().pushComponents('commits', commitId).makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.PullRequestOverviewBuilder} */ overview: function pullRequestOverview() { /** * Pull request overview URL {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PullRequestOverviewBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('overview').makeBuilder( /** * @lends stash/api/util/navbuilder.PullRequestOverviewBuilder.prototype */ { /** * @param {number} commentId - The ID of a comment to view within the overview activity. * @returns {stash/api/util/navbuilder.Builder} */ comment: function pullRequestComment(commentId){ return this._path().addParams({commentId: commentId}).makeBuilder(); } }); }, /** * @returns {stash/api/util/navbuilder.PullRequestDiffBuilder} */ diff: function pullRequestDiff() { /** * Pull request diff-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class PullRequestDiffBuilder * @memberof stash/api/util/navbuilder */ return this._path().pushComponents('diff').makeBuilder( /** * @lends stash/api/util/navbuilder.PullRequestDiffBuilder.prototype */ { /** * @param {string} diffChangePath - The filepath to view the change of, within the PR. * @returns {stash/api/util/navbuilder.Builder} */ change: function (diffChangePath) { return this._path().withFragment(diffChangePath).makeBuilder(); } }); }, /** * @returns {stash/api/util/navbuilder.Builder} */ commits: function pullRequestCommits(){ return this._path().pushComponents('commits').makeBuilder(); }, /** * Documented on Builder * @private */ build: function () { return this._path().pushComponents('overview').toString(); //Default to overview view } }); } /** * Returns the builder for the current page's pull request, if there is one. * @memberof stash/api/util/navbuilder * @returns {stash/api/util/navbuilder.PullRequestBuilder} */ function currentPullRequest() { return currentRepo.call(this).pullRequest(getCurrentPullRequest()); } /** * REST project-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestProjectBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builder * @private */ function restProj(projectOrKey) { var key = getProjectKey(projectOrKey); return this._path().pushComponents('projects', key).makeBuilder( /** * @lends stash/api/util/navbuilder.RestProjectBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ allRepos: function restAllRepos() { return this._path().pushComponents('repos').makeBuilder(); }, /** * @method * @param {string} slug - The slug of the repo to form URLs for. * @returns {stash/api/util/navbuilder.RestRepositoryBuilder} */ repo: restRepo, /** * @method * @returns {stash/api/util/navbuilder.RestProjectPermissionsBuilder} */ permissions: restProjPermissions }); } /** * Documented at parent builder * @private */ function restCurrentProject() { return restProj.call(this, getCurrentProject()); } /** * Documented at parent builder * @private */ function restCurrentRepo() { return restCurrentProject.call(this).repo(getCurrentRepository()); } /** * REST repository hook-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestHookBuilder * @memberof stash/api/util/navbuilder */ /** * @param {string} hookKey - The key of the hook you want to build URLs for. * @returns {stash/api/util/navbuilder.RestHookBuilder} */ function restHook(hookOrKey) { var hookKey = getHookKey(hookOrKey); return this._path().pushComponents('settings').pushComponents('hooks', hookKey).makeBuilder( /** * @lends stash/api/util/navbuilder.RestHookBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ enabled: function hookEnabled() { return this._path().pushComponents('enabled').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ settings: function hookSettings() { return this._path().pushComponents('settings').makeBuilder(); } }); } /** * REST repository-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRepositoryBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function restRepo(repoOrSlug) { var slug = getRepoSlug(repoOrSlug); return this._path().pushComponents('repos', slug).makeBuilder( /** * @lends stash/api/util/navbuilder.RestRepositoryBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ tags: function restRepoTags() { return this._path().pushComponents('tags').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ branches: function restRepoBranches() { return this._path().pushComponents('branches').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ commits : function restRepoAllCommits() { return this._path().pushComponents('commits').makeBuilder(); }, /** * @method * @param {string|JSON.CommitRangeJSON} commitIdOrCommitRange * @returns {stash/api/util/navbuilder.RestCommitBuilder} */ commit: restRepoCommit, /** * @returns {stash/api/util/navbuilder.RestRepoCompareBuilder} */ compare : function restRepoCompare() { /** * REST ref comparison-related {@linkcode stash/api/util/navbuilder.Builder}. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRepoCompareBuilder * @memberof stash/api/util/navbuilder */ var compareParam = function(name, value) { var params = {}; params[name] = value; return this._path().addParams(params).makeBuilder(paramsBuilder); }; var comparePath = function(path) { return function() { return this._path().pushComponents(path).makeBuilder(paramsBuilder); }; }; /** * {@linkcode stash/api/util/navbuilder.Builder} for REST ref comparison-related params. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRepoCompareParamBuilder * @memberof stash/api/util/navbuilder */ var paramsBuilder = /** * @lends stash/api/util/navbuilder.RestRepoCompareParamBuilder.prototype */ { /** * @method * @param {string} refId - The from/until ref's ID for comparison. * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ from: _.partial(compareParam, 'from'), /** * @method * @param {string} refId - The to/since ref's ID for comparison. * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ to: _.partial(compareParam, 'to'), /** * @method * @param {string} repoId - The ID of the repository containing the from/until ref. * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ fromRepo: _.partial(compareParam, 'fromRepo') }; return this._path().pushComponents('compare').makeBuilder( /** * @lends stash/api/util/navbuilder.RestRepoCompareBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ changes : comparePath('changes'), /** * @method * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ commits : comparePath('commits'), /** * @method * @param {JSON.FileChangeJSON} fileChange - The fileChange object describing the files to be compared. * @returns {stash/api/util/navbuilder.RestRepoCompareParamBuilder} */ diff : function(fileChange) { return restDiffInternal.call(this, fileChange, paramsBuilder); } }); }, /** * @method * @param {string|JSON.CommitRangeJSON} commitIdOrCommitRange * @returns {stash/api/util/navbuilder.RestCommitBuilder} */ changeset: restRepoCommit, /** * @param {JSON.CommitRangeJSON} commitRange - describe the range of commits to get changes between. * @returns {stash/api/util/navbuilder.RestCommitPathBuilder|stash/api/util/navbuilder.Builder} */ changes: function routeChangesRequest (commitRange) { commitRange = commitRange.toJSON ? commitRange.toJSON() : commitRange; if (commitRange.pullRequest) { return this.pullRequest(commitRange.pullRequest).changes(); } else if (commitRange.untilRevision) { return this.changeset(commitRange).changes(); } else { throw new Error("A valid commit-range is required to retrieve changes"); } }, /** * @returns {stash/api/util/navbuilder.RepoBrowseBuilder} */ browse: function restRepoBrowse() { return this._path().pushComponents('browse').makeBuilder(RepoBrowseBuilderMethods); }, /** * @method * @returns {stash/api/util/navbuilder.RestRepoFilesListBuilder} */ files: restRepoFind, /** * @returns {stash/api/util/navbuilder.Builder} */ related : function restRepoRelated() { return this._path().pushComponents('related').makeBuilder(); }, /** * @method * @param {number} id - The ID of a pull request. * @returns {stash/api/util/navbuilder.RestPullRequestBuilder} */ pullRequest : restPullRequest, /** * @returns {stash/api/util/navbuilder.Builder} */ allPullRequests : function restAllPullRequests() { return this._path().pushComponents('pull-requests').makeBuilder(); }, /** * @method * @returns {stash/api/util/navbuilder.Builder} */ hooks : repoHooks, /** * @method * @param {string} hookKey - The key of the hook to form URLs about. * @returns {stash/api/util/navbuilder.RestHookBuilder} */ hook : restHook }); } /** * {@linkcode stash/api/util/navbuilder.Builder} for REST pull request info. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestPullRequestBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function restPullRequest(prOrId) { var id = getPullRequestId(prOrId); return this._path().pushComponents('pull-requests', id).makeBuilder( /** * @lends stash/api/util/navbuilder.RestPullRequestBuilder.prototype */ { /** * @returns {stash/api/util/navbuilder.Builder} */ activities : function() { return this._path().pushComponents('activities').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ approve: function restApprove() { return this._path().pushComponents('approve').makeBuilder(); }, /** * @param {number} id - The ID of the comment to generate URLs for. * @returns {stash/api/util/navbuilder.Builder} */ comment : function restComment(id) { return this._path().pushComponents('comments', id).makeBuilder({ comment : restComment /* TODO is this legit?!?!?! Not documenting it for now... */ }); }, /** * @returns {stash/api/util/navbuilder.Builder} */ comments : function() { return this._path().pushComponents('comments').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ changes: function restPullRequestChanges(){ return this._path().pushComponents('changes').makeBuilder(); }, /** * @method * @param {JSON.FileChangeJSON} fileChange * @returns {stash/api/util/navbuilder.Builder} */ diff: restDiff, /** * @returns {stash/api/util/navbuilder.Builder} */ watch: function restPullRequestWatch() { return this._path().pushComponents('watch').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ merge: function restMerge() { return this._path().pushComponents('merge').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ reopen: function restReopen() { return this._path().pushComponents('reopen').makeBuilder(); }, /** * @returns {stash/api/util/navbuilder.Builder} */ decline: function restDecline() { return this._path().pushComponents('decline').makeBuilder(); } }); } /** * Documented at parent builders * @private */ function restCurrentPullRequest() { return restCurrentRepo.call(this).pullRequest(getCurrentPullRequest()); } /** * {@linkcode stash/api/util/navbuilder.Builder} for REST commit URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestCommitBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function restRepoCommit(commitIdOrCommitRange) { commitIdOrCommitRange = commitIdOrCommitRange.toJSON ?commitIdOrCommitRange.toJSON() : commitIdOrCommitRange; var path = this._path().pushComponents('commits'); if (typeof commitIdOrCommitRange === 'string') { path = path.pushComponents(commitIdOrCommitRange); } else if (commitIdOrCommitRange.untilRevision) { path = path.pushComponents(commitIdOrCommitRange.untilRevision.id); var sinceId = commitIdOrCommitRange.sinceRevision && commitIdOrCommitRange.sinceRevision.id; if (sinceId) { path = path.addParams({ since: sinceId }); } } else { throw new Error(AJS.I18n.getText('stash.web.error.no.commit.or.commitRange')); } return path.makeBuilder( /** * @lends stash/api/util/navbuilder.RestCommitBuilder.prototype */ { /** * @method * @param {JSON.FileChangeJSON} fileChange * @returns {stash/api/util/navbuilder.Builder} */ diff: restDiff, /** * @returns {stash/api/util/navbuilder.RestCommitPathBuilder} */ changes: function restChangesetChanges() { return this._path().pushComponents('changes').makeBuilder(restCommitPathBuilderMethods); }, /** * @returns {stash/api/util/navbuilder.RestCommitPathBuilder} */ comments: function restChangesetComment() { return this._path().pushComponents('comments').makeBuilder(restCommitPathBuilderMethods); }, /** * @returns {stash/api/util/navbuilder.RepoBrowseBuilder} */ watch: function restCommitWatch() { return this._path().pushComponents('watch').makeBuilder(); } }); } /** * {@linkcode stash/api/util/navbuilder.Builder} for REST commit path URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestCommitPathBuilder * @memberof stash/api/util/navbuilder */ var restCommitPathBuilderMethods = /** * @lends stash/api/util/navbuilder.RestCommitPathBuilder.prototype */ { /** * @param {string} path - A file path. * @returns {stash/api/util/navbuilder.Builder} */ path : function restChangesetPath(path) { return this._path().addParams({ path: path.toString() }).makeBuilder(); } }; /** * @private */ function restDiffInternal(fileChange, builderMethods) { var fileChangeJSON = fileChange.toJSON ? fileChange.toJSON() : fileChange; var builder = this._path(); builder = builder.pushComponents('diff'); builder = builder.pushComponents.apply(builder, componentsFromArguments([fileChangeJSON.path])); if (fileChangeJSON.srcPath) { builder = builder.addParams({ srcPath: fileChangeJSON.srcPath.toString() }); } return builder.makeBuilder(builderMethods); } /** * Documented at parent builders * @private */ function restDiff(fileChange) { return restDiffInternal.call(this, fileChange); } /** * @returns {stash/api/util/navbuilder.RepoBrowseBuilder} */ function restRepoBrowse() { return this._path().pushComponents('browse').makeBuilder(RepoBrowseBuilderMethods); } /** * {@linkcode stash/api/util/navbuilder.Builder} for specifying revisions in REST repository files list URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRepoFilesListAtBuilder * @memberof stash/api/util/navbuilder */ var restRepoFilesListAtBuilderMethods = /** * @lends stash/api/util/navbuilder.RestRepoFilesListAtBuilder.prototype */ { /** * Set the "at" revision at which to obtain a file list from the repo. * * @method * @param {string} refId - The ID of a ref or commit in the SCM whose history to browse. * @returns {stash/api/util/navbuilder.Builder} */ at: RevisionRangeSpecifyingBuilderMethods.at }; /** * {@linkcode stash/api/util/navbuilder.Builder} for REST repository files list URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestRepoFilesListBuilder * @extends stash/api/util/navbuilder.RestRepoFilesListAtBuilder * @memberof stash/api/util/navbuilder */ var restRepoFilesListBuilderMethods = /** * @lends stash/api/util/navbuilder.RestRepoFilesListBuilder.prototype */ { /** * @param {...string} component - A path component within which to obtain a list of files. * @returns {stash/api/util/navbuilder.RestRepoFilesListAtBuilder} */ path: function restRepoFilesInPath() { var path = this._path(); return path.pushComponents.apply(path, componentsFromArguments(arguments)).makeBuilder(restRepoFilesListAtBuilderMethods); }, at : restRepoFilesListAtBuilderMethods.at }; /** * Documented at parent builder * @private */ function restRepoFind() { return this._path().pushComponents('files').makeBuilder($.extend({ /** * @private */ all: deprecate.fn(restRepoAllFiles, 'nav.rest().{currentRepo()|project().repo()}.files().all()', null, '3.0', '4.0') }, restRepoFilesListBuilderMethods)); } /** * Undocumented * @deprecated * @private */ function restRepoAllFiles() { return this._path().addParams({limit: 100000}).makeBuilder(restRepoFilesListBuilderMethods); } /** * {@linkcode stash/api/util/navbuilder.Builder} for REST project permissions URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestProjectPermissionsBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builder * @private */ function restProjPermissions() { return this._path().pushComponents('permissions').makeBuilder( /** * @lends stash/api/util/navbuilder.RestProjectPermissionsBuilder.prototype */ { /** * {@linkcode stash/api/util/navbuilder.Builder} for REST project read permissions URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestProjectReadPermissionsBuilder * @memberof stash/api/util/navbuilder */ /** * @returns {stash/api/util/navbuilder.RestProjectReadPermissionsBuilder} */ projectRead: function restProjReadPerms() { return this._path().pushComponents('project-read').makeBuilder( /** * @lends stash/api/util/navbuilder.RestProjectReadPermissionsBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.RestPermissionAllowBuilder} */ all: restAllProjPerms, /** * @returns {stash/api/util/navbuilder.RestPermissionAllowBuilder} */ anon: function restAnonProReadPerms() { return this._path().pushComponents('anon').makeBuilder(allowBuilderMethods); } }); }, /** * {@linkcode stash/api/util/navbuilder.Builder} for REST project read permissions URLs. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestProjectWritePermissionsBuilder * @memberof stash/api/util/navbuilder */ /** * @returns {stash/api/util/navbuilder.RestProjectWritePermissionsBuilder} */ projectWrite: function restProjWritePerms() { return this._path().pushComponents('project-write').makeBuilder( /** * @lends stash/api/util/navbuilder.RestProjectWritePermissionsBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.RestPermissionAllowBuilder} */ all: restAllProjPerms }); } }); } /** * {@linkcode stash/api/util/navbuilder.Builder} to grant permissions. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestPermissionAllowBuilder * @memberof stash/api/util/navbuilder */ var allowBuilderMethods = /** * @lends stash/api/util/navbuilder.RestPermissionAllowBuilder.prototype */ { /** * @method * @returns {stash/api/util/navbuilder.Builder} */ allow : restAllowProjPerms }; /** * Documented at parent builders * @private */ function restAllProjPerms() { return this._path().pushComponents('all').makeBuilder(allowBuilderMethods); } /** * Documented at parent builders * @private */ function restAllowProjPerms(allow) { return this._path().addParams({'allow': allow}).makeBuilder(); } /** * {@linkcode stash/api/util/navbuilder.Builder} for info about repository hook plugins. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestHookPluginsBuilder * @memberof stash/api/util/navbuilder */ /** * Documented at parent builders * @private */ function restHookPlugins() { return this._path().pushComponents('hooks').makeBuilder( /** * @lends stash/api/util/navbuilder.RestHookPluginsBuilder.prototype */ { /** * {@linkcode stash/api/util/navbuilder.Builder} for info about a repository hook plugin. * * NOTE: The constructor is not exposed. A new instance can be created through the Builder API. * * @class RestHookPluginBuilder * @memberof stash/api/util/navbuilder */ /** * @param {string} hookKey - The key of the hook. * @returns {stash/api/util/navbuilder.RestHookPluginBuilder} */ hook: function restHookPlugin(hookKey) { return this._path().pushComponents(hookKey).makeBuilder( /** * @lends stash/api/util/navbuilder.RestHookPluginBuilder.prototype */ { /** * @param {string} [version] - A string identifying the version of the hook plugin. * Used only to invalidate browser caches when the plugin updates. * @returns {stash/api/util/navbuilder.Builder} */ avatar: function restHookAvatar(version) { return this._path().pushComponents('avatar').addParams({'version': version}).makeBuilder(); } }); } }); } /** * Documented at parent builders. * @private */ function userAvatar(size) { var builder = this._path().pushComponents('avatar.png'); if (size) { builder = builder.addParams({s: size}); } return builder.makeBuilder(); } // HACKY CODE CHECK: off var fallbackUrlPattern = /(default-avatar-)\d+(\.png)/; /** * @private */ function _avatarUrl(person, size) { return { build : function() { var uri = parse(person.avatarUrl); if (uri.getQueryParamValue("s")) { uri.replaceQueryParam("s", size); } // If what we're looking at is the default avatar, its size is set differently, // so use a regex in the filename, rather than a query string param, to insert the correct size. return uri.toString().replace(fallbackUrlPattern, "$1" + size + "$2"); } }; } // HACKY CODE CHECK: on /** * An object representation of a URI with methods allowing you to read and modify the URI. * * NOTE: The Uri constructor is not exposed. Use {@linkcode stash/api/util/navbuilder.parse} to create an instance. * * @class Uri * @memberof stash/api/util/navbuilder */ /** * Serialize the Uri instance. * * @function toString * @name stash/api/util/navbuilder.Uri#toString * @returns {string} */ /** * Get just the path portion of the URI. * * @function path * @name stash/api/util/navbuilder.Uri#path * @returns {string} */ /** * Get just the query string portion of the URI, as an object. * * @function query * @name stash/api/util/navbuilder.Uri#query * @returns {stash/api/util/navbuilder.Query} */ /** * Get just the anchor/hash portion of the URI. * * @function anchor * @name stash/api/util/navbuilder.Uri#anchor * @returns {string} */ /** * Add a query parameter value. If the key is already present in the URI, the key will be repeated. * * @function addQueryParam * @name stash/api/util/navbuilder.Uri#addQueryParam * @param {string} paramKey - The key/name of the parameter. * @param {string} paramValue - The value for the parameter. * @returns {stash/api/util/navbuilder.Uri} */ /** * Add a query parameter value. If the key is already present in the URI, it will be replaced. * * @function replaceQueryParam * @name stash/api/util/navbuilder.Uri#replaceQueryParam * @param {string} paramKey - The key/name of the parameter. * @param {string} paramValue - The value for the parameter. * @returns {stash/api/util/navbuilder.Uri} */ /** * Remove a query parameter from the URI. * * @function deleteQueryParam * @name stash/api/util/navbuilder.Uri#deleteQueryParam * @param {string} paramKey - The key/name of the parameter. * @returns {stash/api/util/navbuilder.Uri} */ /** * Get a query parameter value. If the key is repeated in the URI, the first instance will be returned. * * @function getQueryParamValue * @name stash/api/util/navbuilder.Uri#getQueryParamValue * @param {string} paramKey - The key/name of the parameter. * @returns {string} */ /** * Get an array of query parameter values for a key. * * @function getQueryParamValues * @name stash/api/util/navbuilder.Uri#getQueryParamValues * @param {string} paramKey - The key/name of the parameter. * @returns {Array<string>} */ /** * Parse an absolute string URI in to a mutable Uri object. * @memberof stash/api/util/navbuilder * @param {string} uri - An absolute URI to be parsed. * @returns {stash/api/util/navbuilder.Uri} */ function parse(uri) { return new Uri(uri); } /** * An object representation of a query string with methods allowing you to read and modify the string. * * NOTE: The Query constructor is not exposed. Use {@linkcode stash/api/util/navbuilder.parseQuery} to create an instance. * * @class Query * @memberof stash/api/util/navbuilder */ /** * Serialize the Query instance. * * @function toString * @name stash/api/util/navbuilder.Query#toString * @returns {string} */ /** * Add a query parameter value. If the key is already present in the Query, the key will be repeated. * * @function addParam * @name stash/api/util/navbuilder.Query#addParam * @param {string} paramKey - The key/name of the parameter. * @param {string} paramValue - The value for the parameter. * @returns {stash/api/util/navbuilder.Query} */ /** * Add a query parameter value. If the key is already present in the Query, it will be replaced. * * @function replaceParam * @name stash/api/util/navbuilder.Query#replaceParam * @param {string} paramKey - The key/name of the parameter. * @param {string} paramValue - The value for the parameter. * @returns {stash/api/util/navbuilder.Query} */ /** * Remove a query parameter from the URI. * * @function deleteParam * @name stash/api/util/navbuilder.Query#deleteParam * @param {string} paramKey - The key/name of the parameter. * @returns {stash/api/util/navbuilder.Query} */ /** * Get a query parameter value. If the key is repeated in the Query, the first instance will be returned. * * @function getParamValue * @name stash/api/util/navbuilder.Query#getParamValue * @param {string} paramKey - The key/name of the parameter. * @returns {string} */ /** * Get an array of query parameter values for a key. * * @function getParamValues * @name stash/api/util/navbuilder.Query#getParamValues * @param {string} paramKey - The key/name of the parameter. * @returns {Array<string>} */ /** * Parse a URI's query string into a mutable object. * @memberof stash/api/util/navbuilder * @param {string} queryString - A query string to be parsed. * @returns {stash/api/util/navbuilder.Query} */ function parseQuery(queryString) { return new Query(queryString); } /** * Get a raw builder instance to form your own URLs. * * @memberof stash/api/util/navbuilder * @param {Array<string>} components - An array of path components that will be URI encoded and joined by forward slashes when the URL is formed. * @param {Object} params - A map of parameter names to values that will form the query string. * @returns {stash/api/util/navbuilder.Builder} */ function newBuilder(components, params) { return new PathAndQuery(components, params).makeBuilder(); } exports._avatarUrl = _avatarUrl; exports.addons = addons; exports.admin = admin; exports.allProjects = allProjects; exports.allRepos = globalAllRepos; exports.captcha = captcha; exports.createProject = createProject; exports.currentProject = currentProject; exports.currentPullRequest = currentPullRequest; exports.currentRepo = currentRepo; exports.login = login; exports.newBuilder = newBuilder; exports.parse = parse; exports.parseQuery = parseQuery; exports.pluginServlets = pluginServlets; exports.project = project; exports.rest = rest; exports.tmp = tmp; exports.user = user; exports.welcome = welcome; exports.gettingStarted = gettingStarted; });