@ryuzaki13/react-foundation-api 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/adt/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e } from "../chunks/fetch-3O2E2pQ9.js";
1
+ import { t as e } from "../chunks/fetch-CPEFkAcU.js";
2
2
  import { isRecord as t } from "@ryuzaki13/react-foundation-lib/validators";
3
3
  import { normalizeText as n } from "@ryuzaki13/react-foundation-lib/formatters";
4
4
  import { arrayUniqueBy as r } from "@ryuzaki13/react-foundation-lib/array";
@@ -14,75 +14,76 @@ function l(e) {
14
14
  return e.split(";")[0] ?? e;
15
15
  }
16
16
  function u(e, t) {
17
- return o.devDp0Service, t ?? "odata";
17
+ let n = o.devDp0Service;
18
+ return (__DEV__ || __PREVIEW__) && n && l(e) === l(n) ? "odataDp0" : t ?? "odata";
18
19
  }
19
20
  function d() {
20
21
  return o.resolveSapClient?.() ?? null;
21
22
  }
22
23
  //#endregion
23
24
  //#region src/odata/transport/url.ts
24
- var f = "/sap/opu/odata/sap", p = "/sap/opu/odata/sap", m = "/sap/opu/odata/UI2", h = "/some/config", g = Object.freeze({
25
+ var f = "/sap/opu/odata/sap", ee = __DEV__ || __PREVIEW__ ? "/sap-dp0/opu/odata/sap" : "/sap/opu/odata/sap", p = __DEV__ || __PREVIEW__ ? "/sap-dp0/opu/odata/UI2" : "/sap/opu/odata/UI2", m = __BASE_APP_CONFIG_URL__, h = Object.freeze({
25
26
  "": "",
26
27
  odata: f,
27
- odataDp0: p,
28
- odataUi2: m,
29
- config: h
28
+ odataDp0: ee,
29
+ odataUi2: p,
30
+ config: m
30
31
  });
31
- function _(e) {
32
+ function g(e) {
32
33
  return typeof e == "string" ? e : typeof Request < "u" && e instanceof Request ? e.url : e.toString();
33
34
  }
34
- function v(e) {
35
+ function _(e) {
35
36
  let t = e.split("?")[0]?.split("#")[0] ?? "";
36
37
  return t ? t.startsWith("/") ? t : `/${t}` : "/";
37
38
  }
38
39
  //#endregion
39
40
  //#region src/odata/transport/errorReport.ts
40
- var ee = 40, te = 1e3;
41
- function y(e) {
41
+ var te = 40, ne = 1e3;
42
+ function v(e) {
42
43
  try {
43
44
  let t = typeof window < "u" ? window.location.origin : "http://localhost", n = new URL(e, t);
44
45
  return `${n.origin === t ? "" : n.origin}${n.pathname}`;
45
46
  } catch {
46
- return v(e);
47
+ return _(e);
47
48
  }
48
49
  }
49
- function ne(e) {
50
+ function re(e) {
50
51
  if (!(typeof DOMParser > "u")) try {
51
52
  return new DOMParser().parseFromString(e, "text/html");
52
53
  } catch {
53
54
  return;
54
55
  }
55
56
  }
56
- function re(e, t) {
57
+ function ie(e, t) {
57
58
  return t?.querySelector("title")?.textContent || /<title[^>]*>([\s\S]*?)<\/title>/i.exec(e)?.[1];
58
59
  }
59
- function ie(e, t) {
60
+ function ae(e, t) {
60
61
  let n = t?.querySelectorAll("form").length;
61
62
  return n === void 0 ? Array.from(e.matchAll(/<form\b/gi)).length : n;
62
63
  }
63
- function ae(e, t) {
64
+ function oe(e, t) {
64
65
  let n = t ? Array.from(t.querySelectorAll("input[name],textarea[name],select[name]")).map((e) => e.name).filter(Boolean) : Array.from(e.matchAll(/\bname\s*=\s*["']([^"']+)["']/gi)).map((e) => e[1]).filter((e) => !!e);
65
- return Array.from(new Set(n)).slice(0, ee);
66
+ return Array.from(new Set(n)).slice(0, te);
66
67
  }
67
- function oe(e, t) {
68
- return a(t?.body?.textContent ?? e.replace(/<script\b[\s\S]*?<\/script>/gi, " ").replace(/<style\b[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " "), te);
68
+ function se(e, t) {
69
+ return a(t?.body?.textContent ?? e.replace(/<script\b[\s\S]*?<\/script>/gi, " ").replace(/<style\b[\s\S]*?<\/style>/gi, " ").replace(/<[^>]+>/g, " "), ne);
69
70
  }
70
- function se(e) {
71
- let t = ne(e);
71
+ function ce(e) {
72
+ let t = re(e);
72
73
  return {
73
74
  length: e.length,
74
- title: a(re(e, t), 200),
75
- formCount: ie(e, t),
76
- inputNames: ae(e, t),
77
- textPreview: oe(e, t)
75
+ title: a(ie(e, t), 200),
76
+ formCount: ae(e, t),
77
+ inputNames: oe(e, t),
78
+ textPreview: se(e, t)
78
79
  };
79
80
  }
80
- function ce(e, t, n, r, a) {
81
- let o = a ? _(a.input) : void 0, s = o?.startsWith("http") ? o : o ? `${g[a?.baseUrlType ?? ""]}${o}` : void 0;
81
+ function y(e, t, n, r, a) {
82
+ let o = a ? g(a.input) : void 0, s = o?.startsWith("http") ? o : o ? `${h[a?.baseUrlType ?? ""]}${o}` : void 0;
82
83
  i(e, {
83
84
  source: t,
84
- requestUrl: s ? y(s) : void 0,
85
- responseUrl: n.url ? y(n.url) : void 0,
85
+ requestUrl: s ? v(s) : void 0,
86
+ responseUrl: n.url ? v(n.url) : void 0,
86
87
  method: a?.init.method?.toUpperCase() ?? "GET",
87
88
  baseUrlType: a?.baseUrlType,
88
89
  sapClient: a?.sapClient,
@@ -91,7 +92,7 @@ function ce(e, t, n, r, a) {
91
92
  contentType: n.headers.get("Content-Type") || void 0,
92
93
  redirected: n.redirected,
93
94
  responseType: n.type,
94
- html: se(r)
95
+ html: ce(r)
95
96
  });
96
97
  }
97
98
  //#endregion
@@ -100,7 +101,7 @@ var b = null, le = 0;
100
101
  function x(e) {
101
102
  if (typeof window > "u") return e;
102
103
  try {
103
- let t = /* @__PURE__ */ RegExp("^https://sapbpc[a-z0-9-]+.some.site$", "i"), n = new URL(e, window.location.origin), r = t.test(n.origin), i = n.origin === "https://sso.some.site";
104
+ let t = new RegExp(__ORIGIN_REG_EXP__, "i"), n = new URL(e, window.location.origin), r = t.test(n.origin), i = n.origin === __SSO_ORIGIN__;
104
105
  return r || i || n.origin === window.location.origin ? `${n.pathname}${n.search}${n.hash}` : n.toString();
105
106
  } catch {
106
107
  return e;
@@ -110,7 +111,7 @@ function S(e) {
110
111
  return e ? typeof e.inputs.SAMLRequest == "string" || typeof e.inputs.SAMLResponse == "string" : !1;
111
112
  }
112
113
  function C() {
113
- let e = `@ryuzaki13/react-foundation-api@1.1.1-sso-iframe-${++le}`, t = document.createElement("iframe");
114
+ let e = `${__APP_ID__}-sso-iframe-${++le}`, t = document.createElement("iframe");
114
115
  return t.name = e, t.style.display = "none", t;
115
116
  }
116
117
  function w(e, t) {
@@ -173,11 +174,11 @@ var O = class e extends Error {
173
174
  }, k = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map(), j = null, M = null;
174
175
  function N(e, t) {
175
176
  if (t !== "") return !0;
176
- let n = v(_(e));
177
+ let n = _(g(e));
177
178
  return n.startsWith("/sap/") || n.startsWith("/sap-dp0/");
178
179
  }
179
180
  function P(e, t) {
180
- return d();
181
+ return __DEV__ || __PREVIEW__ ? N(e, t) ? t === "odataDp0" || t === "" && _(g(e)).startsWith("/sap-dp0/") ? "300" : `${__SAP_CLIENT__}` : null : d();
181
182
  }
182
183
  function F(e) {
183
184
  return new O("Не удалось автоматически восстановить SSO-сессию. Перезагрузите страницу и выполните вход заново.", e.form, e.recoveryUrl, { recoverable: !1 });
@@ -218,10 +219,10 @@ async function R(e, t) {
218
219
  }
219
220
  function z(e, t, n) {
220
221
  if (t === "config") return {
221
- cacheKey: `@ryuzaki13/react-foundation-api@1.1.1:${n ?? ""}`,
222
+ cacheKey: `${__APP_ID__}:${n ?? ""}`,
222
223
  fetchUrl: "/Statistics"
223
224
  };
224
- let [r] = v(_(e)).split("/").filter(Boolean);
225
+ let [r] = _(g(e)).split("/").filter(Boolean);
225
226
  if (!r) throw Error("Не удалось определить сервис для получения CSRF-токена");
226
227
  return {
227
228
  cacheKey: `${t}:${n ?? ""}:${r}`,
@@ -235,13 +236,13 @@ async function B(e, t, n) {
235
236
  if (a) return a;
236
237
  let o = new Headers({ "x-csrf-token": "Fetch" });
237
238
  o.set("sap-language", "ru"), o.set("sap-contextid-accept", "header"), o.set("Accept-Language", "ru"), n && o.set("sap-client", n);
238
- let s = (t && g[t]) ?? "", c = fetch(s + r.fetchUrl, {
239
+ let s = (t && h[t]) ?? "", c = fetch(s + r.fetchUrl, {
239
240
  method: "GET",
240
241
  headers: o,
241
242
  credentials: "include",
242
243
  redirect: "manual"
243
244
  }).then(async (e) => {
244
- if (J(e)) throw new O("Требуется повторная аутентификация", void 0, s + r.fetchUrl);
245
+ if (Y(e)) throw new O("Требуется повторная аутентификация", void 0, s + r.fetchUrl);
245
246
  if (!e.ok) throw Error("Не удалось получить CSRF-токен");
246
247
  let t = e.headers.get("x-csrf-token");
247
248
  if (!t) {
@@ -322,7 +323,7 @@ async function K(t, n) {
322
323
  let e = H(i);
323
324
  if (S(e)) throw new O("Требуется повторная аутентификация", e);
324
325
  let r = /* @__PURE__ */ Error("Unexpected HTML response from OData endpoint");
325
- throw ce(r, "fetch.parseResponse", t, i, n), r;
326
+ throw y(r, "fetch.parseResponse", t, i, n), r;
326
327
  }
327
328
  try {
328
329
  return G(JSON.parse(i));
@@ -330,35 +331,35 @@ async function K(t, n) {
330
331
  throw e(t), Error("Unsupported response content type and body is not JSON");
331
332
  }
332
333
  }
333
- function he(e) {
334
+ function q(e) {
334
335
  if (typeof e != "string") return null;
335
336
  let t = e.trim();
336
337
  return t.length ? t : null;
337
338
  }
338
- function q(e, t) {
339
- let n = he(t);
339
+ function J(e, t) {
340
+ let n = q(t);
340
341
  !n || e.includes(n) || e.push(n);
341
342
  }
342
- function ge(e) {
343
+ function he(e) {
343
344
  let n = [], r = e.error;
344
- typeof r == "string" && q(n, r);
345
+ typeof r == "string" && J(n, r);
345
346
  let i = t(r);
346
- return i && (q(n, i.code), q(n, t(i.message)?.value ?? i.message)), q(n, e.details), q(n, e.message), n;
347
+ return i && (J(n, i.code), J(n, t(i.message)?.value ?? i.message)), J(n, e.details), J(n, e.message), n;
347
348
  }
348
- async function _e(e, t) {
349
+ async function ge(e, t) {
349
350
  let n = (e.headers.get("Content-Type") || "").toLowerCase();
350
351
  try {
351
352
  if (n.includes("application/json") || n.includes("application/odata+json")) {
352
- let t = ge(await e.json());
353
+ let t = he(await e.json());
353
354
  if (t.length) return Error(t.join(" | "));
354
355
  } else {
355
- let r = he(await e.text());
356
+ let r = q(await e.text());
356
357
  if (r) {
357
358
  if (U(n, r)) {
358
359
  let n = H(r);
359
360
  if (S(n)) return new O("Требуется повторная аутентификация", n);
360
361
  let i = /* @__PURE__ */ Error("Unexpected HTML response from OData endpoint");
361
- return ce(i, "fetch.buildHttpError", e, r, t), i;
362
+ return y(i, "fetch.buildHttpError", e, r, t), i;
362
363
  }
363
364
  return Error(r);
364
365
  }
@@ -366,23 +367,23 @@ async function _e(e, t) {
366
367
  } catch {}
367
368
  return /* @__PURE__ */ Error(`HTTP error: ${e.status} ${e.statusText}`);
368
369
  }
369
- function J(e) {
370
+ function Y(e) {
370
371
  return e.type === "opaqueredirect";
371
372
  }
372
- async function ve(e, t = {}, n = "odata") {
373
+ async function _e(e, t = {}, n = "odata") {
373
374
  let i = t.method?.toUpperCase() || "GET", a = new Headers(t.headers), o = !["GET", "HEAD"].includes(i), s = r(t.body), c = N(e, n), l = P(e, n);
374
375
  if (a.set("sap-language", "ru"), c && (a.set("sap-language", "ru"), a.set("sap-contextid-accept", "header")), l && a.set("sap-client", l), o && c) {
375
376
  let t = await B(e, n, l);
376
377
  a.set("x-csrf-token", t);
377
378
  }
378
379
  a.has("Accept") || a.set("Accept", "application/json"), s && o && !a.has("Content-Type") && a.set("Content-Type", "application/json");
379
- let u = (n && g[n]) ?? "", d = typeof e == "string" ? e : e.toString(), f = await fetch(u + d, {
380
+ let u = (n && h[n]) ?? "", d = typeof e == "string" ? e : e.toString(), f = await fetch(u + d, {
380
381
  ...t,
381
382
  headers: a,
382
383
  credentials: "include",
383
384
  redirect: c ? "manual" : t.redirect
384
385
  });
385
- if (c && J(f)) throw new O("Требуется повторная аутентификация", void 0, u + d);
386
+ if (c && Y(f)) throw new O("Требуется повторная аутентификация", void 0, u + d);
386
387
  if ((f.status === 401 || f.status === 403) && o && c && !t.retried) {
387
388
  let r = z(e, n, l);
388
389
  k.delete(r.cacheKey), A.delete(r.cacheKey);
@@ -393,12 +394,12 @@ async function ve(e, t = {}, n = "odata") {
393
394
  credentials: "include",
394
395
  redirect: "manual",
395
396
  retried: !0
396
- }), J(f)) throw new O("Требуется повторная аутентификация", void 0, u + d);
397
+ }), Y(f)) throw new O("Требуется повторная аутентификация", void 0, u + d);
397
398
  }
398
399
  return f;
399
400
  }
400
- async function Y(e, t, n, r, i) {
401
- if (!e.ok) throw e.status === 0 ? Error("Ошибка сети или CORS. Проверьте подключение и настройки сервера.") : await _e(e, {
401
+ async function X(e, t, n, r, i) {
402
+ if (!e.ok) throw e.status === 0 ? Error("Ошибка сети или CORS. Проверьте подключение и настройки сервера.") : await ge(e, {
402
403
  input: t,
403
404
  init: n,
404
405
  baseUrlType: r,
@@ -406,27 +407,27 @@ async function Y(e, t, n, r, i) {
406
407
  });
407
408
  return e;
408
409
  }
409
- async function X(e, t = {}, n = "odata") {
410
+ async function ve(e, t = {}, n = "odata") {
410
411
  let r = P(e, n);
411
- return Y(await ve(e, t, n), e, t, n, r);
412
+ return X(await _e(e, t, n), e, t, n, r);
412
413
  }
413
414
  async function Z(e, t = {}, n = "odata") {
414
- let r = N(e, n), i = P(e, n), a = () => X(e, {
415
+ let r = N(e, n), i = P(e, n), a = () => ve(e, {
415
416
  ...t,
416
417
  ssoRetried: !0
417
418
  }, n);
418
419
  r && await L();
419
420
  let o;
420
421
  try {
421
- o = await ve(e, t, n);
422
+ o = await _e(e, t, n);
422
423
  } catch (e) {
423
424
  if (r && e instanceof O && e.recoverable && !t.ssoRetried) o = await R(e, a);
424
425
  else throw e;
425
426
  }
426
427
  try {
427
- return await Y(o, e, t, n, i);
428
+ return await X(o, e, t, n, i);
428
429
  } catch (o) {
429
- if (r && o instanceof O && o.recoverable && !t.ssoRetried) return Y(await R(o, a), e, t, n, i);
430
+ if (r && o instanceof O && o.recoverable && !t.ssoRetried) return X(await R(o, a), e, t, n, i);
430
431
  throw o;
431
432
  }
432
433
  }
@@ -450,7 +451,7 @@ async function Q(e, t = {}, n = "odata") {
450
451
  ...i,
451
452
  ssoRetried: !0
452
453
  };
453
- return K(await X(e, t, n), {
454
+ return K(await ve(e, t, n), {
454
455
  input: e,
455
456
  init: t,
456
457
  baseUrlType: n,
@@ -503,6 +504,6 @@ function Se(e, t) {
503
504
  }, t);
504
505
  }
505
506
  //#endregion
506
- export { u as C, l as S, g as _, be as a, s as b, me as c, D as d, ue as f, f as g, m as h, xe as i, O as l, p as m, Se as n, Q as o, h as p, $ as r, ye as s, Z as t, S as u, _ as v, d as w, c as x, v as y };
507
+ export { u as C, l as S, h as _, be as a, s as b, me as c, D as d, ue as f, f as g, p as h, xe as i, O as l, ee as m, Se as n, Q as o, m as p, $ as r, ye as s, Z as t, S as u, g as v, d as w, c as x, _ as y };
507
508
 
508
- //# sourceMappingURL=fetch-3O2E2pQ9.js.map
509
+ //# sourceMappingURL=fetch-CPEFkAcU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-3O2E2pQ9.js","names":[],"sources":["../../src/odata/odataProjectAdapter.ts","../../src/odata/transport/url.ts","../../src/odata/transport/errorReport.ts","../../src/odata/transport/SsoRequiredError.ts","../../src/odata/transport/fetch.ts"],"sourcesContent":["import type { BaseURLType } from \"./transport/types\";\n\nexport type ODataProjectTechnicalEndpoint = {\n\tservice: string;\n\ttarget: string;\n\tbaseUrl?: BaseURLType;\n};\n\nexport type ODataProjectAdapter = {\n\t/**\n\t * OData-сервис, который в dev/preview нужно проксировать через DP0.\n\t * В проектах без SAP/OData оставляется пустым.\n\t */\n\tdevDp0Service?: string;\n\tresolveSapClient?: () => string | null | undefined;\n\tmetadataVersion?: ODataProjectTechnicalEndpoint;\n\tcollectionUpdates?: ODataProjectTechnicalEndpoint;\n};\n\nlet odataProjectAdapter: ODataProjectAdapter = {};\n\nexport function configureODataProjectAdapter(adapter: ODataProjectAdapter) {\n\todataProjectAdapter = adapter;\n}\n\nexport function getODataProjectAdapter() {\n\treturn odataProjectAdapter;\n}\n\nexport function normalizeODataServiceName(service: string) {\n\treturn service.split(\";\")[0] ?? service;\n}\n\nexport function resolveODataBaseUrl(service: string, baseUrl?: BaseURLType): BaseURLType {\n\tconst devDp0Service = odataProjectAdapter.devDp0Service;\n\tif ((__DEV__ || __PREVIEW__) && devDp0Service && normalizeODataServiceName(service) === normalizeODataServiceName(devDp0Service)) {\n\t\treturn \"odataDp0\";\n\t}\n\n\treturn baseUrl ?? \"odata\";\n}\n\nexport function resolveODataSapClient() {\n\treturn odataProjectAdapter.resolveSapClient?.() ?? null;\n}\n","import { BaseURLType } from \"./types\";\n\nexport const BaseODataURL = \"/sap/opu/odata/sap\";\n/**\n * DP0-прокси используется только для сервиса, который проект явно указывает\n * через `odataProjectAdapter.devDp0Service`.\n */\nexport const BaseODataDp0URL = __DEV__ || __PREVIEW__ ? \"/sap-dp0/opu/odata/sap\" : \"/sap/opu/odata/sap\";\nexport const BaseODataUI2URL = __DEV__ || __PREVIEW__ ? \"/sap-dp0/opu/odata/UI2\" : \"/sap/opu/odata/UI2\";\nexport const BaseAppConfigURL = __BASE_APP_CONFIG_URL__;\n\nexport const BaseUrlMap = Object.freeze<Record<BaseURLType, string>>({\n\t[\"\"]: \"\",\n\todata: BaseODataURL,\n\todataDp0: BaseODataDp0URL,\n\todataUi2: BaseODataUI2URL,\n\tconfig: BaseAppConfigURL\n});\n\nexport function getInputUrl(input: RequestInfo) {\n\tif (typeof input === \"string\") return input;\n\tif (typeof Request !== \"undefined\" && input instanceof Request) {\n\t\treturn input.url;\n\t}\n\treturn input.toString();\n}\n\nexport function normalizeRelativePath(url: string) {\n\tconst path = url.split(\"?\")[0]?.split(\"#\")[0] ?? \"\";\n\tif (!path) return \"/\";\n\treturn path.startsWith(\"/\") ? path : `/${path}`;\n}\n","import { reportTransportError } from \"@ryuzaki13/react-foundation-lib/error-report\";\nimport { truncateText } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport { FetchErrorReportContext } from \"./types\";\nimport { BaseUrlMap, getInputUrl, normalizeRelativePath } from \"./url\";\n\nconst MAX_HTML_INPUT_NAMES = 40;\nconst MAX_HTML_PREVIEW_LENGTH = 1000;\n\nfunction normalizeUrlForReport(url: string) {\n\ttry {\n\t\tconst baseOrigin = typeof window !== \"undefined\" ? window.location.origin : \"http://localhost\";\n\t\tconst parsedUrl = new URL(url, baseOrigin);\n\t\tconst sameOrigin = parsedUrl.origin === baseOrigin;\n\t\treturn `${sameOrigin ? \"\" : parsedUrl.origin}${parsedUrl.pathname}`;\n\t} catch {\n\t\treturn normalizeRelativePath(url);\n\t}\n}\n\nfunction readHtmlDocument(html: string) {\n\tif (typeof DOMParser === \"undefined\") return undefined;\n\n\ttry {\n\t\treturn new DOMParser().parseFromString(html, \"text/html\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction extractHtmlTitle(html: string, doc: Document | undefined) {\n\tconst title = doc?.querySelector(\"title\")?.textContent;\n\tif (title) return title;\n\n\treturn /<title[^>]*>([\\s\\S]*?)<\\/title>/i.exec(html)?.[1];\n}\n\nfunction countHtmlForms(html: string, doc: Document | undefined) {\n\tconst formsCount = doc?.querySelectorAll(\"form\").length;\n\tif (formsCount !== undefined) return formsCount;\n\n\treturn Array.from(html.matchAll(/<form\\b/gi)).length;\n}\n\nfunction collectHtmlInputNames(html: string, doc: Document | undefined) {\n\tconst names = doc\n\t\t? Array.from(\n\t\t\t\tdoc.querySelectorAll<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(\"input[name],textarea[name],select[name]\")\n\t\t\t)\n\t\t\t\t.map((element) => element.name)\n\t\t\t\t.filter(Boolean)\n\t\t: Array.from(html.matchAll(/\\bname\\s*=\\s*[\"']([^\"']+)[\"']/gi))\n\t\t\t\t.map((match) => match[1])\n\t\t\t\t.filter((name): name is string => !!name);\n\n\treturn Array.from(new Set(names)).slice(0, MAX_HTML_INPUT_NAMES);\n}\n\nfunction extractHtmlTextPreview(html: string, doc: Document | undefined) {\n\tconst text =\n\t\tdoc?.body?.textContent ??\n\t\thtml\n\t\t\t.replace(/<script\\b[\\s\\S]*?<\\/script>/gi, \" \")\n\t\t\t.replace(/<style\\b[\\s\\S]*?<\\/style>/gi, \" \")\n\t\t\t.replace(/<[^>]+>/g, \" \");\n\treturn truncateText(text, MAX_HTML_PREVIEW_LENGTH);\n}\n\nfunction createHtmlResponseSummary(html: string) {\n\tconst doc = readHtmlDocument(html);\n\n\treturn {\n\t\tlength: html.length,\n\t\ttitle: truncateText(extractHtmlTitle(html, doc), 200),\n\t\tformCount: countHtmlForms(html, doc),\n\t\tinputNames: collectHtmlInputNames(html, doc),\n\t\ttextPreview: extractHtmlTextPreview(html, doc)\n\t};\n}\n\nexport function reportUnexpectedHtmlResponse(\n\terror: Error,\n\tsource: \"fetch.parseResponse\" | \"fetch.buildHttpError\",\n\tres: Response,\n\ttext: string,\n\tcontext: FetchErrorReportContext | undefined\n) {\n\tconst inputUrl = context ? getInputUrl(context.input) : undefined;\n\tconst requestUrl = inputUrl?.startsWith(\"http\")\n\t\t? inputUrl\n\t\t: inputUrl\n\t\t\t? `${BaseUrlMap[context?.baseUrlType ?? \"\"]}${inputUrl}`\n\t\t\t: undefined;\n\n\treportTransportError(error, {\n\t\tsource,\n\t\trequestUrl: requestUrl ? normalizeUrlForReport(requestUrl) : undefined,\n\t\tresponseUrl: res.url ? normalizeUrlForReport(res.url) : undefined,\n\t\tmethod: context?.init.method?.toUpperCase() ?? \"GET\",\n\t\tbaseUrlType: context?.baseUrlType,\n\t\tsapClient: context?.sapClient,\n\t\tstatus: res.status,\n\t\tstatusText: res.statusText,\n\t\tcontentType: res.headers.get(\"Content-Type\") || undefined,\n\t\tredirected: res.redirected,\n\t\tresponseType: res.type,\n\t\thtml: createHtmlResponseSummary(text)\n\t});\n}\n","export type SsoForm = {\n\taction: string;\n\tmethod: string;\n\tinputs: Record<string, string>;\n};\n\nexport type SsoRecoveryArgs = {\n\tform?: SsoForm;\n\trecoveryUrl?: string;\n};\n\nexport type SsoRequiredErrorOptions = {\n\trecoverable?: boolean;\n};\n\nlet ssoRecoveryPromise: Promise<boolean> | null = null;\nlet ssoIframeCounter = 0;\n\nfunction normalizeSsoAction(action: string) {\n\tif (typeof window === \"undefined\") return action;\n\n\ttry {\n\t\tconst originRegExp = new RegExp(__ORIGIN_REG_EXP__, \"i\");\n\t\tconst url = new URL(action, window.location.origin);\n\t\tconst isSapHost = originRegExp.test(url.origin);\n\t\tconst isSsoHost = url.origin === __SSO_ORIGIN__;\n\n\t\tif (isSapHost || isSsoHost || url.origin === window.location.origin) {\n\t\t\treturn `${url.pathname}${url.search}${url.hash}`;\n\t\t}\n\n\t\treturn url.toString();\n\t} catch {\n\t\treturn action;\n\t}\n}\n\nexport function isSsoForm(form?: SsoForm): form is SsoForm {\n\tif (!form) return false;\n\n\treturn typeof form.inputs.SAMLRequest === \"string\" || typeof form.inputs.SAMLResponse === \"string\";\n}\n\nfunction createHiddenIframe() {\n\tconst iframeName = `${__APP_ID__}-sso-iframe-${++ssoIframeCounter}`;\n\tconst iframe = document.createElement(\"iframe\");\n\tiframe.name = iframeName;\n\tiframe.style.display = \"none\";\n\treturn iframe;\n}\n\nfunction waitForIframe(iframe: HTMLIFrameElement, cleanup: () => void) {\n\treturn new Promise<boolean>((resolve) => {\n\t\tlet settleTimer: number | null = null;\n\t\tconst complete = () => {\n\t\t\tif (settleTimer !== null) {\n\t\t\t\twindow.clearTimeout(settleTimer);\n\t\t\t}\n\n\t\t\tsettleTimer = window.setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(true);\n\t\t\t}, 400);\n\t\t};\n\n\t\tiframe.addEventListener(\"load\", complete);\n\t\tiframe.addEventListener(\"error\", complete);\n\t});\n}\n\nfunction createSsoFormElement(form: SsoForm, target: string) {\n\tconst formElement = document.createElement(\"form\");\n\tformElement.method = form.method === \"GET\" ? \"GET\" : \"POST\";\n\tformElement.action = normalizeSsoAction(form.action);\n\tformElement.target = target;\n\tformElement.style.display = \"none\";\n\n\tfor (const [name, value] of Object.entries(form.inputs)) {\n\t\tconst input = document.createElement(\"input\");\n\t\tinput.type = \"hidden\";\n\t\tinput.name = name;\n\t\tinput.value = value;\n\t\tformElement.appendChild(input);\n\t}\n\n\treturn formElement;\n}\n\nfunction getMountPoint() {\n\tif (typeof document === \"undefined\") return null;\n\treturn document.body ?? document.documentElement;\n}\n\nexport function submitSsoForm(form?: SsoForm) {\n\tif (!isSsoForm(form)) return false;\n\tif (typeof document === \"undefined\") return false;\n\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return false;\n\n\tconst iframe = createHiddenIframe();\n\tconst formElement = createSsoFormElement(form, iframe.name);\n\n\tmountPoint.appendChild(iframe);\n\tmountPoint.appendChild(formElement);\n\tformElement.submit();\n\treturn true;\n}\n\nfunction recoverBySsoForm(form: SsoForm) {\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return Promise.resolve(false);\n\n\tconst iframe = createHiddenIframe();\n\tconst formElement = createSsoFormElement(form, iframe.name);\n\tconst recovery = waitForIframe(iframe, () => {\n\t\tiframe.remove();\n\t\tformElement.remove();\n\t});\n\n\tmountPoint.appendChild(iframe);\n\tmountPoint.appendChild(formElement);\n\tformElement.submit();\n\n\treturn recovery;\n}\n\nfunction recoverByDocumentNavigation(recoveryUrl: string) {\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return Promise.resolve(false);\n\n\tconst iframe = createHiddenIframe();\n\tconst recovery = waitForIframe(iframe, () => {\n\t\tiframe.remove();\n\t});\n\n\tmountPoint.appendChild(iframe);\n\tiframe.src = normalizeSsoAction(recoveryUrl);\n\n\treturn recovery;\n}\n\nexport function recoverSsoSession({ form, recoveryUrl }: SsoRecoveryArgs = {}) {\n\tif (ssoRecoveryPromise) return ssoRecoveryPromise;\n\tif (typeof window === \"undefined\") return false;\n\n\tssoRecoveryPromise = (async () => {\n\t\tif (isSsoForm(form)) return recoverBySsoForm(form);\n\t\tif (recoveryUrl) return recoverByDocumentNavigation(recoveryUrl);\n\t\treturn false;\n\t})().finally(() => {\n\t\tssoRecoveryPromise = null;\n\t});\n\n\treturn ssoRecoveryPromise;\n}\n\nexport class SsoRequiredError extends Error {\n\tpublic readonly form?: SsoForm;\n\tpublic readonly recoveryUrl?: string;\n\tpublic readonly recoverable: boolean;\n\tconstructor(message: string, form?: SsoForm, recoveryUrl?: string, options: SsoRequiredErrorOptions = {}) {\n\t\tsuper(message);\n\t\tthis.form = form;\n\t\tthis.recoveryUrl = recoveryUrl;\n\t\tthis.recoverable = options.recoverable ?? true;\n\t\tObject.setPrototypeOf(this, SsoRequiredError.prototype);\n\t}\n}\n","import { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { asRecord, isRecord, isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { normalizeODataServiceName, resolveODataBaseUrl, resolveODataSapClient } from \"../odataProjectAdapter\";\n\nimport { reportUnexpectedHtmlResponse } from \"./errorReport\";\nimport { isSsoForm, recoverSsoSession, SsoForm, SsoRequiredError } from \"./SsoRequiredError\";\nimport { BaseURLType, FetchErrorReportContext, RequestInitType } from \"./types\";\nimport { BaseUrlMap, getInputUrl, normalizeRelativePath } from \"./url\";\n\nconst csrfTokenCache = new Map<string, string>();\nconst csrfFetchInProgressCache = new Map<string, Promise<string>>();\nlet ssoRecoveryGate: Promise<void> | null = null;\nlet ssoBlockedError: SsoRequiredError | null = null;\n\nexport { normalizeODataServiceName, resolveODataBaseUrl };\n\nfunction isSapRequest(input: RequestInfo, baseUrlType: BaseURLType) {\n\tif (baseUrlType !== \"\") return true;\n\n\tconst path = normalizeRelativePath(getInputUrl(input));\n\treturn path.startsWith(\"/sap/\") || path.startsWith(\"/sap-dp0/\");\n}\n\nfunction getSapClient(input: RequestInfo, baseUrlType: BaseURLType): string | null {\n\tif (__DEV__ || __PREVIEW__) {\n\t\tif (!isSapRequest(input, baseUrlType)) return null;\n\t\tif (baseUrlType === \"odataDp0\") return \"300\";\n\t\tif (baseUrlType === \"\" && normalizeRelativePath(getInputUrl(input)).startsWith(\"/sap-dp0/\")) {\n\t\t\treturn \"300\";\n\t\t}\n\t\treturn `${__SAP_CLIENT__}`;\n\t}\n\n\treturn resolveODataSapClient();\n}\n\nfunction createUnrecoverableSsoError(source: SsoRequiredError) {\n\treturn new SsoRequiredError(\n\t\t\"Не удалось автоматически восстановить SSO-сессию. Перезагрузите страницу и выполните вход заново.\",\n\t\tsource.form,\n\t\tsource.recoveryUrl,\n\t\t{ recoverable: false }\n\t);\n}\n\nfunction markSsoBlocked(source: SsoRequiredError) {\n\tconst error = createUnrecoverableSsoError(source);\n\tif (typeof window !== \"undefined\") {\n\t\tssoBlockedError = error;\n\t}\n\treturn error;\n}\n\nasync function waitForSsoRecoveryGate() {\n\tconst gate = ssoRecoveryGate;\n\tif (gate) {\n\t\tawait gate.catch(() => {});\n\t}\n\n\tif (ssoBlockedError) {\n\t\tthrow ssoBlockedError;\n\t}\n}\n\nasync function recoverSsoSessionAndRetry<T>(error: SsoRequiredError, retry: () => Promise<T>) {\n\tif (ssoBlockedError) {\n\t\tthrow ssoBlockedError;\n\t}\n\n\tlet retryResult: { value: T } | undefined;\n\n\tif (!ssoRecoveryGate) {\n\t\tssoRecoveryGate = (async () => {\n\t\t\tconst recovered = await Promise.resolve(recoverSsoSession({ form: error.form, recoveryUrl: error.recoveryUrl })).catch(\n\t\t\t\t() => false\n\t\t\t);\n\n\t\t\tif (!recovered) {\n\t\t\t\tthrow markSsoBlocked(error);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tretryResult = { value: await retry() };\n\t\t\t\tssoBlockedError = null;\n\t\t\t} catch (retryError: unknown) {\n\t\t\t\tif (retryError instanceof SsoRequiredError) {\n\t\t\t\t\tthrow markSsoBlocked(retryError);\n\t\t\t\t}\n\n\t\t\t\tthrow retryError;\n\t\t\t}\n\t\t})().finally(() => {\n\t\t\tssoRecoveryGate = null;\n\t\t});\n\n\t\tawait ssoRecoveryGate;\n\n\t\tif (!retryResult) {\n\t\t\tthrow ssoBlockedError ?? createUnrecoverableSsoError(error);\n\t\t}\n\n\t\treturn retryResult.value;\n\t}\n\n\tawait waitForSsoRecoveryGate();\n\ttry {\n\t\treturn await retry();\n\t} catch (retryError: unknown) {\n\t\tif (retryError instanceof SsoRequiredError) {\n\t\t\tthrow markSsoBlocked(retryError);\n\t\t}\n\n\t\tthrow retryError;\n\t}\n}\n\nfunction resolveCsrfScope(input: RequestInfo, baseUrlType: BaseURLType, sapClient: string | null) {\n\tif (baseUrlType === \"config\") {\n\t\treturn {\n\t\t\tcacheKey: `${__APP_ID__}:${sapClient ?? \"\"}`,\n\t\t\tfetchUrl: \"/Statistics\"\n\t\t};\n\t}\n\n\tconst requestPath = normalizeRelativePath(getInputUrl(input));\n\tconst [serviceName] = requestPath.split(\"/\").filter(Boolean);\n\tif (!serviceName) {\n\t\tthrow new Error(\"Не удалось определить сервис для получения CSRF-токена\");\n\t}\n\n\treturn {\n\t\tcacheKey: `${baseUrlType}:${sapClient ?? \"\"}:${serviceName}`,\n\t\tfetchUrl: `/${serviceName}/`\n\t};\n}\n\nasync function getCsrfToken(input: RequestInfo, baseUrlType: BaseURLType, sapClient: string | null): Promise<string> {\n\tconst scope = resolveCsrfScope(input, baseUrlType, sapClient);\n\tconst cachedToken = csrfTokenCache.get(scope.cacheKey);\n\tif (cachedToken) return cachedToken;\n\n\tconst inflightToken = csrfFetchInProgressCache.get(scope.cacheKey);\n\tif (inflightToken) return inflightToken;\n\n\tconst headers = new Headers({ \"x-csrf-token\": \"Fetch\" });\n\theaders.set(\"sap-language\", \"ru\");\n\theaders.set(\"sap-contextid-accept\", \"header\");\n\theaders.set(\"Accept-Language\", \"ru\");\n\tif (sapClient) {\n\t\theaders.set(\"sap-client\", sapClient);\n\t}\n\n\tconst baseUrl = (baseUrlType && BaseUrlMap[baseUrlType]) ?? \"\";\n\tconst tokenPromise = fetch(baseUrl + scope.fetchUrl, {\n\t\tmethod: \"GET\",\n\t\theaders,\n\t\tcredentials: \"include\",\n\t\tredirect: \"manual\"\n\t})\n\t\t.then(async (res) => {\n\t\t\tif (isSsoRedirectResponse(res)) {\n\t\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + scope.fetchUrl);\n\t\t\t}\n\n\t\t\tif (!res.ok) throw new Error(\"Не удалось получить CSRF-токен\");\n\n\t\t\tconst token = res.headers.get(\"x-csrf-token\");\n\t\t\tif (!token) {\n\t\t\t\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\t\t\t\tconst text = await res.text();\n\t\t\t\tif (looksLikeHtmlResponse(contentType, text)) {\n\t\t\t\t\tconst form = extractFormFromHtml(text);\n\t\t\t\t\tif (isSsoForm(form)) {\n\t\t\t\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", form, baseUrl + scope.fetchUrl);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthrow new Error(\"CSRF-токен отсутствует в ответе\");\n\t\t\t}\n\n\t\t\tcsrfTokenCache.set(scope.cacheKey, token);\n\t\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\t\treturn token;\n\t\t})\n\t\t.catch((err) => {\n\t\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\t\tthrow err;\n\t\t});\n\n\tcsrfFetchInProgressCache.set(scope.cacheKey, tokenPromise);\n\treturn tokenPromise;\n}\n\nfunction extractHtmlAttribute(source: string, attributeName: string) {\n\tconst escapedAttributeName = attributeName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\tconst match = new RegExp(`${escapedAttributeName}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`, \"i\").exec(source);\n\treturn match?.[1];\n}\n\n/**\n * Попытка извлечь форму (действие + скрытые входные данные) из HTML, возвращаемого ADFS/SSO.\n * Возвращает undefined, если форма не найдена.\n */\nfunction extractFormFromHtml(html: string): SsoForm | undefined {\n\ttry {\n\t\tif (typeof DOMParser !== \"undefined\") {\n\t\t\tconst parser = new DOMParser();\n\t\t\tconst doc = parser.parseFromString(html, \"text/html\");\n\t\t\tconst form = doc.querySelector(\"form\");\n\t\t\tif (form) {\n\t\t\t\tconst action = form.getAttribute(\"action\") || (typeof window !== \"undefined\" ? window.location.href : \"\");\n\t\t\t\tconst method = (form.getAttribute(\"method\") || \"GET\").toUpperCase();\n\t\t\t\tconst inputs: Record<string, string> = {};\n\t\t\t\tform.querySelectorAll<HTMLInputElement>(\"input[name]\").forEach((i) => {\n\t\t\t\t\tinputs[i.name] = i.value ?? \"\";\n\t\t\t\t});\n\t\t\t\treturn { action, method, inputs };\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Игнорируем и переходим к текстовому fallback-разбору.\n\t}\n\n\tconst formMatch = /<form\\b([^>]*)>([\\s\\S]*?)<\\/form>/i.exec(html);\n\tif (!formMatch) return undefined;\n\n\tconst [, formAttributes = \"\", formBody = \"\"] = formMatch;\n\tconst action = extractHtmlAttribute(formAttributes, \"action\") || (typeof window !== \"undefined\" ? window.location.href : \"\");\n\tconst method = (extractHtmlAttribute(formAttributes, \"method\") || \"GET\").toUpperCase();\n\tconst inputs: Record<string, string> = {};\n\tconst inputTagPattern = /<input\\b([^>]*)>/gi;\n\n\tfor (const match of formBody.matchAll(inputTagPattern)) {\n\t\tconst inputAttributes = match[1] ?? \"\";\n\t\tconst inputName = extractHtmlAttribute(inputAttributes, \"name\");\n\t\tif (!inputName) continue;\n\n\t\tinputs[inputName] = extractHtmlAttribute(inputAttributes, \"value\") ?? \"\";\n\t}\n\n\treturn { action, method, inputs };\n}\n\nfunction looksLikeHtmlResponse(contentType: string, text: string) {\n\treturn contentType.includes(\"text/html\") || /<html/i.test(text) || /<form/i.test(text);\n}\n\nfunction stripODataMetadata(value: unknown) {\n\tif (!isRecord(value)) return value;\n\n\tconst record = { ...value };\n\tdelete record.__metadata;\n\treturn record;\n}\n\nfunction extractJson<T>(json: unknown) {\n\tif (isRecord(json) && isRecord(json.d) && Array.isArray(json.d.results)) {\n\t\tlet totalCount: number | undefined = undefined;\n\t\tif (json.d.__count) {\n\t\t\ttotalCount = Number(json.d.__count);\n\t\t}\n\n\t\tconst data = json.d.results.map(stripODataMetadata) as T;\n\n\t\treturn { data, totalCount };\n\t}\n\tif (isRecord(json) && json.d !== undefined) {\n\t\tconst data = stripODataMetadata(json.d);\n\n\t\treturn { data: data as T };\n\t}\n\treturn {\n\t\tdata: json as T\n\t};\n}\n\nconst NO_CONTENT_RESPONSE = Object.freeze({ __noContent: true } as const);\n\nexport function isNoContentResponse(value: unknown): value is typeof NO_CONTENT_RESPONSE {\n\treturn !!value && typeof value === \"object\" && \"__noContent\" in value;\n}\n\nasync function parseResponse<T>(res: Response, reportContext?: FetchErrorReportContext): Promise<{ data: T; totalCount?: number }> {\n\tif (res.status === 204 || res.status === 205 /*|| res.headers.get(\"Content-Length\") === \"0\"*/) {\n\t\treturn { data: NO_CONTENT_RESPONSE as T };\n\t}\n\n\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\n\t// Если явный JSON — безопасно парсим\n\tif (contentType.includes(\"application/json\") || contentType.includes(\"application/odata+json\")) {\n\t\tconst json = await res.json();\n\t\treturn extractJson<T>(json);\n\t}\n\n\t// Попытка парсинга как текст (на случай, если server неправильно прописал content-type)\n\tconst text = await res.text();\n\n\t// если в теле HTML — проверяем, есть ли форма (SSO)\n\tif (looksLikeHtmlResponse(contentType, text)) {\n\t\tconst form = extractFormFromHtml(text);\n\t\tif (isSsoForm(form)) {\n\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", form);\n\t\t}\n\t\tconst error = new Error(\"Unexpected HTML response from OData endpoint\");\n\t\treportUnexpectedHtmlResponse(error, \"fetch.parseResponse\", res, text, reportContext);\n\t\tthrow error;\n\t}\n\n\t// Попытка безопасно распарсить JSON, если сервер не установил content-type\n\ttry {\n\t\tconst maybeJson = JSON.parse(text);\n\t\treturn extractJson<T>(maybeJson);\n\t} catch (e) {\n\t\tlogError(e);\n\t\t// ни текст, ни JSON — возвращаем ошибку\n\t\tthrow new Error(\"Unsupported response content type and body is not JSON\");\n\t}\n}\n\n/**\n * Безопасно извлекает текстовое сообщение из неизвестного значения.\n */\nfunction asNonEmptyString(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim();\n\treturn normalized.length ? normalized : null;\n}\n\nfunction pushUniqueMessage(parts: string[], value: unknown) {\n\tconst normalized = asNonEmptyString(value);\n\tif (!normalized || parts.includes(normalized)) return;\n\tparts.push(normalized);\n}\n\nfunction extractJsonErrorParts(payload: Record<string, unknown>) {\n\tconst parts: string[] = [];\n\tconst errorValue = payload.error;\n\n\tif (typeof errorValue === \"string\") {\n\t\tpushUniqueMessage(parts, errorValue);\n\t}\n\n\tconst errorRecord = asRecord(errorValue);\n\tif (errorRecord) {\n\t\tpushUniqueMessage(parts, errorRecord.code);\n\n\t\tconst errorMessage = asRecord(errorRecord.message);\n\t\tpushUniqueMessage(parts, errorMessage?.value ?? errorRecord.message);\n\n\t\t// const innerError = asRecord(errorRecord.innererror);\n\t\t// const errorDetails = innerError?.errordetails;\n\t\t// if (Array.isArray(errorDetails)) {\n\t\t// \tfor (const detail of errorDetails) {\n\t\t// \t\tpushUniqueMessage(parts, asRecord(detail)?.message);\n\t\t// \t}\n\t\t// }\n\t}\n\n\tpushUniqueMessage(parts, payload.details);\n\tpushUniqueMessage(parts, payload.message);\n\n\treturn parts;\n}\n\n/**\n * Строит детализированную ошибку HTTP на основе статуса и тела ответа.\n * Для JSON-ответов приоритетно используются поля `error`, `details`, `message`.\n */\nasync function buildHttpError(res: Response, reportContext?: FetchErrorReportContext): Promise<Error> {\n\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\n\ttry {\n\t\tif (contentType.includes(\"application/json\") || contentType.includes(\"application/odata+json\")) {\n\t\t\tconst payload = (await res.json()) as Record<string, unknown>;\n\t\t\tconst parts = extractJsonErrorParts(payload);\n\n\t\t\tif (parts.length) {\n\t\t\t\treturn new Error(parts.join(\" | \"));\n\t\t\t}\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tconst normalizedText = asNonEmptyString(text);\n\t\t\tif (normalizedText) {\n\t\t\t\tif (looksLikeHtmlResponse(contentType, normalizedText)) {\n\t\t\t\t\tconst form = extractFormFromHtml(normalizedText);\n\t\t\t\t\tif (isSsoForm(form)) {\n\t\t\t\t\t\treturn new SsoRequiredError(\"Требуется повторная аутентификация\", form);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst error = new Error(\"Unexpected HTML response from OData endpoint\");\n\t\t\t\t\treportUnexpectedHtmlResponse(error, \"fetch.buildHttpError\", res, normalizedText, reportContext);\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\n\t\t\t\treturn new Error(normalizedText);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ничего не делаем: в этом случае вернем стандартный текст ошибки по статусу.\n\t}\n\n\treturn new Error(`HTTP error: ${res.status} ${res.statusText}`);\n}\n\nfunction isSsoRedirectResponse(res: Response) {\n\treturn res.type === \"opaqueredirect\";\n}\n\nasync function sendFetchBaseRequest(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\"): Promise<Response> {\n\tconst method = init.method?.toUpperCase() || \"GET\";\n\tconst headers = new Headers(init.headers);\n\tconst isWrite = ![\"GET\", \"HEAD\"].includes(method);\n\tconst hasBody = isSafe(init.body);\n\tconst sapRequest = isSapRequest(input, baseUrlType);\n\tconst sapClient = getSapClient(input, baseUrlType);\n\n\theaders.set(\"sap-language\", \"ru\");\n\tif (sapRequest) {\n\t\theaders.set(\"sap-language\", \"ru\");\n\t\theaders.set(\"sap-contextid-accept\", \"header\");\n\t}\n\tif (sapClient) {\n\t\theaders.set(\"sap-client\", sapClient);\n\t}\n\tif (isWrite && sapRequest) {\n\t\tconst token = await getCsrfToken(input, baseUrlType, sapClient);\n\t\theaders.set(\"x-csrf-token\", token);\n\t}\n\n\tif (!headers.has(\"Accept\")) {\n\t\theaders.set(\"Accept\", \"application/json\");\n\t}\n\n\tif (hasBody && isWrite && !headers.has(\"Content-Type\")) {\n\t\theaders.set(\"Content-Type\", \"application/json\");\n\t}\n\n\tconst baseUrl = (baseUrlType && BaseUrlMap[baseUrlType]) ?? \"\";\n\tconst url = typeof input === \"string\" ? input : input.toString();\n\tlet res = await fetch(baseUrl + url, {\n\t\t...init,\n\t\theaders,\n\t\tcredentials: \"include\",\n\t\tredirect: sapRequest ? \"manual\" : init.redirect\n\t});\n\n\tif (sapRequest && isSsoRedirectResponse(res)) {\n\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + url);\n\t}\n\n\t// Если 401 — возможно, токен истёк, пробуем получить заново и повторить\n\tif ((res.status === 401 || res.status === 403) && isWrite && sapRequest && !init.retried) {\n\t\tconst scope = resolveCsrfScope(input, baseUrlType, sapClient);\n\t\tcsrfTokenCache.delete(scope.cacheKey);\n\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\tconst token = await getCsrfToken(input, baseUrlType, sapClient);\n\n\t\tconst retryHeaders = new Headers(headers);\n\t\tretryHeaders.set(\"x-csrf-token\", token);\n\n\t\tres = await fetch(baseUrl + url, {\n\t\t\t...init,\n\t\t\theaders: retryHeaders,\n\t\t\tcredentials: \"include\",\n\t\t\tredirect: \"manual\",\n\t\t\tretried: true // кастомная метка, чтобы избежать бесконечного цикла\n\t\t} as RequestInitType);\n\n\t\tif (isSsoRedirectResponse(res)) {\n\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + url);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nasync function finalizeFetchBaseResponse(\n\tres: Response,\n\tinput: RequestInfo,\n\tinit: RequestInitType,\n\tbaseUrlType: BaseURLType,\n\tsapClient: string | null\n) {\n\tif (!res.ok) {\n\t\tif (res.status === 0) {\n\t\t\tthrow new Error(\"Ошибка сети или CORS. Проверьте подключение и настройки сервера.\");\n\t\t}\n\n\t\tthrow await buildHttpError(res, { input, init, baseUrlType, sapClient });\n\t}\n\n\treturn res;\n}\n\nasync function fetchBaseWithoutSsoRecovery(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst sapClient = getSapClient(input, baseUrlType);\n\tconst res = await sendFetchBaseRequest(input, init, baseUrlType);\n\treturn finalizeFetchBaseResponse(res, input, init, baseUrlType, sapClient);\n}\n\nexport async function fetchBase(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\"): Promise<Response> {\n\tconst sapRequest = isSapRequest(input, baseUrlType);\n\tconst sapClient = getSapClient(input, baseUrlType);\n\tconst retry = () => fetchBaseWithoutSsoRecovery(input, { ...init, ssoRetried: true }, baseUrlType);\n\n\tif (sapRequest) {\n\t\tawait waitForSsoRecoveryGate();\n\t}\n\n\tlet res: Response;\n\ttry {\n\t\tres = await sendFetchBaseRequest(input, init, baseUrlType);\n\t} catch (error: unknown) {\n\t\tif (sapRequest && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\tres = await recoverSsoSessionAndRetry(error, retry);\n\t\t} else {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\ttry {\n\t\treturn await finalizeFetchBaseResponse(res, input, init, baseUrlType, sapClient);\n\t} catch (error: unknown) {\n\t\tif (sapRequest && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\tconst recoveredResponse = await recoverSsoSessionAndRetry(error, retry);\n\t\t\treturn finalizeFetchBaseResponse(recoveredResponse, input, init, baseUrlType, sapClient);\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function fetchODataJson<T = unknown>(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst headers = new Headers(init.headers);\n\n\theaders.set(\"DataServiceVersion\", \"2.0\");\n\theaders.set(\"MaxDataServiceVersion\", \"2.0\");\n\n\tconst requestInit = { ...init, headers };\n\tconst parseContext = { input, init, baseUrlType, sapClient: getSapClient(input, baseUrlType) };\n\n\ttry {\n\t\tconst res = await fetchBase(input, requestInit, baseUrlType);\n\t\treturn await parseResponse<T>(res, parseContext);\n\t} catch (error: unknown) {\n\t\tif (isSapRequest(input, baseUrlType) && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\treturn recoverSsoSessionAndRetry(error, async () => {\n\t\t\t\tconst retryInit = { ...requestInit, ssoRetried: true };\n\t\t\t\tconst res = await fetchBaseWithoutSsoRecovery(input, retryInit, baseUrlType);\n\t\t\t\treturn parseResponse<T>(res, { input, init: retryInit, baseUrlType, sapClient: getSapClient(input, baseUrlType) });\n\t\t\t});\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function fetchJson<T = unknown>(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst response = await fetchODataJson<T>(input, init, baseUrlType);\n\treturn response.data;\n}\n\ninterface FetchQueryFnBaseOptions {\n\tinit?: RequestInit;\n\tbaseUrl?: BaseURLType;\n\t/** Политика кеширования в Service Worker (`\"off\"` | `\"ttl=24h\"` | `\"ttl=24h;max=100;name=ref\"` | `\"bust=24h\"` и т.д.) */\n\tswCache?: string;\n}\n\ninterface FetchQueryFnOptions<R> extends FetchQueryFnBaseOptions {\n\ttransform: (data: Response) => Promise<R>;\n}\n\nexport function fetchQueryFn<R = unknown>(url: string, options: FetchQueryFnOptions<R>) {\n\tconst initValue = options.init || {};\n\tconst baseUrlValue = options.baseUrl;\n\tconst transform = options.transform;\n\n\tif (options.swCache) {\n\t\tconst headers = new Headers(initValue.headers);\n\t\theaders.set(\"x-sw-cache\", options.swCache);\n\t\tinitValue.headers = headers;\n\t}\n\n\treturn async (params?: { signal?: AbortSignal }): Promise<R> => {\n\t\tif (!initValue.signal && params?.signal) {\n\t\t\tinitValue.signal = params.signal;\n\t\t}\n\n\t\tconst data = await fetchBase(url, initValue, baseUrlValue);\n\n\t\tif (typeof transform !== \"function\") {\n\t\t\tthrow new Error(\"fetchQueryFn requires a transformation function!\");\n\t\t}\n\n\t\treturn await transform(data);\n\t};\n}\n\ninterface FetchJsonQueryFnOptions<T, R> extends FetchQueryFnBaseOptions {\n\ttransform?: (data: T) => R;\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchJsonQueryFn<T, R = T>(url: string, options?: FetchJsonQueryFnOptions<T, R>) {\n\tconst baseUrlValue = options?.baseUrl || \"odata\";\n\tconst transform = options?.transform;\n\n\treturn async (params?: { signal: AbortSignal }) => {\n\t\tconst initValue = options?.init || {};\n\t\tif (!initValue.signal && params?.signal) {\n\t\t\tinitValue.signal = params.signal;\n\t\t}\n\n\t\tif (options?.swCache) {\n\t\t\tconst headers = new Headers(initValue.headers);\n\t\t\theaders.set(\"x-sw-cache\", options.swCache);\n\t\t\tinitValue.headers = headers;\n\t\t}\n\n\t\tconst data = await fetchJson<T>(url, initValue, baseUrlValue);\n\n\t\tif (!transform) {\n\t\t\treturn data as unknown as R;\n\t\t}\n\n\t\treturn transform ? transform(data) : (data as unknown as R);\n\t};\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchJsonMutationFn<T = unknown, TBody = unknown>(url: string, method: \"POST\" | \"PUT\" = \"POST\", baseUrl?: BaseURLType) {\n\treturn async (body: TBody, signal?: AbortSignal) => {\n\t\treturn fetchJson<T>(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\tsignal\n\t\t\t},\n\t\t\tbaseUrl\n\t\t);\n\t};\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchDeleteFn<T = unknown>(url: string, baseUrl?: BaseURLType) {\n\treturn async (signal?: AbortSignal) => {\n\t\treturn fetchJson<T>(url, { method: \"DELETE\", signal }, baseUrl);\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fetch-CPEFkAcU.js","names":[],"sources":["../../src/odata/odataProjectAdapter.ts","../../src/odata/transport/url.ts","../../src/odata/transport/errorReport.ts","../../src/odata/transport/SsoRequiredError.ts","../../src/odata/transport/fetch.ts"],"sourcesContent":["import type { BaseURLType } from \"./transport/types\";\n\nexport type ODataProjectTechnicalEndpoint = {\n\tservice: string;\n\ttarget: string;\n\tbaseUrl?: BaseURLType;\n};\n\nexport type ODataProjectAdapter = {\n\t/**\n\t * OData-сервис, который в dev/preview нужно проксировать через DP0.\n\t * В проектах без SAP/OData оставляется пустым.\n\t */\n\tdevDp0Service?: string;\n\tresolveSapClient?: () => string | null | undefined;\n\tmetadataVersion?: ODataProjectTechnicalEndpoint;\n\tcollectionUpdates?: ODataProjectTechnicalEndpoint;\n};\n\nlet odataProjectAdapter: ODataProjectAdapter = {};\n\nexport function configureODataProjectAdapter(adapter: ODataProjectAdapter) {\n\todataProjectAdapter = adapter;\n}\n\nexport function getODataProjectAdapter() {\n\treturn odataProjectAdapter;\n}\n\nexport function normalizeODataServiceName(service: string) {\n\treturn service.split(\";\")[0] ?? service;\n}\n\nexport function resolveODataBaseUrl(service: string, baseUrl?: BaseURLType): BaseURLType {\n\tconst devDp0Service = odataProjectAdapter.devDp0Service;\n\tif ((__DEV__ || __PREVIEW__) && devDp0Service && normalizeODataServiceName(service) === normalizeODataServiceName(devDp0Service)) {\n\t\treturn \"odataDp0\";\n\t}\n\n\treturn baseUrl ?? \"odata\";\n}\n\nexport function resolveODataSapClient() {\n\treturn odataProjectAdapter.resolveSapClient?.() ?? null;\n}\n","import { BaseURLType } from \"./types\";\n\nexport const BaseODataURL = \"/sap/opu/odata/sap\";\n/**\n * DP0-прокси используется только для сервиса, который проект явно указывает\n * через `odataProjectAdapter.devDp0Service`.\n */\nexport const BaseODataDp0URL = __DEV__ || __PREVIEW__ ? \"/sap-dp0/opu/odata/sap\" : \"/sap/opu/odata/sap\";\nexport const BaseODataUI2URL = __DEV__ || __PREVIEW__ ? \"/sap-dp0/opu/odata/UI2\" : \"/sap/opu/odata/UI2\";\nexport const BaseAppConfigURL = __BASE_APP_CONFIG_URL__;\n\nexport const BaseUrlMap = Object.freeze<Record<BaseURLType, string>>({\n\t[\"\"]: \"\",\n\todata: BaseODataURL,\n\todataDp0: BaseODataDp0URL,\n\todataUi2: BaseODataUI2URL,\n\tconfig: BaseAppConfigURL\n});\n\nexport function getInputUrl(input: RequestInfo) {\n\tif (typeof input === \"string\") return input;\n\tif (typeof Request !== \"undefined\" && input instanceof Request) {\n\t\treturn input.url;\n\t}\n\treturn input.toString();\n}\n\nexport function normalizeRelativePath(url: string) {\n\tconst path = url.split(\"?\")[0]?.split(\"#\")[0] ?? \"\";\n\tif (!path) return \"/\";\n\treturn path.startsWith(\"/\") ? path : `/${path}`;\n}\n","import { reportTransportError } from \"@ryuzaki13/react-foundation-lib/error-report\";\nimport { truncateText } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport { FetchErrorReportContext } from \"./types\";\nimport { BaseUrlMap, getInputUrl, normalizeRelativePath } from \"./url\";\n\nconst MAX_HTML_INPUT_NAMES = 40;\nconst MAX_HTML_PREVIEW_LENGTH = 1000;\n\nfunction normalizeUrlForReport(url: string) {\n\ttry {\n\t\tconst baseOrigin = typeof window !== \"undefined\" ? window.location.origin : \"http://localhost\";\n\t\tconst parsedUrl = new URL(url, baseOrigin);\n\t\tconst sameOrigin = parsedUrl.origin === baseOrigin;\n\t\treturn `${sameOrigin ? \"\" : parsedUrl.origin}${parsedUrl.pathname}`;\n\t} catch {\n\t\treturn normalizeRelativePath(url);\n\t}\n}\n\nfunction readHtmlDocument(html: string) {\n\tif (typeof DOMParser === \"undefined\") return undefined;\n\n\ttry {\n\t\treturn new DOMParser().parseFromString(html, \"text/html\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction extractHtmlTitle(html: string, doc: Document | undefined) {\n\tconst title = doc?.querySelector(\"title\")?.textContent;\n\tif (title) return title;\n\n\treturn /<title[^>]*>([\\s\\S]*?)<\\/title>/i.exec(html)?.[1];\n}\n\nfunction countHtmlForms(html: string, doc: Document | undefined) {\n\tconst formsCount = doc?.querySelectorAll(\"form\").length;\n\tif (formsCount !== undefined) return formsCount;\n\n\treturn Array.from(html.matchAll(/<form\\b/gi)).length;\n}\n\nfunction collectHtmlInputNames(html: string, doc: Document | undefined) {\n\tconst names = doc\n\t\t? Array.from(\n\t\t\t\tdoc.querySelectorAll<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(\"input[name],textarea[name],select[name]\")\n\t\t\t)\n\t\t\t\t.map((element) => element.name)\n\t\t\t\t.filter(Boolean)\n\t\t: Array.from(html.matchAll(/\\bname\\s*=\\s*[\"']([^\"']+)[\"']/gi))\n\t\t\t\t.map((match) => match[1])\n\t\t\t\t.filter((name): name is string => !!name);\n\n\treturn Array.from(new Set(names)).slice(0, MAX_HTML_INPUT_NAMES);\n}\n\nfunction extractHtmlTextPreview(html: string, doc: Document | undefined) {\n\tconst text =\n\t\tdoc?.body?.textContent ??\n\t\thtml\n\t\t\t.replace(/<script\\b[\\s\\S]*?<\\/script>/gi, \" \")\n\t\t\t.replace(/<style\\b[\\s\\S]*?<\\/style>/gi, \" \")\n\t\t\t.replace(/<[^>]+>/g, \" \");\n\treturn truncateText(text, MAX_HTML_PREVIEW_LENGTH);\n}\n\nfunction createHtmlResponseSummary(html: string) {\n\tconst doc = readHtmlDocument(html);\n\n\treturn {\n\t\tlength: html.length,\n\t\ttitle: truncateText(extractHtmlTitle(html, doc), 200),\n\t\tformCount: countHtmlForms(html, doc),\n\t\tinputNames: collectHtmlInputNames(html, doc),\n\t\ttextPreview: extractHtmlTextPreview(html, doc)\n\t};\n}\n\nexport function reportUnexpectedHtmlResponse(\n\terror: Error,\n\tsource: \"fetch.parseResponse\" | \"fetch.buildHttpError\",\n\tres: Response,\n\ttext: string,\n\tcontext: FetchErrorReportContext | undefined\n) {\n\tconst inputUrl = context ? getInputUrl(context.input) : undefined;\n\tconst requestUrl = inputUrl?.startsWith(\"http\")\n\t\t? inputUrl\n\t\t: inputUrl\n\t\t\t? `${BaseUrlMap[context?.baseUrlType ?? \"\"]}${inputUrl}`\n\t\t\t: undefined;\n\n\treportTransportError(error, {\n\t\tsource,\n\t\trequestUrl: requestUrl ? normalizeUrlForReport(requestUrl) : undefined,\n\t\tresponseUrl: res.url ? normalizeUrlForReport(res.url) : undefined,\n\t\tmethod: context?.init.method?.toUpperCase() ?? \"GET\",\n\t\tbaseUrlType: context?.baseUrlType,\n\t\tsapClient: context?.sapClient,\n\t\tstatus: res.status,\n\t\tstatusText: res.statusText,\n\t\tcontentType: res.headers.get(\"Content-Type\") || undefined,\n\t\tredirected: res.redirected,\n\t\tresponseType: res.type,\n\t\thtml: createHtmlResponseSummary(text)\n\t});\n}\n","export type SsoForm = {\n\taction: string;\n\tmethod: string;\n\tinputs: Record<string, string>;\n};\n\nexport type SsoRecoveryArgs = {\n\tform?: SsoForm;\n\trecoveryUrl?: string;\n};\n\nexport type SsoRequiredErrorOptions = {\n\trecoverable?: boolean;\n};\n\nlet ssoRecoveryPromise: Promise<boolean> | null = null;\nlet ssoIframeCounter = 0;\n\nfunction normalizeSsoAction(action: string) {\n\tif (typeof window === \"undefined\") return action;\n\n\ttry {\n\t\tconst originRegExp = new RegExp(__ORIGIN_REG_EXP__, \"i\");\n\t\tconst url = new URL(action, window.location.origin);\n\t\tconst isSapHost = originRegExp.test(url.origin);\n\t\tconst isSsoHost = url.origin === __SSO_ORIGIN__;\n\n\t\tif (isSapHost || isSsoHost || url.origin === window.location.origin) {\n\t\t\treturn `${url.pathname}${url.search}${url.hash}`;\n\t\t}\n\n\t\treturn url.toString();\n\t} catch {\n\t\treturn action;\n\t}\n}\n\nexport function isSsoForm(form?: SsoForm): form is SsoForm {\n\tif (!form) return false;\n\n\treturn typeof form.inputs.SAMLRequest === \"string\" || typeof form.inputs.SAMLResponse === \"string\";\n}\n\nfunction createHiddenIframe() {\n\tconst iframeName = `${__APP_ID__}-sso-iframe-${++ssoIframeCounter}`;\n\tconst iframe = document.createElement(\"iframe\");\n\tiframe.name = iframeName;\n\tiframe.style.display = \"none\";\n\treturn iframe;\n}\n\nfunction waitForIframe(iframe: HTMLIFrameElement, cleanup: () => void) {\n\treturn new Promise<boolean>((resolve) => {\n\t\tlet settleTimer: number | null = null;\n\t\tconst complete = () => {\n\t\t\tif (settleTimer !== null) {\n\t\t\t\twindow.clearTimeout(settleTimer);\n\t\t\t}\n\n\t\t\tsettleTimer = window.setTimeout(() => {\n\t\t\t\tcleanup();\n\t\t\t\tresolve(true);\n\t\t\t}, 400);\n\t\t};\n\n\t\tiframe.addEventListener(\"load\", complete);\n\t\tiframe.addEventListener(\"error\", complete);\n\t});\n}\n\nfunction createSsoFormElement(form: SsoForm, target: string) {\n\tconst formElement = document.createElement(\"form\");\n\tformElement.method = form.method === \"GET\" ? \"GET\" : \"POST\";\n\tformElement.action = normalizeSsoAction(form.action);\n\tformElement.target = target;\n\tformElement.style.display = \"none\";\n\n\tfor (const [name, value] of Object.entries(form.inputs)) {\n\t\tconst input = document.createElement(\"input\");\n\t\tinput.type = \"hidden\";\n\t\tinput.name = name;\n\t\tinput.value = value;\n\t\tformElement.appendChild(input);\n\t}\n\n\treturn formElement;\n}\n\nfunction getMountPoint() {\n\tif (typeof document === \"undefined\") return null;\n\treturn document.body ?? document.documentElement;\n}\n\nexport function submitSsoForm(form?: SsoForm) {\n\tif (!isSsoForm(form)) return false;\n\tif (typeof document === \"undefined\") return false;\n\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return false;\n\n\tconst iframe = createHiddenIframe();\n\tconst formElement = createSsoFormElement(form, iframe.name);\n\n\tmountPoint.appendChild(iframe);\n\tmountPoint.appendChild(formElement);\n\tformElement.submit();\n\treturn true;\n}\n\nfunction recoverBySsoForm(form: SsoForm) {\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return Promise.resolve(false);\n\n\tconst iframe = createHiddenIframe();\n\tconst formElement = createSsoFormElement(form, iframe.name);\n\tconst recovery = waitForIframe(iframe, () => {\n\t\tiframe.remove();\n\t\tformElement.remove();\n\t});\n\n\tmountPoint.appendChild(iframe);\n\tmountPoint.appendChild(formElement);\n\tformElement.submit();\n\n\treturn recovery;\n}\n\nfunction recoverByDocumentNavigation(recoveryUrl: string) {\n\tconst mountPoint = getMountPoint();\n\tif (!mountPoint) return Promise.resolve(false);\n\n\tconst iframe = createHiddenIframe();\n\tconst recovery = waitForIframe(iframe, () => {\n\t\tiframe.remove();\n\t});\n\n\tmountPoint.appendChild(iframe);\n\tiframe.src = normalizeSsoAction(recoveryUrl);\n\n\treturn recovery;\n}\n\nexport function recoverSsoSession({ form, recoveryUrl }: SsoRecoveryArgs = {}) {\n\tif (ssoRecoveryPromise) return ssoRecoveryPromise;\n\tif (typeof window === \"undefined\") return false;\n\n\tssoRecoveryPromise = (async () => {\n\t\tif (isSsoForm(form)) return recoverBySsoForm(form);\n\t\tif (recoveryUrl) return recoverByDocumentNavigation(recoveryUrl);\n\t\treturn false;\n\t})().finally(() => {\n\t\tssoRecoveryPromise = null;\n\t});\n\n\treturn ssoRecoveryPromise;\n}\n\nexport class SsoRequiredError extends Error {\n\tpublic readonly form?: SsoForm;\n\tpublic readonly recoveryUrl?: string;\n\tpublic readonly recoverable: boolean;\n\tconstructor(message: string, form?: SsoForm, recoveryUrl?: string, options: SsoRequiredErrorOptions = {}) {\n\t\tsuper(message);\n\t\tthis.form = form;\n\t\tthis.recoveryUrl = recoveryUrl;\n\t\tthis.recoverable = options.recoverable ?? true;\n\t\tObject.setPrototypeOf(this, SsoRequiredError.prototype);\n\t}\n}\n","import { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { asRecord, isRecord, isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { normalizeODataServiceName, resolveODataBaseUrl, resolveODataSapClient } from \"../odataProjectAdapter\";\n\nimport { reportUnexpectedHtmlResponse } from \"./errorReport\";\nimport { isSsoForm, recoverSsoSession, SsoForm, SsoRequiredError } from \"./SsoRequiredError\";\nimport { BaseURLType, FetchErrorReportContext, RequestInitType } from \"./types\";\nimport { BaseUrlMap, getInputUrl, normalizeRelativePath } from \"./url\";\n\nconst csrfTokenCache = new Map<string, string>();\nconst csrfFetchInProgressCache = new Map<string, Promise<string>>();\nlet ssoRecoveryGate: Promise<void> | null = null;\nlet ssoBlockedError: SsoRequiredError | null = null;\n\nexport { normalizeODataServiceName, resolveODataBaseUrl };\n\nfunction isSapRequest(input: RequestInfo, baseUrlType: BaseURLType) {\n\tif (baseUrlType !== \"\") return true;\n\n\tconst path = normalizeRelativePath(getInputUrl(input));\n\treturn path.startsWith(\"/sap/\") || path.startsWith(\"/sap-dp0/\");\n}\n\nfunction getSapClient(input: RequestInfo, baseUrlType: BaseURLType): string | null {\n\tif (__DEV__ || __PREVIEW__) {\n\t\tif (!isSapRequest(input, baseUrlType)) return null;\n\t\tif (baseUrlType === \"odataDp0\") return \"300\";\n\t\tif (baseUrlType === \"\" && normalizeRelativePath(getInputUrl(input)).startsWith(\"/sap-dp0/\")) {\n\t\t\treturn \"300\";\n\t\t}\n\t\treturn `${__SAP_CLIENT__}`;\n\t}\n\n\treturn resolveODataSapClient();\n}\n\nfunction createUnrecoverableSsoError(source: SsoRequiredError) {\n\treturn new SsoRequiredError(\n\t\t\"Не удалось автоматически восстановить SSO-сессию. Перезагрузите страницу и выполните вход заново.\",\n\t\tsource.form,\n\t\tsource.recoveryUrl,\n\t\t{ recoverable: false }\n\t);\n}\n\nfunction markSsoBlocked(source: SsoRequiredError) {\n\tconst error = createUnrecoverableSsoError(source);\n\tif (typeof window !== \"undefined\") {\n\t\tssoBlockedError = error;\n\t}\n\treturn error;\n}\n\nasync function waitForSsoRecoveryGate() {\n\tconst gate = ssoRecoveryGate;\n\tif (gate) {\n\t\tawait gate.catch(() => {});\n\t}\n\n\tif (ssoBlockedError) {\n\t\tthrow ssoBlockedError;\n\t}\n}\n\nasync function recoverSsoSessionAndRetry<T>(error: SsoRequiredError, retry: () => Promise<T>) {\n\tif (ssoBlockedError) {\n\t\tthrow ssoBlockedError;\n\t}\n\n\tlet retryResult: { value: T } | undefined;\n\n\tif (!ssoRecoveryGate) {\n\t\tssoRecoveryGate = (async () => {\n\t\t\tconst recovered = await Promise.resolve(recoverSsoSession({ form: error.form, recoveryUrl: error.recoveryUrl })).catch(\n\t\t\t\t() => false\n\t\t\t);\n\n\t\t\tif (!recovered) {\n\t\t\t\tthrow markSsoBlocked(error);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tretryResult = { value: await retry() };\n\t\t\t\tssoBlockedError = null;\n\t\t\t} catch (retryError: unknown) {\n\t\t\t\tif (retryError instanceof SsoRequiredError) {\n\t\t\t\t\tthrow markSsoBlocked(retryError);\n\t\t\t\t}\n\n\t\t\t\tthrow retryError;\n\t\t\t}\n\t\t})().finally(() => {\n\t\t\tssoRecoveryGate = null;\n\t\t});\n\n\t\tawait ssoRecoveryGate;\n\n\t\tif (!retryResult) {\n\t\t\tthrow ssoBlockedError ?? createUnrecoverableSsoError(error);\n\t\t}\n\n\t\treturn retryResult.value;\n\t}\n\n\tawait waitForSsoRecoveryGate();\n\ttry {\n\t\treturn await retry();\n\t} catch (retryError: unknown) {\n\t\tif (retryError instanceof SsoRequiredError) {\n\t\t\tthrow markSsoBlocked(retryError);\n\t\t}\n\n\t\tthrow retryError;\n\t}\n}\n\nfunction resolveCsrfScope(input: RequestInfo, baseUrlType: BaseURLType, sapClient: string | null) {\n\tif (baseUrlType === \"config\") {\n\t\treturn {\n\t\t\tcacheKey: `${__APP_ID__}:${sapClient ?? \"\"}`,\n\t\t\tfetchUrl: \"/Statistics\"\n\t\t};\n\t}\n\n\tconst requestPath = normalizeRelativePath(getInputUrl(input));\n\tconst [serviceName] = requestPath.split(\"/\").filter(Boolean);\n\tif (!serviceName) {\n\t\tthrow new Error(\"Не удалось определить сервис для получения CSRF-токена\");\n\t}\n\n\treturn {\n\t\tcacheKey: `${baseUrlType}:${sapClient ?? \"\"}:${serviceName}`,\n\t\tfetchUrl: `/${serviceName}/`\n\t};\n}\n\nasync function getCsrfToken(input: RequestInfo, baseUrlType: BaseURLType, sapClient: string | null): Promise<string> {\n\tconst scope = resolveCsrfScope(input, baseUrlType, sapClient);\n\tconst cachedToken = csrfTokenCache.get(scope.cacheKey);\n\tif (cachedToken) return cachedToken;\n\n\tconst inflightToken = csrfFetchInProgressCache.get(scope.cacheKey);\n\tif (inflightToken) return inflightToken;\n\n\tconst headers = new Headers({ \"x-csrf-token\": \"Fetch\" });\n\theaders.set(\"sap-language\", \"ru\");\n\theaders.set(\"sap-contextid-accept\", \"header\");\n\theaders.set(\"Accept-Language\", \"ru\");\n\tif (sapClient) {\n\t\theaders.set(\"sap-client\", sapClient);\n\t}\n\n\tconst baseUrl = (baseUrlType && BaseUrlMap[baseUrlType]) ?? \"\";\n\tconst tokenPromise = fetch(baseUrl + scope.fetchUrl, {\n\t\tmethod: \"GET\",\n\t\theaders,\n\t\tcredentials: \"include\",\n\t\tredirect: \"manual\"\n\t})\n\t\t.then(async (res) => {\n\t\t\tif (isSsoRedirectResponse(res)) {\n\t\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + scope.fetchUrl);\n\t\t\t}\n\n\t\t\tif (!res.ok) throw new Error(\"Не удалось получить CSRF-токен\");\n\n\t\t\tconst token = res.headers.get(\"x-csrf-token\");\n\t\t\tif (!token) {\n\t\t\t\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\t\t\t\tconst text = await res.text();\n\t\t\t\tif (looksLikeHtmlResponse(contentType, text)) {\n\t\t\t\t\tconst form = extractFormFromHtml(text);\n\t\t\t\t\tif (isSsoForm(form)) {\n\t\t\t\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", form, baseUrl + scope.fetchUrl);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthrow new Error(\"CSRF-токен отсутствует в ответе\");\n\t\t\t}\n\n\t\t\tcsrfTokenCache.set(scope.cacheKey, token);\n\t\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\t\treturn token;\n\t\t})\n\t\t.catch((err) => {\n\t\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\t\tthrow err;\n\t\t});\n\n\tcsrfFetchInProgressCache.set(scope.cacheKey, tokenPromise);\n\treturn tokenPromise;\n}\n\nfunction extractHtmlAttribute(source: string, attributeName: string) {\n\tconst escapedAttributeName = attributeName.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\tconst match = new RegExp(`${escapedAttributeName}\\\\s*=\\\\s*[\"']([^\"']*)[\"']`, \"i\").exec(source);\n\treturn match?.[1];\n}\n\n/**\n * Попытка извлечь форму (действие + скрытые входные данные) из HTML, возвращаемого ADFS/SSO.\n * Возвращает undefined, если форма не найдена.\n */\nfunction extractFormFromHtml(html: string): SsoForm | undefined {\n\ttry {\n\t\tif (typeof DOMParser !== \"undefined\") {\n\t\t\tconst parser = new DOMParser();\n\t\t\tconst doc = parser.parseFromString(html, \"text/html\");\n\t\t\tconst form = doc.querySelector(\"form\");\n\t\t\tif (form) {\n\t\t\t\tconst action = form.getAttribute(\"action\") || (typeof window !== \"undefined\" ? window.location.href : \"\");\n\t\t\t\tconst method = (form.getAttribute(\"method\") || \"GET\").toUpperCase();\n\t\t\t\tconst inputs: Record<string, string> = {};\n\t\t\t\tform.querySelectorAll<HTMLInputElement>(\"input[name]\").forEach((i) => {\n\t\t\t\t\tinputs[i.name] = i.value ?? \"\";\n\t\t\t\t});\n\t\t\t\treturn { action, method, inputs };\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Игнорируем и переходим к текстовому fallback-разбору.\n\t}\n\n\tconst formMatch = /<form\\b([^>]*)>([\\s\\S]*?)<\\/form>/i.exec(html);\n\tif (!formMatch) return undefined;\n\n\tconst [, formAttributes = \"\", formBody = \"\"] = formMatch;\n\tconst action = extractHtmlAttribute(formAttributes, \"action\") || (typeof window !== \"undefined\" ? window.location.href : \"\");\n\tconst method = (extractHtmlAttribute(formAttributes, \"method\") || \"GET\").toUpperCase();\n\tconst inputs: Record<string, string> = {};\n\tconst inputTagPattern = /<input\\b([^>]*)>/gi;\n\n\tfor (const match of formBody.matchAll(inputTagPattern)) {\n\t\tconst inputAttributes = match[1] ?? \"\";\n\t\tconst inputName = extractHtmlAttribute(inputAttributes, \"name\");\n\t\tif (!inputName) continue;\n\n\t\tinputs[inputName] = extractHtmlAttribute(inputAttributes, \"value\") ?? \"\";\n\t}\n\n\treturn { action, method, inputs };\n}\n\nfunction looksLikeHtmlResponse(contentType: string, text: string) {\n\treturn contentType.includes(\"text/html\") || /<html/i.test(text) || /<form/i.test(text);\n}\n\nfunction stripODataMetadata(value: unknown) {\n\tif (!isRecord(value)) return value;\n\n\tconst record = { ...value };\n\tdelete record.__metadata;\n\treturn record;\n}\n\nfunction extractJson<T>(json: unknown) {\n\tif (isRecord(json) && isRecord(json.d) && Array.isArray(json.d.results)) {\n\t\tlet totalCount: number | undefined = undefined;\n\t\tif (json.d.__count) {\n\t\t\ttotalCount = Number(json.d.__count);\n\t\t}\n\n\t\tconst data = json.d.results.map(stripODataMetadata) as T;\n\n\t\treturn { data, totalCount };\n\t}\n\tif (isRecord(json) && json.d !== undefined) {\n\t\tconst data = stripODataMetadata(json.d);\n\n\t\treturn { data: data as T };\n\t}\n\treturn {\n\t\tdata: json as T\n\t};\n}\n\nconst NO_CONTENT_RESPONSE = Object.freeze({ __noContent: true } as const);\n\nexport function isNoContentResponse(value: unknown): value is typeof NO_CONTENT_RESPONSE {\n\treturn !!value && typeof value === \"object\" && \"__noContent\" in value;\n}\n\nasync function parseResponse<T>(res: Response, reportContext?: FetchErrorReportContext): Promise<{ data: T; totalCount?: number }> {\n\tif (res.status === 204 || res.status === 205 /*|| res.headers.get(\"Content-Length\") === \"0\"*/) {\n\t\treturn { data: NO_CONTENT_RESPONSE as T };\n\t}\n\n\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\n\t// Если явный JSON — безопасно парсим\n\tif (contentType.includes(\"application/json\") || contentType.includes(\"application/odata+json\")) {\n\t\tconst json = await res.json();\n\t\treturn extractJson<T>(json);\n\t}\n\n\t// Попытка парсинга как текст (на случай, если server неправильно прописал content-type)\n\tconst text = await res.text();\n\n\t// если в теле HTML — проверяем, есть ли форма (SSO)\n\tif (looksLikeHtmlResponse(contentType, text)) {\n\t\tconst form = extractFormFromHtml(text);\n\t\tif (isSsoForm(form)) {\n\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", form);\n\t\t}\n\t\tconst error = new Error(\"Unexpected HTML response from OData endpoint\");\n\t\treportUnexpectedHtmlResponse(error, \"fetch.parseResponse\", res, text, reportContext);\n\t\tthrow error;\n\t}\n\n\t// Попытка безопасно распарсить JSON, если сервер не установил content-type\n\ttry {\n\t\tconst maybeJson = JSON.parse(text);\n\t\treturn extractJson<T>(maybeJson);\n\t} catch (e) {\n\t\tlogError(e);\n\t\t// ни текст, ни JSON — возвращаем ошибку\n\t\tthrow new Error(\"Unsupported response content type and body is not JSON\");\n\t}\n}\n\n/**\n * Безопасно извлекает текстовое сообщение из неизвестного значения.\n */\nfunction asNonEmptyString(value: unknown): string | null {\n\tif (typeof value !== \"string\") return null;\n\tconst normalized = value.trim();\n\treturn normalized.length ? normalized : null;\n}\n\nfunction pushUniqueMessage(parts: string[], value: unknown) {\n\tconst normalized = asNonEmptyString(value);\n\tif (!normalized || parts.includes(normalized)) return;\n\tparts.push(normalized);\n}\n\nfunction extractJsonErrorParts(payload: Record<string, unknown>) {\n\tconst parts: string[] = [];\n\tconst errorValue = payload.error;\n\n\tif (typeof errorValue === \"string\") {\n\t\tpushUniqueMessage(parts, errorValue);\n\t}\n\n\tconst errorRecord = asRecord(errorValue);\n\tif (errorRecord) {\n\t\tpushUniqueMessage(parts, errorRecord.code);\n\n\t\tconst errorMessage = asRecord(errorRecord.message);\n\t\tpushUniqueMessage(parts, errorMessage?.value ?? errorRecord.message);\n\n\t\t// const innerError = asRecord(errorRecord.innererror);\n\t\t// const errorDetails = innerError?.errordetails;\n\t\t// if (Array.isArray(errorDetails)) {\n\t\t// \tfor (const detail of errorDetails) {\n\t\t// \t\tpushUniqueMessage(parts, asRecord(detail)?.message);\n\t\t// \t}\n\t\t// }\n\t}\n\n\tpushUniqueMessage(parts, payload.details);\n\tpushUniqueMessage(parts, payload.message);\n\n\treturn parts;\n}\n\n/**\n * Строит детализированную ошибку HTTP на основе статуса и тела ответа.\n * Для JSON-ответов приоритетно используются поля `error`, `details`, `message`.\n */\nasync function buildHttpError(res: Response, reportContext?: FetchErrorReportContext): Promise<Error> {\n\tconst contentType = (res.headers.get(\"Content-Type\") || \"\").toLowerCase();\n\n\ttry {\n\t\tif (contentType.includes(\"application/json\") || contentType.includes(\"application/odata+json\")) {\n\t\t\tconst payload = (await res.json()) as Record<string, unknown>;\n\t\t\tconst parts = extractJsonErrorParts(payload);\n\n\t\t\tif (parts.length) {\n\t\t\t\treturn new Error(parts.join(\" | \"));\n\t\t\t}\n\t\t} else {\n\t\t\tconst text = await res.text();\n\t\t\tconst normalizedText = asNonEmptyString(text);\n\t\t\tif (normalizedText) {\n\t\t\t\tif (looksLikeHtmlResponse(contentType, normalizedText)) {\n\t\t\t\t\tconst form = extractFormFromHtml(normalizedText);\n\t\t\t\t\tif (isSsoForm(form)) {\n\t\t\t\t\t\treturn new SsoRequiredError(\"Требуется повторная аутентификация\", form);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst error = new Error(\"Unexpected HTML response from OData endpoint\");\n\t\t\t\t\treportUnexpectedHtmlResponse(error, \"fetch.buildHttpError\", res, normalizedText, reportContext);\n\t\t\t\t\treturn error;\n\t\t\t\t}\n\n\t\t\t\treturn new Error(normalizedText);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ничего не делаем: в этом случае вернем стандартный текст ошибки по статусу.\n\t}\n\n\treturn new Error(`HTTP error: ${res.status} ${res.statusText}`);\n}\n\nfunction isSsoRedirectResponse(res: Response) {\n\treturn res.type === \"opaqueredirect\";\n}\n\nasync function sendFetchBaseRequest(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\"): Promise<Response> {\n\tconst method = init.method?.toUpperCase() || \"GET\";\n\tconst headers = new Headers(init.headers);\n\tconst isWrite = ![\"GET\", \"HEAD\"].includes(method);\n\tconst hasBody = isSafe(init.body);\n\tconst sapRequest = isSapRequest(input, baseUrlType);\n\tconst sapClient = getSapClient(input, baseUrlType);\n\n\theaders.set(\"sap-language\", \"ru\");\n\tif (sapRequest) {\n\t\theaders.set(\"sap-language\", \"ru\");\n\t\theaders.set(\"sap-contextid-accept\", \"header\");\n\t}\n\tif (sapClient) {\n\t\theaders.set(\"sap-client\", sapClient);\n\t}\n\tif (isWrite && sapRequest) {\n\t\tconst token = await getCsrfToken(input, baseUrlType, sapClient);\n\t\theaders.set(\"x-csrf-token\", token);\n\t}\n\n\tif (!headers.has(\"Accept\")) {\n\t\theaders.set(\"Accept\", \"application/json\");\n\t}\n\n\tif (hasBody && isWrite && !headers.has(\"Content-Type\")) {\n\t\theaders.set(\"Content-Type\", \"application/json\");\n\t}\n\n\tconst baseUrl = (baseUrlType && BaseUrlMap[baseUrlType]) ?? \"\";\n\tconst url = typeof input === \"string\" ? input : input.toString();\n\tlet res = await fetch(baseUrl + url, {\n\t\t...init,\n\t\theaders,\n\t\tcredentials: \"include\",\n\t\tredirect: sapRequest ? \"manual\" : init.redirect\n\t});\n\n\tif (sapRequest && isSsoRedirectResponse(res)) {\n\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + url);\n\t}\n\n\t// Если 401 — возможно, токен истёк, пробуем получить заново и повторить\n\tif ((res.status === 401 || res.status === 403) && isWrite && sapRequest && !init.retried) {\n\t\tconst scope = resolveCsrfScope(input, baseUrlType, sapClient);\n\t\tcsrfTokenCache.delete(scope.cacheKey);\n\t\tcsrfFetchInProgressCache.delete(scope.cacheKey);\n\t\tconst token = await getCsrfToken(input, baseUrlType, sapClient);\n\n\t\tconst retryHeaders = new Headers(headers);\n\t\tretryHeaders.set(\"x-csrf-token\", token);\n\n\t\tres = await fetch(baseUrl + url, {\n\t\t\t...init,\n\t\t\theaders: retryHeaders,\n\t\t\tcredentials: \"include\",\n\t\t\tredirect: \"manual\",\n\t\t\tretried: true // кастомная метка, чтобы избежать бесконечного цикла\n\t\t} as RequestInitType);\n\n\t\tif (isSsoRedirectResponse(res)) {\n\t\t\tthrow new SsoRequiredError(\"Требуется повторная аутентификация\", undefined, baseUrl + url);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nasync function finalizeFetchBaseResponse(\n\tres: Response,\n\tinput: RequestInfo,\n\tinit: RequestInitType,\n\tbaseUrlType: BaseURLType,\n\tsapClient: string | null\n) {\n\tif (!res.ok) {\n\t\tif (res.status === 0) {\n\t\t\tthrow new Error(\"Ошибка сети или CORS. Проверьте подключение и настройки сервера.\");\n\t\t}\n\n\t\tthrow await buildHttpError(res, { input, init, baseUrlType, sapClient });\n\t}\n\n\treturn res;\n}\n\nasync function fetchBaseWithoutSsoRecovery(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst sapClient = getSapClient(input, baseUrlType);\n\tconst res = await sendFetchBaseRequest(input, init, baseUrlType);\n\treturn finalizeFetchBaseResponse(res, input, init, baseUrlType, sapClient);\n}\n\nexport async function fetchBase(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\"): Promise<Response> {\n\tconst sapRequest = isSapRequest(input, baseUrlType);\n\tconst sapClient = getSapClient(input, baseUrlType);\n\tconst retry = () => fetchBaseWithoutSsoRecovery(input, { ...init, ssoRetried: true }, baseUrlType);\n\n\tif (sapRequest) {\n\t\tawait waitForSsoRecoveryGate();\n\t}\n\n\tlet res: Response;\n\ttry {\n\t\tres = await sendFetchBaseRequest(input, init, baseUrlType);\n\t} catch (error: unknown) {\n\t\tif (sapRequest && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\tres = await recoverSsoSessionAndRetry(error, retry);\n\t\t} else {\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\ttry {\n\t\treturn await finalizeFetchBaseResponse(res, input, init, baseUrlType, sapClient);\n\t} catch (error: unknown) {\n\t\tif (sapRequest && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\tconst recoveredResponse = await recoverSsoSessionAndRetry(error, retry);\n\t\t\treturn finalizeFetchBaseResponse(recoveredResponse, input, init, baseUrlType, sapClient);\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function fetchODataJson<T = unknown>(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst headers = new Headers(init.headers);\n\n\theaders.set(\"DataServiceVersion\", \"2.0\");\n\theaders.set(\"MaxDataServiceVersion\", \"2.0\");\n\n\tconst requestInit = { ...init, headers };\n\tconst parseContext = { input, init, baseUrlType, sapClient: getSapClient(input, baseUrlType) };\n\n\ttry {\n\t\tconst res = await fetchBase(input, requestInit, baseUrlType);\n\t\treturn await parseResponse<T>(res, parseContext);\n\t} catch (error: unknown) {\n\t\tif (isSapRequest(input, baseUrlType) && error instanceof SsoRequiredError && error.recoverable && !init.ssoRetried) {\n\t\t\treturn recoverSsoSessionAndRetry(error, async () => {\n\t\t\t\tconst retryInit = { ...requestInit, ssoRetried: true };\n\t\t\t\tconst res = await fetchBaseWithoutSsoRecovery(input, retryInit, baseUrlType);\n\t\t\t\treturn parseResponse<T>(res, { input, init: retryInit, baseUrlType, sapClient: getSapClient(input, baseUrlType) });\n\t\t\t});\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n\nexport async function fetchJson<T = unknown>(input: RequestInfo, init: RequestInitType = {}, baseUrlType: BaseURLType = \"odata\") {\n\tconst response = await fetchODataJson<T>(input, init, baseUrlType);\n\treturn response.data;\n}\n\ninterface FetchQueryFnBaseOptions {\n\tinit?: RequestInit;\n\tbaseUrl?: BaseURLType;\n\t/** Политика кеширования в Service Worker (`\"off\"` | `\"ttl=24h\"` | `\"ttl=24h;max=100;name=ref\"` | `\"bust=24h\"` и т.д.) */\n\tswCache?: string;\n}\n\ninterface FetchQueryFnOptions<R> extends FetchQueryFnBaseOptions {\n\ttransform: (data: Response) => Promise<R>;\n}\n\nexport function fetchQueryFn<R = unknown>(url: string, options: FetchQueryFnOptions<R>) {\n\tconst initValue = options.init || {};\n\tconst baseUrlValue = options.baseUrl;\n\tconst transform = options.transform;\n\n\tif (options.swCache) {\n\t\tconst headers = new Headers(initValue.headers);\n\t\theaders.set(\"x-sw-cache\", options.swCache);\n\t\tinitValue.headers = headers;\n\t}\n\n\treturn async (params?: { signal?: AbortSignal }): Promise<R> => {\n\t\tif (!initValue.signal && params?.signal) {\n\t\t\tinitValue.signal = params.signal;\n\t\t}\n\n\t\tconst data = await fetchBase(url, initValue, baseUrlValue);\n\n\t\tif (typeof transform !== \"function\") {\n\t\t\tthrow new Error(\"fetchQueryFn requires a transformation function!\");\n\t\t}\n\n\t\treturn await transform(data);\n\t};\n}\n\ninterface FetchJsonQueryFnOptions<T, R> extends FetchQueryFnBaseOptions {\n\ttransform?: (data: T) => R;\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchJsonQueryFn<T, R = T>(url: string, options?: FetchJsonQueryFnOptions<T, R>) {\n\tconst baseUrlValue = options?.baseUrl || \"odata\";\n\tconst transform = options?.transform;\n\n\treturn async (params?: { signal: AbortSignal }) => {\n\t\tconst initValue = options?.init || {};\n\t\tif (!initValue.signal && params?.signal) {\n\t\t\tinitValue.signal = params.signal;\n\t\t}\n\n\t\tif (options?.swCache) {\n\t\t\tconst headers = new Headers(initValue.headers);\n\t\t\theaders.set(\"x-sw-cache\", options.swCache);\n\t\t\tinitValue.headers = headers;\n\t\t}\n\n\t\tconst data = await fetchJson<T>(url, initValue, baseUrlValue);\n\n\t\tif (!transform) {\n\t\t\treturn data as unknown as R;\n\t\t}\n\n\t\treturn transform ? transform(data) : (data as unknown as R);\n\t};\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchJsonMutationFn<T = unknown, TBody = unknown>(url: string, method: \"POST\" | \"PUT\" = \"POST\", baseUrl?: BaseURLType) {\n\treturn async (body: TBody, signal?: AbortSignal) => {\n\t\treturn fetchJson<T>(\n\t\t\turl,\n\t\t\t{\n\t\t\t\tmethod,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\tbody: JSON.stringify(body),\n\t\t\t\tsignal\n\t\t\t},\n\t\t\tbaseUrl\n\t\t);\n\t};\n}\n\n/**\n * @deprecated скоро будет замена\n */\nexport function fetchDeleteFn<T = unknown>(url: string, baseUrl?: BaseURLType) {\n\treturn async (signal?: AbortSignal) => {\n\t\treturn fetchJson<T>(url, { method: \"DELETE\", signal }, baseUrl);\n\t};\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { C as e, S as t, _ as n, c as r, o as i, s as a, x as o } from "./fetch-3O2E2pQ9.js";
1
+ import { C as e, S as t, _ as n, c as r, o as i, s as a, x as o } from "./fetch-CPEFkAcU.js";
2
2
  import { isRecord as s } from "@ryuzaki13/react-foundation-lib/validators";
3
3
  import { formatDateAsODataDatetime as c, parseDate as l } from "@ryuzaki13/react-foundation-lib/formatters";
4
4
  import { useEffect as u, useMemo as d } from "react";
@@ -41,7 +41,7 @@ async function T(e, t = {}, n = {}) {
41
41
  }
42
42
  //#endregion
43
43
  //#region src/odata/metadataVersionCheck.ts
44
- var E = "@ryuzaki13/react-foundation-api@1.1.1", D = 1e3 * 60 * 60 * 24;
44
+ var E = __APP_BUILD_ID__, D = 1e3 * 60 * 60 * 24;
45
45
  function O(e) {
46
46
  if (e) return Array.isArray(e) ? e[0] : e;
47
47
  }
@@ -247,7 +247,9 @@ function Q(...t) {
247
247
  if (!p) throw Error(`Не удалось загрузить metadata OData-сервиса '${a.service}'`);
248
248
  let m = U(p, a.target);
249
249
  W(m, n, a);
250
- let h = "body" in i ? K(i.body, n) : void 0, g = G(m, n), _ = q(m, a, u, n), v = l ? {
250
+ let h = "body" in i ? K(i.body, n) : void 0, g = G(m, n);
251
+ __DEV__ && n === "query" && !("result" in m) && Object.keys(u).length > 0 && console.warn(`OData query для plain entity "${a.service}/${a.target}" получил params, но они будут проигнорированы. Для чтения сущности по ключу используйте odataReadFn.`);
252
+ let _ = q(m, a, u, n), v = l ? {
251
253
  ...o,
252
254
  baseUrl: f,
253
255
  swCache: l
@@ -297,6 +299,6 @@ function ie(e) {
297
299
  return Q("fi", e);
298
300
  }
299
301
  //#endregion
300
- export { re as a, L as c, I as d, R as f, S as h, ie as i, F as l, T as m, te as n, ne as o, z as p, Q as r, ee as s, $ as t, V as u };
302
+ export { S, I as _, re as a, w as b, q as c, K as d, G as f, V as g, F as h, ie as i, H as l, L as m, te as n, ne as o, W as p, Q as r, ee as s, $ as t, U as u, R as v, T as x, z as y };
301
303
 
302
- //# sourceMappingURL=odataFetchFn-BS26nUg7.js.map
304
+ //# sourceMappingURL=odataFetchFn-D8PGKDZM.js.map