@actdim/dynstruct 0.9.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 +8 -0
- package/README.md +2 -0
- package/dist/appDomain/appContracts.d.ts +113 -0
- package/dist/appDomain/appContracts.d.ts.map +1 -0
- package/dist/appDomain/appContracts.es.js +12 -0
- package/dist/appDomain/appContracts.es.js.map +1 -0
- package/dist/appDomain/navigation.d.ts +8 -0
- package/dist/appDomain/navigation.d.ts.map +1 -0
- package/dist/appDomain/navigation.es.js +18 -0
- package/dist/appDomain/navigation.es.js.map +1 -0
- package/dist/appDomain/security/securityContracts.d.ts +94 -0
- package/dist/appDomain/security/securityContracts.d.ts.map +1 -0
- package/dist/appDomain/security/securityContracts.es.js +15 -0
- package/dist/appDomain/security/securityContracts.es.js.map +1 -0
- package/dist/appDomain/security/securityProvider.d.ts +31 -0
- package/dist/appDomain/security/securityProvider.d.ts.map +1 -0
- package/dist/appDomain/security/securityProvider.es.js +265 -0
- package/dist/appDomain/security/securityProvider.es.js.map +1 -0
- package/dist/componentModel/componentModel.d.ts +129 -0
- package/dist/componentModel/componentModel.d.ts.map +1 -0
- package/dist/componentModel/componentModel.es.js +198 -0
- package/dist/componentModel/componentModel.es.js.map +1 -0
- package/dist/componentModel/scope.d.ts +34 -0
- package/dist/componentModel/scope.d.ts.map +1 -0
- package/dist/componentModel/scope.es.js +139 -0
- package/dist/componentModel/scope.es.js.map +1 -0
- package/dist/net/apiError.d.ts +22 -0
- package/dist/net/apiError.d.ts.map +1 -0
- package/dist/net/apiError.es.js +47 -0
- package/dist/net/apiError.es.js.map +1 -0
- package/dist/net/client.d.ts +20 -0
- package/dist/net/client.d.ts.map +1 -0
- package/dist/net/client.es.js +146 -0
- package/dist/net/client.es.js.map +1 -0
- package/dist/net/request.d.ts +44 -0
- package/dist/net/request.d.ts.map +1 -0
- package/dist/net/request.es.js +33 -0
- package/dist/net/request.es.js.map +1 -0
- package/dist/reactHooks.d.ts +2 -0
- package/dist/reactHooks.d.ts.map +1 -0
- package/dist/reactHooks.es.js +9 -0
- package/dist/reactHooks.es.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
var c = Object.defineProperty;
|
|
2
|
+
var d = (n, e, s) => e in n ? c(n, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : n[e] = s;
|
|
3
|
+
var l = (n, e, s) => d(n, typeof e != "symbol" ? e + "" : e, s);
|
|
4
|
+
import { observable as p, autorun as y, observe as u, reaction as f, transaction as h } from "mobx";
|
|
5
|
+
import { deepObserve as v } from "mobx-utils";
|
|
6
|
+
var z = Object.defineProperty, b = (n, e, s, i) => {
|
|
7
|
+
for (var r = void 0, t = n.length - 1, o; t >= 0; t--)
|
|
8
|
+
(o = n[t]) && (r = o(e, s, r) || r);
|
|
9
|
+
return r && z(e, s, r), r;
|
|
10
|
+
};
|
|
11
|
+
class g {
|
|
12
|
+
constructor() {
|
|
13
|
+
// finalizers
|
|
14
|
+
l(this, "finalizers");
|
|
15
|
+
l(this, "isDisposed");
|
|
16
|
+
l(this, "handlers");
|
|
17
|
+
this.isDisposed = !1, this.finalizers = [], this.handlers = /* @__PURE__ */ new Set();
|
|
18
|
+
}
|
|
19
|
+
deepObserve(e, s) {
|
|
20
|
+
const i = v(e, s);
|
|
21
|
+
return this.registerFinalizers(i), i;
|
|
22
|
+
}
|
|
23
|
+
autorun(e, s) {
|
|
24
|
+
const i = y(e, s);
|
|
25
|
+
return this.registerFinalizers(i), i;
|
|
26
|
+
}
|
|
27
|
+
observe(e, s, i = !0) {
|
|
28
|
+
const r = u(e, s);
|
|
29
|
+
return i && this.registerFinalizers(r), r;
|
|
30
|
+
}
|
|
31
|
+
async allHandlersAsync() {
|
|
32
|
+
await Promise.all(this.handlers);
|
|
33
|
+
}
|
|
34
|
+
validateState() {
|
|
35
|
+
if (this.isDisposed)
|
|
36
|
+
throw new Error("Cannot access a disposed object");
|
|
37
|
+
}
|
|
38
|
+
observeAsync(e, s, i = !0, r = this.handlers) {
|
|
39
|
+
this.validateState();
|
|
40
|
+
const t = u(e, (o) => {
|
|
41
|
+
let a = null;
|
|
42
|
+
a = (async () => {
|
|
43
|
+
await s(o), r.delete(a);
|
|
44
|
+
})(), r.add(a);
|
|
45
|
+
});
|
|
46
|
+
return i && this.registerFinalizers(t), t;
|
|
47
|
+
}
|
|
48
|
+
multiObserve(e, s, i, r = (t) => {
|
|
49
|
+
this.registerFinalizer(t);
|
|
50
|
+
}) {
|
|
51
|
+
const t = [];
|
|
52
|
+
for (const o of e) {
|
|
53
|
+
const a = u(o, s, i);
|
|
54
|
+
t.push(a), r && r(a);
|
|
55
|
+
}
|
|
56
|
+
return t;
|
|
57
|
+
}
|
|
58
|
+
reaction(e, s, i) {
|
|
59
|
+
const r = f(e, s, i);
|
|
60
|
+
return this.registerFinalizers(r), r;
|
|
61
|
+
}
|
|
62
|
+
multiReaction(e, s, i = void 0, r = (t) => {
|
|
63
|
+
this.registerFinalizer(t);
|
|
64
|
+
}) {
|
|
65
|
+
const t = [];
|
|
66
|
+
i || (i = void 0);
|
|
67
|
+
for (const o of e) {
|
|
68
|
+
const a = f(o, s, i);
|
|
69
|
+
t.push(a), r && r(a);
|
|
70
|
+
}
|
|
71
|
+
return t;
|
|
72
|
+
}
|
|
73
|
+
// registerDisposers
|
|
74
|
+
registerFinalizers(...e) {
|
|
75
|
+
this.finalizers.push(...e);
|
|
76
|
+
}
|
|
77
|
+
// registerDisposer
|
|
78
|
+
registerFinalizer(e) {
|
|
79
|
+
return this.registerFinalizers(e), e;
|
|
80
|
+
}
|
|
81
|
+
registerDisposable(e) {
|
|
82
|
+
return this.registerFinalizer(e.dispose.bind(e));
|
|
83
|
+
}
|
|
84
|
+
dispose() {
|
|
85
|
+
if (this === void 0 && console.error('undefined "this"'), !this.isDisposed) {
|
|
86
|
+
for (const e of this.finalizers)
|
|
87
|
+
try {
|
|
88
|
+
e && e();
|
|
89
|
+
} catch (s) {
|
|
90
|
+
throw s;
|
|
91
|
+
}
|
|
92
|
+
this.finalizers.length = 0, this.isDisposed = !0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
class F extends g {
|
|
97
|
+
constructor() {
|
|
98
|
+
super(...arguments);
|
|
99
|
+
l(this, "isBusy", !0);
|
|
100
|
+
}
|
|
101
|
+
// isLoading
|
|
102
|
+
async withBusyAsync(s) {
|
|
103
|
+
h(() => {
|
|
104
|
+
this.isBusy = !0;
|
|
105
|
+
});
|
|
106
|
+
try {
|
|
107
|
+
return await s();
|
|
108
|
+
} finally {
|
|
109
|
+
h(() => {
|
|
110
|
+
this.isBusy = !1;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
withBusy(s) {
|
|
115
|
+
h(() => {
|
|
116
|
+
this.isBusy = !0;
|
|
117
|
+
});
|
|
118
|
+
try {
|
|
119
|
+
return s();
|
|
120
|
+
} finally {
|
|
121
|
+
h(() => {
|
|
122
|
+
this.isBusy = !1;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// createViewModel = <T = any>(model: T, options?: IViewModelOptions<T>): T & IRootViewModel<T> => {
|
|
127
|
+
// const vm = createViewModel(model, options);
|
|
128
|
+
// this.registerFinalizer(vm.$().dispose);
|
|
129
|
+
// return vm;
|
|
130
|
+
// };
|
|
131
|
+
}
|
|
132
|
+
b([
|
|
133
|
+
p.ref
|
|
134
|
+
], F.prototype, "isBusy");
|
|
135
|
+
export {
|
|
136
|
+
g as DisposableComponent,
|
|
137
|
+
F as DisposableModel
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=scope.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.es.js","sources":["../../src/componentModel/scope.ts"],"sourcesContent":["// import { createViewModel } from \"@/componentModel\";\r\nimport {\r\n reaction,\r\n observe,\r\n Lambda,\r\n IReactionPublic,\r\n IReactionOptions,\r\n IReactionDisposer,\r\n IObjectDidChange,\r\n // IArrayChange,\r\n IArraySplice,\r\n IMapDidChange,\r\n autorun,\r\n IAutorunOptions\r\n} from \"mobx\";\r\nimport { deepObserve, IDisposer } from \"mobx-utils\";\r\nimport { observable, transaction } from \"mobx\";\r\n\r\nexport type IObjectChange<T> = IObjectDidChange & {\r\n name: keyof T;\r\n object: T;\r\n};\r\n\r\nexport interface IDisposable {\r\n dispose: () => void;\r\n}\r\n\r\nexport class DisposableComponent implements IDisposable {\r\n // finalizers\r\n protected readonly finalizers: IDisposer[];\r\n\r\n protected isDisposed: boolean;\r\n\r\n public handlers: Set<Promise<any>>;\r\n\r\n constructor() {\r\n this.isDisposed = false;\r\n this.finalizers = [];\r\n this.handlers = new Set<Promise<any>>();\r\n }\r\n\r\n protected deepObserve<T = any>(\r\n target: T,\r\n // | IArrayChange\r\n listener: (change: IObjectDidChange | IArraySplice | IMapDidChange, path: string, root: T) => void\r\n ): IDisposer {\r\n const releaser = deepObserve(target, listener);\r\n this.registerFinalizers(releaser);\r\n return releaser;\r\n }\r\n\r\n protected autorun(view: (r: IReactionPublic) => any, opts?: IAutorunOptions): IReactionDisposer {\r\n const releaser = autorun(view, opts);\r\n this.registerFinalizers(releaser);\r\n return releaser;\r\n }\r\n\r\n protected observe<T = Object>(object: T, listener: (change: IObjectChange<T>) => void, registerDisposer = true): Lambda {\r\n const releaser = observe(object, listener);\r\n if (registerDisposer) {\r\n this.registerFinalizers(releaser);\r\n }\r\n return releaser;\r\n }\r\n\r\n public async allHandlersAsync(): Promise<void> {\r\n await Promise.all(this.handlers);\r\n }\r\n\r\n protected validateState() {\r\n if (this.isDisposed) {\r\n throw new Error(\"Cannot access a disposed object\");\r\n }\r\n }\r\n \r\n protected observeAsync<T = Object>(\r\n object: T,\r\n listener: (change: IObjectChange<T>) => Promise<any>,\r\n registerDisposer = true,\r\n handlers = this.handlers\r\n ): Lambda {\r\n this.validateState(); \r\n const releaser = observe(object, (change) => {\r\n let task: Promise<any> = null;\r\n task = (async () => {\r\n await listener(change as IObjectChange<T>);\r\n handlers.delete(task);\r\n })();\r\n handlers.add(task);\r\n });\r\n if (registerDisposer) {\r\n this.registerFinalizers(releaser);\r\n }\r\n return releaser;\r\n }\r\n\r\n protected multiObserve(\r\n objects: Object[],\r\n listener: (change: IObjectDidChange) => void,\r\n fireImmediately?: boolean,\r\n registerDisposer = (d: () => void) => {\r\n this.registerFinalizer(d);\r\n }\r\n ): Lambda[] {\r\n const releasers: Lambda[] = [];\r\n for (const object of objects) {\r\n const releaser = observe(object, listener, fireImmediately);\r\n releasers.push(releaser);\r\n if (registerDisposer) {\r\n registerDisposer(releaser);\r\n }\r\n }\r\n return releasers;\r\n }\r\n\r\n protected reaction<T>(\r\n expression: (r: IReactionPublic) => T,\r\n effect: (arg: T, prev: T, r: IReactionPublic) => void,\r\n opts?: IReactionOptions<T, boolean>\r\n ): IReactionDisposer {\r\n const releaser = reaction(expression, effect, opts);\r\n this.registerFinalizers(releaser);\r\n return releaser;\r\n }\r\n\r\n protected multiReaction<T>(\r\n expressions: ((r: IReactionPublic) => T)[],\r\n effect: (arg: T, prev: T, r: IReactionPublic) => void,\r\n opts: IReactionOptions<T, boolean> = undefined,\r\n registerDisposer = (d: () => void) => {\r\n this.registerFinalizer(d);\r\n }\r\n ): IReactionDisposer[] {\r\n const releasers: IReactionDisposer[] = [];\r\n if (!opts) {\r\n opts = undefined;\r\n }\r\n for (const expression of expressions) {\r\n const releaser = reaction(expression, effect, opts);\r\n releasers.push(releaser);\r\n if (registerDisposer) {\r\n registerDisposer(releaser);\r\n }\r\n }\r\n\r\n return releasers;\r\n }\r\n\r\n // registerDisposers\r\n protected registerFinalizers(...actions: (() => void)[]) {\r\n this.finalizers.push(...actions);\r\n }\r\n\r\n // registerDisposer\r\n protected registerFinalizer(action: () => void) {\r\n this.registerFinalizers(action);\r\n return action;\r\n }\r\n\r\n protected registerDisposable(disposable: IDisposable) {\r\n return this.registerFinalizer(disposable.dispose.bind(disposable));\r\n }\r\n\r\n public dispose() {\r\n if (this === undefined) {\r\n console.error('undefined \"this\"');\r\n }\r\n if (!this.isDisposed) {\r\n for (const d of this.finalizers) {\r\n try {\r\n d && d();\r\n } catch (err) {\r\n throw err; // for debug\r\n }\r\n }\r\n this.finalizers.length = 0;\r\n // while (this.finalizers.length) {\r\n // const d = this.finalizers.pop();\r\n // d && d();\r\n // }\r\n this.isDisposed = true;\r\n }\r\n }\r\n}\r\n\r\nexport class DisposableModel extends DisposableComponent {\r\n @observable.ref\r\n public isBusy: boolean = true; // isLoading\r\n\r\n protected async withBusyAsync<T>(asyncAction: () => Promise<T>) {\r\n transaction(() => {\r\n this.isBusy = true;\r\n });\r\n try {\r\n return await asyncAction();\r\n } finally {\r\n transaction(() => {\r\n this.isBusy = false;\r\n });\r\n }\r\n }\r\n\r\n protected withBusy<T>(action: () => T) {\r\n transaction(() => {\r\n this.isBusy = true;\r\n });\r\n try {\r\n return action();\r\n } finally {\r\n transaction(() => {\r\n this.isBusy = false;\r\n });\r\n }\r\n }\r\n\r\n // createViewModel = <T = any>(model: T, options?: IViewModelOptions<T>): T & IRootViewModel<T> => {\r\n // const vm = createViewModel(model, options);\r\n // this.registerFinalizer(vm.$().dispose);\r\n // return vm;\r\n // };\r\n}\r\n"],"names":["DisposableComponent","__publicField","target","listener","releaser","deepObserve","view","opts","autorun","object","registerDisposer","observe","handlers","change","task","objects","fireImmediately","d","releasers","expression","effect","reaction","expressions","actions","action","disposable","err","DisposableModel","asyncAction","transaction","__decorateClass","observable"],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IRequestState, IResponseState } from './request';
|
|
2
|
+
export declare const API_ERROR_INTERNAL_ERROR = "API_ERROR_INTERNAL_ERROR";
|
|
3
|
+
export interface IApiErrorOptions<TDetails = any> extends ErrorOptions {
|
|
4
|
+
cause?: TDetails;
|
|
5
|
+
name?: string;
|
|
6
|
+
status?: number;
|
|
7
|
+
request: IRequestState;
|
|
8
|
+
response?: Partial<IResponseState>;
|
|
9
|
+
}
|
|
10
|
+
export declare class ApiError<TDetails = any> extends Error {
|
|
11
|
+
isApiError: boolean;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
readonly request: IRequestState;
|
|
15
|
+
readonly response: Partial<IResponseState>;
|
|
16
|
+
readonly status: number;
|
|
17
|
+
constructor(message: string, options?: IApiErrorOptions<TDetails>);
|
|
18
|
+
static create(response: Partial<IResponseState>, request?: IRequestState): ApiError<any>;
|
|
19
|
+
static assert(response: IResponseState, request: IRequestState): Promise<void>;
|
|
20
|
+
static isApiError(obj: any): obj is ApiError;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=apiError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiError.d.ts","sourceRoot":"","sources":["../../src/net/apiError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAqB,MAAM,eAAe,CAAC;AAIjF,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAMnE,MAAM,WAAW,gBAAgB,CAAC,QAAQ,GAAG,GAAG,CAAE,SAAQ,YAAY;IAClE,KAAK,CAAC,EAAE,QAAQ,CAAC;IAEjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,aAAa,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACtC;AAGD,qBAAa,QAAQ,CAAC,QAAQ,GAAG,GAAG,CAAE,SAAQ,KAAK;IACxC,UAAU,UAAQ;IAEzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAEhC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAE3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEL,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC;IAWxE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC,EAAE,aAAa;WA4B3D,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa;IAOpE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,QAAQ;CAG/C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
var o = Object.defineProperty;
|
|
2
|
+
var m = (n, e, t) => e in n ? o(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var a = (n, e, t) => m(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import * as c from "http-status";
|
|
5
|
+
const E = "API_ERROR_INTERNAL_ERROR";
|
|
6
|
+
class u extends Error {
|
|
7
|
+
// code/type
|
|
8
|
+
constructor(t, s) {
|
|
9
|
+
super(t);
|
|
10
|
+
a(this, "isApiError", !0);
|
|
11
|
+
a(this, "name");
|
|
12
|
+
a(this, "message");
|
|
13
|
+
a(this, "request");
|
|
14
|
+
a(this, "response");
|
|
15
|
+
a(this, "status");
|
|
16
|
+
this.status = s.status, this.message = t || s.name, this.request = s.request, this.response = s.response, this.name = s.name || E, Object.setPrototypeOf(this, u.prototype);
|
|
17
|
+
}
|
|
18
|
+
static create(t, s) {
|
|
19
|
+
if (!t)
|
|
20
|
+
return new u("Invalid request", {
|
|
21
|
+
request: s
|
|
22
|
+
});
|
|
23
|
+
const r = t.status;
|
|
24
|
+
if (r === c.OK)
|
|
25
|
+
return null;
|
|
26
|
+
const i = c[`${r}_MESSAGE`], R = `HTTP_STATUS_${r}`;
|
|
27
|
+
return new u(i, {
|
|
28
|
+
status: r,
|
|
29
|
+
request: s,
|
|
30
|
+
response: t,
|
|
31
|
+
name: R
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
static async assert(t, s) {
|
|
35
|
+
const r = await u.create(t, s);
|
|
36
|
+
if (r)
|
|
37
|
+
throw r;
|
|
38
|
+
}
|
|
39
|
+
static isApiError(t) {
|
|
40
|
+
return t.isApiError === !0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
E as API_ERROR_INTERNAL_ERROR,
|
|
45
|
+
u as ApiError
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=apiError.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiError.es.js","sources":["../../src/net/apiError.ts"],"sourcesContent":["import { IRequestState, IResponseState, getResponseResult } from \"@/net/request\";\r\nimport * as HttpStatus from \"http-status\";\r\n\r\n// UNKNOWN/UNRECOGNIZED\r\nexport const API_ERROR_INTERNAL_ERROR = \"API_ERROR_INTERNAL_ERROR\";\r\n\r\n// \"notmodified\", \"nocontent\", \"error\", \"timeout\", \"abort\", or \"parsererror\"\r\n\r\n// TODO: use http-problem-details or error-http-response (application/problem+json)\r\n\r\nexport interface IApiErrorOptions<TDetails = any> extends ErrorOptions {\r\n cause?: TDetails;\r\n // type/code\r\n name?: string;\r\n status?: number;\r\n request: IRequestState;\r\n response?: Partial<IResponseState>;\r\n}\r\n\r\n// RequestError\r\nexport class ApiError<TDetails = any> extends Error {\r\n public isApiError = true;\r\n\r\n readonly name: string;\r\n\r\n readonly message: string;\r\n\r\n readonly request: IRequestState;\r\n\r\n readonly response: Partial<IResponseState>;\r\n\r\n readonly status: number; // code/type\r\n\r\n public constructor(message: string, options?: IApiErrorOptions<TDetails>) {\r\n // status: number, request: IRequestState, response?: Partial<IResponseState>, name?: string\r\n super(message);\r\n this.status = options.status;\r\n this.message = message || options.name; // message ?? options.name\r\n this.request = options.request;\r\n this.response = options.response;\r\n this.name = options.name || API_ERROR_INTERNAL_ERROR;\r\n Object.setPrototypeOf(this, ApiError.prototype);\r\n }\r\n\r\n static create(response: Partial<IResponseState>, request?: IRequestState) {\r\n if (!response) {\r\n return new ApiError(\"Invalid request\", {\r\n request\r\n });\r\n }\r\n\r\n const status = response.status;\r\n\r\n if (status === HttpStatus.OK) {\r\n return null;\r\n }\r\n\r\n // const statusClass = HttpStatus[`${status}_CLASS`] as HttpStatus.HttpStatusClasses;\r\n // const statusClassName = HttpStatus.classes[String(statusClass)]; // HttpStatus.classes[`${statusClass}_NAME`]\r\n // const statusClassMsg = HttpStatus.classes[`${statusClass}_MESSAGE`];\r\n const msg = HttpStatus[`${status}_MESSAGE`] as string; // || \"An unexpected server error occurred.\"\r\n const name = `HTTP_STATUS_${status}`;\r\n // response.resolved\r\n const error = new ApiError(msg, {\r\n status,\r\n request,\r\n response,\r\n name\r\n });\r\n return error;\r\n }\r\n\r\n static async assert(response: IResponseState, request: IRequestState) {\r\n const err = await ApiError.create(response, request);\r\n if (err) {\r\n throw err;\r\n }\r\n }\r\n\r\n static isApiError(obj: any): obj is ApiError {\r\n return obj.isApiError === true;\r\n }\r\n}\r\n"],"names":["API_ERROR_INTERNAL_ERROR","ApiError","message","options","__publicField","response","request","status","HttpStatus","msg","name","err","obj"],"mappings":";;;;AAIO,MAAMA,IAA2B;AAgBjC,MAAMC,UAAiC,MAAM;AAAA;AAAA,EAazC,YAAYC,GAAiBC,GAAsC;AAEtE,UAAMD,CAAO;AAdV,IAAAE,EAAA,oBAAa;AAEX,IAAAA,EAAA;AAEA,IAAAA,EAAA;AAEA,IAAAA,EAAA;AAEA,IAAAA,EAAA;AAEA,IAAAA,EAAA;AAKL,SAAK,SAASD,EAAQ,QACjB,KAAA,UAAUD,KAAWC,EAAQ,MAClC,KAAK,UAAUA,EAAQ,SACvB,KAAK,WAAWA,EAAQ,UACnB,KAAA,OAAOA,EAAQ,QAAQH,GACrB,OAAA,eAAe,MAAMC,EAAS,SAAS;AAAA,EAClD;AAAA,EAEA,OAAO,OAAOI,GAAmCC,GAAyB;AACtE,QAAI,CAACD;AACM,aAAA,IAAIJ,EAAS,mBAAmB;AAAA,QACnC,SAAAK;AAAA,MAAA,CACH;AAGL,UAAMC,IAASF,EAAS;AAEpB,QAAAE,MAAWC,EAAW;AACf,aAAA;AAMX,UAAMC,IAAMD,EAAW,GAAGD,CAAM,UAAU,GACpCG,IAAO,eAAeH,CAAM;AAQ3B,WANO,IAAIN,EAASQ,GAAK;AAAA,MAC5B,QAAAF;AAAA,MACA,SAAAD;AAAA,MACA,UAAAD;AAAA,MACA,MAAAK;AAAA,IAAA,CACH;AAAA,EAEL;AAAA,EAEA,aAAa,OAAOL,GAA0BC,GAAwB;AAClE,UAAMK,IAAM,MAAMV,EAAS,OAAOI,GAAUC,CAAO;AACnD,QAAIK;AACM,YAAAA;AAAA,EAEd;AAAA,EAEA,OAAO,WAAWC,GAA2B;AACzC,WAAOA,EAAI,eAAe;AAAA,EAC9B;AACJ;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IFetcher, IRequestParams } from './request';
|
|
2
|
+
import { BaseAppContext } from '../appDomain/appContracts';
|
|
3
|
+
export declare function extractApiName(name: string, suffixes: string[]): string | null;
|
|
4
|
+
export declare class ClientBase {
|
|
5
|
+
protected baseUrl: string;
|
|
6
|
+
protected name: string;
|
|
7
|
+
private requestStateMap;
|
|
8
|
+
private fetcher;
|
|
9
|
+
private msgBus;
|
|
10
|
+
private accessToken;
|
|
11
|
+
private init;
|
|
12
|
+
constructor(context: BaseAppContext, fetcher?: IFetcher);
|
|
13
|
+
protected getBaseUrlAsync(): Promise<void>;
|
|
14
|
+
private updateSecurityAsync;
|
|
15
|
+
private addAuthorizationAsync;
|
|
16
|
+
private executeRequestInternalAsync;
|
|
17
|
+
private executeRequestAsync;
|
|
18
|
+
fetchAsync<T>(requestParams: IRequestParams): Promise<T>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/net/client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,QAAQ,EAAqB,cAAc,EAAiB,MAAM,WAAW,CAAC;AAE1G,OAAO,EAAoB,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAS5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAY9E;AAID,qBAAa,UAAU;IACnB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,eAAe,CAA6B;IAEpD,OAAO,CAAC,OAAO,CAAW;IAE1B,OAAO,CAAC,MAAM,CAA2B;IAEzC,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,IAAI,CAAe;gBAEf,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,QAAQ;cAevC,eAAe;YAUjB,mBAAmB;YAUnB,qBAAqB;YAqBrB,2BAA2B;YAkD3B,mBAAmB;IA+CpB,UAAU,CAAC,CAAC,EAAE,aAAa,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;CA2CxE"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var p = (c, e, t) => e in c ? u(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
|
|
3
|
+
var i = (c, e, t) => p(c, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { v4 as f } from "uuid";
|
|
5
|
+
import r from "http-status";
|
|
6
|
+
import { getResponseResult as y } from "./request.es.js";
|
|
7
|
+
import { ApiError as l } from "./apiError.es.js";
|
|
8
|
+
function A(c, e) {
|
|
9
|
+
if (!c)
|
|
10
|
+
return c;
|
|
11
|
+
const a = e.map((o) => o.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"), s = new RegExp(`(_?(${a}))+?$`, "i");
|
|
12
|
+
let n = c.replace(s, "");
|
|
13
|
+
return n = n.trim(), n.length > 0 ? n : c;
|
|
14
|
+
}
|
|
15
|
+
const w = ["api", "controller", "client", "fetcher"];
|
|
16
|
+
class S {
|
|
17
|
+
constructor(e, t) {
|
|
18
|
+
i(this, "baseUrl");
|
|
19
|
+
i(this, "name");
|
|
20
|
+
// private requestStates
|
|
21
|
+
i(this, "requestStateMap");
|
|
22
|
+
i(this, "fetcher");
|
|
23
|
+
i(this, "msgBus");
|
|
24
|
+
i(this, "accessToken");
|
|
25
|
+
i(this, "init");
|
|
26
|
+
this.fetcher = t || window, this.requestStateMap = /* @__PURE__ */ new Map(), this.msgBus = e.msgBus, this.msgBus.on({
|
|
27
|
+
channel: "APP-SECURITY-AUTH-SIGNIN",
|
|
28
|
+
group: "out",
|
|
29
|
+
callback: (a) => {
|
|
30
|
+
this.accessToken = a.payload.accessToken;
|
|
31
|
+
}
|
|
32
|
+
}), this.init = Promise.all([this.getBaseUrlAsync(), this.updateSecurityAsync()]);
|
|
33
|
+
}
|
|
34
|
+
async getBaseUrlAsync() {
|
|
35
|
+
const t = (await this.msgBus.dispatchAsync({
|
|
36
|
+
channel: "APP-CONFIG-GET"
|
|
37
|
+
})).payload, a = A(this.name, w), s = Object.entries(t.apis).find((n) => n[0].toLowerCase() === (a == null ? void 0 : a.toLowerCase()));
|
|
38
|
+
this.baseUrl = (s == null ? void 0 : s[1].url) || t.baseUrl;
|
|
39
|
+
}
|
|
40
|
+
async updateSecurityAsync() {
|
|
41
|
+
if (!this.accessToken) {
|
|
42
|
+
const e = await this.msgBus.dispatchAsync({
|
|
43
|
+
channel: "APP-SECURITY-GET-CONTEXT"
|
|
44
|
+
});
|
|
45
|
+
this.accessToken = e.payload.accessToken;
|
|
46
|
+
}
|
|
47
|
+
return this.accessToken;
|
|
48
|
+
}
|
|
49
|
+
async addAuthorizationAsync(e) {
|
|
50
|
+
const t = await this.updateSecurityAsync();
|
|
51
|
+
if (!t)
|
|
52
|
+
throw l.create({
|
|
53
|
+
status: r.UNAUTHORIZED
|
|
54
|
+
});
|
|
55
|
+
const a = "Authorization", s = e.headers, n = `Bearer ${t}`;
|
|
56
|
+
if (s instanceof Headers)
|
|
57
|
+
s.set(a, n);
|
|
58
|
+
else
|
|
59
|
+
throw new Error("Unsupported headers");
|
|
60
|
+
}
|
|
61
|
+
async executeRequestInternalAsync(e) {
|
|
62
|
+
try {
|
|
63
|
+
let t = !0;
|
|
64
|
+
const a = e.callbacks && e.callbacks.onBeforeSendRequest;
|
|
65
|
+
if (a) {
|
|
66
|
+
const s = {
|
|
67
|
+
request: e,
|
|
68
|
+
cancel: !1,
|
|
69
|
+
handled: !1
|
|
70
|
+
};
|
|
71
|
+
if (await a(s), s.cancel)
|
|
72
|
+
if (t = !1, e.status = "canceled", s.handled)
|
|
73
|
+
e.result = s.result;
|
|
74
|
+
else
|
|
75
|
+
throw new Error("The request was aborted");
|
|
76
|
+
}
|
|
77
|
+
if (t) {
|
|
78
|
+
e.status = "executing";
|
|
79
|
+
const s = await this.fetcher.fetch(e.url, e);
|
|
80
|
+
l.assert(s, e);
|
|
81
|
+
let n = e.callbacks && e.callbacks.onResponseRead;
|
|
82
|
+
n || (n = async (h) => {
|
|
83
|
+
const d = await y(s, e);
|
|
84
|
+
h.result = d;
|
|
85
|
+
});
|
|
86
|
+
const o = {
|
|
87
|
+
response: s
|
|
88
|
+
};
|
|
89
|
+
await n(o), e.result = o.result, e.status = "succeeded";
|
|
90
|
+
}
|
|
91
|
+
} catch (t) {
|
|
92
|
+
throw e.status = "failed", t;
|
|
93
|
+
}
|
|
94
|
+
return e;
|
|
95
|
+
}
|
|
96
|
+
async executeRequestAsync(e) {
|
|
97
|
+
var a, s;
|
|
98
|
+
let t = 0;
|
|
99
|
+
do
|
|
100
|
+
try {
|
|
101
|
+
return e.useAuth && await this.addAuthorizationAsync(e), this.executeRequestInternalAsync(e);
|
|
102
|
+
} catch (n) {
|
|
103
|
+
if (n instanceof l) {
|
|
104
|
+
if (t > 0 || n.status === r.UPGRADE_REQUIRED)
|
|
105
|
+
throw n;
|
|
106
|
+
if (n.status === r.UNAUTHORIZED) {
|
|
107
|
+
(s = (a = n.response) == null ? void 0 : a.headers) != null && s.get("token-expired") ? await this.msgBus.dispatchAsync({
|
|
108
|
+
channel: "APP-SECURITY-AUTH-REFRESH"
|
|
109
|
+
}) : await this.msgBus.dispatchAsync({
|
|
110
|
+
channel: "APP-SECURITY-REQUEST-AUTH"
|
|
111
|
+
});
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
throw n;
|
|
117
|
+
} finally {
|
|
118
|
+
t++;
|
|
119
|
+
}
|
|
120
|
+
while (!0);
|
|
121
|
+
}
|
|
122
|
+
// T extends IApiResponse
|
|
123
|
+
async fetchAsync(e) {
|
|
124
|
+
await this.init, e = { ...{
|
|
125
|
+
contentType: "application/json",
|
|
126
|
+
method: "POST",
|
|
127
|
+
body: null,
|
|
128
|
+
headers: {},
|
|
129
|
+
cache: "default",
|
|
130
|
+
credentials: "same-origin",
|
|
131
|
+
mode: "cors"
|
|
132
|
+
}, ...e }, e.id || (e.id = f());
|
|
133
|
+
let a = {
|
|
134
|
+
...e,
|
|
135
|
+
status: "queued",
|
|
136
|
+
response: void 0,
|
|
137
|
+
result: void 0
|
|
138
|
+
};
|
|
139
|
+
return this.requestStateMap.set(e.id, a), e.headers instanceof Headers || (e.headers = new Headers(e.headers)), e.headers.append("Content-Type", e.contentType), e.method === "POST" && (e.body || (e.body = "")), await this.executeRequestAsync(a), a.result;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export {
|
|
143
|
+
S as ClientBase,
|
|
144
|
+
A as extractApiName
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=client.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.es.js","sources":["../../src/net/client.ts"],"sourcesContent":["import { v4 as uuid } from \"uuid\";\r\nimport httpStatus from \"http-status\";\r\nimport { getResponseResult, IFetcher, IRequestCallbacks, IRequestParams, IRequestState } from \"./request\";\r\nimport { ApiError } from \"./apiError\";\r\nimport { BaseAppBusStruct, BaseAppContext } from \"@/appDomain/appContracts\";\r\nimport { MsgBus } from \"@actdim/msgmesh/msgBusCore\";\r\n\r\n// MLWEB-2172\r\n\r\n// TODO: support request cancellation\r\n// https://stackoverflow.com/questions/31061838/how-do-i-cancel-an-http-fetch-request\r\n// https://mukeshprajapati0251.medium.com/cancel-rest-api-pending-request-1af65e70366d\r\n\r\nexport function extractApiName(name: string, suffixes: string[]): string | null {\r\n if (!name) {\r\n return name;\r\n }\r\n const escaped = suffixes.map((s) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\r\n const group = escaped.join(\"|\");\r\n const pattern = new RegExp(`(_?(${group}))+?$`, \"i\");\r\n\r\n let result = name.replace(pattern, \"\");\r\n\r\n result = result.trim();\r\n return result.length > 0 ? result : name;\r\n}\r\n\r\nconst API_SUFFIXES = [\"api\", \"controller\", \"client\", \"fetcher\"];\r\n// App(Api)ClientBase\r\nexport class ClientBase {\r\n protected baseUrl: string;\r\n protected name: string;\r\n // private requestStates\r\n private requestStateMap: Map<string, IRequestState>;\r\n\r\n private fetcher: IFetcher;\r\n\r\n private msgBus: MsgBus<BaseAppBusStruct>;\r\n\r\n private accessToken: string;\r\n\r\n private init: Promise<any>;\r\n\r\n constructor(context: BaseAppContext, fetcher?: IFetcher) {\r\n this.fetcher = fetcher || window;\r\n this.requestStateMap = new Map<string, IRequestState>();\r\n this.msgBus = context.msgBus;\r\n // TODO: unsubscribe\r\n this.msgBus.on({\r\n channel: \"APP-SECURITY-AUTH-SIGNIN\",\r\n group: \"out\",\r\n callback: (msg) => {\r\n this.accessToken = msg.payload.accessToken;\r\n }\r\n });\r\n this.init = Promise.all([this.getBaseUrlAsync(), this.updateSecurityAsync()]);\r\n }\r\n\r\n protected async getBaseUrlAsync() {\r\n const msg = await this.msgBus.dispatchAsync({\r\n channel: \"APP-CONFIG-GET\"\r\n });\r\n const config = msg.payload;\r\n const apiName = extractApiName(this.name, API_SUFFIXES);\r\n const apiEntry = Object.entries(config.apis).find((entry) => entry[0].toLowerCase() === apiName?.toLowerCase());\r\n this.baseUrl = apiEntry?.[1].url || config.baseUrl;\r\n }\r\n\r\n private async updateSecurityAsync() {\r\n if (!this.accessToken) {\r\n const msg = await this.msgBus.dispatchAsync({\r\n channel: \"APP-SECURITY-GET-CONTEXT\"\r\n });\r\n this.accessToken = msg.payload.accessToken;\r\n }\r\n return this.accessToken;\r\n }\r\n\r\n private async addAuthorizationAsync(request: IRequestParams) {\r\n const accessToken = await this.updateSecurityAsync();\r\n if (!accessToken) {\r\n throw ApiError.create({\r\n status: httpStatus.UNAUTHORIZED\r\n });\r\n }\r\n const authorizationHeader = \"Authorization\";\r\n const headers = request.headers;\r\n const headerValue = `Bearer ${accessToken}`;\r\n if (headers instanceof Headers) {\r\n // if (headers.has(authorizationHeader)) {\r\n // headers.delete(authorizationHeader)\r\n // }\r\n // headers.append(authorizationHeader, headerValue);\r\n headers.set(authorizationHeader, headerValue);\r\n } else {\r\n throw new Error(\"Unsupported headers\"); // object type\r\n }\r\n }\r\n\r\n private async executeRequestInternalAsync(request: IRequestState) {\r\n try {\r\n let proceed = true;\r\n const onBeforeSendRequest = request.callbacks && request.callbacks.onBeforeSendRequest;\r\n if (onBeforeSendRequest) {\r\n const event = {\r\n request: request,\r\n cancel: false,\r\n handled: false\r\n } as Parameters<IRequestCallbacks[\"onBeforeSendRequest\"]>[0];\r\n await onBeforeSendRequest(event);\r\n if (event.cancel) {\r\n // interrupt\r\n proceed = false;\r\n request.status = \"canceled\";\r\n if (event.handled) {\r\n request.result = event.result;\r\n } else {\r\n // ApiError?\r\n throw new Error(\"The request was aborted\"); // has been? canceled?\r\n }\r\n }\r\n }\r\n if (proceed) {\r\n request.status = \"executing\";\r\n const response = await this.fetcher.fetch(request.url, request);\r\n ApiError.assert(response, request);\r\n let onResponseRead = request.callbacks && request.callbacks.onResponseRead;\r\n if (!onResponseRead) {\r\n onResponseRead = async (event) => {\r\n const result = await getResponseResult(response, request);\r\n event.result = result;\r\n };\r\n }\r\n const event = {\r\n response: response\r\n } as Parameters<IRequestCallbacks[\"onResponseRead\"]>[0];\r\n\r\n await onResponseRead(event);\r\n request.result = event.result;\r\n request.status = \"succeeded\";\r\n }\r\n } catch (err) {\r\n request.status = \"failed\";\r\n // throw ApiError.create(undefined, request);\r\n throw err;\r\n }\r\n return request;\r\n }\r\n\r\n private async executeRequestAsync(request: IRequestState): Promise<IRequestState> {\r\n let attempt = 0;\r\n do {\r\n try {\r\n if (request.useAuth) {\r\n await this.addAuthorizationAsync(request);\r\n }\r\n return this.executeRequestInternalAsync(request);\r\n } catch (err) {\r\n if (err instanceof ApiError) {\r\n if (attempt > 0) {\r\n throw err;\r\n }\r\n if (err.status === httpStatus.UPGRADE_REQUIRED) {\r\n // await this.context.msgBus.dispatchAsync({\r\n // channel: \"APP_RELOAD\" // APP_REQUEST_UPDGRADE\r\n // });\r\n throw err;\r\n } else if (err.status === httpStatus.UNAUTHORIZED) {\r\n if (err.response?.headers?.get(\"token-expired\")) {\r\n // token expired or invalid\r\n await this.msgBus.dispatchAsync({\r\n channel: \"APP-SECURITY-AUTH-REFRESH\"\r\n });\r\n } else {\r\n await this.msgBus.dispatchAsync({\r\n channel: \"APP-SECURITY-REQUEST-AUTH\"\r\n });\r\n }\r\n // codes:\r\n // TOKEN_EXPIRED\r\n // TOKEN_INVALID\r\n // TOKEN_MISSING\r\n // AUTH_REQUIRED\r\n // header: WWW-Authenticate\r\n continue;\r\n }\r\n continue;\r\n }\r\n throw err;\r\n } finally {\r\n attempt++;\r\n }\r\n } while (true);\r\n }\r\n\r\n // T extends IApiResponse\r\n public async fetchAsync<T>(requestParams: IRequestParams): Promise<T> {\r\n await this.init;\r\n\r\n const defaultParams: Partial<IRequestParams> = {\r\n contentType: \"application/json\",\r\n method: \"POST\",\r\n body: null,\r\n headers: {},\r\n cache: \"default\",\r\n credentials: \"same-origin\",\r\n mode: \"cors\"\r\n };\r\n\r\n requestParams = { ...defaultParams, ...requestParams };\r\n if (!requestParams.id) {\r\n requestParams.id = uuid();\r\n }\r\n\r\n let request = {\r\n ...requestParams,\r\n status: \"queued\",\r\n response: undefined,\r\n result: undefined\r\n } as IRequestState;\r\n\r\n this.requestStateMap.set(requestParams.id, request);\r\n\r\n if (!(requestParams.headers instanceof Headers)) {\r\n requestParams.headers = new Headers(requestParams.headers);\r\n }\r\n\r\n requestParams.headers.append(\"Content-Type\", requestParams.contentType);\r\n // \"api-version\"\r\n\r\n if (requestParams.method === \"POST\") {\r\n if (!requestParams.body) {\r\n requestParams.body = \"\";\r\n }\r\n }\r\n\r\n await this.executeRequestAsync(request);\r\n return request.result;\r\n }\r\n}\r\n/* \r\nif (status === 404) {\r\n return response.text().then((_responseText) => {\r\n let result404: any = null;\r\n result404 = _responseText === \"\" ? null : JSON.parse(_responseText, this.jsonParseReviver) as __API__ProblemDetails;\r\n return throwException(\"Not Found\", status, _responseText, _headers, result404);\r\n });\r\n } else if (status !== 200 && status !== 204) {\r\n return response.text().then((_responseText) => {\r\n return throwException(\"An unexpected server error occurred.\", status, _responseText, _headers);\r\n });\r\n }\r\n\r\nBLOB\r\nlet reader = new FileReader();\r\n reader.onload = event => resolve((event.target as any).result);\r\n reader.readAsText(blob);\r\n*/\r\n"],"names":["extractApiName","name","suffixes","group","s","pattern","result","API_SUFFIXES","ClientBase","context","fetcher","__publicField","msg","config","apiName","apiEntry","entry","request","accessToken","ApiError","httpStatus","authorizationHeader","headers","headerValue","proceed","onBeforeSendRequest","event","response","onResponseRead","getResponseResult","err","attempt","_b","_a","requestParams","uuid"],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { AsyncFunc, AwaitedReturnType, MaybeExtends } from '@actdim/utico/typeCore';
|
|
2
|
+
export type IFetcher = {
|
|
3
|
+
fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
4
|
+
};
|
|
5
|
+
export type IResolvedBody = {
|
|
6
|
+
[K in keyof Body as Body[K] extends AsyncFunc ? K : never]?: AwaitedReturnType<MaybeExtends<Body[K], AsyncFunc>>;
|
|
7
|
+
};
|
|
8
|
+
export type MimeType = "application/atom+xml" | "application/json" | "application/javascript" | "application/octet-stream" | "application/pdf" | "application/postscript" | "application/soap+xml" | "application/font-woff" | "application/xhtml+xml" | "application/zip" | "application/gzip" | "application/x-tex" | "application/xml" | "application/msword" | "text/cmd" | "text/css" | "text/csv" | "text/html" | "text/plain" | "text/xml" | "text/markdown" | "image/png" | "image/jpeg" | "image/tiff";
|
|
9
|
+
export type RequestStatus = "" | "queued" | "executing" | "succeeded" | "failed" | "canceled";
|
|
10
|
+
export type IResponseState = Response & {
|
|
11
|
+
resolved?: IResolvedBody;
|
|
12
|
+
};
|
|
13
|
+
export type IRequestState = IRequestParams & {
|
|
14
|
+
status: RequestStatus;
|
|
15
|
+
result?: any;
|
|
16
|
+
};
|
|
17
|
+
export declare const getResponseBlob: (response: Response) => Promise<Blob>;
|
|
18
|
+
export declare const getResponseJson: (response: Response) => Promise<any>;
|
|
19
|
+
export declare const getResponseText: (response: Response) => Promise<string>;
|
|
20
|
+
export declare const getResponseArrayBuffer: (response: Response) => Promise<ArrayBuffer>;
|
|
21
|
+
export declare function getResponseResult(response: IResponseState, request: IRequestState): Promise<any>;
|
|
22
|
+
export interface IRequestCallbacks<TResult = any> {
|
|
23
|
+
onBeforeSendRequest?: (event: {
|
|
24
|
+
request: IRequestParams;
|
|
25
|
+
cancel: boolean;
|
|
26
|
+
handled: boolean;
|
|
27
|
+
result?: TResult;
|
|
28
|
+
}) => Promise<void>;
|
|
29
|
+
onResponseRead?: (event: {
|
|
30
|
+
response: Response;
|
|
31
|
+
result: TResult;
|
|
32
|
+
}) => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export interface IRequestParams<TResult = any> extends RequestInit {
|
|
35
|
+
id?: string;
|
|
36
|
+
tag?: string;
|
|
37
|
+
url: string;
|
|
38
|
+
useAuth?: boolean;
|
|
39
|
+
crossDomain?: boolean;
|
|
40
|
+
contentType?: MimeType;
|
|
41
|
+
httpOnly?: boolean;
|
|
42
|
+
callbacks?: IRequestCallbacks<TResult>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/net/request.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAQ,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE1F,MAAM,MAAM,QAAQ,GAAG;IACnB,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACxE,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG;KACvB,CAAC,IAAI,MAAM,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,SAAS,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;CACnH,CAAC;AAGF,MAAM,MAAM,QAAQ,GAEd,sBAAsB,GACtB,kBAAkB,GAClB,wBAAwB,GACxB,0BAA0B,GAC1B,iBAAiB,GACjB,wBAAwB,GACxB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,GACvB,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,GAEpB,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GAEX,YAAY,GACZ,UAAU,GACV,eAAe,GAEf,WAAW,GACX,YAAY,GACZ,YAAY,CAAC;AAGnB,MAAM,MAAM,aAAa,GAEnB,EAAE,GAEF,QAAQ,GAER,WAAW,GAGX,WAAW,GAEX,QAAQ,GAER,UAAU,CAAC;AAEjB,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG;IAEpC,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG;IACzC,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,QAAQ,kBAAoB,CAAC;AAEvE,eAAO,MAAM,eAAe,GAAI,UAAU,QAAQ,iBAAoB,CAAC;AAEvE,eAAO,MAAM,eAAe,GAAI,UAAU,QAAQ,oBAAoB,CAAC;AAEvE,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,yBAA2B,CAAC;AAGrF,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CA+CtG;AAED,MAAM,WAAW,iBAAiB,CAAC,OAAO,GAAG,GAAG;IAE5C,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE;QAC1B,OAAO,EAAE,cAAc,CAAC;QAExB,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;KACpB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtF;AAGD,MAAM,WAAW,cAAc,CAAC,OAAO,GAAG,GAAG,CAAE,SAAQ,WAAW;IAE9D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IAEZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAKlB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,SAAS,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;CAC1C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import n from "http-status";
|
|
2
|
+
const l = (t) => t.blob(), d = (t) => t.json(), c = (t) => t.text(), f = (t) => t.arrayBuffer();
|
|
3
|
+
async function h(t, s) {
|
|
4
|
+
let e = s.contentType || (s.headers && s.headers instanceof Headers ? s.headers.get("content-type") : s.headers["Content-Type"]);
|
|
5
|
+
t.headers && (e = t.headers instanceof Headers ? t.headers.get("content-type") : t.headers["content-type"]);
|
|
6
|
+
let a;
|
|
7
|
+
t.resolved || (t.resolved = {});
|
|
8
|
+
const o = t.resolved;
|
|
9
|
+
if (e = (e || "").toLowerCase(), t.status === n.OK || t.status === n.NO_CONTENT)
|
|
10
|
+
if (e.startsWith("text/"))
|
|
11
|
+
a = await t.text();
|
|
12
|
+
else if (e.startsWith("image/"))
|
|
13
|
+
a = await t.blob();
|
|
14
|
+
else if (e.startsWith("application/json"))
|
|
15
|
+
a = await t.json(), o.json = a;
|
|
16
|
+
else if (e.startsWith("octet-stream"))
|
|
17
|
+
a = await t.blob(), o.blob = a;
|
|
18
|
+
else
|
|
19
|
+
throw new Error(`Unsupported mime type: ${e}`);
|
|
20
|
+
else {
|
|
21
|
+
const i = await t.json();
|
|
22
|
+
throw o.json = i, new Error(`Response status: ${t.status}`);
|
|
23
|
+
}
|
|
24
|
+
return s.result = a, a;
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
f as getResponseArrayBuffer,
|
|
28
|
+
l as getResponseBlob,
|
|
29
|
+
d as getResponseJson,
|
|
30
|
+
h as getResponseResult,
|
|
31
|
+
c as getResponseText
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=request.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.es.js","sources":["../../src/net/request.ts"],"sourcesContent":["// Transport\r\n\r\nimport httpStatus from \"http-status\";\r\nimport { AsyncFunc, AwaitedReturnType, Func, MaybeExtends } from \"@actdim/utico/typeCore\";\r\n\r\nexport type IFetcher = {\r\n fetch(url: RequestInfo | URL, init?: RequestInit): Promise<Response>;\r\n};\r\n\r\n// IParsedBody\r\nexport type IResolvedBody = {\r\n [K in keyof Body as Body[K] extends AsyncFunc ? K : never]?: AwaitedReturnType<MaybeExtends<Body[K], AsyncFunc>>;\r\n};\r\n\r\n// https://www.iana.org/assignments/media-types/media-types.xhtml\r\nexport type MimeType =\r\n // application\r\n | \"application/atom+xml\"\r\n | \"application/json\"\r\n | \"application/javascript\"\r\n | \"application/octet-stream\"\r\n | \"application/pdf\"\r\n | \"application/postscript\"\r\n | \"application/soap+xml\"\r\n | \"application/font-woff\"\r\n | \"application/xhtml+xml\"\r\n | \"application/zip\"\r\n | \"application/gzip\"\r\n | \"application/x-tex\"\r\n | \"application/xml\"\r\n | \"application/msword\"\r\n // text\r\n | \"text/cmd\"\r\n | \"text/css\"\r\n | \"text/csv\"\r\n | \"text/html\"\r\n // \"text/javascript\" |\r\n | \"text/plain\"\r\n | \"text/xml\"\r\n | \"text/markdown\"\r\n // image\r\n | \"image/png\"\r\n | \"image/jpeg\"\r\n | \"image/tiff\";\r\n\r\n// RequestExecutionStatus\r\nexport type RequestStatus =\r\n // Created\r\n | \"\" // none/created/new/unsent\r\n // Queued\r\n | \"queued\" // scheduled\r\n // Executing\r\n | \"executing\" // sent/pending/processing/in-progress\r\n // \"suspended\" | // on-hold\r\n // Successful\r\n | \"succeeded\" // successful/resolved/done/completed/finished/fulfilled/complete\r\n // Unsuccessful\r\n | \"failed\" // unsuccessful/rejected\r\n // Aborted\r\n | \"canceled\"; // aborted/terminated\r\n\r\nexport type IResponseState = Response & {\r\n // parsed?\r\n resolved?: IResolvedBody;\r\n};\r\n\r\nexport type IRequestState = IRequestParams & {\r\n status: RequestStatus;\r\n result?: any;\r\n};\r\n\r\nexport const getResponseBlob = (response: Response) => response.blob();\r\n\r\nexport const getResponseJson = (response: Response) => response.json();\r\n\r\nexport const getResponseText = (response: Response) => response.text();\r\n\r\nexport const getResponseArrayBuffer = (response: Response) => response.arrayBuffer();\r\n\r\n// https://stackoverflow.com/questions/64781995/how-to-get-mime-type-of-an-array-buffer-object\r\nexport async function getResponseResult(response: IResponseState, request: IRequestState): Promise<any> {\r\n // const headers: { [key: string]: string } = {};\r\n let mimeType =\r\n request.contentType ||\r\n (request.headers && request.headers instanceof Headers ? request.headers.get(\"content-type\") : request.headers[\"Content-Type\"]);\r\n if (response.headers) {\r\n // for (const k in response.headers.keys()) {\r\n // headers[k] = response.headers.get[k];\r\n // }\r\n // if (response.headers.forEach) {\r\n // response.headers.forEach((v, k) => headers[k] = v);\r\n // }\r\n mimeType = response.headers instanceof Headers ? response.headers.get(\"content-type\") : response.headers[\"content-type\"];\r\n }\r\n let result: any = undefined;\r\n if (!response.resolved) {\r\n response.resolved = {};\r\n }\r\n const resolved = response.resolved;\r\n mimeType = (mimeType || \"\").toLowerCase();\r\n if (response.status === httpStatus.OK || response.status === httpStatus.NO_CONTENT) {\r\n if (mimeType.startsWith(\"text/\")) {\r\n result = await response.text();\r\n } else if (mimeType.startsWith(\"image/\")) {\r\n result = await response.blob();\r\n } else {\r\n if (mimeType.startsWith(\"application/json\")) {\r\n result = await response.json();\r\n resolved.json = result;\r\n } else if (mimeType.startsWith(\"octet-stream\")) {\r\n result = await response.blob();\r\n resolved.blob = result;\r\n } else {\r\n throw new Error(`Unsupported mime type: ${mimeType}`);\r\n }\r\n }\r\n } else {\r\n const json = await response.json();\r\n resolved.json = json;\r\n // const text = await response.text();\r\n // text === \"\" ? null : JSON.parse(text);\r\n // unexpected response\r\n throw new Error(`Response status: ${response.status}`);\r\n }\r\n\r\n request.result = result;\r\n return result;\r\n}\r\n\r\nexport interface IRequestCallbacks<TResult = any> {\r\n // onBeforeExecuteRequest\r\n onBeforeSendRequest?: (event: {\r\n request: IRequestParams;\r\n // interrupt\r\n cancel: boolean;\r\n handled: boolean;\r\n result?: TResult;\r\n }) => Promise<void>;\r\n onResponseRead?: (event: { response: Response; result: TResult }) => Promise<void>;\r\n}\r\n\r\n// IRequestOptions\r\nexport interface IRequestParams<TResult = any> extends RequestInit {\r\n // TODO: support WebSocket transport\r\n id?: string;\r\n tag?: string;\r\n url: string;\r\n // authType?: ...;\r\n useAuth?: boolean;\r\n // authToken?: string; // bearerToken\r\n // TODO: support\r\n // accepts: string[]; // https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Accept\r\n // TODO: support\r\n crossDomain?: boolean;\r\n contentType?: MimeType; // dataType\r\n httpOnly?: boolean;\r\n // transportType: ...;\r\n callbacks?: IRequestCallbacks<TResult>;\r\n}\r\n"],"names":["getResponseBlob","response","getResponseJson","getResponseText","getResponseArrayBuffer","getResponseResult","request","mimeType","result","resolved","httpStatus","json"],"mappings":";AAuEO,MAAMA,IAAkB,CAACC,MAAuBA,EAAS,KAAK,GAExDC,IAAkB,CAACD,MAAuBA,EAAS,KAAK,GAExDE,IAAkB,CAACF,MAAuBA,EAAS,KAAK,GAExDG,IAAyB,CAACH,MAAuBA,EAAS,YAAY;AAG7D,eAAAI,EAAkBJ,GAA0BK,GAAsC;AAEpG,MAAIC,IACAD,EAAQ,gBACPA,EAAQ,WAAWA,EAAQ,mBAAmB,UAAUA,EAAQ,QAAQ,IAAI,cAAc,IAAIA,EAAQ,QAAQ,cAAc;AACjI,EAAIL,EAAS,YAOEM,IAAAN,EAAS,mBAAmB,UAAUA,EAAS,QAAQ,IAAI,cAAc,IAAIA,EAAS,QAAQ,cAAc;AAE3H,MAAIO;AACA,EAACP,EAAS,aACVA,EAAS,WAAW;AAExB,QAAMQ,IAAWR,EAAS;AAE1B,MADYM,KAAAA,KAAY,IAAI,YAAY,GACpCN,EAAS,WAAWS,EAAW,MAAMT,EAAS,WAAWS,EAAW;AAChE,QAAAH,EAAS,WAAW,OAAO;AAClB,MAAAC,IAAA,MAAMP,EAAS;aACjBM,EAAS,WAAW,QAAQ;AAC1B,MAAAC,IAAA,MAAMP,EAAS;aAEpBM,EAAS,WAAW,kBAAkB;AAC7B,MAAAC,IAAA,MAAMP,EAAS,QACxBQ,EAAS,OAAOD;AAAA,aACTD,EAAS,WAAW,cAAc;AAChC,MAAAC,IAAA,MAAMP,EAAS,QACxBQ,EAAS,OAAOD;AAAA;AAEhB,YAAM,IAAI,MAAM,0BAA0BD,CAAQ,EAAE;AAAA,OAGzD;AACG,UAAAI,IAAO,MAAMV,EAAS;AAC5B,UAAAQ,EAAS,OAAOE,GAIV,IAAI,MAAM,oBAAoBV,EAAS,MAAM,EAAE;AAAA,EACzD;AAEA,SAAAK,EAAQ,SAASE,GACVA;AACX;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactHooks.d.ts","sourceRoot":"","sources":["../src/reactHooks.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAM7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactHooks.es.js","sources":["../src/reactHooks.ts"],"sourcesContent":["import { useRef } from \"react\";\r\n\r\nexport function useLazyRef<T>(factory: () => T) {\r\n const ref = useRef<T | null>(null);\r\n if (ref.current === null) {\r\n ref.current = factory();\r\n }\r\n return ref;\r\n}\r\n"],"names":["useLazyRef","factory","ref","useRef"],"mappings":";AAEO,SAASA,EAAcC,GAAkB;AACtC,QAAAC,IAAMC,EAAiB,IAAI;AAC7B,SAAAD,EAAI,YAAY,SAChBA,EAAI,UAAUD,MAEXC;AACX;"}
|