Convert gr-rest-api-interface.js to typescript

Some methods in gr-rest-api-interface doesn't define output type. Types can
be added later when needed.

Change-Id: I9e93ad83354a08b81a01e733a6e6bbfa95d2910f
This commit is contained in:
Dmitrii Filippov
2020-08-11 11:06:03 +02:00
parent 52bb484869
commit d5b1dc734c
15 changed files with 2487 additions and 883 deletions

View File

@@ -201,3 +201,130 @@ export enum InheritedBooleanInfoConfiguredValue {
export enum AccountTag {
SERVICE_USER = 'SERVICE_USER',
}
/**
* Enum for possible PermissionRuleInfo actions
* https://gerrit-review.googlesource.com/Documentation/rest-api-access.html#permission-info
*/
export enum PermissionAction {
ALLOW = 'ALLOW',
DENY = 'DENY',
BLOCK = 'BLOCK',
// Special values for global capabilities
INTERACTIVE = 'INTERACTIVE',
BATCH = 'BATCH',
}
/**
* This capability allows users to use the thread pool reserved for 'Non-Interactive Users'.
* https://gerrit-review.googlesource.com/Documentation/access-control.html#capability_priority
*/
export enum UserPriority {
BATCH = 'BATCH',
INTERACTIVE = 'INTERACTIVE',
}
/**
* Enum for all http methods used in Gerrit.
*/
export enum HttpMethod {
HEAD = 'HEAD',
POST = 'POST',
GET = 'GET',
DELETE = 'DELETE',
PUT = 'PUT',
}
/**
* The side on which the comment was added
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-info
*/
export enum CommentSide {
REVISION = 'REVISION',
PARENT = 'PARENT',
}
/**
* Allowed app themes
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum AppTheme {
DARK = 'DARK',
LIGHT = 'LIGHT',
}
/**
* Date formats in preferences
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum DateFormat {
STD = 'STD',
US = 'US',
ISO = 'ISO',
EURO = 'EURO',
UK = 'UK',
}
/**
* Time formats in preferences
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum TimeFormat {
HHMM_12 = 'HHMM_12',
HHMM_24 = 'HHMM_24',
}
/**
* Diff type in preferences
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum DiffViewMode {
SIDE_BY_SIDE = 'SIDE_BY_SIDE',
UNIFIED = 'UNIFIED_DIFF',
}
/**
* The type of email strategy to use.
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum EmailStrategy {
ENABLED = 'ENABLED',
CC_ON_OWN_COMMENTS = 'CC_ON_OWN_COMMENTS',
DISABLED = 'DISABLED',
}
/**
* The base which should be pre-selected in the 'Diff Against' drop-down list when the change screen is opened for a merge commit
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export enum DefaultBase {
AUTO_MERGE = 'AUTO_MERGE',
FIRST_PARENT = 'FIRST_PARENT',
}
/**
* Whether whitespace changes should be ignored and if yes, which whitespace changes should be ignored
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#diff-preferences-input
*/
export enum IgnoreWhitespaceType {
IGNORE_NONE = 'IGNORE_NONE',
IGNORE_TRAILING = 'IGNORE_TRAILING',
IGNORE_LEADING_AND_TRAILING = 'IGNORE_LEADING_AND_TRAILING',
IGNORE_ALL = 'IGNORE_ALL',
}
/**
* how draft comments are handled
*/
export enum DraftsAction {
PUBLISH = 'PUBLISH',
PUBLISH_ALL_REVISIONS = 'PUBLISH_ALL_REVISIONS',
KEEP = 'KEEP',
}
export enum NotifyType {
NONE = 'NONE',
OWNER = 'OWNER',
OWNER_REVIEWERS = 'OWNER_REVIEWERS',
ALL = 'ALL',
}

View File

@@ -17,6 +17,8 @@
import {getBaseUrl} from '../../../utils/url-util';
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
import {HttpMethod} from '../../../constants/constants';
import {RequestPayload} from '../../../types/common';
export const PRELOADED_PROTOCOL = 'preloaded:';
export const PLUGIN_LOADING_TIMEOUT_MS = 10000;
@@ -76,10 +78,10 @@ export function getPluginNameFromUrl(url: URL | string) {
// TODO(taoalpha): to be deprecated.
export function send(
method: string,
method: HttpMethod,
url: string,
opt_callback?: (response: unknown) => void,
opt_payload?: unknown
opt_payload?: RequestPayload
) {
return getRestAPI()
.send(method, url, opt_payload)

View File

@@ -16,10 +16,10 @@
*/
import {
ApiElement,
RestApiService,
GrChangeActions,
ActionType,
ActionPriority,
JsApiService,
} from '../../../services/services/gr-rest-api/gr-rest-api';
interface Plugin {
@@ -62,7 +62,7 @@ export class GrChangeActionsInterface {
if (!this._el) {
const sharedApiElement = (document.createElement(
'gr-js-api-interface'
) as unknown) as RestApiService;
) as unknown) as JsApiService;
this.setEl(sharedApiElement.getElement(ApiElement.CHANGE_ACTIONS));
}
return this._el!;

View File

@@ -18,7 +18,7 @@
import {
ApiElement,
GrReplyDialog,
RestApiService,
JsApiService,
} from '../../../services/services/gr-rest-api/gr-rest-api';
// TODO(TS): maybe move interfaces\types to other files when convertion complete
@@ -86,7 +86,7 @@ interface PluginApi {
export class GrChangeReplyInterface {
constructor(
readonly plugin: PluginApi,
readonly sharedApiElement: RestApiService
readonly sharedApiElement: JsApiService
) {}
get _el(): GrReplyDialog {

View File

@@ -15,9 +15,10 @@
* limitations under the License.
*/
import {GrPluginRestApi, HttpMethod} from './gr-plugin-rest-api';
import {GrPluginRestApi} from './gr-plugin-rest-api';
import {GrEventHelper} from '../../plugins/gr-event-helper/gr-event-helper';
import {RevisionInfo, ChangeInfo} from '../../../types/common';
import {RevisionInfo, ChangeInfo, RequestPayload} from '../../../types/common';
import {HttpMethod} from '../../../constants/constants';
interface PluginApi {
restApi(): GrPluginRestApi;
@@ -113,7 +114,7 @@ export class GrPluginActionContext {
return this.label(checkbox, title);
}
call(payload: unknown, onSuccess: (result: unknown) => void) {
call(payload: RequestPayload, onSuccess: (result: unknown) => void) {
if (!this.action.__url) {
console.warn(`Unable to ${this.action.method} to ${this.action.__key}!`);
return;
@@ -122,7 +123,7 @@ export class GrPluginActionContext {
.restApi()
.send(this.action.method, this.action.__url, payload)
.then(onSuccess)
.catch(error => {
.catch((error: unknown) => {
document.dispatchEvent(
new CustomEvent('show-alert', {
detail: {

View File

@@ -18,17 +18,8 @@ import {
ErrorCallback,
RestApiService,
} from '../../../services/services/gr-rest-api/gr-rest-api';
/**
* Enum for all http methods used in Gerrit.
* TODO(TS): might move to common later.
*/
export enum HttpMethod {
POST = 'POST',
GET = 'GET',
DELETE = 'DELETE',
PUT = 'PUT',
}
import {HttpMethod} from '../../../constants/constants';
import {RequestPayload} from '../../../types/common';
let restApi: RestApiService | null = null;
@@ -76,16 +67,40 @@ export class GrPluginRestApi {
return getRestApi().getRepos(filter, reposPerPage, offset);
}
fetch(
method: HttpMethod,
url: string,
payload?: RequestPayload,
errFn?: undefined,
contentType?: string
): Promise<Response>;
fetch(
method: HttpMethod,
url: string,
payload: RequestPayload | undefined,
errFn: ErrorCallback,
contentType?: string
): Promise<Response | void>;
fetch(
method: HttpMethod,
url: string,
payload: RequestPayload | undefined,
errFn?: ErrorCallback,
contentType?: string
): Promise<Response | void>;
/**
* Fetch and return native browser REST API Response.
*/
fetch(
method: HttpMethod,
url: string,
payload?: unknown,
payload?: RequestPayload,
errFn?: ErrorCallback,
contentType?: string
): Promise<Response> {
): Promise<Response | void> {
return getRestApi().send(
method,
this.prefix + url,
@@ -101,12 +116,18 @@ export class GrPluginRestApi {
send(
method: HttpMethod,
url: string,
payload?: unknown,
payload?: RequestPayload,
errFn?: ErrorCallback,
contentType?: string
) {
return this.fetch(method, url, payload, errFn, contentType).then(
response => {
if (!response) {
// TODO(TS): Fix method definition
// If errFn exists and doesn't throw an exception, the fetch method
// returns empty response
throw new Error('errFn must throw an exception');
}
if (response.status < 200 || response.status >= 300) {
return response.text().then(text => {
if (text) {
@@ -128,7 +149,7 @@ export class GrPluginRestApi {
post(
url: string,
payload?: unknown,
payload?: RequestPayload,
errFn?: ErrorCallback,
contentType?: string
) {
@@ -137,7 +158,7 @@ export class GrPluginRestApi {
put(
url: string,
payload?: unknown,
payload?: RequestPayload,
errFn?: ErrorCallback,
contentType?: string
) {

View File

@@ -935,8 +935,7 @@ suite('gr-rest-api-interface tests', () => {
const changeNum = 4321;
element._projectLookup[changeNum] = 'test';
const expectedUrl =
window.CANONICAL_PATH + '/changes/test~4321/detail?'+
'0=5&1=1&2=6&3=7&4=1&5=4';
window.CANONICAL_PATH + '/changes/test~4321/detail?O=516714';
sinon.stub(element._etags, 'getOptions');
sinon.stub(element._etags, 'collect');
return element._getChangeDetail(changeNum, '516714').then(() => {
@@ -979,7 +978,6 @@ suite('gr-rest-api-interface tests', () => {
let requestUrl;
let mockResponseSerial;
let collectSpy;
let getPayloadSpy;
setup(() => {
requestUrl = '/foo/bar';
@@ -991,10 +989,10 @@ suite('gr-rest-api-interface tests', () => {
sinon.stub(element, 'getChangeActionURL')
.returns(Promise.resolve(requestUrl));
collectSpy = sinon.spy(element._etags, 'collect');
getPayloadSpy = sinon.spy(element._etags, 'getCachedPayload');
});
test('contributes to cache', () => {
const getPayloadSpy = sinon.spy(element._etags, 'getCachedPayload');
sinon.stub(element._restApiHelper, 'fetchRawJSON')
.returns(Promise.resolve({
text: () => Promise.resolve(mockResponseSerial),
@@ -1011,16 +1009,18 @@ suite('gr-rest-api-interface tests', () => {
});
test('uses cache on HTTP 304', () => {
const getPayloadStub = sinon.stub(element._etags, 'getCachedPayload');
getPayloadStub.returns(mockResponseSerial);
sinon.stub(element._restApiHelper, 'fetchRawJSON')
.returns(Promise.resolve({
text: () => Promise.resolve(mockResponseSerial),
text: () => Promise.resolve(''),
status: 304,
ok: true,
}));
return element._getChangeDetail(123, {}).then(detail => {
return element._getChangeDetail(123, '').then(detail => {
assert.isFalse(collectSpy.called);
assert.isTrue(getPayloadSpy.calledOnce);
assert.isTrue(getPayloadStub.calledOnce);
});
});
});

View File

@@ -16,6 +16,7 @@
*/
import {getBaseUrl} from '../../../../utils/url-util';
import {
CancelConditionCallback,
ErrorCallback,
RestApiService,
} from '../../../../services/services/gr-rest-api/gr-rest-api';
@@ -24,10 +25,26 @@ import {
AuthService,
} from '../../../../services/gr-auth/gr-auth';
import {hasOwnProperty} from '../../../../utils/common-util';
import {HttpMethod} from '../../../../types/common';
import {
AccountDetailInfo,
EmailInfo,
ParsedJSON,
RequestPayload,
} from '../../../../types/common';
import {HttpMethod} from '../../../../constants/constants';
const JSON_PREFIX = ")]}'";
export interface ResponsePayload {
// TODO(TS): readResponsePayload can assign null to the parsed property if
// it can't parse input data. However polygerrit assumes in many places
// that the parsed property can't be null. We should update
// readResponsePayload method and reject a promise instead of assigning
// null to the parsed property
parsed: ParsedJSON; // Can be null!!! See comment above
raw: string;
}
/**
* Wrapper around Map for caching server responses. Site-based so that
* changes to CANONICAL_PATH will result in a different cache going into
@@ -38,7 +55,7 @@ export class SiteBasedCache {
// Container of per-canonical-path caches.
private readonly _data = new Map<
string | undefined,
unknown | Map<string, ParsedJSON>
unknown | Map<string, ParsedJSON | null>
>();
constructor() {
@@ -47,28 +64,43 @@ export class SiteBasedCache {
// so that we spare more round trips to the server when the app loads
// initially.
Object.entries(window.INITIAL_DATA).forEach(e =>
this._cache().set(e[0], e[1])
this._cache().set(e[0], (e[1] as unknown) as ParsedJSON)
);
}
}
// Returns the cache for the current canonical path.
_cache(): Map<string, ParsedJSON> {
_cache(): Map<string, unknown> {
if (!this._data.has(window.CANONICAL_PATH)) {
this._data.set(window.CANONICAL_PATH, new Map());
}
return this._data.get(window.CANONICAL_PATH) as Map<string, ParsedJSON>;
return this._data.get(window.CANONICAL_PATH) as Map<
string,
ParsedJSON | null
>;
}
has(key: string) {
return this._cache().has(key);
}
get(key: string) {
get(key: '/accounts/self/emails'): EmailInfo[] | null;
get(key: '/accounts/self/detail'): AccountDetailInfo[] | null;
get(key: string): ParsedJSON | null;
get(key: string): unknown {
return this._cache().get(key);
}
set(key: string, value: ParsedJSON) {
set(key: '/accounts/self/emails', value: EmailInfo[]): void;
set(key: '/accounts/self/detail', value: AccountDetailInfo[]): void;
set(key: string, value: ParsedJSON | null): void;
set(key: string, value: unknown) {
this._cache().set(key, value);
}
@@ -87,12 +119,9 @@ export class SiteBasedCache {
}
}
/**
* Type alias for parsed json object to make code cleaner
*/
export type ParsedJSON = unknown;
type FetchPromisesCacheData = {[url: string]: Promise<ParsedJSON> | undefined};
type FetchPromisesCacheData = {
[url: string]: Promise<ParsedJSON | undefined> | undefined;
};
export class FetchPromisesCache {
private _data: FetchPromisesCacheData;
@@ -101,6 +130,10 @@ export class FetchPromisesCache {
this._data = {};
}
public testOnlyGetData() {
return this._data;
}
/**
* @return true only if a value for a key sets and it is not undefined
*/
@@ -116,7 +149,7 @@ export class FetchPromisesCache {
* @param value a Promise to store in the cache. Pass undefined value to
* mark key as deleted.
*/
set(key: string, value: Promise<ParsedJSON> | undefined) {
set(key: string, value: Promise<ParsedJSON | undefined> | undefined) {
this._data[key] = value;
}
@@ -131,14 +164,14 @@ export class FetchPromisesCache {
}
}
export type FetchParams = {
[name: string]: string | number | boolean | undefined | null;
[name: string]: string[] | string | number | boolean | undefined | null;
};
interface SendRequestBase {
method: HttpMethod;
body: string | object;
body?: RequestPayload;
contentType?: string;
headers: Record<string, string>;
headers?: Record<string, string>;
url: string;
reportUrlAsIs?: boolean;
anonymizedUrl?: string;
@@ -157,17 +190,29 @@ export type SendRequest = SendRawRequest | SendJSONRequest;
export interface FetchRequest {
url: string;
fetchOptions: AuthRequestInit;
fetchOptions?: AuthRequestInit;
anonymizedUrl?: string;
}
export interface FetchJSONRequest extends FetchRequest {
reportUrlAsIs?: boolean;
cancelCondition?: () => boolean;
errFn: ErrorCallback;
params: FetchParams;
params?: FetchParams;
cancelCondition?: CancelConditionCallback;
errFn?: ErrorCallback;
}
// export function isRequestWithCancel<T extends FetchJSONRequest>(
// x: T
// ): x is T & RequestWithCancel {
// return !!(x as RequestWithCancel).cancelCondition;
// }
//
// export function isRequestWithErrFn<T extends FetchJSONRequest>(
// x: T
// ): x is T & RequestWithErrFn {
// return !!(x as RequestWithErrFn).errFn;
// }
export class GrRestApiHelper {
constructor(
private readonly _cache: SiteBasedCache,
@@ -287,7 +332,7 @@ s */
fetchJSON(
req: FetchJSONRequest,
noAcceptHeader?: boolean
): Promise<ParsedJSON> {
): Promise<ParsedJSON | undefined> {
if (!noAcceptHeader) {
req = this.addAcceptJsonHeader(req);
}
@@ -309,7 +354,7 @@ s */
);
return;
}
return response && this.getResponseObject(response);
return this.getResponseObject(response);
});
}
@@ -352,13 +397,11 @@ s */
);
}
getResponseObject(response: Response): ParsedJSON {
getResponseObject(response: Response): Promise<ParsedJSON> {
return this.readResponsePayload(response).then(payload => payload.parsed);
}
readResponsePayload(
response: Response
): Promise<{parsed: ParsedJSON | string; raw: string}> {
readResponsePayload(response: Response): Promise<ResponsePayload> {
return response.text().then(text => {
let result;
try {
@@ -366,7 +409,12 @@ s */
} catch (_) {
result = null;
}
return {parsed: result, raw: text};
// TODO(TS): readResponsePayload can assign null to the parsed property if
// it can't parse input data. However polygerrit assumes in many places
// that the parsed property can't be null. We should update
// readResponsePayload method and reject a promise instead of assigning
// null to the parsed property
return {parsed: result!, raw: text};
});
}
@@ -389,18 +437,18 @@ s */
return this._restApiInterface.dispatchEvent(type, detail);
}
fetchCacheURL(req: FetchJSONRequest): Promise<ParsedJSON> {
fetchCacheURL(req: FetchJSONRequest): Promise<ParsedJSON | undefined> {
if (this._fetchPromisesCache.has(req.url)) {
return this._fetchPromisesCache.get(req.url)!;
}
// TODO(andybons): Periodic cache invalidation.
if (this._cache.has(req.url)) {
return Promise.resolve(this._cache.get(req.url));
return Promise.resolve(this._cache.get(req.url)!);
}
this._fetchPromisesCache.set(
req.url,
this.fetchJSON(req)
.then((response: ParsedJSON) => {
.then(response => {
if (response !== undefined) {
this._cache.set(req.url, response);
}
@@ -415,20 +463,23 @@ s */
return this._fetchPromisesCache.get(req.url)!;
}
/**
* @return Promise resolves to Response only if the request is successful
* (i.e. no exception and response.ok is true). If response fails then
* promise resolves either to void if errFn is set or rejects if errFn
* is not set
*/
send(req: SendRawRequest): Promise<Response | void>;
// if errFn is not set, then only Response possible
send(req: SendRawRequest & {errFn?: undefined}): Promise<Response>;
send(req: SendRawRequest): Promise<Response | undefined>;
send(req: SendJSONRequest): Promise<ParsedJSON>;
send(req: SendRequest): Promise<Response | ParsedJSON | undefined>;
/**
* Send an XHR.
*/
send(req: SendRequest) {
*
* @return Promise resolves to Response/ParsedJSON only if the request is successful
* (i.e. no exception and response.ok is trsue). If response fails then
* promise resolves either to void if errFn is set or rejects if errFn
* is not set */
send(req: SendRequest): Promise<Response | ParsedJSON | undefined> {
const options: AuthRequestInit = {method: req.method};
if (req.body) {
options.headers = new Headers();
@@ -460,7 +511,8 @@ s */
.then(response => {
if (!response.ok) {
if (req.errFn) {
return req.errFn.call(undefined, response);
req.errFn.call(undefined, response);
return;
}
this.dispatchEvent(
new CustomEvent('server-error', {
@@ -495,8 +547,9 @@ s */
// different type of callback if parseResponse is true, etc...).
return xhr.then(res => this.getResponseObject(res as Response));
}
return xhr;
// The actual xhr type is Promise<Response|undefined|void> because of the
// catch callback
return xhr as Promise<Response | undefined>;
}
invalidateFetchPromisesPrefix(prefix: string) {

View File

@@ -289,7 +289,9 @@ export class GrReviewerUpdatesParser {
});
}
static parse(change: ChangeInfo): ParsedChangeInfo {
static parse(
change: ChangeInfo | undefined | null
): ParsedChangeInfo | undefined | null {
// TODO(TS): The !change condition should be removed when all files are converted to TS
if (!change || !isChangeInfoParserInput(change)) {
return change;

View File

@@ -18,13 +18,15 @@ import {
getAccountDisplayName,
getGroupDisplayName,
} from '../../utils/display-name-util';
import {RestApiService} from '../../services/services/gr-rest-api/gr-rest-api';
import {
RestApiService,
SuggestedReviewerAccountInfo,
SuggestedReviewerGroupInfo,
AccountInfo,
isReviewerAccountSuggestion,
isReviewerGroupSuggestion,
NumericChangeId,
ServerInfo,
SuggestedReviewerInfo,
} from '../../services/services/gr-rest-api/gr-rest-api';
import {AccountInfo, NumericChangeId, ServerInfo} from '../../types/common';
} from '../../types/common';
import {assertNever} from '../../utils/common-util';
// TODO(TS): enum name doesn't follow typescript style guid rules
@@ -41,19 +43,7 @@ export function isAccountSuggestions(s: Suggestion): s is AccountInfo {
return (s as AccountInfo)._account_id !== undefined;
}
export function isReviewerAccountSuggestion(
s: Suggestion
): s is SuggestedReviewerAccountInfo {
return (s as SuggestedReviewerAccountInfo).account !== undefined;
}
export function isReviewerGroupSuggestion(
s: Suggestion
): s is SuggestedReviewerGroupInfo {
return (s as SuggestedReviewerGroupInfo).group !== undefined;
}
type ApiCallCallback = (input: string) => Promise<Suggestion[]>;
type ApiCallCallback = (input: string) => Promise<Suggestion[] | void>;
export interface SuggestionItem {
name: string;

View File

@@ -18,52 +18,21 @@
import {
AccountDetailInfo,
AccountInfo,
CapabilityInfo,
GroupBaseInfo,
NumericChangeId,
ServerInfo,
ProjectInfo,
ActionInfo,
GroupInfo,
ChangeInfo,
AccountCapabilityInfo,
SuggestedReviewerInfo,
GroupNameToGroupInfoMap,
ParsedJSON,
RequestPayload,
} from '../../../types/common';
import {ParsedChangeInfo} from '../../../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
import {HttpMethod} from '../../../constants/constants';
export type ErrorCallback = (response?: Response | null, err?: Error) => void;
/**
* Contains information about an account that can be added to a change
*/
export interface SuggestedReviewerAccountInfo {
account: AccountInfo;
/**
* The total number of accounts in the suggestion - always 1
*/
count: 1;
}
/**
* Contains information about a group that can be added to a change
*/
export interface SuggestedReviewerGroupInfo {
group: GroupBaseInfo;
/**
* The total number of accounts that are members of the group is returned
* (this count includes members of nested groups)
*/
count: number;
/**
* True if group is present and count is above the threshold where the
* confirmed flag must be passed to add the group as a reviewer
*/
confirm?: boolean;
}
/**
* Contains information about a reviewer that can be added to a change
*/
export type SuggestedReviewerInfo =
| SuggestedReviewerAccountInfo
| SuggestedReviewerGroupInfo;
export type CancelConditionCallback = () => boolean;
export enum ApiElement {
CHANGE_ACTIONS = 'changeactions',
@@ -119,59 +88,74 @@ export interface RestApiTagNameMap {
[ApiElement.CHANGE_ACTIONS]: GrChangeActions;
}
export interface JsApiService {
getElement<K extends keyof RestApiTagNameMap>(
elementKey: K
): RestApiTagNameMap[K];
}
export interface RestApiService {
// TODO(TS): unclear what is a second parameter. Looks like it is a mistake
// and it must be removed
dispatchEvent(event: Event, detail?: unknown): boolean;
getConfig(): Promise<ServerInfo>;
getConfig(noCache?: boolean): Promise<ServerInfo | undefined>;
getLoggedIn(): Promise<boolean>;
getVersion(): Promise<string>;
getVersion(): Promise<string | undefined>;
invalidateReposCache(): void;
getAccount(): Promise<AccountDetailInfo>;
getAccountCapabilities(params?: string[]): Promise<CapabilityInfo>;
getAccount(): Promise<AccountDetailInfo | undefined>;
getAccountCapabilities(
params?: string[]
): Promise<AccountCapabilityInfo | undefined>;
getRepos(
filter: string,
reposPerPage: number,
offset?: number
): Promise<ProjectInfo>;
): Promise<ProjectInfo | undefined>;
send(
method: string,
method: HttpMethod,
url: string,
body?: unknown,
errFn?: ErrorCallback,
body?: RequestPayload,
errFn?: null | undefined,
contentType?: string,
headers?: unknown
headers?: Record<string, string>
): Promise<Response>;
getResponseObject(response: Response): null | unknown;
send(
method: HttpMethod,
url: string,
body?: RequestPayload,
errFn?: ErrorCallback,
contentType?: string,
headers?: Record<string, string>
): Promise<Response | void>;
getResponseObject(response: Response): Promise<ParsedJSON>;
getChangeSuggestedReviewers(
changeNum: NumericChangeId,
input: string,
errFn?: ErrorCallback
): Promise<SuggestedReviewerInfo[]>;
): Promise<SuggestedReviewerInfo[] | undefined>;
getChangeSuggestedCCs(
changeNum: NumericChangeId,
input: string,
errFn?: ErrorCallback
): Promise<SuggestedReviewerInfo[]>;
): Promise<SuggestedReviewerInfo[] | undefined>;
getSuggestedAccounts(
input: string,
n?: number,
errFn?: ErrorCallback
): Promise<AccountInfo[]>;
): Promise<AccountInfo[] | undefined>;
getSuggestedGroups(
input: string,
n?: number,
errFn?: ErrorCallback
): Promise<Record<string, GroupInfo>>;
): Promise<GroupNameToGroupInfoMap | undefined>;
getElement<K extends keyof RestApiTagNameMap>(
elementKey: K
): RestApiTagNameMap[K];
getChangeDetail(
changeNum: number | string,
opt_errFn?: Function,
opt_cancelCondition?: Function
): Promise<ChangeInfo>;
): Promise<ParsedChangeInfo | null | undefined>;
}

View File

@@ -29,13 +29,36 @@ import {
InheritedBooleanInfoConfiguredValue,
ConfigParameterInfoType,
AccountTag,
PermissionAction,
HttpMethod,
CommentSide,
AppTheme,
DateFormat,
TimeFormat,
EmailStrategy,
DefaultBase,
IgnoreWhitespaceType,
UserPriority,
DiffViewMode,
DraftsAction,
NotifyType,
} from '../constants/constants';
import {Suggestion} from '../scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider';
export type BrandType<T, BrandName extends string> = T &
{[__brand in BrandName]: never};
/**
* Type alias for parsed json object to make code cleaner
*/
export type ParsedJSON = BrandType<unknown, '_parsedJSON'>;
export type PatchSetNum = BrandType<'edit' | number, '_patchSet'>;
export const EditPatchSetNum = 'edit' as PatchSetNum;
// TODO(TS): This is not correct, it is better to have a separate ApiPatchSetNum
// without 'parent'.
export const ParentPatchSetNum = 'PARENT' as PatchSetNum;
export type ChangeId = BrandType<string, '_changeId'>;
export type ChangeMessageId = BrandType<string, '_changeMessageId'>;
@@ -44,13 +67,16 @@ export type NumericChangeId = BrandType<number, '_numericChangeId'>;
export type ProjectName = BrandType<string, '_projectName'>;
export type UrlEncodedProjectName = BrandType<string, '_urlEncodedProjectName'>;
export type TopicName = BrandType<string, '_topicName'>;
// TODO(TS): Probably, we should separate AccountId and EncodedAccountId
export type AccountId = BrandType<number, '_accountId'>;
export type HttpMethod = BrandType<string, '_httpMethod'>;
export type GitRef = BrandType<string, '_gitRef'>;
export type RequirementType = BrandType<string, '_requirementType'>;
export type TrackingId = BrandType<string, '_trackingId'>;
export type ReviewInputTag = BrandType<string, '_reviewInputTag'>;
export type RepositoryName = BrandType<string, '_repositoryName'>;
export type RobotId = BrandType<string, '_robotId'>;
export type RobotRunId = BrandType<string, '_robotRunId'>;
export type FixId = BrandType<string, '_fixId'>;
// The URL encoded UUID of the comment
export type UrlEncodedCommentId = BrandType<string, '_urlEncodedCommentId'>;
@@ -88,6 +114,9 @@ export type CommitId = BrandType<string, '_commitId'>;
// The UUID of the group
export type GroupId = BrandType<string, '_groupId'>;
// The Encoded UUID of the group
export type EncodedGroupId = BrandType<string, '_encodedGroupId'>;
// The timezone offset from UTC in minutes
export type TimezoneOffset = BrandType<number, '_timezoneOffset'>;
@@ -249,6 +278,8 @@ export interface GroupInfo {
includes?: GroupInfo[];
}
export type GroupNameToGroupInfoMap = {[groupName: string]: GroupInfo};
/**
* The 'GroupInput' entity contains information for the creation of a new
* internal group.
@@ -590,7 +621,7 @@ export interface CacheOperationInput {
/**
* The CapabilityInfo entity contains information about a capability.
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html#capability-info
*/
export interface CapabilityInfo {
id: string;
@@ -827,16 +858,16 @@ export interface PluginConfigInfo {
/**
* The ReceiveInfo entity contains information about the configuration of
* git-receive-pack behavior on the server.
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html#receive-info
*/
export interface ReceiveInfo {
enableSignedPush?: string;
enable_signed_push?: string;
}
/**
* The ServerInfo entity contains information about the configuration of the
* Gerrit server.
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html#server-info
*/
export interface ServerInfo {
accounts: AccountsConfigInfo;
@@ -856,7 +887,7 @@ export interface ServerInfo {
/**
* The SuggestInfo entity contains information about Gerritconfiguration from
* the suggest section.
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html
* https://gerrit-review.googlesource.com/Documentation/rest-api-config.html#suggest-info
*/
export interface SuggestInfo {
from: string;
@@ -948,7 +979,7 @@ export interface CommentInfo {
patch_set?: PatchSetNum;
id: UrlEncodedCommentId;
path?: string;
side?: string;
side?: CommentSide;
parent?: string;
line?: string;
range?: CommentRange;
@@ -962,6 +993,8 @@ export interface CommentInfo {
commit_id?: string;
}
export type PathToCommentsInfoMap = {[path: string]: CommentInfo[]};
/**
* The CommentRange entity describes the range of an inline comment.
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-range
@@ -994,6 +1027,8 @@ export interface ProjectInfo {
web_links?: WebLinkInfo[];
}
export type NameToProjectInfoMap = {[projectName: string]: ProjectInfo};
/**
* The LabelTypeInfo entity contains metadata about the labels that a project
* has.
@@ -1056,31 +1091,37 @@ export interface DiffWebLinkInfo {
/**
* The DiffPreferencesInfo entity contains information about the diff preferences of a user.
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#diff-preferences-info
*/
export interface DiffPreferencesInfo {
context: string;
expand_all_comments: boolean;
ignore_whitespace: string;
intraline_difference: boolean;
context: number;
expand_all_comments?: boolean;
ignore_whitespace: IgnoreWhitespaceType;
intraline_difference?: boolean;
line_length: number;
cursor_blink_rate: string;
manual_review: boolean;
retain_header: boolean;
show_line_endings: boolean;
show_tabs: boolean;
show_whitespace_errors: boolean;
skip_deleted: boolean;
skip_uncommented: boolean;
syntax_highlighting: boolean;
hide_top_menu: boolean;
auto_hide_diff_table_header: boolean;
hide_line_numbers: boolean;
cursor_blink_rate: number;
manual_review?: boolean;
retain_header?: boolean;
show_line_endings?: boolean;
show_tabs?: boolean;
show_whitespace_errors?: boolean;
skip_deleted?: boolean;
skip_uncommented?: boolean;
syntax_highlighting?: boolean;
hide_top_menu?: boolean;
auto_hide_diff_table_header?: boolean;
hide_line_numbers?: boolean;
tab_size: number;
font_size: string;
hide_empty_pane: boolean;
match_brackets: boolean;
line_wrapping: boolean;
show_file_comment_button: boolean;
font_size: number;
hide_empty_pane?: boolean;
match_brackets?: boolean;
line_wrapping?: boolean;
// TODO(TS): show_file_comment_button exists in JS code, but doesn't exist in the doc.
// Either remove or update doc
show_file_comment_button?: boolean;
// TODO(TS): theme exists in JS code, but doesn't exist in the doc.
// Either remove or update doc
theme?: string;
}
/**
@@ -1207,3 +1248,591 @@ export interface ConfigInfo {
actions?: {[viewName: string]: ActionInfo};
reject_empty_commit?: InheritedBooleanInfo;
}
/**
* The ProjectAccessInfo entity contains information about the access rights for a project
* https://gerrit-review.googlesource.com/Documentation/rest-api-access.html#project-access-info
*/
export interface ProjectAccessInfo {
revision: string; // The revision of the refs/meta/config branch from which the access rights were loaded
inherits_from?: ProjectInfo; // not set for the All-Project project
local: LocalAccessSectionInfo;
is_owner?: boolean;
owner_of: GitRef[];
can_upload?: boolean;
can_add?: boolean;
can_add_tags?: boolean;
config_visible?: boolean;
groups: ProjectAccessGroups;
configWebLinks: string[];
}
export type ProjectAccessInfoMap = {[projectName: string]: ProjectAccessInfo};
export type LocalAccessSectionInfo = {[ref: string]: AccessSectionInfo};
export type ProjectAccessGroups = {[uuid: string]: GroupInfo};
/**
* The AccessSectionInfo describes the access rights that are assigned on a ref.
* https://gerrit-review.googlesource.com/Documentation/rest-api-access.html#access-section-info
*/
export interface AccessSectionInfo {
permissions: AccessPermissionsMap;
}
export type AccessPermissionsMap = {[permissionName: string]: PermissionInfo};
/**
* The PermissionInfo entity contains information about an assigned permission
* https://gerrit-review.googlesource.com/Documentation/rest-api-access.html#permission-info
*/
export interface PermissionInfo {
label?: string; // The name of the label. Not set if its not a label permission.
exclusive?: boolean;
rules: PermissionInfoRules;
}
export type PermissionInfoRules = {[groupUUID: string]: PermissionRuleInfo};
/**
* The PermissionRuleInfo entity contains information about a permission rule that is assigned to group
* https://gerrit-review.googlesource.com/Documentation/rest-api-access.html#permission-info
*/
export interface PermissionRuleInfo {
action: PermissionAction;
force?: boolean;
min?: number; // not set if range is empty (from 0 to 0) or not set
max?: number; // not set if range is empty (from 0 to 0) or not set
}
/**
* The DashboardInfo entity contains information about a project dashboard
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#dashboard-info
*/
export interface DashboardInfo {
id: DashboardId;
project: ProjectName;
defining_project: ProjectName;
ref: string; // The name of the ref in which the dashboard is defined, without the refs/meta/dashboards/ prefix
description?: string;
foreach?: string;
url: string;
is_default?: boolean;
title?: boolean;
sections: DashboardSectionInfo[];
}
/**
* The DashboardSectionInfo entity contains information about a section in a dashboard.
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#dashboard-section-info
*/
export interface DashboardSectionInfo {
name: string;
query: string;
}
/**
* The ConfigInput entity describes a new project configuration
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#config-input
*/
export interface ConfigInput {
description?: string;
use_contributor_agreements?: InheritedBooleanInfoConfiguredValue;
use_content_merge?: InheritedBooleanInfoConfiguredValue;
use_signed_off_by?: InheritedBooleanInfoConfiguredValue;
create_new_change_for_all_not_in_target?: InheritedBooleanInfoConfiguredValue;
require_change_id?: InheritedBooleanInfoConfiguredValue;
reject_implicit_merges?: InheritedBooleanInfoConfiguredValue;
max_object_size_limit?: MaxObjectSizeLimitInfo;
submit_type?: SubmitType;
state?: ProjectState;
plugin_config_values?: PluginConfigValues;
reject_empty_commit?: InheritedBooleanInfoConfiguredValue;
commentlinks?: ConfigInfoCommentLinks;
}
/**
* Plugin configuration values as map which maps the plugin name to a map of parameter names to values
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#config-input
*/
export type PluginConfigValues = {
[pluginName: string]: ParameterNameToValueMap;
};
export type ParameterNameToValueMap = {[parameterName: string]: string};
export type ConfigInfoCommentLinks = {
[commentLinkName: string]: CommentLinkInfo;
};
/**
* The ProjectInput entity contains information for the creation of a new project
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#project-input
*/
export interface ProjectInput {
name?: ProjectName;
parent?: ProjectName;
description?: string;
permissions_only?: boolean;
create_empty_commit?: boolean;
submit_type?: SubmitType;
branches?: BranchName[];
owners?: GroupId[];
use_contributor_agreements?: InheritedBooleanInfoConfiguredValue;
use_signed_off_by?: InheritedBooleanInfoConfiguredValue;
create_new_change_for_all_not_in_target?: InheritedBooleanInfoConfiguredValue;
use_content_merge?: InheritedBooleanInfoConfiguredValue;
require_change_id?: InheritedBooleanInfoConfiguredValue;
enable_signed_push?: InheritedBooleanInfoConfiguredValue;
require_signed_push?: InheritedBooleanInfoConfiguredValue;
max_object_size_limit?: string;
plugin_config_values?: PluginConfigValues;
reject_empty_commit?: InheritedBooleanInfoConfiguredValue;
}
/**
* The BranchInfo entity contains information about a branch
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#branch-info
*/
export interface BranchInfo {
ref: GitRef;
revision: string;
can_delete?: boolean;
web_links?: WebLinkInfo[];
}
/**
* The ProjectAccessInput describes changes that should be applied to a project access config
* https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#project-access-input
*/
export interface ProjectAccessInput {
remove?: ProjectAccessInfo[];
add?: ProjectAccessInfo[];
message?: string;
parent?: string;
}
/**
* Represent a file in a base64 encoding
*/
export interface Base64File {
body: string;
type: string | null;
}
/**
* Represent a file in a base64 encoding; GrRestApiInterface returns it from some
* methods
*/
export interface Base64FileContent {
content: string | null;
type: string | null;
ok: true;
}
/**
* The WatchedProjectsInfo entity contains information about a project watch for a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#project-watch-info
*/
export interface ProjectWatchInfo {
project: ProjectName;
filter?: string;
notify_new_changes?: boolean;
notify_new_patch_sets?: boolean;
notify_all_comments?: boolean;
notify_submitted_changes?: boolean;
notify_abandoned_changes?: boolean;
}
/**
* The DeleteDraftCommentsInput entity contains information specifying a set of draft comments that should be deleted
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#delete-draft-comments-input
*/
export interface DeleteDraftCommentsInput {
query: string;
}
/**
* The AssigneeInput entity contains the identity of the user to be set as assignee
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#assignee-input
*/
export interface AssigneeInput {
assignee: AccountId;
}
/**
* The SshKeyInfo entity contains information about an SSH key of a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#ssh-key-info
*/
export interface SshKeyInfo {
seq: number;
ssh_public_key: string;
encoded_key: string;
algorithm: string;
comment?: string;
valid: boolean;
}
/**
* The HashtagsInput entity contains information about hashtags to add to, and/or remove from, a change
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#hashtags-input
*/
export interface HashtagsInput {
add?: Hashtag[];
remove?: Hashtag[];
}
/**
* Defines a patch ranges. Used as input for gr-rest-api-interface methods,
* doesn't exist in Rest API
*/
export interface PatchRange {
patchNum: PatchSetNum;
basePatchNum: PatchSetNum;
}
/**
* The CommentInput entity contains information for creating an inline comment
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#comment-input
*/
export interface CommentInput {
id?: UrlEncodedCommentId;
path?: string;
side?: CommentSide;
line?: number;
range?: CommentRange;
in_reply_to?: UrlEncodedCommentId;
updated: Timestamp;
message?: string;
tag?: string;
unresolved?: boolean;
}
/**
* The EditPreferencesInfo entity contains information about the edit preferences of a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#edit-preferences-info
*/
export interface EditPreferencesInfo {
tab_size: number;
line_length: number;
indent_unit: number;
cursor_blink_rate: number;
hide_top_menu?: boolean;
show_tabs?: boolean;
show_whitespace_errors?: boolean;
syntax_highlighting?: boolean;
hide_line_numbers?: boolean;
match_brackets?: boolean;
line_wrapping?: boolean;
indent_with_tabs?: boolean;
auto_close_brackets?: boolean;
show_base?: boolean;
// TODO(TS): the following proeprties doesn't exist in RestAPI doc
key_map_type?: string;
theme?: string;
}
/**
* The PreferencesInput entity contains information for setting the user preferences. Fields which are not set will not be updated
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-input
*/
export interface PreferencesInput {
changes_per_page: 10 | 25 | 50 | 100;
theme: AppTheme;
expand_inline_diffs?: boolean;
download_scheme?: string;
date_format: DateFormat;
time_format: TimeFormat;
relative_date_in_change_table?: boolean;
diff_view: DiffViewMode;
size_bar_in_change_table?: boolean;
legacycid_in_change_table?: boolean;
mute_common_path_prefixes?: boolean;
signed_off_by?: boolean;
my?: TopMenuItemInfo[];
change_table: string[];
email_strategy: EmailStrategy;
default_base_for_merges: DefaultBase;
}
/**
* The DiffPreferencesInput entity contains information for setting the diff preferences of a user. Fields which are not set will not be updated
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#diff-preferences-input
*/
export interface DiffPreferenceInput {
context?: number;
expand_all_comments?: number;
ignore_whitespace: IgnoreWhitespaceType;
intraline_difference?: boolean;
line_length?: number;
manual_review?: boolean;
retain_header?: boolean;
show_line_endings?: boolean;
show_tabs?: boolean;
show_whitespace_errors?: boolean;
skip_deleted?: boolean;
skip_uncommented?: boolean;
syntax_highlighting?: boolean;
hide_top_menu?: boolean;
auto_hide_diff_table_header?: boolean;
hide_line_numbers?: boolean;
tab_size?: number;
font_size?: number;
line_wrapping?: boolean;
indent_with_tabs?: boolean;
}
/**
* The EmailInfo entity contains information about an email address of a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#email-info
*/
export interface EmailInfo {
email: string;
preferred?: boolean;
pending_confirmation?: boolean;
}
/**
* The CapabilityInfo entity contains information about the global capabilities of a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#capability-info
*/
export interface AccountCapabilityInfo {
accessDatabase?: boolean;
administrateServer?: boolean;
createAccount?: boolean;
createGroup?: boolean;
createProject?: boolean;
emailReviewers?: boolean;
flushCaches?: boolean;
killTask?: boolean;
maintainServer?: boolean;
priority: UserPriority;
queryLimit: QueryLimitInfo;
runAs?: boolean;
runGC?: boolean;
streamEvents?: boolean;
viewAllAccounts?: boolean;
viewCaches?: boolean;
viewConnections?: boolean;
viewPlugins?: boolean;
viewQueue?: boolean;
}
/**
* The QueryLimitInfo entity contains information about the Query Limit of a user
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#query-limit-info
*/
export interface QueryLimitInfo {
min: number;
max: number;
}
/**
* The PreferencesInfo entity contains information about a users preferences
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#preferences-info
*/
export interface PreferencesInfo {
changes_per_page: 10 | 25 | 50 | 100;
theme: AppTheme;
expand_inline_diffs?: boolean;
download_scheme?: string;
date_format: DateFormat;
time_format: TimeFormat;
relative_date_in_change_table?: boolean;
diff_view: DiffViewMode;
size_bar_in_change_table?: boolean;
legacycid_in_change_table?: boolean;
mute_common_path_prefixes?: boolean;
signed_off_by?: boolean;
my: TopMenuItemInfo[];
change_table: string[];
email_strategy: EmailStrategy;
default_base_for_merges: DefaultBase;
publish_comments_on_push?: boolean;
work_in_progress_by_default?: boolean;
// The following property doesn't exist in RestAPI, it is added by GrRestApiInterface
default_diff_view?: DiffViewMode;
}
/**
* Contains information about diff images
* There is no RestAPI interface for it
*/
export interface ImagesForDiff {
baseImage: Base64ImageFile | null;
revisionImage: Base64ImageFile | null;
}
/**
* Contains information about diff image
* There is no RestAPI interface for it
*/
export interface Base64ImageFile extends Base64File {
_expectedType: string;
_name: string;
}
/**
* The ReviewInput entity contains information for adding a review to a revision
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#review-input
*/
export interface ReviewInput {
message?: string;
tag?: ReviewInputTag;
labels?: LabelNameToValuesMap;
comments?: PathToCommentsInputMap;
robot_comments?: PathToRobotCommentsMap;
drafts: DraftsAction;
notify?: NotifyType;
notify_details: RecipientTypeToNotifyInfoMap;
omit_duplicate_comments?: boolean;
on_behalf_of?: AccountId;
reviewers: ReviewerInput[];
ready?: boolean;
work_in_progress?: boolean;
add_to_attention_set?: AttentionSetInput[];
remove_from_attention_set?: AttentionSetInput[];
ignore_automatic_attention_set_rules?: boolean;
}
export type LabelNameToValuesMap = {[labelName: string]: string};
export type PathToCommentsInputMap = {[path: string]: CommentInput};
export type PathToRobotCommentsMap = {[path: string]: RobotCommentInput};
export type RecipientTypeToNotifyInfoMap = {
[recepientType: string]: NotifyInfo;
};
/**
* The RobotCommentInput entity contains information for creating an inline robot comment
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#robot-comment-input
*/
export type RobotCommentInput = RobotCommentInfo;
/**
* The RobotCommentInfo entity contains information about a robot inline comment
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#robot-comment-info
*/
export interface RobotCommentInfo extends CommentInfo {
robot_id: RobotId;
robot_run_id: RobotRunId;
url?: string;
properties: {[propertyName: string]: string};
fix_suggestions: FixSuggestionInfo[];
}
export type PathToRobotCommentsInfoMap = {[path: string]: RobotCommentInfo[]};
/**
* The FixSuggestionInfo entity represents a suggested fix
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#fix-suggestion-info
*/
export interface FixSuggestionInfo {
fix_id?: FixId;
description: string;
replacements: FixReplacementInfo[];
}
/**
* The FixReplacementInfo entity describes how the content of a file should be replaced by another content
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#fix-replacement-info
*/
export interface FixReplacementInfo {
path: string;
range: CommentRange;
replacement: string;
}
/**
* The NotifyInfo entity contains detailed information about who should be notified about an update
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#notify-info
*/
export interface NotifyInfo {
accounts?: AccountId[];
}
/**
* The ReviewerInput entity contains information for adding a reviewer to a change
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#reviewer-input
*/
export interface ReviewerInput {
reviewer: AccountId | GroupId;
state?: ReviewerState;
confirmed?: boolean;
notify?: NotifyType;
notify_details?: RecipientTypeToNotifyInfoMap;
}
/**
* The AttentionSetInput entity contains details for adding users to the attention set and removing them from it
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#attention-set-input
*/
export interface AttentionSetInput {
user?: AccountId;
reason: string;
notify: NotifyType;
notify_details?: RecipientTypeToNotifyInfoMap;
}
/**
* The EditInfo entity contains information about a change edit
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#edit-info
*/
export interface EditInfo {
commit: CommitInfo;
base_patch_set_number: PatchSetNum;
base_revision: string;
ref: GitRef;
fetch: ProtocolToFetchInfoMap;
files: FileNameToFileInfoMap;
}
export type ProtocolToFetchInfoMap = {[protocol: string]: FetchInfo};
export type FileNameToFileInfoMap = {[name: string]: FileInfo};
/**
* Contains information about an account that can be added to a change
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#suggested-reviewer-info
*/
export interface SuggestedReviewerAccountInfo {
account: AccountInfo;
/**
* The total number of accounts in the suggestion - always 1
*/
count: 1;
}
/**
* Contains information about a group that can be added to a change
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#suggested-reviewer-info
*/
export interface SuggestedReviewerGroupInfo {
group: GroupBaseInfo;
/**
* The total number of accounts that are members of the group is returned
* (this count includes members of nested groups)
*/
count: number;
/**
* True if group is present and count is above the threshold where the
* confirmed flag must be passed to add the group as a reviewer
*/
confirm?: boolean;
}
/**
* The SuggestedReviewerInfo entity contains information about a reviewer that can be added to a change (an account or a group)
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#suggested-reviewer-info
*/
export type SuggestedReviewerInfo =
| SuggestedReviewerAccountInfo
| SuggestedReviewerGroupInfo;
export function isReviewerAccountSuggestion(
s: Suggestion
): s is SuggestedReviewerAccountInfo {
return (s as SuggestedReviewerAccountInfo).account !== undefined;
}
export function isReviewerGroupSuggestion(
s: Suggestion
): s is SuggestedReviewerGroupInfo {
return (s as SuggestedReviewerGroupInfo).group !== undefined;
}
export type RequestPayload = string | object;

View File

@@ -14,12 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ParsedJSON} from './common';
export {};
declare global {
interface Window {
CANONICAL_PATH?: string;
INITIAL_DATA?: {[key: string]: string};
INITIAL_DATA?: {[key: string]: ParsedJSON};
ShadyCSS?: {
getComputedStyleValue(el: Element, name: string): string;
};
@@ -32,6 +34,12 @@ declare global {
options: {callback: (text: string, href?: string) => void}
): void;
ASSETS_PATH?: string;
DEFAULT_DETAIL_HEXES?: {
diffPage?: string;
changePage?: string;
dashboardPage?: string;
};
}
interface Performance {

View File

@@ -1,5 +1,6 @@
import {RevisionInfo, ChangeInfo, PatchSetNum} from '../types/common';
import {RestApiService} from '../services/services/gr-rest-api/gr-rest-api';
import {ParsedChangeInfo} from '../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
/**
* @license
@@ -160,7 +161,7 @@ export function sortRevisions<T extends RevisionInfo>(revisions: T[]): T[] {
* @return Sorted list of patch set objects, as described
* above
*/
export function computeAllPatchSets(change: ChangeInfo): PatchSet[] {
export function computeAllPatchSets(change: ParsedChangeInfo): PatchSet[] {
if (!change) {
return [];
}
@@ -195,7 +196,10 @@ export function computeAllPatchSets(change: ChangeInfo): PatchSet[] {
* @return The given list of patch set objects, with the
* wip property set on each of them
*/
function _computeWipForPatchSets(change: ChangeInfo, patchNums: PatchSet[]) {
function _computeWipForPatchSets(
change: ParsedChangeInfo,
patchNums: PatchSet[]
) {
if (!change.messages || !change.messages.length) {
return patchNums;
}