@devtron-labs/devtron-fe-common-lib 0.0.6-beta-8
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/.eslintrc.js +41 -0
- package/.github/workflows/release-package.yml +49 -0
- package/.prettierrc.js +7 -0
- package/dist/Common/Api.d.ts +5 -0
- package/dist/Common/Constants.d.ts +2 -0
- package/dist/Common/ServerError.d.ts +15 -0
- package/dist/Common/Types.d.ts +11 -0
- package/dist/Common/index.d.ts +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +41 -0
- package/rollup.config.js +29 -0
- package/src/Common/Api.ts +222 -0
- package/src/Common/Constants.ts +2 -0
- package/src/Common/ServerError.ts +30 -0
- package/src/Common/Types.ts +13 -0
- package/src/Common/index.ts +4 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +39 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
parser: '@typescript-eslint/parser',
|
|
3
|
+
plugins: ['@typescript-eslint'],
|
|
4
|
+
env: {
|
|
5
|
+
commonjs: true,
|
|
6
|
+
browser: true,
|
|
7
|
+
es6: true,
|
|
8
|
+
},
|
|
9
|
+
parserOptions: {
|
|
10
|
+
ecmaVersion: 2018,
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
ecmaFeatures: {
|
|
13
|
+
jsx: true,
|
|
14
|
+
},
|
|
15
|
+
project: ['./tsconfig.json'],
|
|
16
|
+
},
|
|
17
|
+
rules: {
|
|
18
|
+
'no-var': 'error',
|
|
19
|
+
'no-duplicate-imports': 'error',
|
|
20
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
21
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
22
|
+
'@typescript-eslint/no-use-before-define': 'off',
|
|
23
|
+
'@typescript-eslint/explicit-member-accessibility': 'off',
|
|
24
|
+
curly: [2, 'all'],
|
|
25
|
+
'keyword-spacing': 'error',
|
|
26
|
+
'prettier/prettier': ['error', { semi: false }],
|
|
27
|
+
},
|
|
28
|
+
extends: [
|
|
29
|
+
'eslint:recommended',
|
|
30
|
+
'plugin:@typescript-eslint/eslint-recommended',
|
|
31
|
+
'plugin:@typescript-eslint/recommended',
|
|
32
|
+
'prettier/@typescript-eslint',
|
|
33
|
+
'plugin:prettier/recommended',
|
|
34
|
+
'plugin:react/recommended',
|
|
35
|
+
],
|
|
36
|
+
settings: {
|
|
37
|
+
react: {
|
|
38
|
+
version: 'detect',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Node.js Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v3
|
|
12
|
+
- uses: actions/setup-node@v3
|
|
13
|
+
with:
|
|
14
|
+
node-version: 16
|
|
15
|
+
- run: npm ci
|
|
16
|
+
- run: npm test
|
|
17
|
+
|
|
18
|
+
publish-gpr:
|
|
19
|
+
needs: build
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
permissions:
|
|
22
|
+
packages: write
|
|
23
|
+
contents: read
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v3
|
|
26
|
+
- uses: actions/setup-node@v3
|
|
27
|
+
with:
|
|
28
|
+
node-version: 16
|
|
29
|
+
registry-url: https://npm.pkg.github.com/
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- run: npm run build-lib
|
|
32
|
+
- run: npm publish
|
|
33
|
+
env:
|
|
34
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
35
|
+
publish-npm:
|
|
36
|
+
name: Publish to NPM Registry
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v3
|
|
40
|
+
- uses: actions/setup-node@v3
|
|
41
|
+
with:
|
|
42
|
+
node-version: 16
|
|
43
|
+
registry-url: 'https://registry.npmjs.org/'
|
|
44
|
+
- run: npm ci
|
|
45
|
+
- run: npm run build-lib
|
|
46
|
+
- run: npm publish --access public
|
|
47
|
+
env:
|
|
48
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
49
|
+
|
package/.prettierrc.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ResponseType, APIOptions } from './Types';
|
|
2
|
+
export declare const post: (url: string, data: object, options?: APIOptions, isMultipartRequest?: boolean) => Promise<ResponseType>;
|
|
3
|
+
export declare const put: (url: string, data: object, options?: APIOptions) => Promise<ResponseType>;
|
|
4
|
+
export declare const get: (url: string, options?: APIOptions) => Promise<ResponseType>;
|
|
5
|
+
export declare const trash: (url: string, data?: object, options?: APIOptions) => Promise<ResponseType>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class ServerError {
|
|
2
|
+
code: number;
|
|
3
|
+
internalMessage: string | null;
|
|
4
|
+
userMessage: string | null;
|
|
5
|
+
moreInfo?: string | null;
|
|
6
|
+
constructor(error: any);
|
|
7
|
+
}
|
|
8
|
+
export declare class ServerErrors extends Error {
|
|
9
|
+
code: number;
|
|
10
|
+
errors: ServerError[];
|
|
11
|
+
constructor(obj: {
|
|
12
|
+
code: number;
|
|
13
|
+
errors: ServerError[];
|
|
14
|
+
});
|
|
15
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Common";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=6e4,t=process.env.REACT_APP_ORCHESTRATOR_ROOT,n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},n(e,t)};function r(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}c((r=r.apply(e,t||[])).next())}))}function o(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(c){return function(s){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&s[0]?r.return:s[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,s[1])).done)return o;switch(r=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,r=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(e){s=[6,e],r=0}finally{n=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}}var a=function(e){this.code=e.code||0,this.userMessage=e.userMessage||"",this.internalMessage=e.internalMessage||"",this.moreInfo=e.moreInfo||""},i=function(e){function t(t){var n=e.call(this)||this;n.code=t.code;var r=t.errors.reduce((function(e,t){return e+="".concat(t.internalMessage||t.userMessage)}),"");return n.name="[".concat(t.code.toString(),"]"),n.message=r,n.errors=t.errors.map((function(e){return new a(e)})),n}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}(t,e),t}(Error),s={100:"Continue",101:"Switching Protocols",102:"Processing(WebDAV)",200:"OK",201:"Created",202:"Accepted",203:"Non - Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi - Status(WebDAV)",208:"Already Reported(WebDAV)",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",307:"Temporary Redirect",308:"Permanent Redirect(experimental)",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request - URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",418:"I'm a teapot",420:"Enhance Your Calm(Twitter)",422:"Unprocessable Entity(WebDAV)",423:"Locked(WebDAV)",424:"Failed Dependency(WebDAV)",425:"Reserved for WebDAV",426:"Upgrade Required",428:"Precondition Required",429:"Too Many Requests",431:"Request Header Fields Too Large",444:"No Response(Nginx)",449:"Retry With(Microsoft)",450:"Blocked by Windows Parental Controls(Microsoft)",451:"Unavailable For Legal Reasons",499:"Client Closed Request(Nginx)",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates(Experimental)",507:"Insufficient Storage(WebDAV)",508:"Loop Detected(WebDAV)",509:"Bandwidth Limit Exceeded(Apache)",510:"Not Extended",511:"Network Authentication Required",598:"Network read timeout error",599:"Network connect timeout error"};function c(e,t){return r(this,void 0,void 0,(function(){var n,r,a,c;return o(this,(function(o){switch(o.label){case 0:return n=t.status,r=t.statusText||s[n],a=new i({code:n,errors:[]}),"application/json"===e?[3,1]:(r="".concat(s[n],". Please try again."),[3,3]);case 1:return[4,t.json()];case 2:(c=o.sent()).errors&&(a.errors=c.errors),o.label=3;case 3:throw a.errors=a.errors.length>0?a.errors:[{code:n,internalMessage:r,userMessage:r}],a}}))}))}function u(e,n,a,s,u,l){return void 0===u&&(u=!1),r(this,void 0,void 0,(function(){var d,f=this;return o(this,(function(p){return(d={method:n,signal:s,body:a?JSON.stringify(a):void 0}).credentials="include",[2,fetch("".concat(t,"/").concat(e),l?{method:n,body:a}:d).then((function(e){return r(f,void 0,void 0,(function(){var t;return o(this,(function(n){switch(n.label){case 0:if(t=e.headers.get("Content-Type"),401!==e.status)return[3,1];if(u)throw new i({code:401,errors:[{code:401,internalMessage:"Please login again",userMessage:"Please login again"}]});return[2,{code:401,status:"Unauthorized",result:[]}];case 1:return e.status>=300&&e.status<=599?[4,c(t,e)]:[3,3];case 2:return[2,n.sent()];case 3:if("application/json"===t)return[2,e.json().then((function(e){if(e.code>=300&&e.code<=599)throw new i({code:e.code,errors:e.errors});return e}))];if("octet-stream"===t||"application/octet-stream"===t)return[2,e];n.label=4;case 4:return[2]}}))}))}),(function(e){var t={code:0,userMessage:e.message,internalMessage:e.message,moreInfo:e.message};throw new i({code:0,errors:[t]})}))]}))}))}function l(e,t,n,r,o){var a=new AbortController,s=a.signal,c=new Promise((function(e,t){var n=(null==r?void 0:r.timeout)?r.timeout:6e4;setTimeout((function(){a.abort(),t({code:408,errors:[{code:408,internalMessage:"Request cancelled",userMessage:"Request Cancelled"}]})}),n)}));return Promise.race([u(e,t,n,(null==r?void 0:r.signal)||s,(null==r?void 0:r.preventAutoLogout)||!1,o),c]).catch((function(e){throw e instanceof i?e:new i({code:408,errors:[{code:408,internalMessage:"That took longer than expected.",userMessage:"That took longer than expected."}]})}))}var d=function(e,t,n,r){return l(e,"POST",t,n,r)},f=function(e,t,n){return l(e,"PUT",t,n)},p=function(e,t){return l(e,"GET",null,t)},h=function(e,t,n){return l(e,"DELETE",t,n)};export{t as Host,e as RequestTimeout,a as ServerError,i as ServerErrors,p as get,d as post,f as put,h as trash};
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@devtron-labs/devtron-fe-common-lib",
|
|
3
|
+
"version": "0.0.6-beta-8",
|
|
4
|
+
"description": "Supporting common component library",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "exit 0",
|
|
8
|
+
"build-lib": "rollup -c --bundleConfigAsCjs",
|
|
9
|
+
"build-watch": "rollup -c --bundleConfigAsCjs -w"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/devtron-labs/devtron-fe-common-lib.git"
|
|
14
|
+
},
|
|
15
|
+
"author": "Devtron",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/devtron-labs/devtron-fe-common-lib/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/devtron-labs/devtron-fe-common-lib#readme",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@rollup/plugin-babel": "^6.0.3",
|
|
23
|
+
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
24
|
+
"@rollup/plugin-terser": "^0.2.0",
|
|
25
|
+
"@types/react": "17.0.39",
|
|
26
|
+
"@types/react-dom": "17.0.13",
|
|
27
|
+
"rollup": "^3.7.3",
|
|
28
|
+
"rollup-plugin-delete": "^2.0.0",
|
|
29
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
30
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
31
|
+
"rollup-plugin-typescript2": "^0.34.1",
|
|
32
|
+
"typescript": "^4.9.4"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": "^17.0.2",
|
|
36
|
+
"react-dom": "^17.0.2"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"sass": "^1.56.2"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
|
|
2
|
+
import resolve from "@rollup/plugin-node-resolve";
|
|
3
|
+
import typescript from "rollup-plugin-typescript2";
|
|
4
|
+
import postcss from "rollup-plugin-postcss";
|
|
5
|
+
import { babel } from '@rollup/plugin-babel';
|
|
6
|
+
import terser from '@rollup/plugin-terser';
|
|
7
|
+
import del from 'rollup-plugin-delete';
|
|
8
|
+
import pkg from './package.json';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
input: "./src/index.ts",
|
|
12
|
+
output: [
|
|
13
|
+
{ file: pkg.main, format: 'es' },
|
|
14
|
+
],
|
|
15
|
+
plugins: [
|
|
16
|
+
peerDepsExternal(),
|
|
17
|
+
resolve(),
|
|
18
|
+
typescript(),
|
|
19
|
+
postcss({
|
|
20
|
+
extensions: ['.css']
|
|
21
|
+
}),
|
|
22
|
+
terser(),
|
|
23
|
+
babel({
|
|
24
|
+
exclude: "node_modules/**"
|
|
25
|
+
}),
|
|
26
|
+
del({ targets: ['dist/*'] }),
|
|
27
|
+
],
|
|
28
|
+
external: Object.keys(pkg.peerDependencies || {}),
|
|
29
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { ServerErrors } from './ServerError'
|
|
2
|
+
import { RequestTimeout, Host } from './Constants'
|
|
3
|
+
import { ResponseType, APIOptions } from './Types'
|
|
4
|
+
|
|
5
|
+
const responseMessages = {
|
|
6
|
+
100: 'Continue',
|
|
7
|
+
101: 'Switching Protocols',
|
|
8
|
+
102: 'Processing(WebDAV)',
|
|
9
|
+
200: 'OK',
|
|
10
|
+
201: 'Created',
|
|
11
|
+
202: 'Accepted',
|
|
12
|
+
203: 'Non - Authoritative Information',
|
|
13
|
+
204: 'No Content',
|
|
14
|
+
205: 'Reset Content',
|
|
15
|
+
206: 'Partial Content',
|
|
16
|
+
207: 'Multi - Status(WebDAV)',
|
|
17
|
+
208: 'Already Reported(WebDAV)',
|
|
18
|
+
226: 'IM Used',
|
|
19
|
+
300: 'Multiple Choices',
|
|
20
|
+
301: 'Moved Permanently',
|
|
21
|
+
302: 'Found',
|
|
22
|
+
303: 'See Other',
|
|
23
|
+
304: 'Not Modified',
|
|
24
|
+
305: 'Use Proxy',
|
|
25
|
+
307: 'Temporary Redirect',
|
|
26
|
+
308: 'Permanent Redirect(experimental)',
|
|
27
|
+
400: 'Bad Request',
|
|
28
|
+
401: 'Unauthorized',
|
|
29
|
+
402: 'Payment Required',
|
|
30
|
+
403: 'Forbidden',
|
|
31
|
+
404: 'Not Found',
|
|
32
|
+
405: 'Method Not Allowed',
|
|
33
|
+
406: 'Not Acceptable',
|
|
34
|
+
407: 'Proxy Authentication Required',
|
|
35
|
+
408: 'Request Timeout',
|
|
36
|
+
409: 'Conflict',
|
|
37
|
+
410: 'Gone',
|
|
38
|
+
411: 'Length Required',
|
|
39
|
+
412: 'Precondition Failed',
|
|
40
|
+
413: 'Request Entity Too Large',
|
|
41
|
+
414: 'Request - URI Too Long',
|
|
42
|
+
415: 'Unsupported Media Type',
|
|
43
|
+
416: 'Requested Range Not Satisfiable',
|
|
44
|
+
417: 'Expectation Failed',
|
|
45
|
+
418: "I'm a teapot",
|
|
46
|
+
420: 'Enhance Your Calm(Twitter)',
|
|
47
|
+
422: 'Unprocessable Entity(WebDAV)',
|
|
48
|
+
423: 'Locked(WebDAV)',
|
|
49
|
+
424: 'Failed Dependency(WebDAV)',
|
|
50
|
+
425: 'Reserved for WebDAV',
|
|
51
|
+
426: 'Upgrade Required',
|
|
52
|
+
428: 'Precondition Required',
|
|
53
|
+
429: 'Too Many Requests',
|
|
54
|
+
431: 'Request Header Fields Too Large',
|
|
55
|
+
444: 'No Response(Nginx)',
|
|
56
|
+
449: 'Retry With(Microsoft)',
|
|
57
|
+
450: 'Blocked by Windows Parental Controls(Microsoft)',
|
|
58
|
+
451: 'Unavailable For Legal Reasons',
|
|
59
|
+
499: 'Client Closed Request(Nginx)',
|
|
60
|
+
500: 'Internal Server Error',
|
|
61
|
+
501: 'Not Implemented',
|
|
62
|
+
502: 'Bad Gateway',
|
|
63
|
+
503: 'Service Unavailable',
|
|
64
|
+
504: 'Gateway Timeout',
|
|
65
|
+
505: 'HTTP Version Not Supported',
|
|
66
|
+
506: 'Variant Also Negotiates(Experimental)',
|
|
67
|
+
507: 'Insufficient Storage(WebDAV)',
|
|
68
|
+
508: 'Loop Detected(WebDAV)',
|
|
69
|
+
509: 'Bandwidth Limit Exceeded(Apache)',
|
|
70
|
+
510: 'Not Extended',
|
|
71
|
+
511: 'Network Authentication Required',
|
|
72
|
+
598: 'Network read timeout error',
|
|
73
|
+
599: 'Network connect timeout error',
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function handleServerError(contentType, response) {
|
|
77
|
+
//Test for HTTP Status Code
|
|
78
|
+
let code: number = response.status
|
|
79
|
+
let status: string = response.statusText || responseMessages[code]
|
|
80
|
+
let serverError = new ServerErrors({ code, errors: [] })
|
|
81
|
+
if (contentType !== 'application/json') {
|
|
82
|
+
//used for better debugging,
|
|
83
|
+
status = `${responseMessages[code]}. Please try again.`
|
|
84
|
+
} else {
|
|
85
|
+
const responseBody = await response.json()
|
|
86
|
+
if (responseBody.errors) {
|
|
87
|
+
serverError.errors = responseBody.errors
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
serverError.errors =
|
|
91
|
+
serverError.errors.length > 0 ? serverError.errors : [{ code, internalMessage: status, userMessage: status }]
|
|
92
|
+
throw serverError
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function fetchAPI(
|
|
96
|
+
url: string,
|
|
97
|
+
type: string,
|
|
98
|
+
data: object,
|
|
99
|
+
signal: AbortSignal,
|
|
100
|
+
preventAutoLogout = false,
|
|
101
|
+
isMultipartRequest?: boolean,
|
|
102
|
+
): Promise<ResponseType> {
|
|
103
|
+
let options = {
|
|
104
|
+
method: type,
|
|
105
|
+
signal,
|
|
106
|
+
body: data ? JSON.stringify(data) : undefined,
|
|
107
|
+
}
|
|
108
|
+
options['credentials'] = 'include' as RequestCredentials
|
|
109
|
+
return fetch(
|
|
110
|
+
`${Host}/${url}`,
|
|
111
|
+
!isMultipartRequest
|
|
112
|
+
? options
|
|
113
|
+
: ({
|
|
114
|
+
method: type,
|
|
115
|
+
body: data,
|
|
116
|
+
} as RequestInit),
|
|
117
|
+
).then(
|
|
118
|
+
async (response) => {
|
|
119
|
+
let contentType = response.headers.get('Content-Type')
|
|
120
|
+
if (response.status === 401) {
|
|
121
|
+
if (preventAutoLogout) {
|
|
122
|
+
throw new ServerErrors({
|
|
123
|
+
code: 401,
|
|
124
|
+
errors: [
|
|
125
|
+
{ code: 401, internalMessage: 'Please login again', userMessage: 'Please login again' },
|
|
126
|
+
],
|
|
127
|
+
})
|
|
128
|
+
} else {
|
|
129
|
+
return { code: 401, status: 'Unauthorized', result: [] }
|
|
130
|
+
}
|
|
131
|
+
} else if (response.status >= 300 && response.status <= 599) {
|
|
132
|
+
return await handleServerError(contentType, response)
|
|
133
|
+
} else {
|
|
134
|
+
if (contentType === 'application/json') {
|
|
135
|
+
return response.json().then((responseBody) => {
|
|
136
|
+
if (responseBody.code >= 300 && responseBody.code <= 599) {
|
|
137
|
+
//Test Code in Response Body, despite successful HTTP Response Code
|
|
138
|
+
throw new ServerErrors({ code: responseBody.code, errors: responseBody.errors })
|
|
139
|
+
} else {
|
|
140
|
+
//Successfull Response. Expected Response Type {code, result, status}
|
|
141
|
+
return responseBody
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
} else if (contentType === 'octet-stream' || contentType === 'application/octet-stream') {
|
|
145
|
+
//used in getArtifact() API only
|
|
146
|
+
return response
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
(error) => {
|
|
151
|
+
//Network call fails. Handle Failed to Fetch
|
|
152
|
+
let err = {
|
|
153
|
+
code: 0,
|
|
154
|
+
userMessage: error.message,
|
|
155
|
+
internalMessage: error.message,
|
|
156
|
+
moreInfo: error.message,
|
|
157
|
+
}
|
|
158
|
+
throw new ServerErrors({ code: 0, errors: [err] })
|
|
159
|
+
},
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function fetchInTime(
|
|
164
|
+
url: string,
|
|
165
|
+
type: string,
|
|
166
|
+
data: object,
|
|
167
|
+
options?: APIOptions,
|
|
168
|
+
isMultipartRequest?: boolean,
|
|
169
|
+
): Promise<ResponseType> {
|
|
170
|
+
const controller = new AbortController()
|
|
171
|
+
const { signal } = controller
|
|
172
|
+
const timeoutPromise: Promise<ResponseType> = new Promise((resolve, reject) => {
|
|
173
|
+
let timeout = options?.timeout ? options.timeout : RequestTimeout
|
|
174
|
+
setTimeout(() => {
|
|
175
|
+
controller.abort()
|
|
176
|
+
reject({
|
|
177
|
+
code: 408,
|
|
178
|
+
errors: [{ code: 408, internalMessage: 'Request cancelled', userMessage: 'Request Cancelled' }],
|
|
179
|
+
})
|
|
180
|
+
}, timeout)
|
|
181
|
+
})
|
|
182
|
+
return Promise.race([
|
|
183
|
+
fetchAPI(url, type, data, options?.signal || signal, options?.preventAutoLogout || false, isMultipartRequest),
|
|
184
|
+
timeoutPromise,
|
|
185
|
+
]).catch((err) => {
|
|
186
|
+
if (err instanceof ServerErrors) {
|
|
187
|
+
throw err
|
|
188
|
+
} else {
|
|
189
|
+
throw new ServerErrors({
|
|
190
|
+
code: 408,
|
|
191
|
+
errors: [
|
|
192
|
+
{
|
|
193
|
+
code: 408,
|
|
194
|
+
internalMessage: 'That took longer than expected.',
|
|
195
|
+
userMessage: 'That took longer than expected.',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export const post = (
|
|
204
|
+
url: string,
|
|
205
|
+
data: object,
|
|
206
|
+
options?: APIOptions,
|
|
207
|
+
isMultipartRequest?: boolean,
|
|
208
|
+
): Promise<ResponseType> => {
|
|
209
|
+
return fetchInTime(url, 'POST', data, options, isMultipartRequest)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export const put = (url: string, data: object, options?: APIOptions): Promise<ResponseType> => {
|
|
213
|
+
return fetchInTime(url, 'PUT', data, options)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export const get = (url: string, options?: APIOptions): Promise<ResponseType> => {
|
|
217
|
+
return fetchInTime(url, 'GET', null, options)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export const trash = (url: string, data?: object, options?: APIOptions): Promise<ResponseType> => {
|
|
221
|
+
return fetchInTime(url, 'DELETE', data, options)
|
|
222
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class ServerError {
|
|
2
|
+
code: number;
|
|
3
|
+
internalMessage: string | null;
|
|
4
|
+
userMessage: string | null;
|
|
5
|
+
moreInfo?: string | null;
|
|
6
|
+
|
|
7
|
+
constructor(error) {
|
|
8
|
+
this.code = error.code || 0;
|
|
9
|
+
this.userMessage = error.userMessage || '';
|
|
10
|
+
this.internalMessage = error.internalMessage || '';
|
|
11
|
+
this.moreInfo = error.moreInfo || '';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class ServerErrors extends Error {
|
|
16
|
+
code: number;
|
|
17
|
+
errors: ServerError[];
|
|
18
|
+
|
|
19
|
+
constructor(obj: { code: number; errors: ServerError[] }) {
|
|
20
|
+
super();
|
|
21
|
+
this.code = obj.code;
|
|
22
|
+
let message = obj.errors.reduce((str: string, err: ServerError) => {
|
|
23
|
+
str += `${err.internalMessage || err.userMessage}`;
|
|
24
|
+
return str;
|
|
25
|
+
}, '');
|
|
26
|
+
this.name = `[${obj.code.toString()}]`;
|
|
27
|
+
this.message = message;
|
|
28
|
+
this.errors = obj.errors.map((err) => new ServerError(err));
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Common"
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es5",
|
|
4
|
+
"downlevelIteration": true,
|
|
5
|
+
"lib": [
|
|
6
|
+
"dom",
|
|
7
|
+
"dom.iterable",
|
|
8
|
+
"esnext"
|
|
9
|
+
],
|
|
10
|
+
"allowJs": true,
|
|
11
|
+
"checkJs": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"allowSyntheticDefaultImports": true,
|
|
15
|
+
"strict": true,
|
|
16
|
+
"forceConsistentCasingInFileNames": true,
|
|
17
|
+
"module": "esnext",
|
|
18
|
+
"moduleResolution": "node",
|
|
19
|
+
"resolveJsonModule": true,
|
|
20
|
+
"isolatedModules": true,
|
|
21
|
+
"noEmit": true,
|
|
22
|
+
"jsx": "react-jsx",
|
|
23
|
+
"noImplicitAny": false,
|
|
24
|
+
"strictNullChecks": false,
|
|
25
|
+
"noFallthroughCasesInSwitch": true,
|
|
26
|
+
"declaration": true,
|
|
27
|
+
},
|
|
28
|
+
"exclude": [
|
|
29
|
+
"node_modules",
|
|
30
|
+
"**/*.spec.ts",
|
|
31
|
+
"**/*.spec.tsx",
|
|
32
|
+
"**/*.test.ts",
|
|
33
|
+
"**/*.test.tsx",
|
|
34
|
+
"build"
|
|
35
|
+
],
|
|
36
|
+
"include": [
|
|
37
|
+
"src"
|
|
38
|
+
]
|
|
39
|
+
}
|