dce-reactkit 3.2.1 → 3.2.2-beta.1
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/dist/cjs/index.js +186 -177
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/types/LogBuiltInMetadata.d.ts +1 -0
- package/dist/esm/index.js +186 -177
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/types/LogBuiltInMetadata.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/components/AppWrapper.tsx +11 -0
- package/src/types/LogBuiltInMetadata.ts +1 -0
package/dist/esm/index.js
CHANGED
|
@@ -491,6 +491,184 @@ class ErrorWithCode extends Error {
|
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
+
/**
|
|
495
|
+
* Path that all routes start with
|
|
496
|
+
* @author Gabe Abrams
|
|
497
|
+
*/
|
|
498
|
+
const ROUTE_PATH_PREFIX = '/dce-reactkit';
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Path of the route for storing client-side logs
|
|
502
|
+
* @author Gabe Abrams
|
|
503
|
+
*/
|
|
504
|
+
const LOG_ROUTE_PATH = `${ROUTE_PATH_PREFIX}/log`;
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Built-in metadata for logs
|
|
508
|
+
* @author Gabe Abrams
|
|
509
|
+
*/
|
|
510
|
+
const LogBuiltInMetadata = {
|
|
511
|
+
// Contexts
|
|
512
|
+
Context: {
|
|
513
|
+
Uncategorized: 'n/a',
|
|
514
|
+
ServerRenderedErrorPage: '_server-rendered-error-page',
|
|
515
|
+
ServerEndpointError: '_server-endpoint-error',
|
|
516
|
+
ClientFatalError: '_client-fatal-error',
|
|
517
|
+
},
|
|
518
|
+
// Targets
|
|
519
|
+
Target: {
|
|
520
|
+
NoSpecificTarget: 'n/a',
|
|
521
|
+
},
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
// Keep track of whether or not session expiry has already been handled
|
|
525
|
+
let sessionAlreadyExpired = false;
|
|
526
|
+
/*------------------------------------------------------------------------*/
|
|
527
|
+
/* Stub Logic */
|
|
528
|
+
/*------------------------------------------------------------------------*/
|
|
529
|
+
// Stored stub responses
|
|
530
|
+
const stubResponses = {};
|
|
531
|
+
/**
|
|
532
|
+
* Add a stub response
|
|
533
|
+
* @author Gabe Abrams
|
|
534
|
+
* @param opts object containing all arguments
|
|
535
|
+
* @param [opts.method=GET] http request method
|
|
536
|
+
* @param opts.path pathname of the request
|
|
537
|
+
* @param [opts.body] body of the response if successful
|
|
538
|
+
* @param [opts.errorMessage] error message if not successful
|
|
539
|
+
* @param [opts.errorCode] error code if not successful
|
|
540
|
+
*/
|
|
541
|
+
const _setStubResponse = (opts) => {
|
|
542
|
+
var _a, _b, _c;
|
|
543
|
+
const { path, body, } = opts;
|
|
544
|
+
const method = ((_a = opts.method) !== null && _a !== void 0 ? _a : 'GET').toUpperCase();
|
|
545
|
+
const errorMessage = ((_b = opts.errorMessage) !== null && _b !== void 0 ? _b : 'An unknown error has occurred.');
|
|
546
|
+
const errorCode = ((_c = opts.errorCode) !== null && _c !== void 0 ? _c : ReactKitErrorCode$1.NoCode);
|
|
547
|
+
// Store to stub responses
|
|
548
|
+
if (!stubResponses[method]) {
|
|
549
|
+
stubResponses[method] = {};
|
|
550
|
+
}
|
|
551
|
+
stubResponses[method][path] = ((opts.errorMessage || opts.errorCode)
|
|
552
|
+
? {
|
|
553
|
+
success: false,
|
|
554
|
+
errorMessage,
|
|
555
|
+
errorCode,
|
|
556
|
+
}
|
|
557
|
+
: {
|
|
558
|
+
success: true,
|
|
559
|
+
body: body !== null && body !== void 0 ? body : undefined,
|
|
560
|
+
});
|
|
561
|
+
};
|
|
562
|
+
/*------------------------------------------------------------------------*/
|
|
563
|
+
/* Main */
|
|
564
|
+
/*------------------------------------------------------------------------*/
|
|
565
|
+
/**
|
|
566
|
+
* Visit an endpoint on the server [for client only]
|
|
567
|
+
* @author Gabe Abrams
|
|
568
|
+
* @param opts object containing all arguments
|
|
569
|
+
* @param opts.path - the path of the server endpoint
|
|
570
|
+
* @param [opts.method=GET] - the method of the endpoint
|
|
571
|
+
* @param [opts.params] - query/body parameters to include
|
|
572
|
+
* @returns response from server
|
|
573
|
+
*/
|
|
574
|
+
const visitServerEndpoint = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
575
|
+
var _a, _b, _c;
|
|
576
|
+
const method = ((_a = opts.method) !== null && _a !== void 0 ? _a : 'GET');
|
|
577
|
+
// Handle stubs
|
|
578
|
+
const stubResponse = (_b = stubResponses[method]) === null || _b === void 0 ? void 0 : _b[opts.path];
|
|
579
|
+
if (stubResponse) {
|
|
580
|
+
// Remove from list
|
|
581
|
+
try {
|
|
582
|
+
stubResponses[method][opts.path] = undefined;
|
|
583
|
+
}
|
|
584
|
+
catch (err) {
|
|
585
|
+
// Ignore
|
|
586
|
+
}
|
|
587
|
+
// Success
|
|
588
|
+
if (stubResponse.success) {
|
|
589
|
+
return stubResponse.body;
|
|
590
|
+
}
|
|
591
|
+
// Error
|
|
592
|
+
throw new ErrorWithCode(stubResponse.errorMessage, stubResponse.errorCode);
|
|
593
|
+
}
|
|
594
|
+
// Send the request
|
|
595
|
+
const response = yield cacclSendRequest({
|
|
596
|
+
path: opts.path,
|
|
597
|
+
method: (_c = opts.method) !== null && _c !== void 0 ? _c : 'GET',
|
|
598
|
+
params: opts.params,
|
|
599
|
+
});
|
|
600
|
+
// Check for failure
|
|
601
|
+
if (!response || !response.body) {
|
|
602
|
+
throw new ErrorWithCode('We didn\'t get a response from the server. Please check your internet connection.', ReactKitErrorCode$1.NoResponse);
|
|
603
|
+
}
|
|
604
|
+
if (!response.body.success) {
|
|
605
|
+
// Session expired
|
|
606
|
+
if (response.body.code === ReactKitErrorCode$1.SessionExpired) {
|
|
607
|
+
// Skip notice if session was already expired
|
|
608
|
+
if (sessionAlreadyExpired) {
|
|
609
|
+
// Never return (browser is already reloading)
|
|
610
|
+
yield new Promise(() => {
|
|
611
|
+
// Promise that never returns
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
sessionAlreadyExpired = true;
|
|
615
|
+
// Show session expiration message
|
|
616
|
+
{
|
|
617
|
+
// Fallback to alert
|
|
618
|
+
// eslint-disable-next-line no-alert
|
|
619
|
+
alert('Your session has expired. Please start over.');
|
|
620
|
+
}
|
|
621
|
+
// Never return (don't continue execution)
|
|
622
|
+
yield new Promise(() => {
|
|
623
|
+
// Promise that never returns
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
// Other errors
|
|
627
|
+
throw new ErrorWithCode((response.body.message
|
|
628
|
+
|| 'An unknown error occurred. Please contact an admin.'), (response.body.code
|
|
629
|
+
|| ReactKitErrorCode$1.NoCode));
|
|
630
|
+
}
|
|
631
|
+
// Success! Extract the body
|
|
632
|
+
const { body } = response.body;
|
|
633
|
+
// Return
|
|
634
|
+
return body;
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Log a user action on the client (cannot be used on the server)
|
|
639
|
+
* @author Gabe Abrams
|
|
640
|
+
*/
|
|
641
|
+
const logClientEvent = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
642
|
+
var _a, _b, _c, _d, _e, _f;
|
|
643
|
+
return visitServerEndpoint({
|
|
644
|
+
path: LOG_ROUTE_PATH,
|
|
645
|
+
method: 'POST',
|
|
646
|
+
params: {
|
|
647
|
+
context: (typeof opts.context === 'string'
|
|
648
|
+
? opts.context
|
|
649
|
+
: ((_b = ((_a = opts.context) !== null && _a !== void 0 ? _a : {})._) !== null && _b !== void 0 ? _b : LogBuiltInMetadata.Context.Uncategorized)),
|
|
650
|
+
subcontext: ((_c = opts.subcontext) !== null && _c !== void 0 ? _c : LogBuiltInMetadata.Context.Uncategorized),
|
|
651
|
+
tags: JSON.stringify((_d = opts.tags) !== null && _d !== void 0 ? _d : []),
|
|
652
|
+
metadata: JSON.stringify((_e = opts.metadata) !== null && _e !== void 0 ? _e : {}),
|
|
653
|
+
errorMessage: (opts.error
|
|
654
|
+
? opts.error.message
|
|
655
|
+
: undefined),
|
|
656
|
+
errorCode: (opts.error
|
|
657
|
+
? opts.error.code
|
|
658
|
+
: undefined),
|
|
659
|
+
errorStack: (opts.error
|
|
660
|
+
? opts.error.stack
|
|
661
|
+
: undefined),
|
|
662
|
+
target: (opts.action
|
|
663
|
+
? ((_f = opts.target) !== null && _f !== void 0 ? _f : LogBuiltInMetadata.Target.NoSpecificTarget)
|
|
664
|
+
: undefined),
|
|
665
|
+
action: (opts.action
|
|
666
|
+
? opts.action
|
|
667
|
+
: undefined),
|
|
668
|
+
},
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
|
|
494
672
|
/**
|
|
495
673
|
* A wrapper for the entire React app that adds global functionality like
|
|
496
674
|
* handling for fatal error messages, adds bootstrap support
|
|
@@ -610,6 +788,14 @@ const showFatalError = (error, errorTitle = 'An Error Occurred') => {
|
|
|
610
788
|
const code = (typeof error === 'string'
|
|
611
789
|
? ReactKitErrorCode$1.NoCode
|
|
612
790
|
: String((_b = error.code) !== null && _b !== void 0 ? _b : ReactKitErrorCode$1.NoCode));
|
|
791
|
+
// Add log
|
|
792
|
+
logClientEvent({
|
|
793
|
+
context: LogBuiltInMetadata.Context.ClientFatalError,
|
|
794
|
+
error,
|
|
795
|
+
metadata: {
|
|
796
|
+
errorTitle,
|
|
797
|
+
},
|
|
798
|
+
});
|
|
613
799
|
// Handle case where app hasn't loaded
|
|
614
800
|
if (!setFatalErrorMessage || !setFatalErrorCode) {
|
|
615
801
|
alert$1(errorTitle, `${message} (code: ${code}). Please contact support.`);
|
|
@@ -2003,131 +2189,6 @@ const roundToNumDecimals = (num, numDecimals) => {
|
|
|
2003
2189
|
return (Math.round(num * rounder) / rounder);
|
|
2004
2190
|
};
|
|
2005
2191
|
|
|
2006
|
-
// Keep track of whether or not session expiry has already been handled
|
|
2007
|
-
let sessionAlreadyExpired = false;
|
|
2008
|
-
/*------------------------------------------------------------------------*/
|
|
2009
|
-
/* Stub Logic */
|
|
2010
|
-
/*------------------------------------------------------------------------*/
|
|
2011
|
-
// Stored stub responses
|
|
2012
|
-
const stubResponses = {};
|
|
2013
|
-
/**
|
|
2014
|
-
* Add a stub response
|
|
2015
|
-
* @author Gabe Abrams
|
|
2016
|
-
* @param opts object containing all arguments
|
|
2017
|
-
* @param [opts.method=GET] http request method
|
|
2018
|
-
* @param opts.path pathname of the request
|
|
2019
|
-
* @param [opts.body] body of the response if successful
|
|
2020
|
-
* @param [opts.errorMessage] error message if not successful
|
|
2021
|
-
* @param [opts.errorCode] error code if not successful
|
|
2022
|
-
*/
|
|
2023
|
-
const _setStubResponse = (opts) => {
|
|
2024
|
-
var _a, _b, _c;
|
|
2025
|
-
const { path, body, } = opts;
|
|
2026
|
-
const method = ((_a = opts.method) !== null && _a !== void 0 ? _a : 'GET').toUpperCase();
|
|
2027
|
-
const errorMessage = ((_b = opts.errorMessage) !== null && _b !== void 0 ? _b : 'An unknown error has occurred.');
|
|
2028
|
-
const errorCode = ((_c = opts.errorCode) !== null && _c !== void 0 ? _c : ReactKitErrorCode$1.NoCode);
|
|
2029
|
-
// Store to stub responses
|
|
2030
|
-
if (!stubResponses[method]) {
|
|
2031
|
-
stubResponses[method] = {};
|
|
2032
|
-
}
|
|
2033
|
-
stubResponses[method][path] = ((opts.errorMessage || opts.errorCode)
|
|
2034
|
-
? {
|
|
2035
|
-
success: false,
|
|
2036
|
-
errorMessage,
|
|
2037
|
-
errorCode,
|
|
2038
|
-
}
|
|
2039
|
-
: {
|
|
2040
|
-
success: true,
|
|
2041
|
-
body: body !== null && body !== void 0 ? body : undefined,
|
|
2042
|
-
});
|
|
2043
|
-
};
|
|
2044
|
-
/*------------------------------------------------------------------------*/
|
|
2045
|
-
/* Main */
|
|
2046
|
-
/*------------------------------------------------------------------------*/
|
|
2047
|
-
/**
|
|
2048
|
-
* Visit an endpoint on the server [for client only]
|
|
2049
|
-
* @author Gabe Abrams
|
|
2050
|
-
* @param opts object containing all arguments
|
|
2051
|
-
* @param opts.path - the path of the server endpoint
|
|
2052
|
-
* @param [opts.method=GET] - the method of the endpoint
|
|
2053
|
-
* @param [opts.params] - query/body parameters to include
|
|
2054
|
-
* @returns response from server
|
|
2055
|
-
*/
|
|
2056
|
-
const visitServerEndpoint = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2057
|
-
var _a, _b, _c;
|
|
2058
|
-
const method = ((_a = opts.method) !== null && _a !== void 0 ? _a : 'GET');
|
|
2059
|
-
// Handle stubs
|
|
2060
|
-
const stubResponse = (_b = stubResponses[method]) === null || _b === void 0 ? void 0 : _b[opts.path];
|
|
2061
|
-
if (stubResponse) {
|
|
2062
|
-
// Remove from list
|
|
2063
|
-
try {
|
|
2064
|
-
stubResponses[method][opts.path] = undefined;
|
|
2065
|
-
}
|
|
2066
|
-
catch (err) {
|
|
2067
|
-
// Ignore
|
|
2068
|
-
}
|
|
2069
|
-
// Success
|
|
2070
|
-
if (stubResponse.success) {
|
|
2071
|
-
return stubResponse.body;
|
|
2072
|
-
}
|
|
2073
|
-
// Error
|
|
2074
|
-
throw new ErrorWithCode(stubResponse.errorMessage, stubResponse.errorCode);
|
|
2075
|
-
}
|
|
2076
|
-
// Send the request
|
|
2077
|
-
const response = yield cacclSendRequest({
|
|
2078
|
-
path: opts.path,
|
|
2079
|
-
method: (_c = opts.method) !== null && _c !== void 0 ? _c : 'GET',
|
|
2080
|
-
params: opts.params,
|
|
2081
|
-
});
|
|
2082
|
-
// Check for failure
|
|
2083
|
-
if (!response || !response.body) {
|
|
2084
|
-
throw new ErrorWithCode('We didn\'t get a response from the server. Please check your internet connection.', ReactKitErrorCode$1.NoResponse);
|
|
2085
|
-
}
|
|
2086
|
-
if (!response.body.success) {
|
|
2087
|
-
// Session expired
|
|
2088
|
-
if (response.body.code === ReactKitErrorCode$1.SessionExpired) {
|
|
2089
|
-
// Skip notice if session was already expired
|
|
2090
|
-
if (sessionAlreadyExpired) {
|
|
2091
|
-
// Never return (browser is already reloading)
|
|
2092
|
-
yield new Promise(() => {
|
|
2093
|
-
// Promise that never returns
|
|
2094
|
-
});
|
|
2095
|
-
}
|
|
2096
|
-
sessionAlreadyExpired = true;
|
|
2097
|
-
// Show session expiration message
|
|
2098
|
-
{
|
|
2099
|
-
// Fallback to alert
|
|
2100
|
-
// eslint-disable-next-line no-alert
|
|
2101
|
-
alert('Your session has expired. Please start over.');
|
|
2102
|
-
}
|
|
2103
|
-
// Never return (don't continue execution)
|
|
2104
|
-
yield new Promise(() => {
|
|
2105
|
-
// Promise that never returns
|
|
2106
|
-
});
|
|
2107
|
-
}
|
|
2108
|
-
// Other errors
|
|
2109
|
-
throw new ErrorWithCode((response.body.message
|
|
2110
|
-
|| 'An unknown error occurred. Please contact an admin.'), (response.body.code
|
|
2111
|
-
|| ReactKitErrorCode$1.NoCode));
|
|
2112
|
-
}
|
|
2113
|
-
// Success! Extract the body
|
|
2114
|
-
const { body } = response.body;
|
|
2115
|
-
// Return
|
|
2116
|
-
return body;
|
|
2117
|
-
});
|
|
2118
|
-
|
|
2119
|
-
/**
|
|
2120
|
-
* Path that all routes start with
|
|
2121
|
-
* @author Gabe Abrams
|
|
2122
|
-
*/
|
|
2123
|
-
const ROUTE_PATH_PREFIX = '/dce-reactkit';
|
|
2124
|
-
|
|
2125
|
-
/**
|
|
2126
|
-
* Path of the route for storing client-side logs
|
|
2127
|
-
* @author Gabe Abrams
|
|
2128
|
-
*/
|
|
2129
|
-
const LOG_ROUTE_PATH = `${ROUTE_PATH_PREFIX}/log`;
|
|
2130
|
-
|
|
2131
2192
|
/**
|
|
2132
2193
|
* Server-side API param types
|
|
2133
2194
|
* @author Gabe Abrams
|
|
@@ -2583,23 +2644,6 @@ var LogSource;
|
|
|
2583
2644
|
})(LogSource || (LogSource = {}));
|
|
2584
2645
|
var LogSource$1 = LogSource;
|
|
2585
2646
|
|
|
2586
|
-
/**
|
|
2587
|
-
* Built-in metadata for logs
|
|
2588
|
-
* @author Gabe Abrams
|
|
2589
|
-
*/
|
|
2590
|
-
const LogBuiltInMetadata = {
|
|
2591
|
-
// Contexts
|
|
2592
|
-
Context: {
|
|
2593
|
-
Uncategorized: 'n/a',
|
|
2594
|
-
ServerRenderedErrorPage: '_server-rendered-error-page',
|
|
2595
|
-
ServerEndpointError: '_server-endpoint-error',
|
|
2596
|
-
},
|
|
2597
|
-
// Targets
|
|
2598
|
-
Target: {
|
|
2599
|
-
NoSpecificTarget: 'n/a',
|
|
2600
|
-
},
|
|
2601
|
-
};
|
|
2602
|
-
|
|
2603
2647
|
/**
|
|
2604
2648
|
* Types of actions
|
|
2605
2649
|
* @author Gabe Abrams
|
|
@@ -3386,41 +3430,6 @@ const parallelLimit = (taskFunctions, limit) => __awaiter(void 0, void 0, void 0
|
|
|
3386
3430
|
return results;
|
|
3387
3431
|
});
|
|
3388
3432
|
|
|
3389
|
-
/**
|
|
3390
|
-
* Log a user action on the client (cannot be used on the server)
|
|
3391
|
-
* @author Gabe Abrams
|
|
3392
|
-
*/
|
|
3393
|
-
const logClientEvent = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
3394
|
-
var _a, _b, _c, _d, _e, _f;
|
|
3395
|
-
return visitServerEndpoint({
|
|
3396
|
-
path: LOG_ROUTE_PATH,
|
|
3397
|
-
method: 'POST',
|
|
3398
|
-
params: {
|
|
3399
|
-
context: (typeof opts.context === 'string'
|
|
3400
|
-
? opts.context
|
|
3401
|
-
: ((_b = ((_a = opts.context) !== null && _a !== void 0 ? _a : {})._) !== null && _b !== void 0 ? _b : LogBuiltInMetadata.Context.Uncategorized)),
|
|
3402
|
-
subcontext: ((_c = opts.subcontext) !== null && _c !== void 0 ? _c : LogBuiltInMetadata.Context.Uncategorized),
|
|
3403
|
-
tags: JSON.stringify((_d = opts.tags) !== null && _d !== void 0 ? _d : []),
|
|
3404
|
-
metadata: JSON.stringify((_e = opts.metadata) !== null && _e !== void 0 ? _e : {}),
|
|
3405
|
-
errorMessage: (opts.error
|
|
3406
|
-
? opts.error.message
|
|
3407
|
-
: undefined),
|
|
3408
|
-
errorCode: (opts.error
|
|
3409
|
-
? opts.error.code
|
|
3410
|
-
: undefined),
|
|
3411
|
-
errorStack: (opts.error
|
|
3412
|
-
? opts.error.stack
|
|
3413
|
-
: undefined),
|
|
3414
|
-
target: (opts.action
|
|
3415
|
-
? ((_f = opts.target) !== null && _f !== void 0 ? _f : LogBuiltInMetadata.Target.NoSpecificTarget)
|
|
3416
|
-
: undefined),
|
|
3417
|
-
action: (opts.action
|
|
3418
|
-
? opts.action
|
|
3419
|
-
: undefined),
|
|
3420
|
-
},
|
|
3421
|
-
});
|
|
3422
|
-
});
|
|
3423
|
-
|
|
3424
3433
|
/**
|
|
3425
3434
|
* Initialize a log collection given the dce-mango Collection class
|
|
3426
3435
|
* @author Gabe Abrams
|