@gitbeaker/requester-utils 43.8.0 → 44.0.0-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +131 -131
- package/dist/index.d.mts +101 -96
- package/dist/index.mjs +177 -198
- package/package.json +20 -27
- package/dist/index.d.ts +0 -133
- package/dist/index.js +0 -241
package/dist/index.d.mts
CHANGED
|
@@ -1,133 +1,138 @@
|
|
|
1
|
-
import { Agent } from
|
|
2
|
-
|
|
1
|
+
import { Agent } from "http";
|
|
2
|
+
//#region src/RequesterUtils.d.ts
|
|
3
3
|
type RateLimiterFn = () => Promise<number>;
|
|
4
4
|
type RateLimiters = Record<string, RateLimiterFn | {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
method: string;
|
|
6
|
+
limit: RateLimiterFn;
|
|
7
7
|
}>;
|
|
8
8
|
type RateLimitOptions = Record<string, number | {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
method: string;
|
|
10
|
+
limit: number;
|
|
11
11
|
}>;
|
|
12
|
-
type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
type RequesterFn = (resourceOptions: ResourceOptions) => RequesterType;
|
|
13
|
+
type ResponseBodyType = Record<string, unknown>[] | string[] | Record<string, unknown> | ReadableStream | Blob | string | number | null;
|
|
14
|
+
type ResponseType = ResponseBodyType | void;
|
|
15
|
+
interface FormattedResponse<T extends ResponseType = ResponseType> {
|
|
16
|
+
body: T;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
status: number;
|
|
17
19
|
}
|
|
18
20
|
interface Constructable<T = any> {
|
|
19
|
-
|
|
21
|
+
new (...args: any[]): T;
|
|
20
22
|
}
|
|
21
23
|
type ResourceOptions = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
33
|
-
type DefaultRequestOptions = {
|
|
34
|
-
body?: FormData | Record<string, unknown>;
|
|
35
|
-
searchParams?: Record<string, unknown>;
|
|
36
|
-
sudo?: string | number;
|
|
37
|
-
method?: string;
|
|
38
|
-
asStream?: boolean;
|
|
39
|
-
signal?: AbortSignal;
|
|
24
|
+
headers: {
|
|
25
|
+
[header: string]: string;
|
|
26
|
+
};
|
|
27
|
+
authHeaders: {
|
|
28
|
+
[authHeader: string]: () => Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
url: string;
|
|
31
|
+
rateLimits?: RateLimitOptions;
|
|
32
|
+
rateLimitDuration?: number;
|
|
33
|
+
agent?: Agent;
|
|
40
34
|
};
|
|
41
|
-
type
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
signal?: AbortSignal;
|
|
50
|
-
rateLimiters?: Record<string, RateLimiterFn>;
|
|
51
|
-
agent?: Agent;
|
|
35
|
+
type RequesterBodyType = Record<string, unknown> | Record<string, unknown>[] | FormData | Blob | ArrayBuffer;
|
|
36
|
+
type RequesterSearchParams = Record<string, Record<string, string | number>[] | number[] | string[] | Record<string, string | number> | string | number | boolean>;
|
|
37
|
+
type DefaultRequesterOptions = {
|
|
38
|
+
body?: RequesterBodyType;
|
|
39
|
+
searchParams?: RequesterSearchParams;
|
|
40
|
+
sudo?: string | number;
|
|
41
|
+
asStream?: boolean;
|
|
42
|
+
signal?: AbortSignal;
|
|
52
43
|
};
|
|
53
44
|
interface RequesterType {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
45
|
+
get<T extends ResponseType>(endpoint: string, options?: DefaultRequesterOptions): Promise<FormattedResponse<T>>;
|
|
46
|
+
post<T extends ResponseType>(endpoint: string, options?: DefaultRequesterOptions): Promise<FormattedResponse<T>>;
|
|
47
|
+
put<T extends ResponseType>(endpoint: string, options?: DefaultRequesterOptions): Promise<FormattedResponse<T>>;
|
|
48
|
+
patch<T extends ResponseType>(endpoint: string, options?: DefaultRequesterOptions): Promise<FormattedResponse<T>>;
|
|
49
|
+
delete<T extends ResponseType>(endpoint: string, options?: DefaultRequesterOptions): Promise<FormattedResponse<T>>;
|
|
59
50
|
}
|
|
60
|
-
type
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
type RequestOptions = {
|
|
52
|
+
headers?: Record<string, string>;
|
|
53
|
+
timeout?: number;
|
|
54
|
+
method?: string;
|
|
55
|
+
searchParams?: string;
|
|
56
|
+
prefixUrl?: string;
|
|
57
|
+
body?: BodyInit;
|
|
58
|
+
asStream?: boolean;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
rateLimiters?: RateLimiters;
|
|
61
|
+
agent?: Agent;
|
|
62
|
+
};
|
|
63
|
+
type RequestHandlerFn<T extends ResponseType = ResponseType> = (endpoint: string, options?: RequestOptions) => Promise<FormattedResponse<T>>;
|
|
63
64
|
type OptionsHandlerFn = (serviceOptions: ResourceOptions, requestOptions: RequestOptions) => Promise<RequestOptions>;
|
|
64
|
-
|
|
65
|
+
type PresetConstructors<T> = { [K in keyof T]: T[K]; };
|
|
66
|
+
declare function generateRateLimiterFn(limit: number, interval: number): () => Promise<number>;
|
|
67
|
+
declare function formatQuery(params?: Record<string, unknown>): string;
|
|
68
|
+
declare function defaultOptionsHandler(resourceOptions: ResourceOptions, { body, searchParams, sudo, signal, asStream, method }?: {
|
|
69
|
+
method?: string;
|
|
70
|
+
} & DefaultRequesterOptions): Promise<RequestOptions>;
|
|
65
71
|
declare function createRateLimiters(rateLimitOptions?: RateLimitOptions, rateLimitDuration?: number): RateLimiters;
|
|
66
72
|
declare function createRequesterFn(optionsHandler: OptionsHandlerFn, requestHandler: RequestHandlerFn): (serviceOptions: ResourceOptions) => RequesterType;
|
|
67
|
-
|
|
68
|
-
[K in keyof T]: T[K];
|
|
69
|
-
};
|
|
70
|
-
declare function presetResourceArguments<T extends Record<string, any>>(resources: T, customConfig?: Record<string, unknown>): PresetConstructors<T>;
|
|
73
|
+
declare function presetResourceArguments<T extends Record<string, any>, Config extends Record<string, unknown>>(resources: T, customConfig?: Config): PresetConstructors<T>;
|
|
71
74
|
declare function getMatchingRateLimiter(endpoint: string, rateLimiters?: RateLimiters, method?: string): RateLimiterFn;
|
|
72
|
-
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/BaseResource.d.ts
|
|
73
77
|
interface RootResourceOptions<C> {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
requesterFn?: RequesterFn;
|
|
79
|
+
host?: string;
|
|
80
|
+
prefixUrl?: string;
|
|
81
|
+
camelize?: C;
|
|
82
|
+
queryTimeout?: number;
|
|
83
|
+
rateLimitDuration?: number;
|
|
84
|
+
sudo?: string | number;
|
|
85
|
+
profileToken?: string;
|
|
86
|
+
profileMode?: 'execution' | 'memory';
|
|
87
|
+
rateLimits?: RateLimitOptions;
|
|
88
|
+
agent?: Agent;
|
|
85
89
|
}
|
|
86
90
|
type GitlabToken = string | (() => Promise<string>);
|
|
87
91
|
interface BaseRequestOptionsWithOAuthToken<C> extends RootResourceOptions<C> {
|
|
88
|
-
|
|
92
|
+
oauthToken: GitlabToken;
|
|
89
93
|
}
|
|
90
94
|
interface BaseRequestOptionsWithAccessToken<C> extends RootResourceOptions<C> {
|
|
91
|
-
|
|
95
|
+
token: GitlabToken;
|
|
92
96
|
}
|
|
93
97
|
interface BaseRequestOptionsWithJobToken<C> extends RootResourceOptions<C> {
|
|
94
|
-
|
|
98
|
+
jobToken: GitlabToken;
|
|
95
99
|
}
|
|
96
100
|
type BaseRequestOptionsWithoutToken<C> = RootResourceOptions<C>;
|
|
97
101
|
type BaseResourceOptions<C> = BaseRequestOptionsWithoutToken<C> | BaseRequestOptionsWithOAuthToken<C> | BaseRequestOptionsWithAccessToken<C> | BaseRequestOptionsWithJobToken<C>;
|
|
98
102
|
declare class BaseResource<C extends boolean = false> {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
readonly url: string;
|
|
104
|
+
readonly requester: RequesterType;
|
|
105
|
+
headers: {
|
|
106
|
+
[header: string]: string;
|
|
107
|
+
};
|
|
108
|
+
readonly authHeaders: {
|
|
109
|
+
[authHeader: string]: () => Promise<string>;
|
|
110
|
+
};
|
|
111
|
+
readonly camelize: C | undefined;
|
|
112
|
+
readonly queryTimeout?: number;
|
|
113
|
+
constructor({ sudo, profileToken, camelize, requesterFn, agent, profileMode, host, prefixUrl, queryTimeout, rateLimitDuration, rateLimits, ...tokens }?: BaseResourceOptions<C>);
|
|
110
114
|
}
|
|
111
|
-
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/GitbeakerError.d.ts
|
|
112
117
|
declare class GitbeakerRequestError extends Error {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
readonly cause?: {
|
|
119
|
+
description: string;
|
|
120
|
+
request: Request;
|
|
121
|
+
response: Response;
|
|
122
|
+
};
|
|
123
|
+
constructor(message: string, options?: {
|
|
124
|
+
cause?: {
|
|
125
|
+
description: string;
|
|
126
|
+
request: Request;
|
|
127
|
+
response: Response;
|
|
117
128
|
};
|
|
118
|
-
|
|
119
|
-
cause?: {
|
|
120
|
-
description: string;
|
|
121
|
-
request: Request;
|
|
122
|
-
response: Response;
|
|
123
|
-
};
|
|
124
|
-
});
|
|
129
|
+
});
|
|
125
130
|
}
|
|
126
131
|
declare class GitbeakerTimeoutError extends Error {
|
|
127
|
-
|
|
132
|
+
constructor(message: string, options?: ErrorOptions);
|
|
128
133
|
}
|
|
129
134
|
declare class GitbeakerRetryError extends Error {
|
|
130
|
-
|
|
135
|
+
constructor(message: string, options?: ErrorOptions);
|
|
131
136
|
}
|
|
132
|
-
|
|
133
|
-
export {
|
|
137
|
+
//#endregion
|
|
138
|
+
export { BaseRequestOptionsWithAccessToken, BaseRequestOptionsWithJobToken, BaseRequestOptionsWithOAuthToken, BaseRequestOptionsWithoutToken, BaseResource, BaseResourceOptions, Constructable, DefaultRequesterOptions, FormattedResponse, GitbeakerRequestError, GitbeakerRetryError, GitbeakerTimeoutError, GitlabToken, OptionsHandlerFn, RateLimitOptions, RateLimiterFn, RateLimiters, RequestHandlerFn, RequestOptions, RequesterBodyType, RequesterFn, RequesterSearchParams, RequesterType, ResourceOptions, ResponseBodyType, ResponseType, RootResourceOptions, createRateLimiters, createRequesterFn, defaultOptionsHandler, formatQuery, generateRateLimiterFn, getMatchingRateLimiter, presetResourceArguments };
|
package/dist/index.mjs
CHANGED
|
@@ -1,225 +1,204 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var { isMatch: isGlobMatch } = Picomatch;
|
|
1
|
+
import Picomatch from "picomatch";
|
|
2
|
+
import { stringify } from "picoquery";
|
|
3
|
+
import { RateLimiterMemory, RateLimiterQueue } from "rate-limiter-flexible";
|
|
4
|
+
import { decamelizeKeys } from "xcase";
|
|
5
|
+
//#region src/RequesterUtils.ts
|
|
6
|
+
const { isMatch: isGlobMatch } = Picomatch;
|
|
8
7
|
function generateRateLimiterFn(limit, interval) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const limiter = new RateLimiterQueue(new RateLimiterMemory({
|
|
9
|
+
points: limit,
|
|
10
|
+
duration: interval
|
|
11
|
+
}));
|
|
12
|
+
return () => limiter.removeTokens(1);
|
|
13
13
|
}
|
|
14
14
|
function formatQuery(params = {}) {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
return stringify(decamelizeKeys(params), {
|
|
16
|
+
nesting: true,
|
|
17
|
+
nestingSyntax: "index",
|
|
18
|
+
arrayRepeat: true,
|
|
19
|
+
arrayRepeatSyntax: "bracket"
|
|
20
|
+
});
|
|
17
21
|
}
|
|
18
|
-
async function defaultOptionsHandler(resourceOptions, {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
if (Object.keys(authHeaders).length > 0) {
|
|
45
|
-
const [authHeaderKey, authHeaderFn] = Object.entries(authHeaders)[0];
|
|
46
|
-
defaultOptions.headers[authHeaderKey] = await authHeaderFn();
|
|
47
|
-
}
|
|
48
|
-
const q = formatQuery(searchParams);
|
|
49
|
-
if (q) defaultOptions.searchParams = q;
|
|
50
|
-
return Promise.resolve(defaultOptions);
|
|
22
|
+
async function defaultOptionsHandler(resourceOptions, { body, searchParams, sudo, signal, asStream = false, method = "GET" } = {}) {
|
|
23
|
+
const { headers: preconfiguredHeaders, authHeaders, url, agent } = resourceOptions;
|
|
24
|
+
const defaultOptions = {
|
|
25
|
+
method,
|
|
26
|
+
asStream,
|
|
27
|
+
signal,
|
|
28
|
+
prefixUrl: url,
|
|
29
|
+
agent
|
|
30
|
+
};
|
|
31
|
+
defaultOptions.headers = { ...preconfiguredHeaders };
|
|
32
|
+
if (sudo) defaultOptions.headers.sudo = `${sudo}`;
|
|
33
|
+
if (body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer || typeof body === "string") {
|
|
34
|
+
defaultOptions.body = body;
|
|
35
|
+
if (body instanceof Blob && body.type) defaultOptions.headers["Content-Type"] = body.type;
|
|
36
|
+
} else if (body != null) {
|
|
37
|
+
defaultOptions.body = JSON.stringify(decamelizeKeys(body));
|
|
38
|
+
defaultOptions.headers["Content-Type"] = "application/json";
|
|
39
|
+
}
|
|
40
|
+
if (Object.keys(authHeaders).length > 0) {
|
|
41
|
+
const [authHeaderKey, authHeaderFn] = Object.entries(authHeaders)[0];
|
|
42
|
+
defaultOptions.headers[authHeaderKey] = await authHeaderFn();
|
|
43
|
+
}
|
|
44
|
+
const q = formatQuery(searchParams);
|
|
45
|
+
if (q) defaultOptions.searchParams = q;
|
|
46
|
+
return Promise.resolve(defaultOptions);
|
|
51
47
|
}
|
|
52
48
|
function createRateLimiters(rateLimitOptions = {}, rateLimitDuration = 60) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
63
|
-
return rateLimiters;
|
|
49
|
+
const rateLimiters = {};
|
|
50
|
+
Object.entries(rateLimitOptions).forEach(([key, config]) => {
|
|
51
|
+
if (typeof config === "number") rateLimiters[key] = generateRateLimiterFn(config, rateLimitDuration);
|
|
52
|
+
else rateLimiters[key] = {
|
|
53
|
+
method: config.method.toUpperCase(),
|
|
54
|
+
limit: generateRateLimiterFn(config.limit, rateLimitDuration)
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
return rateLimiters;
|
|
64
58
|
}
|
|
65
59
|
function createRequesterFn(optionsHandler, requestHandler) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
60
|
+
const methods = [
|
|
61
|
+
"get",
|
|
62
|
+
"post",
|
|
63
|
+
"put",
|
|
64
|
+
"patch",
|
|
65
|
+
"delete"
|
|
66
|
+
];
|
|
67
|
+
return (serviceOptions) => {
|
|
68
|
+
const requester = {};
|
|
69
|
+
const rateLimiters = createRateLimiters(serviceOptions.rateLimits, serviceOptions.rateLimitDuration);
|
|
70
|
+
methods.forEach((m) => {
|
|
71
|
+
requester[m] = async (endpoint, options) => {
|
|
72
|
+
return requestHandler(endpoint, {
|
|
73
|
+
...await optionsHandler(serviceOptions, await defaultOptionsHandler(serviceOptions, {
|
|
74
|
+
...options,
|
|
75
|
+
method: m.toUpperCase()
|
|
76
|
+
})),
|
|
77
|
+
rateLimiters
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
return requester;
|
|
82
|
+
};
|
|
85
83
|
}
|
|
86
84
|
function createPresetConstructor(Constructor, presetConfig) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
return class extends Constructor {
|
|
86
|
+
constructor(...args) {
|
|
87
|
+
const [config, ...rest] = args;
|
|
88
|
+
super({
|
|
89
|
+
...presetConfig,
|
|
90
|
+
...config
|
|
91
|
+
}, ...rest);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
93
94
|
}
|
|
94
95
|
function presetResourceArguments(resources, customConfig = {}) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
);
|
|
102
|
-
} else {
|
|
103
|
-
result[key] = Constructor;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
return result;
|
|
96
|
+
const result = {};
|
|
97
|
+
Object.entries(resources).forEach(([key, Constructor]) => {
|
|
98
|
+
if (typeof Constructor === "function") result[key] = createPresetConstructor(Constructor, customConfig);
|
|
99
|
+
else result[key] = Constructor;
|
|
100
|
+
});
|
|
101
|
+
return result;
|
|
107
102
|
}
|
|
108
103
|
function getMatchingRateLimiter(endpoint, rateLimiters = {}, method = "GET") {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return rateLimitConfig.limit;
|
|
115
|
-
}
|
|
116
|
-
return generateRateLimiterFn(3e3, 60);
|
|
104
|
+
const match = Object.keys(rateLimiters).sort().reverse().find((ep) => isGlobMatch(endpoint, ep));
|
|
105
|
+
const rateLimitConfig = match && rateLimiters[match];
|
|
106
|
+
if (typeof rateLimitConfig === "function") return rateLimitConfig;
|
|
107
|
+
if (rateLimitConfig && rateLimitConfig?.method?.toUpperCase() === method.toUpperCase()) return rateLimitConfig.limit;
|
|
108
|
+
return generateRateLimiterFn(3e3, 60);
|
|
117
109
|
}
|
|
118
|
-
|
|
119
|
-
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/BaseResource.ts
|
|
120
112
|
function getDynamicToken(tokenArgument) {
|
|
121
|
-
|
|
113
|
+
return tokenArgument instanceof Function ? tokenArgument() : Promise.resolve(tokenArgument);
|
|
122
114
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"projects/*/repository/archive*": 5,
|
|
152
|
-
// Project Jobs
|
|
153
|
-
"projects/*/jobs": 600,
|
|
154
|
-
// Member deletion
|
|
155
|
-
"projects/*/members": 60,
|
|
156
|
-
"groups/*/members": 60
|
|
115
|
+
const DEFAULT_RATE_LIMITS = Object.freeze({
|
|
116
|
+
"**": 3e3,
|
|
117
|
+
"projects/import": 6,
|
|
118
|
+
"projects/*/export": 6,
|
|
119
|
+
"projects/*/download": 1,
|
|
120
|
+
"groups/import": 6,
|
|
121
|
+
"groups/*/export": 6,
|
|
122
|
+
"groups/*/download": 1,
|
|
123
|
+
"projects/*/issues/*/notes": {
|
|
124
|
+
method: "post",
|
|
125
|
+
limit: 300
|
|
126
|
+
},
|
|
127
|
+
"projects/*/snippets/*/notes": {
|
|
128
|
+
method: "post",
|
|
129
|
+
limit: 300
|
|
130
|
+
},
|
|
131
|
+
"projects/*/merge_requests/*/notes": {
|
|
132
|
+
method: "post",
|
|
133
|
+
limit: 300
|
|
134
|
+
},
|
|
135
|
+
"groups/*/epics/*/notes": {
|
|
136
|
+
method: "post",
|
|
137
|
+
limit: 300
|
|
138
|
+
},
|
|
139
|
+
"projects/*/repository/archive*": 5,
|
|
140
|
+
"projects/*/jobs": 600,
|
|
141
|
+
"projects/*/members": 60,
|
|
142
|
+
"groups/*/members": 60
|
|
157
143
|
});
|
|
158
144
|
var BaseResource = class {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (profileToken) {
|
|
195
|
-
this.headers["X-Profile-Token"] = profileToken;
|
|
196
|
-
this.headers["X-Profile-Mode"] = profileMode;
|
|
197
|
-
}
|
|
198
|
-
if (sudo) this.headers.Sudo = `${sudo}`;
|
|
199
|
-
this.requester = requesterFn({ ...this, rateLimits, rateLimitDuration, agent });
|
|
200
|
-
}
|
|
145
|
+
url;
|
|
146
|
+
requester;
|
|
147
|
+
headers;
|
|
148
|
+
authHeaders;
|
|
149
|
+
camelize;
|
|
150
|
+
queryTimeout;
|
|
151
|
+
constructor({ sudo, profileToken, camelize, requesterFn, agent, profileMode = "execution", host = "https://gitlab.com", prefixUrl = "", queryTimeout = 3e5, rateLimitDuration = 60, rateLimits = DEFAULT_RATE_LIMITS, ...tokens } = {}) {
|
|
152
|
+
if (!requesterFn) throw new ReferenceError("Missing requesterFn: BaseResource requires a function to handle HTTP requests");
|
|
153
|
+
this.url = [
|
|
154
|
+
host,
|
|
155
|
+
"api",
|
|
156
|
+
"v4",
|
|
157
|
+
prefixUrl
|
|
158
|
+
].join("/");
|
|
159
|
+
this.headers = {};
|
|
160
|
+
this.authHeaders = {};
|
|
161
|
+
this.camelize = camelize;
|
|
162
|
+
this.queryTimeout = queryTimeout;
|
|
163
|
+
if ("oauthToken" in tokens) this.authHeaders.authorization = async () => {
|
|
164
|
+
return `Bearer ${await getDynamicToken(tokens.oauthToken)}`;
|
|
165
|
+
};
|
|
166
|
+
else if ("jobToken" in tokens) this.authHeaders["job-token"] = async () => getDynamicToken(tokens.jobToken);
|
|
167
|
+
else if ("token" in tokens) this.authHeaders["private-token"] = async () => getDynamicToken(tokens.token);
|
|
168
|
+
if (profileToken) {
|
|
169
|
+
this.headers["X-Profile-Token"] = profileToken;
|
|
170
|
+
this.headers["X-Profile-Mode"] = profileMode;
|
|
171
|
+
}
|
|
172
|
+
if (sudo) this.headers.Sudo = `${sudo}`;
|
|
173
|
+
this.requester = requesterFn({
|
|
174
|
+
...this,
|
|
175
|
+
rateLimits,
|
|
176
|
+
rateLimitDuration,
|
|
177
|
+
agent
|
|
178
|
+
});
|
|
179
|
+
}
|
|
201
180
|
};
|
|
202
|
-
|
|
203
|
-
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region src/GitbeakerError.ts
|
|
204
183
|
var GitbeakerRequestError = class extends Error {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
184
|
+
cause;
|
|
185
|
+
constructor(message, options) {
|
|
186
|
+
super(message, options);
|
|
187
|
+
this.cause = options?.cause;
|
|
188
|
+
this.name = "GitbeakerRequestError";
|
|
189
|
+
}
|
|
211
190
|
};
|
|
212
191
|
var GitbeakerTimeoutError = class extends Error {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
192
|
+
constructor(message, options) {
|
|
193
|
+
super(message, options);
|
|
194
|
+
this.name = "GitbeakerTimeoutError";
|
|
195
|
+
}
|
|
217
196
|
};
|
|
218
197
|
var GitbeakerRetryError = class extends Error {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
198
|
+
constructor(message, options) {
|
|
199
|
+
super(message, options);
|
|
200
|
+
this.name = "GitbeakerRetryError";
|
|
201
|
+
}
|
|
223
202
|
};
|
|
224
|
-
|
|
203
|
+
//#endregion
|
|
225
204
|
export { BaseResource, GitbeakerRequestError, GitbeakerRetryError, GitbeakerTimeoutError, createRateLimiters, createRequesterFn, defaultOptionsHandler, formatQuery, generateRateLimiterFn, getMatchingRateLimiter, presetResourceArguments };
|