npm package diff
Package: @forge/events
Versions: 2.0.1-next.0 - 2.0.1-next.1
File: package/src/validators.ts
Index: package/src/validators.ts
===================================================================
--- package/src/validators.ts
+++ package/src/validators.ts
@@ -1,160 +0,0 @@
-import { APIResponse } from '@forge/api';
-import {
- InternalServerError,
- InvalidQueueNameError,
- JobDoesNotExistError,
- InvalidPayloadError,
- NoEventsToPushError,
- PartialSuccessError,
- PayloadTooBigError,
- RateLimitError,
- TooManyEventsError,
- InvalidPushSettingsError,
- InvocationLimitReachedError
-} from './errors';
-import { Text } from './text';
-import { CancelJobRequest, GetStatsRequest, PushEvent, PushRequest, PushResult } from './types';
-
-const VALID_QUEUE_NAME_PATTERN = /^[a-zA-Z0-9-_]+$/;
-const MAXIMUM_EVENTS = 50;
-const MAXIMUM_PAYLOAD_SIZE_KB = 200;
-
-export const validateQueueKey = (queueName: string) => {
- if (!queueName || !VALID_QUEUE_NAME_PATTERN.test(queueName)) {
- throw new InvalidQueueNameError(Text.error.invalidQueueName);
- }
-};
-
-export const validatePushSettings = (event: PushEvent) => {
- if ((event.delayInSeconds && event.delayInSeconds > 900) || (event.delayInSeconds && event.delayInSeconds < 0)) {
- throw new InvalidPushSettingsError(Text.error.invalidDelayInSecondsSetting);
- }
-};
-
-export function validatePushEvents(arg: PushEvent | PushEvent[]): PushEvent[] {
- const events = Array.isArray(arg) ? arg : [arg];
-
- if (events.length === 0) {
- throw new NoEventsToPushError(Text.error.noEventsPushed);
- }
-
- if (events.length > MAXIMUM_EVENTS) {
- throw new TooManyEventsError(Text.error.maxEventsAllowed(MAXIMUM_EVENTS));
- }
-
- for (const event of events) {
- if (typeof event !== 'object' || Array.isArray(event) || event === null) {
- throw new InvalidPayloadError(Text.error.invalidEvent);
- }
-
- if (typeof event.body !== 'object' || Array.isArray(event.body) || event.body === null) {
- throw new InvalidPayloadError(Text.error.invalidEventBody);
- }
-
- validatePushSettings(event);
- }
-
- const payloadSizeKB = Buffer.byteLength(JSON.stringify(events)) / 1024;
- if (payloadSizeKB > MAXIMUM_PAYLOAD_SIZE_KB) {
- throw new PayloadTooBigError(Text.error.maxPayloadAllowed(MAXIMUM_PAYLOAD_SIZE_KB));
- }
-
- return events;
-}
-
-export const validateGetStatsPayload = (getStatsRequest: GetStatsRequest) => {
- if (!getStatsRequest.jobId) {
- throw new JobDoesNotExistError(Text.error.jobIdEmpty);
- }
- validateQueueKey(getStatsRequest.queueName);
-};
-
-export const validateCancelJobRequest = (cancelJobRequest: CancelJobRequest) => {
- if (!cancelJobRequest.jobId) {
- throw new JobDoesNotExistError(Text.error.jobIdEmpty);
- }
- validateQueueKey(cancelJobRequest.queueName);
-};
-
-export const validateAPIResponse = async (response: APIResponse, expectedSuccessStatus: number) => {
- if (response.status === 429) {
- throw new RateLimitError(Text.error.rateLimitError);
- }
-
- if (response.status === 405) {
- throw new InvocationLimitReachedError(Text.error.invocationLimitReachedError);
- }
-
- if (response.status != expectedSuccessStatus && response.status) {
- //Catch all errors from server that we have not handled
- let internalServerError;
-
- try {
- const responseBody = await response.json();
- const errorMessage = responseBody.message ? `: ${responseBody.message}` : '';
- const errors = responseBody.errors ? `: ${responseBody.errors.join(', ')}` : ''; //Dropwizard returns an array of errors when request body validation failed
- internalServerError = new InternalServerError(
- `${response.status} ${response.statusText}${errorMessage}${errors}`,
- responseBody.code,
- responseBody.details
- );
- } catch (ignore) {
- //response body is not a json
- internalServerError = new InternalServerError(`${response.status} ${response.statusText}`, response.status);
- }
-
- throw internalServerError;
- }
-};
-
-export const validatePushAPIResponse = async (requestBody: PushRequest, response: APIResponse, result: PushResult) => {
- if (response.status === 413) {
- //Server can return this error response if it has a different max payload size and max number of events limits
- const responseBody = await response.json();
- throw new PayloadTooBigError(responseBody.errorMessage);
- }
-
- if (response.status === 202) {
- const responseBody = await response.json();
- const defaultErrorMessage = 'Failed to process some events.';
- const partialSuccessError = new PartialSuccessError(defaultErrorMessage, result, []);
-
- if (responseBody.failedEvents && responseBody.failedEvents.length > 0) {
- partialSuccessError.message = `Failed to process ${responseBody.failedEvents.length} event(s).`;
- partialSuccessError.failedEvents = responseBody.failedEvents.map((failedEvent: any) => {
- return {
- errorMessage: failedEvent.errorMessage,
- payload: requestBody.payload[+failedEvent.index]
- };
- });
- }
-
- if (responseBody.errorMessage) {
- //Append any extra error message from backend
- partialSuccessError.message =
- partialSuccessError.message !== defaultErrorMessage
- ? `${partialSuccessError.message} ${responseBody.errorMessage}`
- : responseBody.errorMessage;
- }
-
- throw partialSuccessError;
- }
-
- await validateAPIResponse(response, 201);
-};
-
-export const validateGetStatsAPIResponse = async (response: APIResponse, getStatsRequest: GetStatsRequest) => {
- if (response.status === 404) {
- throw new JobDoesNotExistError(Text.error.jobDoesNotExit(getStatsRequest.jobId, getStatsRequest.queueName));
- }
-
- await validateAPIResponse(response, 200);
-};
-
-export const validateCancelJobAPIResponse = async (response: APIResponse, cancelJobRequest: GetStatsRequest) => {
- if (response.status === 404) {
- throw new JobDoesNotExistError(Text.error.jobDoesNotExit(cancelJobRequest.jobId, cancelJobRequest.queueName));
- }
-
- await validateAPIResponse(response, 204);
-};