@actdim/dynstruct 0.9.8 → 1.0.2

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.
@@ -5,9 +5,9 @@ import { ApiError as r } from "./apiError.es.js";
5
5
  function u(c, e) {
6
6
  if (!c)
7
7
  return c;
8
- const t = e.map((i) => i.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"), n = new RegExp(`(_?(${t}))+?$`, "i");
9
- let a = c.replace(n, "");
10
- return a = a.trim(), a.length > 0 ? a : c;
8
+ const t = e.map((i) => i.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"), a = new RegExp(`(_?(${t}))+?$`, "i");
9
+ let n = c.replace(a, "");
10
+ return n = n.trim(), n.length > 0 ? n : c;
11
11
  }
12
12
  const f = ["api", "controller", "client", "fetcher"];
13
13
  class R {
@@ -31,8 +31,8 @@ class R {
31
31
  async getBaseUrlAsync() {
32
32
  const s = (await this.msgBus.dispatchAsync({
33
33
  channel: "APP-CONFIG-GET"
34
- })).payload, t = u(this.name, f), n = Object.entries(s.apis).find((a) => a[0].toLowerCase() === t?.toLowerCase());
35
- this.baseUrl = n?.[1].url || s.baseUrl;
34
+ })).payload, t = u(this.name, f), a = Object.entries(s.apis).find((n) => n[0].toLowerCase() === t?.toLowerCase());
35
+ this.baseUrl = a?.[1].url || s.baseUrl;
36
36
  }
37
37
  async updateSecurityAsync() {
38
38
  if (!this.accessToken) {
@@ -49,9 +49,9 @@ class R {
49
49
  throw r.create({
50
50
  status: o.UNAUTHORIZED
51
51
  });
52
- const t = "Authorization", n = e.headers, a = `Bearer ${s}`;
53
- if (n instanceof Headers)
54
- n.set(t, a);
52
+ const t = "Authorization", a = e.headers, n = `Bearer ${s}`;
53
+ if (a instanceof Headers)
54
+ a.set(t, n);
55
55
  else
56
56
  throw new Error("Unsupported headers");
57
57
  }
@@ -60,30 +60,30 @@ class R {
60
60
  let s = !0;
61
61
  const t = e.callbacks && e.callbacks.onBeforeSendRequest;
62
62
  if (t) {
63
- const n = {
63
+ const a = {
64
64
  request: e,
65
65
  cancel: !1,
66
66
  handled: !1
67
67
  };
68
- if (await t(n), n.cancel)
69
- if (s = !1, e.status = "canceled", n.handled)
70
- e.result = n.result;
68
+ if (await t(a), a.cancel)
69
+ if (s = !1, e.status = "canceled", a.handled)
70
+ e.result = a.result;
71
71
  else
72
72
  throw new Error("The request was aborted");
73
73
  }
74
74
  if (s) {
75
75
  e.status = "executing";
76
- const n = await this.fetcher.fetch(e.url, e);
77
- r.assert(n, e);
78
- let a = e.callbacks && e.callbacks.onResponseRead;
79
- a || (a = async (l) => {
80
- const h = await p(n, e);
76
+ const a = await this.fetcher.fetch(e.url, e);
77
+ r.assert(a, e);
78
+ let n = e.callbacks && e.callbacks.onResponseRead;
79
+ n || (n = async (l) => {
80
+ const h = await p(a, e);
81
81
  l.result = h;
82
82
  });
83
83
  const i = {
84
- response: n
84
+ response: a
85
85
  };
86
- await a(i), e.result = i.result, e.status = "succeeded";
86
+ await n(i), e.result = i.result, e.status = "succeeded";
87
87
  }
88
88
  } catch (s) {
89
89
  throw e.status = "failed", s;
@@ -94,7 +94,7 @@ class R {
94
94
  let s = 0;
95
95
  do
96
96
  try {
97
- return e.useAuth && await this.addAuthorizationAsync(e), this.executeRequestInternalAsync(e);
97
+ return e.useAuth && await this.addAuthorizationAsync(e), await this.executeRequestInternalAsync(e);
98
98
  } catch (t) {
99
99
  if (t instanceof r) {
100
100
  if (s > 0 || t.status === o.UPGRADE_REQUIRED)
@@ -125,14 +125,14 @@ class R {
125
125
  cache: "default",
126
126
  credentials: "same-origin",
127
127
  mode: "cors"
128
- }, ...e }, e.id || (e.id = d());
128
+ }, ...e }, e.id || (e.id = d()), e.headers instanceof Headers || (e.headers = new Headers(e.headers)), e.headers.append("Content-Type", e.contentType), e.method === "POST" && (e.body || (e.body = ""));
129
129
  let t = {
130
130
  ...e,
131
131
  status: "queued",
132
132
  response: void 0,
133
133
  result: void 0
134
134
  };
135
- return this.requestStateMap.set(e.id, t), 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(t), t.result;
135
+ return this.requestStateMap.set(e.id, t), await this.executeRequestAsync(t), t.result;
136
136
  }
137
137
  }
138
138
  export {
@@ -1 +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","msg","config","apiName","apiEntry","entry","request","accessToken","ApiError","httpStatus","authorizationHeader","headers","headerValue","proceed","onBeforeSendRequest","event","response","onResponseRead","getResponseResult","err","attempt","requestParams","uuid"],"mappings":"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"}
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 await 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 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 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 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","msg","config","apiName","apiEntry","entry","request","accessToken","ApiError","httpStatus","authorizationHeader","headers","headerValue","proceed","onBeforeSendRequest","event","response","onResponseRead","getResponseResult","err","attempt","requestParams","uuid"],"mappings":"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"}
@@ -1 +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"}
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;AAG1F,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,CAmDtG;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"}
@@ -1,33 +1,38 @@
1
- import n from "http-status";
2
- const l = (t) => t.blob(), c = (t) => t.json(), d = (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;
1
+ import s from "http-status";
2
+ import { ApiError as n } from "./apiError.es.js";
3
+ const l = (t) => t.blob(), f = (t) => t.json(), h = (t) => t.text(), d = (t) => t.arrayBuffer();
4
+ async function y(t, a) {
5
+ let o = a.contentType || (a.headers && a.headers instanceof Headers ? a.headers.get("content-type") : a.headers["Content-Type"]);
6
+ t.headers && (o = t.headers instanceof Headers ? t.headers.get("content-type") : t.headers["content-type"]);
7
+ let e;
7
8
  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;
9
+ const i = t.resolved;
10
+ if (o = (o || "").toLowerCase(), o.startsWith("text/"))
11
+ e = await t.text();
12
+ else if (o.startsWith("image/"))
13
+ e = await t.blob();
14
+ else if (o.startsWith("application/json"))
15
+ e = await t.json(), i.json = e;
16
+ else if (o.startsWith("octet-stream"))
17
+ e = await t.blob(), i.blob = e;
18
+ else
19
+ try {
20
+ i.json = await t.clone().json();
21
+ } catch {
22
+ try {
23
+ i.text = await t.text();
24
+ } catch {
25
+ }
26
+ }
27
+ if (!(t.status === s.OK || t.status === s.NO_CONTENT))
28
+ throw n.create(t, a);
29
+ return a.result = e, e;
25
30
  }
26
31
  export {
27
- f as getResponseArrayBuffer,
32
+ d as getResponseArrayBuffer,
28
33
  l as getResponseBlob,
29
- c as getResponseJson,
30
- h as getResponseResult,
31
- d as getResponseText
34
+ f as getResponseJson,
35
+ y as getResponseResult,
36
+ h as getResponseText
32
37
  };
33
38
  //# sourceMappingURL=request.es.js.map
@@ -1 +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,KAAA,GAEnDC,IAAkB,CAACD,MAAuBA,EAAS,KAAA,GAEnDE,IAAkB,CAACF,MAAuBA,EAAS,KAAA,GAEnDG,IAAyB,CAACH,MAAuBA,EAAS,YAAA;AAGvE,eAAsBI,EAAkBJ,GAA0BK,GAAsC;AAEpG,MAAIC,IACAD,EAAQ,gBACPA,EAAQ,WAAWA,EAAQ,mBAAmB,UAAUA,EAAQ,QAAQ,IAAI,cAAc,IAAIA,EAAQ,QAAQ,cAAc;AACjI,EAAIL,EAAS,YAOTM,IAAWN,EAAS,mBAAmB,UAAUA,EAAS,QAAQ,IAAI,cAAc,IAAIA,EAAS,QAAQ,cAAc;AAE3H,MAAIO;AACJ,EAAKP,EAAS,aACVA,EAAS,WAAW,CAAA;AAExB,QAAMQ,IAAWR,EAAS;AAE1B,MADAM,KAAYA,KAAY,IAAI,YAAA,GACxBN,EAAS,WAAWS,EAAW,MAAMT,EAAS,WAAWS,EAAW;AACpE,QAAIH,EAAS,WAAW,OAAO;AAC3B,MAAAC,IAAS,MAAMP,EAAS,KAAA;AAAA,aACjBM,EAAS,WAAW,QAAQ;AACnC,MAAAC,IAAS,MAAMP,EAAS,KAAA;AAAA,aAEpBM,EAAS,WAAW,kBAAkB;AACtC,MAAAC,IAAS,MAAMP,EAAS,KAAA,GACxBQ,EAAS,OAAOD;AAAA,aACTD,EAAS,WAAW,cAAc;AACzC,MAAAC,IAAS,MAAMP,EAAS,KAAA,GACxBQ,EAAS,OAAOD;AAAA;AAEhB,YAAM,IAAI,MAAM,0BAA0BD,CAAQ,EAAE;AAAA,OAGzD;AACH,UAAMI,IAAO,MAAMV,EAAS,KAAA;AAC5B,UAAAQ,EAAS,OAAOE,GAIV,IAAI,MAAM,oBAAoBV,EAAS,MAAM,EAAE;AAAA,EACzD;AAEA,SAAAK,EAAQ,SAASE,GACVA;AACX;"}
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\nimport { ApiError } from \"./apiError\";\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 contentType =\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 contentType = 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 contentType = (contentType || \"\").toLowerCase();\r\n if (contentType.startsWith(\"text/\")) {\r\n result = await response.text();\r\n } else if (contentType.startsWith(\"image/\")) {\r\n result = await response.blob();\r\n } else {\r\n if (contentType.startsWith(\"application/json\")) {\r\n result = await response.json();\r\n resolved.json = result;\r\n } else if (contentType.startsWith(\"octet-stream\")) {\r\n result = await response.blob();\r\n resolved.blob = result;\r\n } else {\r\n try {\r\n resolved.json = await response.clone().json();\r\n } catch {\r\n try {\r\n resolved.text = await response.text();\r\n } catch {\r\n }\r\n }\r\n // unexpected response\r\n // throw new Error(`Unsupported content type: ${contentType}`);\r\n }\r\n }\r\n if (!(response.status === httpStatus.OK || response.status === httpStatus.NO_CONTENT)) {\r\n // JSON.stringify(resolved)\r\n throw ApiError.create(response, request);\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","contentType","result","resolved","httpStatus","ApiError"],"mappings":";;AAwEO,MAAMA,IAAkB,CAACC,MAAuBA,EAAS,KAAA,GAEnDC,IAAkB,CAACD,MAAuBA,EAAS,KAAA,GAEnDE,IAAkB,CAACF,MAAuBA,EAAS,KAAA,GAEnDG,IAAyB,CAACH,MAAuBA,EAAS,YAAA;AAGvE,eAAsBI,EAAkBJ,GAA0BK,GAAsC;AAEpG,MAAIC,IACAD,EAAQ,gBACPA,EAAQ,WAAWA,EAAQ,mBAAmB,UAAUA,EAAQ,QAAQ,IAAI,cAAc,IAAIA,EAAQ,QAAQ,cAAc;AACjI,EAAIL,EAAS,YAOTM,IAAcN,EAAS,mBAAmB,UAAUA,EAAS,QAAQ,IAAI,cAAc,IAAIA,EAAS,QAAQ,cAAc;AAE9H,MAAIO;AACJ,EAAKP,EAAS,aACVA,EAAS,WAAW,CAAA;AAExB,QAAMQ,IAAWR,EAAS;AAE1B,MADAM,KAAeA,KAAe,IAAI,YAAA,GAC9BA,EAAY,WAAW,OAAO;AAC9B,IAAAC,IAAS,MAAMP,EAAS,KAAA;AAAA,WACjBM,EAAY,WAAW,QAAQ;AACtC,IAAAC,IAAS,MAAMP,EAAS,KAAA;AAAA,WAEpBM,EAAY,WAAW,kBAAkB;AACzC,IAAAC,IAAS,MAAMP,EAAS,KAAA,GACxBQ,EAAS,OAAOD;AAAA,WACTD,EAAY,WAAW,cAAc;AAC5C,IAAAC,IAAS,MAAMP,EAAS,KAAA,GACxBQ,EAAS,OAAOD;AAAA;AAEhB,QAAI;AACA,MAAAC,EAAS,OAAO,MAAMR,EAAS,MAAA,EAAQ,KAAA;AAAA,IAC3C,QAAQ;AACJ,UAAI;AACA,QAAAQ,EAAS,OAAO,MAAMR,EAAS,KAAA;AAAA,MACnC,QAAQ;AAAA,MACR;AAAA,IACJ;AAKR,MAAI,EAAEA,EAAS,WAAWS,EAAW,MAAMT,EAAS,WAAWS,EAAW;AAEtE,UAAMC,EAAS,OAAOV,GAAUK,CAAO;AAG3C,SAAAA,EAAQ,SAASE,GACVA;AACX;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@actdim/dynstruct",
3
- "version": "0.9.8",
3
+ "version": "1.0.2",
4
4
  "description": "A type-safe component system for large-scale apps: explicit dependencies, message bus communication, and structure-first, declarative design",
5
5
  "author": "Pavel Borodaev",
6
6
  "license": "Proprietary",
@@ -50,24 +50,23 @@
50
50
  },
51
51
  "sideEffects": false,
52
52
  "sideEffects?": [],
53
- "scripts": {
54
- "test": "npx vitest",
55
- "wtest": "npx vitest --watch",
56
- "dtest": "node --inspect-brk node_modules/vitest/vitest.mjs run --poolOptions.threads.singleThread",
53
+ "scripts": {
54
+ "test": "npx vitest --config=vitest.node.config.ts --no-cache",
55
+ "test:w": "npx vitest --config=vitest.node.config.ts --watch",
56
+ "test:v8": "npx vite",
57
57
  "lint": "eslint . -f visualstudio --ext .ts,.tsx --report-unused-disable-directives --max-warnings 0",
58
- "online": "vite --host",
59
58
  "build": "tsc -b && vite build",
60
- "npm:u": "npm update",
61
- "npm:ou": "npm outdated",
62
- "ncu": "ncu",
59
+ "pnpm:u": "pnpm update",
60
+ "pnpm:ou": "pnpm outdated",
61
+ "ncu:l": "ncu",
63
62
  "ncu:u": "ncu -u",
64
63
  "ncu:ud": "ncu -u --dev",
65
64
  "nvm:la": "nvm list available",
66
- "nvm:il": "nvm install lts"
65
+ "nvm:il": "nvm install lts",
66
+ "format": "prettier --write .",
67
+ "format:check": "prettier --check ."
67
68
  },
68
69
  "peerDependencies": {
69
- "rxjs": "^7.8.2",
70
- "uuid": "^13.0.0",
71
70
  "http-status": "^2.1.0",
72
71
  "jwt-decode": "^4.0.0",
73
72
  "mobx": "^6.15.0",
@@ -78,35 +77,40 @@
78
77
  "react-dom": "^19.2.0",
79
78
  "react-router": "^7.9.3",
80
79
  "react-router-dom": "^7.9.4",
81
- "@actdim/utico": "^0.9.7",
82
- "@actdim/msgmesh": "^0.9.7"
80
+ "@actdim/utico": "^1.0.2",
81
+ "@actdim/msgmesh": "^1.0.2",
82
+ "rxjs": "^7.8.2",
83
+ "dexie": "^4.2.0",
84
+ "moment": "^2.30.1",
85
+ "uuid": "^13.0.0"
83
86
  },
84
87
  "devDependencies": {
85
- "@swc/core": "^1.13.5",
86
- "@types/node": "^24.7.0",
87
- "@types/uuid": "^11.0.0",
88
- "@typescript-eslint/eslint-plugin": "^8.45.0",
89
- "@typescript-eslint/parser": "^8.46.0",
90
- "@vitejs/plugin-react-swc": "^4.1.0",
91
- "eslint": "^9.37.0",
92
- "eslint-config-prettier": "^10.1.8",
93
- "eslint-formatter-visualstudio": "^8.40.0",
94
- "eslint-plugin-jsx-a11y": "^6.10.2",
95
- "eslint-plugin-prettier": "^5.5.4",
88
+ "@swc/core": "^1.15.1",
89
+ "@vitejs/plugin-react-swc": "^4.2.1",
96
90
  "eslint-plugin-react": "^7.37.5",
97
- "eslint-plugin-react-hooks": "^7.0.0",
98
- "eslint-plugin-react-refresh": "^0.4.23",
99
- "globals": "^16.4.0",
100
- "npm-check-updates": "^19.0.0",
91
+ "eslint-plugin-react-hooks": "^7.0.1",
92
+ "eslint-plugin-react-refresh": "^0.4.24",
93
+ "@types/chai": "^5.2.3",
94
+ "@types/mocha": "^10.0.10",
95
+ "@types/node": "^24.10.0",
96
+ "@typescript-eslint/eslint-plugin": "^8.46.3",
97
+ "@typescript-eslint/parser": "^8.46.3",
98
+ "chai": "^6.2.0",
99
+ "eslint": "^9.39.1",
100
+ "eslint-config-prettier": "^10.1.8",
101
+ "eslint-formatter-visualstudio": "^9.0.1",
102
+ "eslint-plugin-prettier": "^5.5.4",
103
+ "globals": "^16.5.0",
104
+ "mocha": "^11.7.5",
105
+ "npm-check-updates": "^19.1.2",
101
106
  "prettier": "^3.6.2",
102
- "prettier-plugin-classnames": "^0.8.4",
107
+ "prettier-plugin-classnames": "^0.8.5",
103
108
  "shx": "^0.4.0",
104
- "ts-node": "^10.9.2",
105
109
  "typescript": "^5.9.3",
106
- "typescript-eslint": "^8.46.0",
107
- "vite": "^7.1.9",
110
+ "typescript-eslint": "^8.46.3",
111
+ "vite": "^7.2.2",
108
112
  "vite-plugin-dts": "^4.5.4",
109
113
  "vite-tsconfig-paths": "^5.1.4",
110
- "vitest": "^3.2.4"
114
+ "vitest": "^4.0.8"
111
115
  }
112
116
  }