@forge/events 1.1.0-next.0 → 2.0.0-next.2
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/CHANGELOG.md +14 -0
- package/README.md +32 -26
- package/out/__test__/jobProgress.test.js +15 -16
- package/out/__test__/queue.test.js +89 -40
- package/out/__test__/utils.js +1 -1
- package/out/errors.d.ts +17 -19
- package/out/errors.d.ts.map +1 -1
- package/out/errors.js +21 -34
- package/out/index.d.ts +2 -1
- package/out/index.d.ts.map +1 -1
- package/out/jobProgress.d.ts +11 -4
- package/out/jobProgress.d.ts.map +1 -1
- package/out/jobProgress.js +9 -9
- package/out/queue.d.ts +2 -2
- package/out/queue.d.ts.map +1 -1
- package/out/queue.js +8 -13
- package/out/text.d.ts +2 -0
- package/out/text.d.ts.map +1 -1
- package/out/text.js +2 -0
- package/out/types.d.ts +24 -9
- package/out/types.d.ts.map +1 -1
- package/out/validators.d.ts +4 -4
- package/out/validators.d.ts.map +1 -1
- package/out/validators.js +22 -11
- package/package.json +1 -1
- package/src/__test__/jobProgress.test.ts +16 -16
- package/src/__test__/queue.test.ts +103 -44
- package/src/__test__/utils.ts +1 -1
- package/src/errors.ts +20 -43
- package/src/index.ts +2 -1
- package/src/jobProgress.ts +17 -12
- package/src/queue.ts +10 -16
- package/src/text.ts +2 -0
- package/src/types.ts +30 -7
- package/src/validators.ts +27 -10
- package/tsconfig.tsbuildinfo +1 -1
package/out/jobProgress.js
CHANGED
|
@@ -5,35 +5,35 @@ const api_1 = require("@forge/api");
|
|
|
5
5
|
const queries_1 = require("./queries");
|
|
6
6
|
const validators_1 = require("./validators");
|
|
7
7
|
class JobProgress {
|
|
8
|
+
queueParams;
|
|
8
9
|
id;
|
|
9
10
|
apiClient;
|
|
10
|
-
constructor(id, apiClient = api_1.__requestAtlassianAsApp) {
|
|
11
|
+
constructor(queueParams, id, apiClient = api_1.__requestAtlassianAsApp) {
|
|
12
|
+
this.queueParams = queueParams;
|
|
11
13
|
this.id = id;
|
|
12
14
|
this.apiClient = apiClient;
|
|
13
15
|
}
|
|
14
16
|
async getStats() {
|
|
15
|
-
const [queueName, jobId] = this.id.split('#');
|
|
16
17
|
const getStatsRequest = {
|
|
17
|
-
queueName:
|
|
18
|
-
jobId:
|
|
18
|
+
queueName: this.queueParams.key,
|
|
19
|
+
jobId: this.id,
|
|
19
20
|
time: new Date().toISOString()
|
|
20
21
|
};
|
|
21
22
|
(0, validators_1.validateGetStatsPayload)(getStatsRequest);
|
|
22
23
|
const response = await (0, queries_1.post)(queries_1.GET_STATS_PATH, getStatsRequest, this.apiClient);
|
|
23
24
|
await (0, validators_1.validateGetStatsAPIResponse)(response, getStatsRequest);
|
|
24
|
-
|
|
25
|
+
const { success, inProgress, failed } = await response.json();
|
|
26
|
+
return { success, inProgress, failed };
|
|
25
27
|
}
|
|
26
28
|
async cancel() {
|
|
27
|
-
const [queueName, jobId] = this.id.split('#');
|
|
28
29
|
const cancelJobRequest = {
|
|
29
|
-
queueName:
|
|
30
|
-
jobId:
|
|
30
|
+
queueName: this.queueParams.key,
|
|
31
|
+
jobId: this.id,
|
|
31
32
|
time: new Date().toISOString()
|
|
32
33
|
};
|
|
33
34
|
(0, validators_1.validateCancelJobRequest)(cancelJobRequest);
|
|
34
35
|
const response = await (0, queries_1.post)(queries_1.CANCEL_JOB_PATH, cancelJobRequest, this.apiClient);
|
|
35
36
|
await (0, validators_1.validateCancelJobAPIResponse)(response, cancelJobRequest);
|
|
36
|
-
return response;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
exports.JobProgress = JobProgress;
|
package/out/queue.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { FetchMethod } from '@forge/api';
|
|
2
|
-
import {
|
|
2
|
+
import { QueueParams, PushEvent, PushResult } from './types';
|
|
3
3
|
import { JobProgress } from './jobProgress';
|
|
4
4
|
export declare class Queue {
|
|
5
5
|
private readonly queueParams;
|
|
6
6
|
private readonly apiClient;
|
|
7
7
|
constructor(queueParams: QueueParams, apiClient?: FetchMethod);
|
|
8
|
-
push(
|
|
8
|
+
push(events: PushEvent | PushEvent[]): Promise<PushResult>;
|
|
9
9
|
getJob(jobId: string): JobProgress;
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=queue.d.ts.map
|
package/out/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAe,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,qBAAa,KAAK;IAEd,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,WAAW,EAAE,WAAW,EACxB,SAAS,GAAE,WAAqC;IAK7D,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAoBhE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;CAGnC"}
|
package/out/queue.js
CHANGED
|
@@ -14,30 +14,25 @@ class Queue {
|
|
|
14
14
|
this.apiClient = apiClient;
|
|
15
15
|
(0, validators_1.validateQueueKey)(this.queueParams.key);
|
|
16
16
|
}
|
|
17
|
-
async push(
|
|
18
|
-
(0, validators_1.
|
|
17
|
+
async push(events) {
|
|
18
|
+
const validEvents = (0, validators_1.validatePushEvents)(events);
|
|
19
19
|
const queueName = this.queueParams.key;
|
|
20
20
|
const jobId = (0, uuid_1.v4)();
|
|
21
21
|
const pushRequest = {
|
|
22
22
|
queueName: queueName,
|
|
23
23
|
jobId: jobId,
|
|
24
24
|
type: 'avi:forge:app:event',
|
|
25
|
-
schema: 'ari:cloud:ecosystem::forge/app-event',
|
|
26
|
-
payload:
|
|
25
|
+
schema: 'ari:cloud:ecosystem::forge/app-event-2',
|
|
26
|
+
payload: validEvents,
|
|
27
27
|
time: new Date().toISOString()
|
|
28
28
|
};
|
|
29
|
-
if (pushSettings) {
|
|
30
|
-
(0, validators_1.validatePushSettings)(pushSettings);
|
|
31
|
-
if (pushSettings.delayInSeconds) {
|
|
32
|
-
pushRequest.delayInSeconds = pushSettings.delayInSeconds;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
29
|
const response = await (0, queries_1.post)(queries_1.PUSH_PATH, pushRequest, this.apiClient);
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
const result = { jobId };
|
|
31
|
+
await (0, validators_1.validatePushAPIResponse)(pushRequest, response, result);
|
|
32
|
+
return result;
|
|
38
33
|
}
|
|
39
34
|
getJob(jobId) {
|
|
40
|
-
return new jobProgress_1.JobProgress(jobId, this.apiClient);
|
|
35
|
+
return new jobProgress_1.JobProgress(this.queueParams, jobId, this.apiClient);
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
exports.Queue = Queue;
|
package/out/text.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const Text: {
|
|
2
2
|
error: {
|
|
3
3
|
invalidQueueName: string;
|
|
4
|
+
invalidEvent: string;
|
|
5
|
+
invalidEventBody: string;
|
|
4
6
|
invalidDelayInSecondsSetting: string;
|
|
5
7
|
maxEventsAllowed: (maxEventsCount: number) => string;
|
|
6
8
|
maxPayloadAllowed: (maxPayloadSize: number) => string;
|
package/out/text.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI;;;;;;2CAMsB,MAAM,KAAG,MAAM;4CAEd,MAAM,KAAG,MAAM;;;;;gCAK3B,MAAM,aAAa,MAAM,KAAG,MAAM;;CAG7D,CAAC"}
|
package/out/text.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.Text = void 0;
|
|
|
4
4
|
exports.Text = {
|
|
5
5
|
error: {
|
|
6
6
|
invalidQueueName: `Queue names can only contain alphanumeric characters, dashes and underscores.`,
|
|
7
|
+
invalidEvent: `Event must be an object.`,
|
|
8
|
+
invalidEventBody: `Event body must be an object.`,
|
|
7
9
|
invalidDelayInSecondsSetting: `The delayInSeconds setting must be between 0 and 900.`,
|
|
8
10
|
maxEventsAllowed: (maxEventsCount) => `This push contains more than the ${maxEventsCount} events allowed.`,
|
|
9
11
|
maxPayloadAllowed: (maxPayloadSize) => `The maximum payload size is ${maxPayloadSize}KB.`,
|
package/out/types.d.ts
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
};
|
|
4
|
-
export interface PushSettings {
|
|
5
|
-
delayInSeconds: number;
|
|
6
|
-
}
|
|
1
|
+
import { InvocationErrorCode } from './invocationErrorCode';
|
|
2
|
+
export declare type Payload = Record<string, unknown>;
|
|
7
3
|
export interface QueueParams {
|
|
8
4
|
key: string;
|
|
9
5
|
}
|
|
10
6
|
export interface PushRequest extends APIRequest {
|
|
11
|
-
payload:
|
|
7
|
+
payload: PushEvent[];
|
|
12
8
|
schema: string;
|
|
13
9
|
type: string;
|
|
14
|
-
|
|
10
|
+
jobId: string;
|
|
15
11
|
}
|
|
16
12
|
export interface APIRequest {
|
|
17
13
|
queueName: string;
|
|
18
14
|
jobId: string;
|
|
19
15
|
time: string;
|
|
20
16
|
}
|
|
17
|
+
export interface PushEvent {
|
|
18
|
+
body: Body;
|
|
19
|
+
delayInSeconds?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare type Body = Record<string, unknown>;
|
|
22
|
+
export interface PushResult {
|
|
23
|
+
jobId: string;
|
|
24
|
+
}
|
|
21
25
|
export interface FailedEvent {
|
|
22
26
|
errorMessage: string;
|
|
23
|
-
|
|
27
|
+
event: PushEvent;
|
|
28
|
+
}
|
|
29
|
+
export interface AsyncEvent extends PushEvent {
|
|
30
|
+
queueName: string;
|
|
31
|
+
jobId: string;
|
|
32
|
+
eventId: string;
|
|
33
|
+
retryContext?: RetryContext;
|
|
34
|
+
}
|
|
35
|
+
export interface RetryContext {
|
|
36
|
+
retryCount: number;
|
|
37
|
+
retryReason: InvocationErrorCode;
|
|
38
|
+
retryData: any;
|
|
24
39
|
}
|
|
25
40
|
export declare type GetStatsRequest = APIRequest;
|
|
26
41
|
export declare type CancelJobRequest = APIRequest;
|
package/out/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,oBAAY,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,oBAAY,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,mBAAmB,CAAC;IACjC,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,oBAAY,eAAe,GAAG,UAAU,CAAC;AACzC,oBAAY,gBAAgB,GAAG,UAAU,CAAC"}
|
package/out/validators.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { APIResponse } from '@forge/api';
|
|
2
|
-
import { CancelJobRequest, GetStatsRequest,
|
|
2
|
+
import { CancelJobRequest, GetStatsRequest, PushEvent, PushRequest, PushResult } from './types';
|
|
3
3
|
export declare const validateQueueKey: (queueName: string) => void;
|
|
4
|
-
export declare const validatePushSettings: (
|
|
5
|
-
export declare
|
|
4
|
+
export declare const validatePushSettings: (event: PushEvent) => void;
|
|
5
|
+
export declare function validatePushEvents(arg: PushEvent | PushEvent[]): PushEvent[];
|
|
6
6
|
export declare const validateGetStatsPayload: (getStatsRequest: GetStatsRequest) => void;
|
|
7
7
|
export declare const validateCancelJobRequest: (cancelJobRequest: CancelJobRequest) => void;
|
|
8
8
|
export declare const validateAPIResponse: (response: APIResponse, expectedSuccessStatus: number) => Promise<void>;
|
|
9
|
-
export declare const validatePushAPIResponse: (response: APIResponse,
|
|
9
|
+
export declare const validatePushAPIResponse: (requestBody: PushRequest, response: APIResponse, result: PushResult) => Promise<void>;
|
|
10
10
|
export declare const validateGetStatsAPIResponse: (response: APIResponse, getStatsRequest: GetStatsRequest) => Promise<void>;
|
|
11
11
|
export declare const validateCancelJobAPIResponse: (response: APIResponse, cancelJobRequest: GetStatsRequest) => Promise<void>;
|
|
12
12
|
//# sourceMappingURL=validators.d.ts.map
|
package/out/validators.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../src/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAezC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAMhG,eAAO,MAAM,gBAAgB,cAAe,MAAM,SAIjD,CAAC;AAEF,eAAO,MAAM,oBAAoB,UAAW,SAAS,SAIpD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,EAAE,GAAG,SAAS,EAAE,CA6B5E;AAED,eAAO,MAAM,uBAAuB,oBAAqB,eAAe,SAKvE,CAAC;AAEF,eAAO,MAAM,wBAAwB,qBAAsB,gBAAgB,SAK1E,CAAC;AAEF,eAAO,MAAM,mBAAmB,aAAoB,WAAW,yBAAyB,MAAM,kBA6B7F,CAAC;AAEF,eAAO,MAAM,uBAAuB,gBAAuB,WAAW,YAAY,WAAW,UAAU,UAAU,kBAkChH,CAAC;AAEF,eAAO,MAAM,2BAA2B,aAAoB,WAAW,mBAAmB,eAAe,kBAMxG,CAAC;AAEF,eAAO,MAAM,4BAA4B,aAAoB,WAAW,oBAAoB,eAAe,kBAM1G,CAAC"}
|
package/out/validators.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateCancelJobAPIResponse = exports.validateGetStatsAPIResponse = exports.validatePushAPIResponse = exports.validateAPIResponse = exports.validateCancelJobRequest = exports.validateGetStatsPayload = exports.
|
|
3
|
+
exports.validateCancelJobAPIResponse = exports.validateGetStatsAPIResponse = exports.validatePushAPIResponse = exports.validateAPIResponse = exports.validateCancelJobRequest = exports.validateGetStatsPayload = exports.validatePushEvents = exports.validatePushSettings = exports.validateQueueKey = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
5
|
const text_1 = require("./text");
|
|
6
6
|
const VALID_QUEUE_NAME_PATTERN = /^[a-zA-Z0-9-_]+$/;
|
|
@@ -12,25 +12,36 @@ const validateQueueKey = (queueName) => {
|
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
14
|
exports.validateQueueKey = validateQueueKey;
|
|
15
|
-
const validatePushSettings = (
|
|
16
|
-
if ((
|
|
15
|
+
const validatePushSettings = (event) => {
|
|
16
|
+
if ((event.delayInSeconds && event.delayInSeconds > 900) || (event.delayInSeconds && event.delayInSeconds < 0)) {
|
|
17
17
|
throw new errors_1.InvalidPushSettingsError(text_1.Text.error.invalidDelayInSecondsSetting);
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
exports.validatePushSettings = validatePushSettings;
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function validatePushEvents(arg) {
|
|
22
|
+
const events = Array.isArray(arg) ? arg : [arg];
|
|
23
|
+
if (events.length === 0) {
|
|
23
24
|
throw new errors_1.NoEventsToPushError(text_1.Text.error.noEventsPushed);
|
|
24
25
|
}
|
|
25
|
-
if (
|
|
26
|
+
if (events.length > MAXIMUM_EVENTS) {
|
|
26
27
|
throw new errors_1.TooManyEventsError(text_1.Text.error.maxEventsAllowed(MAXIMUM_EVENTS));
|
|
27
28
|
}
|
|
28
|
-
const
|
|
29
|
+
for (const event of events) {
|
|
30
|
+
if (typeof event !== 'object' || Array.isArray(event) || event === null) {
|
|
31
|
+
throw new errors_1.InvalidPayloadError(text_1.Text.error.invalidEvent);
|
|
32
|
+
}
|
|
33
|
+
if (typeof event.body !== 'object' || Array.isArray(event.body) || event.body === null) {
|
|
34
|
+
throw new errors_1.InvalidPayloadError(text_1.Text.error.invalidEventBody);
|
|
35
|
+
}
|
|
36
|
+
(0, exports.validatePushSettings)(event);
|
|
37
|
+
}
|
|
38
|
+
const payloadSizeKB = Buffer.byteLength(JSON.stringify(events)) / 1024;
|
|
29
39
|
if (payloadSizeKB > MAXIMUM_PAYLOAD_SIZE_KB) {
|
|
30
40
|
throw new errors_1.PayloadTooBigError(text_1.Text.error.maxPayloadAllowed(MAXIMUM_PAYLOAD_SIZE_KB));
|
|
31
41
|
}
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
return events;
|
|
43
|
+
}
|
|
44
|
+
exports.validatePushEvents = validatePushEvents;
|
|
34
45
|
const validateGetStatsPayload = (getStatsRequest) => {
|
|
35
46
|
if (!getStatsRequest.jobId) {
|
|
36
47
|
throw new errors_1.JobDoesNotExistError(text_1.Text.error.jobIdEmpty);
|
|
@@ -67,7 +78,7 @@ const validateAPIResponse = async (response, expectedSuccessStatus) => {
|
|
|
67
78
|
}
|
|
68
79
|
};
|
|
69
80
|
exports.validateAPIResponse = validateAPIResponse;
|
|
70
|
-
const validatePushAPIResponse = async (response,
|
|
81
|
+
const validatePushAPIResponse = async (requestBody, response, result) => {
|
|
71
82
|
if (response.status === 413) {
|
|
72
83
|
const responseBody = await response.json();
|
|
73
84
|
throw new errors_1.PayloadTooBigError(responseBody.errorMessage);
|
|
@@ -75,7 +86,7 @@ const validatePushAPIResponse = async (response, requestBody) => {
|
|
|
75
86
|
if (response.status === 202) {
|
|
76
87
|
const responseBody = await response.json();
|
|
77
88
|
const defaultErrorMessage = 'Failed to process some events.';
|
|
78
|
-
const partialSuccessError = new errors_1.PartialSuccessError(defaultErrorMessage, []);
|
|
89
|
+
const partialSuccessError = new errors_1.PartialSuccessError(defaultErrorMessage, result, []);
|
|
79
90
|
if (responseBody.failedEvents && responseBody.failedEvents.length > 0) {
|
|
80
91
|
partialSuccessError.message = `Failed to process ${responseBody.failedEvents.length} event(s).`;
|
|
81
92
|
partialSuccessError.failedEvents = responseBody.failedEvents.map((failedEvent) => {
|
package/package.json
CHANGED
|
@@ -2,12 +2,14 @@ import { getMockFetchMethod, verifyApiClientCalledWith } from './utils';
|
|
|
2
2
|
import { InternalServerError, InvalidQueueNameError, JobDoesNotExistError, RateLimitError } from '../errors';
|
|
3
3
|
import { JobProgress } from '../jobProgress';
|
|
4
4
|
import { __requestAtlassianAsApp } from '@forge/api';
|
|
5
|
+
import { QueueParams } from '../types';
|
|
5
6
|
|
|
6
7
|
jest.mock('@forge/api', () => ({
|
|
7
|
-
__requestAtlassianAsApp: getMockFetchMethod(
|
|
8
|
+
__requestAtlassianAsApp: getMockFetchMethod({ done: true }, 200)
|
|
8
9
|
}));
|
|
9
10
|
|
|
10
|
-
const
|
|
11
|
+
const queueParams: QueueParams = { key: 'test-queue-name' };
|
|
12
|
+
const getJobProgress = (jobId: string, apiClientMock?: any) => new JobProgress(queueParams, jobId, apiClientMock);
|
|
11
13
|
|
|
12
14
|
describe('JobProgress methods', () => {
|
|
13
15
|
describe('getStats', () => {
|
|
@@ -20,9 +22,8 @@ describe('JobProgress methods', () => {
|
|
|
20
22
|
},
|
|
21
23
|
200
|
|
22
24
|
);
|
|
23
|
-
const jobProgress = getJobProgress('test-
|
|
24
|
-
const
|
|
25
|
-
const { success, inProgress, failed } = await response.json();
|
|
25
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
26
|
+
const { success, inProgress, failed } = await jobProgress.getStats();
|
|
26
27
|
verifyApiClientCalledWith(
|
|
27
28
|
apiClientMock,
|
|
28
29
|
'/webhook/queue/stats/{contextAri}/{environmentId}/{appId}/{appVersion}',
|
|
@@ -44,7 +45,7 @@ describe('JobProgress methods', () => {
|
|
|
44
45
|
},
|
|
45
46
|
404
|
|
46
47
|
);
|
|
47
|
-
const jobProgress = getJobProgress('test-
|
|
48
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
48
49
|
await expect(jobProgress.getStats()).rejects.toThrow(
|
|
49
50
|
new JobDoesNotExistError(`The job test-job-id was not found for the queue test-queue-name.`)
|
|
50
51
|
);
|
|
@@ -60,7 +61,7 @@ describe('JobProgress methods', () => {
|
|
|
60
61
|
|
|
61
62
|
it('should throw RateLimitError', async () => {
|
|
62
63
|
const apiClientMock = getMockFetchMethod({}, 429);
|
|
63
|
-
const jobProgress = getJobProgress('test-
|
|
64
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
64
65
|
await expect(jobProgress.getStats()).rejects.toThrow(new RateLimitError(`Too many requests.`));
|
|
65
66
|
verifyApiClientCalledWith(
|
|
66
67
|
apiClientMock,
|
|
@@ -81,7 +82,7 @@ describe('JobProgress methods', () => {
|
|
|
81
82
|
},
|
|
82
83
|
513
|
|
83
84
|
);
|
|
84
|
-
const jobProgress = getJobProgress('test-
|
|
85
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
85
86
|
await expect(jobProgress.getStats()).rejects.toThrow(
|
|
86
87
|
new InternalServerError(`513 Status Text: Service is not available`, 513)
|
|
87
88
|
);
|
|
@@ -99,8 +100,8 @@ describe('JobProgress methods', () => {
|
|
|
99
100
|
describe('cancel', () => {
|
|
100
101
|
it('should call the queue/cancel endpoint', async () => {
|
|
101
102
|
const apiClientMock = getMockFetchMethod({}, 204);
|
|
102
|
-
const jobProgress = getJobProgress('test-
|
|
103
|
-
|
|
103
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
104
|
+
await jobProgress.cancel();
|
|
104
105
|
verifyApiClientCalledWith(
|
|
105
106
|
apiClientMock,
|
|
106
107
|
'/webhook/queue/cancel/{contextAri}/{environmentId}/{appId}/{appVersion}',
|
|
@@ -109,7 +110,6 @@ describe('JobProgress methods', () => {
|
|
|
109
110
|
jobId: 'test-job-id'
|
|
110
111
|
}
|
|
111
112
|
);
|
|
112
|
-
expect(response.status).toEqual(204);
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
it('should throw JobDoesNotExistError', async () => {
|
|
@@ -120,7 +120,7 @@ describe('JobProgress methods', () => {
|
|
|
120
120
|
},
|
|
121
121
|
404
|
|
122
122
|
);
|
|
123
|
-
const jobProgress = getJobProgress('test-
|
|
123
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
124
124
|
await expect(jobProgress.cancel()).rejects.toThrow(
|
|
125
125
|
new JobDoesNotExistError(`The job test-job-id was not found for the queue test-queue-name.`)
|
|
126
126
|
);
|
|
@@ -142,7 +142,7 @@ describe('JobProgress methods', () => {
|
|
|
142
142
|
},
|
|
143
143
|
422
|
|
144
144
|
);
|
|
145
|
-
const jobProgress = getJobProgress('test-
|
|
145
|
+
const jobProgress = getJobProgress('test-job-id', apiClientMock);
|
|
146
146
|
await expect(jobProgress.getStats()).rejects.toThrow(
|
|
147
147
|
new InternalServerError(`422 Status Text: jobId must not be null, queueName must not be null`)
|
|
148
148
|
);
|
|
@@ -162,10 +162,10 @@ describe('JobProgress methods', () => {
|
|
|
162
162
|
},
|
|
163
163
|
200
|
|
164
164
|
);
|
|
165
|
-
const jobProgress1 = getJobProgress('
|
|
165
|
+
const jobProgress1 = getJobProgress('', apiClientMock);
|
|
166
166
|
await expect(jobProgress1.getStats()).rejects.toThrow(new JobDoesNotExistError(`jobId cannot be empty.`));
|
|
167
167
|
|
|
168
|
-
const jobProgress2 =
|
|
168
|
+
const jobProgress2 = new JobProgress({ key: '!' }, 'test-job-id', apiClientMock);
|
|
169
169
|
await expect(jobProgress2.getStats()).rejects.toThrow(
|
|
170
170
|
new InvalidQueueNameError('Queue names can only contain alphanumeric characters, dashes and underscores.')
|
|
171
171
|
);
|
|
@@ -177,7 +177,7 @@ describe('JobProgress methods', () => {
|
|
|
177
177
|
});
|
|
178
178
|
|
|
179
179
|
it('requests stargate if no api client is provided', async () => {
|
|
180
|
-
const jobProgress = getJobProgress('
|
|
180
|
+
const jobProgress = getJobProgress('job-id');
|
|
181
181
|
await jobProgress.getStats();
|
|
182
182
|
expect(__requestAtlassianAsApp).toHaveBeenCalledTimes(1);
|
|
183
183
|
});
|