studiokit-scaffolding-js 5.2.0-next.2.5 → 5.2.0-next.2.7
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/lib/components/HOC/ModelErrorRedirectComponent.js +3 -2
- package/lib/constants/fetchErrorData.d.ts +3 -0
- package/lib/constants/fetchErrorData.js +14 -0
- package/lib/constants/mockData.d.ts +9 -1
- package/lib/constants/mockData.js +38 -1
- package/lib/redux/sagas/authSaga.js +5 -4
- package/lib/redux/sagas/modelFetchSaga.js +7 -10
- package/lib/services/fetchService.js +2 -1
- package/lib/types/net/HTTPStatusCode.d.ts +4 -0
- package/lib/types/net/HTTPStatusCode.js +4 -0
- package/package.json +1 -1
|
@@ -46,6 +46,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
46
46
|
var react_1 = __importStar(require("react"));
|
|
47
47
|
var react_router_dom_1 = require("react-router-dom");
|
|
48
48
|
var modelStatus_1 = require("../../constants/modelStatus");
|
|
49
|
+
var types_1 = require("../../types");
|
|
49
50
|
/**
|
|
50
51
|
* This component exists as a child to CollectionItemComponent to
|
|
51
52
|
* redirect the user to a 404/500 page if errors occur while fetching data.
|
|
@@ -71,13 +72,13 @@ function modelErrorRedirectComponent(WrappedComponent) {
|
|
|
71
72
|
model._metadata &&
|
|
72
73
|
model._metadata.hasError &&
|
|
73
74
|
model._metadata.lastFetchErrorData &&
|
|
74
|
-
model._metadata.lastFetchErrorData.status ===
|
|
75
|
+
model._metadata.lastFetchErrorData.status === types_1.HTTP_STATUS_CODE.NOT_FOUND;
|
|
75
76
|
var errorRoute = previousModelStatus === modelStatus_1.MODEL_STATUS.UNINITIALIZED &&
|
|
76
77
|
modelStatus === modelStatus_1.MODEL_STATUS.ERROR &&
|
|
77
78
|
model._metadata &&
|
|
78
79
|
model._metadata.hasError &&
|
|
79
80
|
model._metadata.lastFetchErrorData &&
|
|
80
|
-
model._metadata.lastFetchErrorData.status ===
|
|
81
|
+
model._metadata.lastFetchErrorData.status === types_1.HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR;
|
|
81
82
|
if (notFoundRoute) {
|
|
82
83
|
var pathname = window.location.pathname;
|
|
83
84
|
return (react_1.default.createElement(react_router_dom_1.Redirect, { to: {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.networkOfflineErrorData = exports.unknownErrorData = void 0;
|
|
4
|
+
var __1 = require("..");
|
|
5
|
+
exports.unknownErrorData = {
|
|
6
|
+
title: 'Unknown Error',
|
|
7
|
+
detail: 'An unknown error has occurred.',
|
|
8
|
+
status: __1.CUSTOM_ERROR_STATUS_CODE.UNKNOWN
|
|
9
|
+
};
|
|
10
|
+
exports.networkOfflineErrorData = {
|
|
11
|
+
title: 'Network Offline',
|
|
12
|
+
detail: 'There is no network connection.',
|
|
13
|
+
status: __1.CUSTOM_ERROR_STATUS_CODE.NO_NETWORK_CONNECTION
|
|
14
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppConfiguration, ExternalProvider, ExternalTerm, Group, GroupUserRole, ModelCollection, SimpleLocation, UserInfo, UserRole } from '../types';
|
|
1
|
+
import { AppConfiguration, ExternalProvider, ExternalTerm, FetchErrorData, Group, GroupUserRole, ModelCollection, SimpleLocation, UserInfo, UserRole } from '../types';
|
|
2
2
|
export declare const defaultAppConfiguration: AppConfiguration;
|
|
3
3
|
export declare const defaultLocation: SimpleLocation;
|
|
4
4
|
export declare function mockHistory(): History;
|
|
@@ -31,6 +31,7 @@ export declare const defaultNamelessUserInfo: {
|
|
|
31
31
|
dateDemoGenerationSucceeded: string | null;
|
|
32
32
|
dateStored: string;
|
|
33
33
|
dateLastUpdated: string;
|
|
34
|
+
/** 5/15/18 - 8/14/18 */
|
|
34
35
|
isImpersonated: boolean;
|
|
35
36
|
lockDownBrowserTestLaunchUrl: string | null;
|
|
36
37
|
id: string;
|
|
@@ -52,6 +53,7 @@ export declare const defaultNamedUserInfo: {
|
|
|
52
53
|
dateDemoGenerationSucceeded: string | null;
|
|
53
54
|
dateStored: string;
|
|
54
55
|
dateLastUpdated: string;
|
|
56
|
+
/** 5/15/18 - 8/14/18 */
|
|
55
57
|
isImpersonated: boolean;
|
|
56
58
|
lockDownBrowserTestLaunchUrl: string | null;
|
|
57
59
|
id: string;
|
|
@@ -81,3 +83,9 @@ export declare function mockPastGroups(activities?: string[], roles?: string[]):
|
|
|
81
83
|
export declare function mockPastAndCurrentGroups(activities?: string[], roles?: string[]): ModelCollection<Group>;
|
|
82
84
|
export declare const defaultExternalProviders: ModelCollection<ExternalProvider>;
|
|
83
85
|
export declare const defaultExternalTerms: ModelCollection<ExternalTerm>;
|
|
86
|
+
export declare const internalServerErrorData: FetchErrorData;
|
|
87
|
+
export declare const requestTimedOutErrorData: FetchErrorData;
|
|
88
|
+
export declare const forbiddenErrorData: FetchErrorData;
|
|
89
|
+
export declare const unauthorizedErrorData: FetchErrorData;
|
|
90
|
+
export declare const badRequestErrorData: FetchErrorData;
|
|
91
|
+
export declare const badRequestFullErrorData: FetchErrorData;
|
|
@@ -11,9 +11,10 @@ var __assign = (this && this.__assign) || function () {
|
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.defaultExternalTerms = exports.defaultExternalProviders = exports.mockPastAndCurrentGroups = exports.mockPastGroups = exports.mockTermAndUniTimeGroups = exports.mockTermGroups = exports.mockLtiGroups = exports.mockSyncedGroups = exports.mockGroups = exports.defaultGroup = exports.defaultAdminUserRoles = exports.defaultGroupUserRoles = exports.defaultGroupGrader = exports.defaultExternalGroupLearner = exports.defaultGroupLearner = exports.defaultNamedGroupLearner = exports.defaultNamelessGroupLearner = exports.defaultGroupOwner = exports.defaultGroupOwnerUserInfo = exports.mockUser = exports.defaultNamedUserInfo = exports.defaultNamelessUserInfo = exports.defaultUser = exports.defaultDate = exports.currentDates = exports.pastDates = exports.mockHistory = exports.defaultLocation = exports.defaultAppConfiguration = void 0;
|
|
14
|
+
exports.badRequestFullErrorData = exports.badRequestErrorData = exports.unauthorizedErrorData = exports.forbiddenErrorData = exports.requestTimedOutErrorData = exports.internalServerErrorData = exports.defaultExternalTerms = exports.defaultExternalProviders = exports.mockPastAndCurrentGroups = exports.mockPastGroups = exports.mockTermAndUniTimeGroups = exports.mockTermGroups = exports.mockLtiGroups = exports.mockSyncedGroups = exports.mockGroups = exports.defaultGroup = exports.defaultAdminUserRoles = exports.defaultGroupUserRoles = exports.defaultGroupGrader = exports.defaultExternalGroupLearner = exports.defaultGroupLearner = exports.defaultNamedGroupLearner = exports.defaultNamelessGroupLearner = exports.defaultGroupOwner = exports.defaultGroupOwnerUserInfo = exports.mockUser = exports.defaultNamedUserInfo = exports.defaultNamelessUserInfo = exports.defaultUser = exports.defaultDate = exports.currentDates = exports.pastDates = exports.mockHistory = exports.defaultLocation = exports.defaultAppConfiguration = void 0;
|
|
15
15
|
var lodash_1 = require("lodash");
|
|
16
16
|
var externalProviderType_1 = require("../constants/externalProviderType");
|
|
17
|
+
var types_1 = require("../types");
|
|
17
18
|
var baseRole_1 = require("./baseRole");
|
|
18
19
|
var tier_1 = require("./tier");
|
|
19
20
|
//#region General
|
|
@@ -335,3 +336,39 @@ exports.defaultExternalTerms = {
|
|
|
335
336
|
}
|
|
336
337
|
};
|
|
337
338
|
//#endregion ExternalTerms + ExternalProviders
|
|
339
|
+
//#region FetchErrorData
|
|
340
|
+
exports.internalServerErrorData = {
|
|
341
|
+
title: 'Error',
|
|
342
|
+
detail: 'An error has occurred.',
|
|
343
|
+
status: types_1.HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR
|
|
344
|
+
};
|
|
345
|
+
exports.requestTimedOutErrorData = {
|
|
346
|
+
title: 'Request Timeout',
|
|
347
|
+
detail: null,
|
|
348
|
+
status: types_1.HTTP_STATUS_CODE.REQUEST_TIMEOUT
|
|
349
|
+
};
|
|
350
|
+
exports.forbiddenErrorData = {
|
|
351
|
+
title: 'Forbidden',
|
|
352
|
+
detail: 'Your request has been denied. You do not have access.',
|
|
353
|
+
status: types_1.HTTP_STATUS_CODE.FORBIDDEN
|
|
354
|
+
};
|
|
355
|
+
exports.unauthorizedErrorData = {
|
|
356
|
+
title: 'Unauthorized',
|
|
357
|
+
detail: 'Your request is unauthorized. You must authenticate.',
|
|
358
|
+
status: types_1.HTTP_STATUS_CODE.UNAUTHORIZED
|
|
359
|
+
};
|
|
360
|
+
exports.badRequestErrorData = {
|
|
361
|
+
status: types_1.HTTP_STATUS_CODE.BAD_REQUEST,
|
|
362
|
+
title: 'Bad Request',
|
|
363
|
+
detail: 'Reasons'
|
|
364
|
+
};
|
|
365
|
+
exports.badRequestFullErrorData = {
|
|
366
|
+
status: types_1.HTTP_STATUS_CODE.BAD_REQUEST,
|
|
367
|
+
title: 'Bad Request',
|
|
368
|
+
detail: 'Reasons',
|
|
369
|
+
// include all optional properties
|
|
370
|
+
type: 'https://tools.ietf.org/html/rfc7231#section-6.6.1',
|
|
371
|
+
instance: 'instance',
|
|
372
|
+
traceId: '00-3914b43b452b94e3ff4c327922880a03-4cfed6fe42afdd8f-00'
|
|
373
|
+
};
|
|
374
|
+
//#endregion FetchErrorData
|
|
@@ -43,6 +43,7 @@ var effects_1 = require("redux-saga/effects");
|
|
|
43
43
|
var codeProviderService_1 = require("../../services/codeProviderService");
|
|
44
44
|
var ticketProviderService_1 = require("../../services/ticketProviderService");
|
|
45
45
|
var tokenPersistenceService_1 = require("../../services/tokenPersistenceService");
|
|
46
|
+
var types_1 = require("../../types");
|
|
46
47
|
var logger_1 = require("../../utils/logger");
|
|
47
48
|
var actions_1 = require("../actions");
|
|
48
49
|
//#region Helpers
|
|
@@ -137,9 +138,9 @@ function getTokenFromRefreshToken(oauthTokenParam) {
|
|
|
137
138
|
_a = _c.sent(), fetchResultAction = _a.fetchResultAction, fetchErrorAction = _a.fetchErrorAction;
|
|
138
139
|
// any error response
|
|
139
140
|
if (fetchErrorAction) {
|
|
140
|
-
// ignore
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
// ignore server errors
|
|
142
|
+
if (((_b = fetchErrorAction.errorData) === null || _b === void 0 ? void 0 : _b.status) &&
|
|
143
|
+
fetchErrorAction.errorData.status >= types_1.HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR) {
|
|
143
144
|
return [2 /*return*/, oauthTokenParam];
|
|
144
145
|
}
|
|
145
146
|
return [2 /*return*/, null];
|
|
@@ -286,7 +287,7 @@ function handleAuthFailure(action) {
|
|
|
286
287
|
return __generator(this, function (_a) {
|
|
287
288
|
switch (_a.label) {
|
|
288
289
|
case 0:
|
|
289
|
-
if (!(oauthToken && action.errorData && action.errorData.status ===
|
|
290
|
+
if (!(oauthToken && action.errorData && action.errorData.status === types_1.HTTP_STATUS_CODE.UNAUTHORIZED)) return [3 /*break*/, 2];
|
|
290
291
|
logger.debug('token expired - refreshing');
|
|
291
292
|
return [4 /*yield*/, effects_1.call(performTokenRefresh)];
|
|
292
293
|
case 1:
|
|
@@ -34,6 +34,7 @@ exports.modelFetchRecurring = exports.modelFetchLoop = exports.modelFetch = expo
|
|
|
34
34
|
var lodash_1 = require("lodash");
|
|
35
35
|
var moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
36
36
|
var effects_1 = require("redux-saga/effects");
|
|
37
|
+
var fetchErrorData_1 = require("../../constants/fetchErrorData");
|
|
37
38
|
var dateService_1 = require("../../services/dateService");
|
|
38
39
|
var fetchService_1 = require("../../services/fetchService");
|
|
39
40
|
var windowService_1 = require("../../services/windowService");
|
|
@@ -278,13 +279,7 @@ function modelFetch(modelFetchRequestAction) {
|
|
|
278
279
|
baseErrorMessage = "'modelFetch' failed for '" + modelPath + "'";
|
|
279
280
|
error = error_1.constructErrorFromCaughtError(caughtError_1, 'ModelFetchError', baseErrorMessage);
|
|
280
281
|
isNetworkOnline = windowService_1.windowService.getIsOnline();
|
|
281
|
-
errorData =
|
|
282
|
-
title: isNetworkOnline ? 'Unknown Error' : 'Network Offline',
|
|
283
|
-
detail: isNetworkOnline ? 'An unknown error has occurred.' : 'There is no network connection.',
|
|
284
|
-
status: isNetworkOnline
|
|
285
|
-
? types_1.CUSTOM_ERROR_STATUS_CODE.UNKNOWN
|
|
286
|
-
: types_1.CUSTOM_ERROR_STATUS_CODE.NO_NETWORK_CONNECTION
|
|
287
|
-
};
|
|
282
|
+
errorData = isNetworkOnline ? fetchErrorData_1.unknownErrorData : fetchErrorData_1.networkOfflineErrorData;
|
|
288
283
|
// update `errorData` from the `fetchResult.data`
|
|
289
284
|
// for when the fetch got a result, but it was an unsuccessful status
|
|
290
285
|
if ((fetchResult === null || fetchResult === void 0 ? void 0 : fetchResult.data) && types_1.isFetchErrorData(fetchResult.data)) {
|
|
@@ -313,8 +308,10 @@ function modelFetch(modelFetchRequestAction) {
|
|
|
313
308
|
// log to the console
|
|
314
309
|
logger.error(error);
|
|
315
310
|
didFail = true;
|
|
316
|
-
// Do not continue to retry if the response is between 400-500 (except 408:
|
|
317
|
-
if (errorData.status >=
|
|
311
|
+
// Do not continue to retry if the response is between 400-500 (except 408: request timeout)
|
|
312
|
+
if (errorData.status >= types_1.HTTP_STATUS_CODE.BAD_REQUEST &&
|
|
313
|
+
errorData.status < types_1.HTTP_STATUS_CODE.INTERNAL_SERVER_ERROR &&
|
|
314
|
+
errorData.status !== types_1.HTTP_STATUS_CODE.REQUEST_TIMEOUT) {
|
|
318
315
|
tryCount = tryLimit;
|
|
319
316
|
}
|
|
320
317
|
if (!(tryCount < tryLimit)) return [3 /*break*/, 16];
|
|
@@ -345,7 +342,7 @@ function modelFetch(modelFetchRequestAction) {
|
|
|
345
342
|
// dispatch that the fetch failed, which updates `_metadata` (and `guid`, if provided) at the target redux `modelPath`
|
|
346
343
|
_a.sent();
|
|
347
344
|
// Send error to error handler, except for 401s
|
|
348
|
-
if (errorData.status !==
|
|
345
|
+
if (errorData.status !== types_1.HTTP_STATUS_CODE.UNAUTHORIZED) {
|
|
349
346
|
errorHandler(error, modelFetchRequestAction, fetchConfig, lastFetchResult, errorData);
|
|
350
347
|
}
|
|
351
348
|
_a.label = 20;
|
|
@@ -30,6 +30,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
30
30
|
exports.sendFetch = exports.constructPath = exports.getApiRoot = exports.setApiRoot = void 0;
|
|
31
31
|
var lodash_1 = require("lodash");
|
|
32
32
|
var effects_1 = require("redux-saga/effects");
|
|
33
|
+
var types_1 = require("../types");
|
|
33
34
|
var error_1 = require("../utils/error");
|
|
34
35
|
var apiRoot;
|
|
35
36
|
/**
|
|
@@ -138,7 +139,7 @@ function sendFetch(config) {
|
|
|
138
139
|
isResponseJson = !!response_1.headers &&
|
|
139
140
|
response_1.headers.has('Content-Type') &&
|
|
140
141
|
isContentTypeJson(response_1.headers.get('Content-Type'));
|
|
141
|
-
if (!(response_1.status ===
|
|
142
|
+
if (!(response_1.status === types_1.HTTP_STATUS_CODE.NO_CONTENT)) return [3 /*break*/, 3];
|
|
142
143
|
result.data = isBodyJson ? config.body : undefined;
|
|
143
144
|
return [3 /*break*/, 8];
|
|
144
145
|
case 3:
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
/** Commonly used HTTP status code values */
|
|
1
2
|
export declare enum HTTP_STATUS_CODE {
|
|
3
|
+
OK = 200,
|
|
4
|
+
NO_CONTENT = 204,
|
|
2
5
|
BAD_REQUEST = 400,
|
|
3
6
|
UNAUTHORIZED = 401,
|
|
4
7
|
FORBIDDEN = 403,
|
|
8
|
+
NOT_FOUND = 404,
|
|
5
9
|
REQUEST_TIMEOUT = 408,
|
|
6
10
|
INTERNAL_SERVER_ERROR = 500
|
|
7
11
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HTTP_STATUS_CODE = void 0;
|
|
4
|
+
/** Commonly used HTTP status code values */
|
|
4
5
|
var HTTP_STATUS_CODE;
|
|
5
6
|
(function (HTTP_STATUS_CODE) {
|
|
7
|
+
HTTP_STATUS_CODE[HTTP_STATUS_CODE["OK"] = 200] = "OK";
|
|
8
|
+
HTTP_STATUS_CODE[HTTP_STATUS_CODE["NO_CONTENT"] = 204] = "NO_CONTENT";
|
|
6
9
|
HTTP_STATUS_CODE[HTTP_STATUS_CODE["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
7
10
|
HTTP_STATUS_CODE[HTTP_STATUS_CODE["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
8
11
|
HTTP_STATUS_CODE[HTTP_STATUS_CODE["FORBIDDEN"] = 403] = "FORBIDDEN";
|
|
12
|
+
HTTP_STATUS_CODE[HTTP_STATUS_CODE["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
9
13
|
HTTP_STATUS_CODE[HTTP_STATUS_CODE["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
|
|
10
14
|
HTTP_STATUS_CODE[HTTP_STATUS_CODE["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
|
|
11
15
|
})(HTTP_STATUS_CODE = exports.HTTP_STATUS_CODE || (exports.HTTP_STATUS_CODE = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "studiokit-scaffolding-js",
|
|
3
|
-
"version": "5.2.0-next.2.
|
|
3
|
+
"version": "5.2.0-next.2.7",
|
|
4
4
|
"description": "Common scaffolding for Studio apps at Purdue",
|
|
5
5
|
"repository": "https://gitlab.com/purdue-informatics/studiokit/studiokit-scaffolding-js",
|
|
6
6
|
"license": "MIT",
|