@kcuf/fetcher-interceptor-login 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Alibaba Cloud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # @kcuf/fetcher-interceptor-login
2
+
3
+ 无感登录是很常见的需求。
4
+
5
+ 利用该拦截器,可以对需要登录的特定错误进行登录后重新发起请求,实现丝滑的登录流程。
6
+
7
+ ## 前提
8
+
9
+ 拦截器内部会判断 `error.name` 和 `error.code`,只有业务错误才会继续处理登录逻辑,因此需要 `@kcuf/fetcher-interceptor-biz`。
10
+
11
+ ## 使用
12
+
13
+ ```ts
14
+ import interceptLogin from '@kcuf/fetcher-interceptor-login';
15
+
16
+ import needLogin from './need-login';
17
+ import doLogin from './do-login';
18
+
19
+ interceptLogin(fetcher, needLogin, doLogin);
20
+ ```
21
+
22
+ 由于业务的特殊性,你需要自定义 `needLogin` 和 `doLogin`。
23
+
24
+ ### needLogin
25
+
26
+ ```ts
27
+ function needLogin(code: string): boolean;
28
+ ```
29
+
30
+ 以下条件满足,拦截器才调用 `needLogin`:
31
+
32
+ - `error.name` 判定为业务错误
33
+ - `error.code` 存在(且 `@kcuf/fetcher-interceptor-biz` 会保证它一定是 `string` 类型)
34
+
35
+ ### doLogin
36
+
37
+ ```ts
38
+ function doLogin(): Promise<void>;
39
+ ```
40
+
41
+ 这是一个无参的返回 `Promise<void>` 的方法,一般来说对弹窗登录的 `Promise` 封装。
42
+
43
+ ## FAQ
44
+
45
+ ### ❓登录窗怎么实现?
46
+
47
+ 由于需要的是 `Promise`,你需要使用命令式的弹窗,而不应该是组件式。比如 `@alicloud/console-base-rc-dialog` 的命令式弹窗就很强。
48
+
49
+ ### ❓登录窗登录成功,需要做什么?
50
+
51
+ 登录成功,一般是设置 Cookie 或者 `localStorage` 存取用户登录相关的信息。如果是 Cookie 的话,一般不需要在做什么,因为 `fetch` 会默认带 Cookie 的,
52
+ 如果记录到 `localStorage` 的,你需要写一个请求公共信息的拦截器(使用 `fetcher.interceptRequest`)。
53
+
54
+ ### ❓多个接口同时报错要登录,会不会同时出现多个登录窗?
55
+
56
+ 不会。内部对 `doLogin` 做了单例包裹,不会有这样的事情发生,只要登录未完成,就会在当前的登录队列中增加回调,而不会多弹窗。
57
+
58
+ ### ❓登录窗可否取消登录?
59
+
60
+ 可以,但取消登录后,错误就会变性,`error.name` 会变,`error.code` 不变,并且此次接口调用最终为失败。
61
+
62
+ 建议在用户完成登录前,不允许用户关闭或取消。
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _intercept.default;
11
+ }
12
+ });
13
+ var _intercept = _interopRequireDefault(require("./util/intercept"));
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = createInterceptorResponseRejected;
8
+ var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/regeneratorRuntime"));
9
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
+ var _fetcher = require("@kcuf/fetcher");
11
+ var _shouldDoLogin = _interopRequireDefault(require("./should-do-login"));
12
+ var _singletonPromise = _interopRequireDefault(require("./singleton-promise"));
13
+ function createInterceptorResponseRejected(needLogin, doLogin) {
14
+ var singletonLogin = (0, _singletonPromise.default)(doLogin);
15
+ return /*#__PURE__*/function () {
16
+ var _ref = (0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee(error, fetcherConfig, _, requestByInterceptor) {
17
+ return (0, _regeneratorRuntime2.default)().wrap(function _callee$(_context) {
18
+ while (1) switch (_context.prev = _context.next) {
19
+ case 0:
20
+ if ((0, _shouldDoLogin.default)(error, needLogin)) {
21
+ _context.next = 2;
22
+ break;
23
+ }
24
+ throw error;
25
+ case 2:
26
+ return _context.abrupt("return", singletonLogin().then(function () {
27
+ return requestByInterceptor(fetcherConfig); // 登录完成,重新发起原请求
28
+ }, function () {
29
+ // 一般登录弹窗在登录成功之前是不应该被关闭或取消的,但若真允许取消,这里需要修改错误为「取消登录」
30
+ error.name = _fetcher.FetcherErrorName.LOGIN_CANCELLED;
31
+ throw error; // 以新的 name 继续抛错
32
+ }));
33
+ case 3:
34
+ case "end":
35
+ return _context.stop();
36
+ }
37
+ }, _callee);
38
+ }));
39
+ return function (_x, _x2, _x3, _x4) {
40
+ return _ref.apply(this, arguments);
41
+ };
42
+ }();
43
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = intercept;
8
+ var _createInterceptorResponseRejected = _interopRequireDefault(require("./create-interceptor-response-rejected"));
9
+ function intercept(fetcher, needLogin, doLogin) {
10
+ var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 40;
11
+ return fetcher.interceptResponse(undefined, (0, _createInterceptorResponseRejected.default)(needLogin, doLogin), priority);
12
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = shouldDoLogin;
7
+ var _fetcher = require("@kcuf/fetcher");
8
+ function shouldDoLogin(error, needLogin) {
9
+ return error.name === _fetcher.FetcherErrorName.BIZ && error.code ? needLogin(error.code) : false;
10
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = singletonPromise;
8
+ var _cloneDeep2 = _interopRequireDefault(require("lodash/cloneDeep"));
9
+ function singletonPromise(fn) {
10
+ var queue = null;
11
+ function resolveQueue(data) {
12
+ if (queue) {
13
+ queue.forEach(function (v) {
14
+ v.resolve(data ? (0, _cloneDeep2.default)(data) : data);
15
+ });
16
+ queue = null;
17
+ }
18
+ }
19
+ function rejectQueue(err) {
20
+ if (queue) {
21
+ queue.forEach(function (v) {
22
+ v.reject(err);
23
+ });
24
+ queue = null;
25
+ }
26
+ }
27
+ return function () {
28
+ if (!queue) {
29
+ queue = [];
30
+ }
31
+ var promise = new Promise(function (resolve, reject) {
32
+ var _queue;
33
+ return (_queue = queue) === null || _queue === void 0 ? void 0 : _queue.push({
34
+ resolve: resolve,
35
+ reject: reject
36
+ });
37
+ });
38
+ if (queue.length === 1) {
39
+ fn().then(function (data) {
40
+ return resolveQueue(data);
41
+ }, function (err) {
42
+ return rejectQueue(err);
43
+ });
44
+ }
45
+ return promise;
46
+ };
47
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './util/intercept';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["default"],"sources":["../../src/index.ts"],"sourcesContent":["export { default } from './util/intercept';\n"],"mappings":"AAAA,SAASA,OAAO,QAAQ,kBAAkB","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/types/index.ts"],"sourcesContent":["export type TNeedLogin = (code: string) => boolean;\nexport type TDoLogin = () => Promise<void>;"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,37 @@
1
+ import _regeneratorRuntime from "@babel/runtime/helpers/regeneratorRuntime";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import { FetcherErrorName } from '@kcuf/fetcher';
4
+ import shouldDoLogin from './should-do-login';
5
+ import singletonPromise from './singleton-promise';
6
+ export default function createInterceptorResponseRejected(needLogin, doLogin) {
7
+ var singletonLogin = singletonPromise(doLogin);
8
+ return /*#__PURE__*/function () {
9
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(error, fetcherConfig, _, requestByInterceptor) {
10
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
11
+ while (1) switch (_context.prev = _context.next) {
12
+ case 0:
13
+ if (shouldDoLogin(error, needLogin)) {
14
+ _context.next = 2;
15
+ break;
16
+ }
17
+ throw error;
18
+ case 2:
19
+ return _context.abrupt("return", singletonLogin().then(function () {
20
+ return requestByInterceptor(fetcherConfig); // 登录完成,重新发起原请求
21
+ }, function () {
22
+ // 一般登录弹窗在登录成功之前是不应该被关闭或取消的,但若真允许取消,这里需要修改错误为「取消登录」
23
+ error.name = FetcherErrorName.LOGIN_CANCELLED;
24
+ throw error; // 以新的 name 继续抛错
25
+ }));
26
+ case 3:
27
+ case "end":
28
+ return _context.stop();
29
+ }
30
+ }, _callee);
31
+ }));
32
+ return function (_x, _x2, _x3, _x4) {
33
+ return _ref.apply(this, arguments);
34
+ };
35
+ }();
36
+ }
37
+ //# sourceMappingURL=create-interceptor-response-rejected.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-interceptor-response-rejected.js","names":["FetcherErrorName","shouldDoLogin","singletonPromise","createInterceptorResponseRejected","needLogin","doLogin","singletonLogin","_ref","_asyncToGenerator","_regeneratorRuntime","mark","_callee","error","fetcherConfig","_","requestByInterceptor","wrap","_callee$","_context","prev","next","abrupt","then","name","LOGIN_CANCELLED","stop","_x","_x2","_x3","_x4","apply","arguments"],"sources":["../../../src/util/create-interceptor-response-rejected.ts"],"sourcesContent":["import {\n FetcherErrorName,\n FetcherConfig,\n FetcherError,\n FetcherResponse,\n FetcherCallRequest,\n FetcherInterceptResponseRejected\n} from '@kcuf/fetcher';\n\nimport {\n TNeedLogin,\n TDoLogin\n} from '../types';\n\nimport shouldDoLogin from './should-do-login';\nimport singletonPromise from './singleton-promise';\n\nexport default function createInterceptorResponseRejected(needLogin: TNeedLogin, doLogin: TDoLogin): FetcherInterceptResponseRejected {\n const singletonLogin = singletonPromise(doLogin);\n \n return async (error: FetcherError, fetcherConfig: FetcherConfig, _: FetcherResponse<unknown> | undefined, requestByInterceptor: FetcherCallRequest) => {\n if (!shouldDoLogin(error, needLogin)) {\n throw error;\n }\n \n return singletonLogin().then(() => {\n return requestByInterceptor(fetcherConfig); // 登录完成,重新发起原请求\n }, () => {\n // 一般登录弹窗在登录成功之前是不应该被关闭或取消的,但若真允许取消,这里需要修改错误为「取消登录」\n error.name = FetcherErrorName.LOGIN_CANCELLED;\n \n throw error; // 以新的 name 继续抛错\n });\n };\n}\n"],"mappings":";;AAAA,SACEA,gBAAgB,QAMX,eAAe;AAOtB,OAAOC,aAAa,MAAM,mBAAmB;AAC7C,OAAOC,gBAAgB,MAAM,qBAAqB;AAElD,eAAe,SAASC,iCAAiCA,CAACC,SAAqB,EAAEC,OAAiB,EAAoC;EACpI,IAAMC,cAAc,GAAGJ,gBAAgB,CAACG,OAAO,CAAC;EAEhD;IAAA,IAAAE,IAAA,GAAAC,iBAAA,cAAAC,mBAAA,GAAAC,IAAA,CAAO,SAAAC,QAAOC,KAAmB,EAAEC,aAA4B,EAAEC,CAAuC,EAAEC,oBAAwC;MAAA,OAAAN,mBAAA,GAAAO,IAAA,UAAAC,SAAAC,QAAA;QAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;UAAA;YAAA,IAC3InB,aAAa,CAACW,KAAK,EAAER,SAAS,CAAC;cAAAc,QAAA,CAAAE,IAAA;cAAA;YAAA;YAAA,MAC5BR,KAAK;UAAA;YAAA,OAAAM,QAAA,CAAAG,MAAA,WAGNf,cAAc,CAAC,CAAC,CAACgB,IAAI,CAAC,YAAM;cACjC,OAAOP,oBAAoB,CAACF,aAAa,CAAC,CAAC,CAAC;YAC9C,CAAC,EAAE,YAAM;cACP;cACAD,KAAK,CAACW,IAAI,GAAGvB,gBAAgB,CAACwB,eAAe;cAE7C,MAAMZ,KAAK,CAAC,CAAC;YACf,CAAC,CAAC;UAAA;UAAA;YAAA,OAAAM,QAAA,CAAAO,IAAA;QAAA;MAAA,GAAAd,OAAA;IAAA,CACH;IAAA,iBAAAe,EAAA,EAAAC,GAAA,EAAAC,GAAA,EAAAC,GAAA;MAAA,OAAAtB,IAAA,CAAAuB,KAAA,OAAAC,SAAA;IAAA;EAAA;AACH","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ import createInterceptorResponseRejected from './create-interceptor-response-rejected';
2
+ export default function intercept(fetcher, needLogin, doLogin) {
3
+ var priority = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 40;
4
+ return fetcher.interceptResponse(undefined, createInterceptorResponseRejected(needLogin, doLogin), priority);
5
+ }
6
+ //# sourceMappingURL=intercept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intercept.js","names":["createInterceptorResponseRejected","intercept","fetcher","needLogin","doLogin","priority","arguments","length","undefined","interceptResponse"],"sources":["../../../src/util/intercept.ts"],"sourcesContent":["import {\n Fetcher\n} from '@kcuf/fetcher';\n\nimport {\n TDoLogin,\n TNeedLogin\n} from '../types';\n\nimport createInterceptorResponseRejected from './create-interceptor-response-rejected';\n\nexport default function intercept(fetcher: Fetcher, needLogin: TNeedLogin, doLogin: TDoLogin, priority = 40): () => void {\n return fetcher.interceptResponse(undefined, createInterceptorResponseRejected(needLogin, doLogin), priority);\n}\n"],"mappings":"AASA,OAAOA,iCAAiC,MAAM,wCAAwC;AAEtF,eAAe,SAASC,SAASA,CAACC,OAAgB,EAAEC,SAAqB,EAAEC,OAAiB,EAA6B;EAAA,IAA3BC,QAAQ,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,EAAE;EACzG,OAAOJ,OAAO,CAACO,iBAAiB,CAACD,SAAS,EAAER,iCAAiC,CAACG,SAAS,EAAEC,OAAO,CAAC,EAAEC,QAAQ,CAAC;AAC9G","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ import { FetcherErrorName } from '@kcuf/fetcher';
2
+ export default function shouldDoLogin(error, needLogin) {
3
+ return error.name === FetcherErrorName.BIZ && error.code ? needLogin(error.code) : false;
4
+ }
5
+ //# sourceMappingURL=should-do-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"should-do-login.js","names":["FetcherErrorName","shouldDoLogin","error","needLogin","name","BIZ","code"],"sources":["../../../src/util/should-do-login.ts"],"sourcesContent":["import {\n FetcherErrorName,\n FetcherError\n} from '@kcuf/fetcher';\n\nimport {\n TNeedLogin\n} from '../types';\n\nexport default function shouldDoLogin(error: FetcherError, needLogin: TNeedLogin): boolean {\n return error.name === FetcherErrorName.BIZ && error.code ? needLogin(error.code) : false;\n}\n"],"mappings":"AAAA,SACEA,gBAAgB,QAEX,eAAe;AAMtB,eAAe,SAASC,aAAaA,CAACC,KAAmB,EAAEC,SAAqB,EAAW;EACzF,OAAOD,KAAK,CAACE,IAAI,KAAKJ,gBAAgB,CAACK,GAAG,IAAIH,KAAK,CAACI,IAAI,GAAGH,SAAS,CAACD,KAAK,CAACI,IAAI,CAAC,GAAG,KAAK;AAC1F","ignoreList":[]}
@@ -0,0 +1,41 @@
1
+ import _cloneDeep from 'lodash/cloneDeep';
2
+ export default function singletonPromise(fn) {
3
+ var queue = null;
4
+ function resolveQueue(data) {
5
+ if (queue) {
6
+ queue.forEach(function (v) {
7
+ v.resolve(data ? _cloneDeep(data) : data);
8
+ });
9
+ queue = null;
10
+ }
11
+ }
12
+ function rejectQueue(err) {
13
+ if (queue) {
14
+ queue.forEach(function (v) {
15
+ v.reject(err);
16
+ });
17
+ queue = null;
18
+ }
19
+ }
20
+ return function () {
21
+ if (!queue) {
22
+ queue = [];
23
+ }
24
+ var promise = new Promise(function (resolve, reject) {
25
+ var _queue;
26
+ return (_queue = queue) === null || _queue === void 0 ? void 0 : _queue.push({
27
+ resolve: resolve,
28
+ reject: reject
29
+ });
30
+ });
31
+ if (queue.length === 1) {
32
+ fn().then(function (data) {
33
+ return resolveQueue(data);
34
+ }, function (err) {
35
+ return rejectQueue(err);
36
+ });
37
+ }
38
+ return promise;
39
+ };
40
+ }
41
+ //# sourceMappingURL=singleton-promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singleton-promise.js","names":["_cloneDeep","singletonPromise","fn","queue","resolveQueue","data","forEach","v","resolve","rejectQueue","err","reject","promise","Promise","_queue","push","length","then"],"sources":["../../../src/util/singleton-promise.ts"],"sourcesContent":["import _cloneDeep from 'lodash/cloneDeep';\n\ninterface IPromiseQueueItem<T = void, E extends Error = Error> {\n resolve(data: T): void;\n reject(err: E): void;\n}\n\nexport default function singletonPromise<T>(fn: () => Promise<T>): () => Promise<T> {\n let queue: IPromiseQueueItem<T>[] | null = null;\n \n function resolveQueue(data: T): void {\n if (queue) {\n queue.forEach(v => {\n v.resolve(data ? _cloneDeep(data) : data);\n });\n \n queue = null;\n }\n }\n \n function rejectQueue(err: Error): void {\n if (queue) {\n queue.forEach(v => {\n v.reject(err);\n });\n \n queue = null;\n }\n }\n \n return (): Promise<T> => {\n if (!queue) {\n queue = [];\n }\n \n const promise = new Promise<T>((resolve, reject) => queue?.push({\n resolve,\n reject\n }));\n \n if (queue.length === 1) {\n fn().then(data => resolveQueue(data), err => rejectQueue(err));\n }\n \n return promise;\n };\n}\n"],"mappings":"AAAA,OAAOA,UAAU,MAAM,kBAAkB;AAOzC,eAAe,SAASC,gBAAgBA,CAAIC,EAAoB,EAAoB;EAClF,IAAIC,KAAoC,GAAG,IAAI;EAE/C,SAASC,YAAYA,CAACC,IAAO,EAAQ;IACnC,IAAIF,KAAK,EAAE;MACTA,KAAK,CAACG,OAAO,CAAC,UAAAC,CAAC,EAAI;QACjBA,CAAC,CAACC,OAAO,CAACH,IAAI,GAAGL,UAAU,CAACK,IAAI,CAAC,GAAGA,IAAI,CAAC;MAC3C,CAAC,CAAC;MAEFF,KAAK,GAAG,IAAI;IACd;EACF;EAEA,SAASM,WAAWA,CAACC,GAAU,EAAQ;IACrC,IAAIP,KAAK,EAAE;MACTA,KAAK,CAACG,OAAO,CAAC,UAAAC,CAAC,EAAI;QACjBA,CAAC,CAACI,MAAM,CAACD,GAAG,CAAC;MACf,CAAC,CAAC;MAEFP,KAAK,GAAG,IAAI;IACd;EACF;EAEA,OAAO,YAAkB;IACvB,IAAI,CAACA,KAAK,EAAE;MACVA,KAAK,GAAG,EAAE;IACZ;IAEA,IAAMS,OAAO,GAAG,IAAIC,OAAO,CAAI,UAACL,OAAO,EAAEG,MAAM;MAAA,IAAAG,MAAA;MAAA,QAAAA,MAAA,GAAKX,KAAK,cAAAW,MAAA,uBAALA,MAAA,CAAOC,IAAI,CAAC;QAC9DP,OAAO,EAAPA,OAAO;QACPG,MAAM,EAANA;MACF,CAAC,CAAC;IAAA,EAAC;IAEH,IAAIR,KAAK,CAACa,MAAM,KAAK,CAAC,EAAE;MACtBd,EAAE,CAAC,CAAC,CAACe,IAAI,CAAC,UAAAZ,IAAI;QAAA,OAAID,YAAY,CAACC,IAAI,CAAC;MAAA,GAAE,UAAAK,GAAG;QAAA,OAAID,WAAW,CAACC,GAAG,CAAC;MAAA,EAAC;IAChE;IAEA,OAAOE,OAAO;EAChB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1 @@
1
+ export { default } from './util/intercept';
@@ -0,0 +1,2 @@
1
+ export type TNeedLogin = (code: string) => boolean;
2
+ export type TDoLogin = () => Promise<void>;
@@ -0,0 +1,3 @@
1
+ import { FetcherInterceptResponseRejected } from '@kcuf/fetcher';
2
+ import { TNeedLogin, TDoLogin } from '../types';
3
+ export default function createInterceptorResponseRejected(needLogin: TNeedLogin, doLogin: TDoLogin): FetcherInterceptResponseRejected;
@@ -0,0 +1,3 @@
1
+ import { Fetcher } from '@kcuf/fetcher';
2
+ import { TDoLogin, TNeedLogin } from '../types';
3
+ export default function intercept(fetcher: Fetcher, needLogin: TNeedLogin, doLogin: TDoLogin, priority?: number): () => void;
@@ -0,0 +1,3 @@
1
+ import { FetcherError } from '@kcuf/fetcher';
2
+ import { TNeedLogin } from '../types';
3
+ export default function shouldDoLogin(error: FetcherError, needLogin: TNeedLogin): boolean;
@@ -0,0 +1 @@
1
+ export default function singletonPromise<T>(fn: () => Promise<T>): () => Promise<T>;
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@kcuf/fetcher-interceptor-login",
3
+ "version": "0.1.0",
4
+ "description": "Fetcher interceptor seamless login and redo request.",
5
+ "keywords": [],
6
+ "license": "MIT",
7
+ "sideEffects": false,
8
+ "main": "dist/cjs/index.js",
9
+ "module": "dist/esm/index.js",
10
+ "types": "dist/types/index.d.ts",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/justnewbee/kcuf.git"
14
+ },
15
+ "homepage": "https://github.com/justnewbee/kcuf/tree/master/packages-fetcher/fetcher-interceptor-login",
16
+ "bugs": "https://github.com/justnewbee/kcuf/issues",
17
+ "author": {
18
+ "name": "Jianchun Wang",
19
+ "email": "justnewbee@gmail.com"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "devDependencies": {
25
+ "@babel/cli": "^7.25.7",
26
+ "@babel/core": "^7.25.8",
27
+ "@babel/plugin-transform-runtime": "^7.25.7",
28
+ "@babel/preset-env": "^7.25.8",
29
+ "@babel/preset-typescript": "^7.25.7",
30
+ "@types/lodash": "^4.17.12",
31
+ "@vitest/coverage-v8": "^2.1.3",
32
+ "fetch-mock": "^11.1.5",
33
+ "jsdom": "^25.0.1",
34
+ "rimraf": "^6.0.1",
35
+ "typescript": "^5.6.3",
36
+ "vitest": "^2.1.3",
37
+ "@kcuf/ts-config": "^0.0.1",
38
+ "@kcuf/demo-rc": "^0.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "@babel/runtime": "^7.24.8"
42
+ },
43
+ "dependencies": {
44
+ "lodash": "^4.17.21",
45
+ "@kcuf/fetcher": "^0.1.6"
46
+ },
47
+ "scripts": {
48
+ "build:clean": "rimraf dist",
49
+ "build:esm": "ESM=1 babel src -d dist/esm --extensions .ts,.tsx --source-maps",
50
+ "build:cjs": "ESM=0 babel src -d dist/cjs --extensions .ts,.tsx",
51
+ "build:types": "tsc -rootDir src --outDir dist/types --declaration --noEmit false --emitDeclarationOnly --isolatedModules false",
52
+ "build": "pnpm build:esm && pnpm build:cjs && pnpm build:types",
53
+ "watch": "pnpm build:esm -w",
54
+ "test": "vitest",
55
+ "test:cov": "vitest --coverage --coverage.include=src"
56
+ }
57
+ }