@ryuzaki13/react-foundation-api 1.1.12 → 1.1.13
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/odata/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { C as e, S as t, _ as n, a as r, b as i, c as a, d as o, f as s, g as c, h as l, i as u, l as d, m as f, n as p, o as m, p as h, r as g, s as _, t as v, u as y, v as b, w as x, x as S, y as C } from "../chunks/fetch-PmN9NBra.js";
|
|
2
|
-
import { S as w, _ as ee, a as te, b as ne, c as re, d as ie, f as ae, g as
|
|
2
|
+
import { S as w, _ as ee, a as te, b as ne, c as re, d as ie, f as ae, g as T, h as oe, i as se, l as ce, m as le, n as ue, o as de, p as fe, r as E, s as pe, t as me, u as he, v as ge, x as D, y as _e } from "../chunks/odataFetchFn-CzhXMYXj.js";
|
|
3
3
|
import { logError as ve } from "@ryuzaki13/react-foundation-lib/utils";
|
|
4
4
|
import { parseDate as ye } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
5
|
-
import { compareStrings as
|
|
6
|
-
import { useCallback as
|
|
7
|
-
import { queryOptions as
|
|
8
|
-
import { buildSeparatedArrays as
|
|
9
|
-
import { persistedQueryMeta as
|
|
10
|
-
import { buildEntityPath as
|
|
11
|
-
import { createTableColumnVisibilityFromODataMetadata as
|
|
12
|
-
import { notify as
|
|
5
|
+
import { compareStrings as be } from "@ryuzaki13/react-foundation-lib/string-comparison";
|
|
6
|
+
import { useCallback as O, useEffect as k, useMemo as A, useRef as xe, useState as j } from "react";
|
|
7
|
+
import { queryOptions as Se, useQuery as M, useQueryClient as N } from "@tanstack/react-query";
|
|
8
|
+
import { buildSeparatedArrays as Ce, useODataCollectionStore as we } from "@ryuzaki13/react-foundation-lib/odata";
|
|
9
|
+
import { persistedQueryMeta as P } from "@ryuzaki13/react-foundation-lib/query-client";
|
|
10
|
+
import { buildEntityPath as Te } from "@ryuzaki13/react-foundation-lib/odata-service";
|
|
11
|
+
import { createTableColumnVisibilityFromODataMetadata as Ee, createTableColumnsFromODataMetadata as De, enrichTableColumnsWithODataFormatting as Oe, resolveStableColumnId as ke } from "@ryuzaki13/react-foundation-lib/table";
|
|
12
|
+
import { notify as Ae } from "@ryuzaki13/react-foundation-lib/notifications";
|
|
13
13
|
//#region src/odata/createODataCollectionQueryKey.ts
|
|
14
|
-
var
|
|
15
|
-
version:
|
|
14
|
+
var je = 2, Me = () => [...w, "collection"], F = ({ service: e, target: t, limitedKeys: n, serverFilter: r }) => [...Me(), {
|
|
15
|
+
version: je,
|
|
16
16
|
service: e,
|
|
17
17
|
target: t,
|
|
18
18
|
limitedKeys: n,
|
|
@@ -20,7 +20,7 @@ var ke = 2, L = () => [...w, "collection"], R = ({ service: e, target: t, limite
|
|
|
20
20
|
}];
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/odata/flattenODataDependentServices.ts
|
|
23
|
-
function
|
|
23
|
+
function Ne(e) {
|
|
24
24
|
let t = [];
|
|
25
25
|
for (let [n, r] of e.entries()) {
|
|
26
26
|
let e = `${r.odata.service}.${r.odata.target}`;
|
|
@@ -42,7 +42,7 @@ function Ae(e) {
|
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
44
|
//#region src/odata/sortODataDependentSegmentItemsByChains.ts
|
|
45
|
-
function
|
|
45
|
+
function Pe(e, t, n) {
|
|
46
46
|
let r = /* @__PURE__ */ new Map();
|
|
47
47
|
for (let [e, n] of Object.entries(t)) r.set(e, new Map(n.map((e, t) => [e.codeKey, t])));
|
|
48
48
|
let i = [...e].map((e, t) => ({
|
|
@@ -64,7 +64,7 @@ function je(e, t, n) {
|
|
|
64
64
|
}
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region src/odata/sortODataDependentServicesByChains.ts
|
|
67
|
-
function
|
|
67
|
+
function Fe(e, t) {
|
|
68
68
|
if (!t?.length) return [...e];
|
|
69
69
|
let n = /* @__PURE__ */ new Set();
|
|
70
70
|
for (let t of e) for (let e of Object.keys(t.segments)) n.add(e);
|
|
@@ -83,13 +83,13 @@ function Me(e, t) {
|
|
|
83
83
|
return (n ? o.get(n) ?? 2 ** 53 - 1 : 2 ** 53 - 1) - (r ? o.get(r) ?? 2 ** 53 - 1 : 2 ** 53 - 1);
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
function
|
|
87
|
-
return
|
|
86
|
+
function Ie(e, t, n) {
|
|
87
|
+
return Fe(e.map((e) => {
|
|
88
88
|
let n = t[`${e.odata.service}.${e.odata.target}`];
|
|
89
89
|
if (!n?.length) return e;
|
|
90
90
|
let r = new Map(n.map((e, t) => [e.codeKey, t])), i = Object.entries(e.segments).sort(([e], [t]) => {
|
|
91
91
|
let n = r.get(e), i = r.get(t);
|
|
92
|
-
return n !== void 0 && i !== void 0 ? n - i : n === void 0 ? i === void 0 ?
|
|
92
|
+
return n !== void 0 && i !== void 0 ? n - i : n === void 0 ? i === void 0 ? be(e, t) : 1 : -1;
|
|
93
93
|
});
|
|
94
94
|
return {
|
|
95
95
|
...e,
|
|
@@ -99,7 +99,7 @@ function Ne(e, t, n) {
|
|
|
99
99
|
}
|
|
100
100
|
//#endregion
|
|
101
101
|
//#region src/odata/fetchCollectionData.ts
|
|
102
|
-
async function
|
|
102
|
+
async function Le(e) {
|
|
103
103
|
let { url: t, query: n, signal: r } = e;
|
|
104
104
|
try {
|
|
105
105
|
let e = await D(t, n, { signal: r });
|
|
@@ -111,61 +111,66 @@ async function Pe(e) {
|
|
|
111
111
|
}
|
|
112
112
|
//#endregion
|
|
113
113
|
//#region src/odata/projectODataCollectionSort.ts
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
var I = /* @__PURE__ */ new WeakMap();
|
|
115
|
+
function Re(e) {
|
|
116
|
+
let t = I.get(e);
|
|
117
|
+
if (t) return t;
|
|
118
|
+
let n = !1, r = Object.fromEntries(Object.entries(e.separated).map(([t, r]) => {
|
|
119
|
+
let i = e.keyPairsMap[t];
|
|
120
|
+
return !i || r.length < 2 ? [t, r] : (n = !0, [t, [...r].sort((e, t) => be(String(e[i] ?? ""), String(t[i] ?? "")))]);
|
|
118
121
|
}));
|
|
119
|
-
|
|
122
|
+
if (!n) return e;
|
|
123
|
+
let i = {
|
|
120
124
|
...e,
|
|
121
|
-
separated:
|
|
122
|
-
}
|
|
125
|
+
separated: r
|
|
126
|
+
};
|
|
127
|
+
return I.set(e, i), i;
|
|
123
128
|
}
|
|
124
129
|
//#endregion
|
|
125
130
|
//#region src/odata/useODataCollectionUpdatesQuery.ts
|
|
126
|
-
var
|
|
131
|
+
var ze = __APP_BUILD_ID__, Be = 1e3 * 60 * 60 * 4, L = 1e3 * 60 * 60 * 24 * 7, R = "ttl=forever;name=ref", z = "bust=forever;name=ref", B = "ttl=4h;name=ref-updates", V = () => [
|
|
127
132
|
...w,
|
|
128
133
|
"collection-updates",
|
|
129
|
-
{ buildId:
|
|
134
|
+
{ buildId: ze }
|
|
130
135
|
];
|
|
131
|
-
function
|
|
136
|
+
function Ve(e) {
|
|
132
137
|
return {
|
|
133
138
|
...e,
|
|
134
139
|
lastChangedAt: ye(e.lastChanged)
|
|
135
140
|
};
|
|
136
141
|
}
|
|
137
|
-
function
|
|
138
|
-
let n = e.map(
|
|
142
|
+
function H(e, t) {
|
|
143
|
+
let n = e.map(Ve);
|
|
139
144
|
return {
|
|
140
145
|
items: n,
|
|
141
146
|
byEntityName: n.reduce((e, t) => (t.entityName && (e[t.entityName] = t), e), {}),
|
|
142
147
|
fetchedAt: t,
|
|
143
|
-
coverageStartedAt: t -
|
|
148
|
+
coverageStartedAt: t - L
|
|
144
149
|
};
|
|
145
150
|
}
|
|
146
|
-
function
|
|
151
|
+
function U() {
|
|
147
152
|
return async ({ signal: t }) => {
|
|
148
153
|
let n = Date.now(), r = S().collectionUpdates;
|
|
149
|
-
return r ?
|
|
154
|
+
return r ? H((await D(`/${r.service}/${r.target}`, {
|
|
150
155
|
baseUrl: e(r.service, r.baseUrl),
|
|
151
|
-
swCache:
|
|
152
|
-
}, { signal: t })).data, Math.max(n, Date.now())) :
|
|
156
|
+
swCache: B
|
|
157
|
+
}, { signal: t })).data, Math.max(n, Date.now())) : H([], n);
|
|
153
158
|
};
|
|
154
159
|
}
|
|
155
|
-
var
|
|
156
|
-
queryKey:
|
|
157
|
-
queryFn:
|
|
158
|
-
meta:
|
|
159
|
-
staleTime: e.staleTime ??
|
|
160
|
+
var W = (e = {}) => Se({
|
|
161
|
+
queryKey: V(),
|
|
162
|
+
queryFn: U(),
|
|
163
|
+
meta: P,
|
|
164
|
+
staleTime: e.staleTime ?? Be,
|
|
160
165
|
gcTime: Infinity
|
|
161
166
|
});
|
|
162
|
-
function
|
|
163
|
-
return
|
|
167
|
+
function G(e = {}) {
|
|
168
|
+
return M(W(e));
|
|
164
169
|
}
|
|
165
170
|
//#endregion
|
|
166
171
|
//#region src/odata/useODataMetadata.ts
|
|
167
172
|
function K(e) {
|
|
168
|
-
let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } =
|
|
173
|
+
let { data: t, dataUpdatedAt: n = 0, isLoading: r, isLoadingError: i } = ge({ service: e.service }), a = t?.entities[e.target];
|
|
169
174
|
if (!r && !a && t?.functionImports[e.target]) throw Error(`OData target '${e.target}' является FunctionImport и не может использоваться как сущность`);
|
|
170
175
|
if (i) throw Error(`Ошибка загрузки метаданных сервиса ${e.service}`);
|
|
171
176
|
return {
|
|
@@ -177,17 +182,17 @@ function K(e) {
|
|
|
177
182
|
//#endregion
|
|
178
183
|
//#region src/odata/useODataEntity.ts
|
|
179
184
|
var q = "Использование actions недопустимо до окончания загрузки metadata";
|
|
180
|
-
function
|
|
185
|
+
function J(e) {
|
|
181
186
|
let { metadata: t, metadataUpdatedAt: n, isLoading: r } = K(e);
|
|
182
187
|
return {
|
|
183
188
|
config: e,
|
|
184
189
|
metadata: t,
|
|
185
190
|
metadataUpdatedAt: n,
|
|
186
191
|
isLoading: r,
|
|
187
|
-
actions:
|
|
192
|
+
actions: A(() => ({
|
|
188
193
|
getEntityPath: (n = {}) => {
|
|
189
194
|
if (!t) throw Error(q);
|
|
190
|
-
return
|
|
195
|
+
return Te(t, e, n);
|
|
191
196
|
},
|
|
192
197
|
getKeys: () => {
|
|
193
198
|
if (!t) throw Error(q);
|
|
@@ -211,20 +216,20 @@ function Ve(e) {
|
|
|
211
216
|
}
|
|
212
217
|
//#endregion
|
|
213
218
|
//#region src/odata/useODataCollectionQuery.ts
|
|
214
|
-
function
|
|
219
|
+
function Y(e, t) {
|
|
215
220
|
if (!t) return e;
|
|
216
221
|
let n = e.trim().toLowerCase();
|
|
217
|
-
return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") :
|
|
222
|
+
return n === "off" || n.startsWith("bust=") ? e : n.startsWith("ttl=") ? e.replace(/^\s*ttl=/i, "bust=") : z;
|
|
218
223
|
}
|
|
219
|
-
function
|
|
224
|
+
function X(e) {
|
|
220
225
|
return typeof e == "number" && Number.isFinite(e) && e > 0;
|
|
221
226
|
}
|
|
222
|
-
function
|
|
227
|
+
function He(e, t) {
|
|
223
228
|
let n = t?.cacheUpdatedAt ?? 0, r = e.update?.lastChangedAt?.getTime();
|
|
224
|
-
return !!(
|
|
229
|
+
return !!(X(r) && (!t || !n || r > n) || X(e.metadataUpdatedAt) && (!t || !n || e.metadataUpdatedAt > n) || X(e.updatesCoverageStartedAt) && (!t || !n || n < e.updatesCoverageStartedAt));
|
|
225
230
|
}
|
|
226
|
-
function
|
|
227
|
-
let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c =
|
|
231
|
+
function Ue(e) {
|
|
232
|
+
let { service: t, target: n, limitedKeys: r, excludeEmpty: i, sortByCode: a, serverFilter: o, clientFilter: s, swCache: c = R } = e, l = N(), { actions: u, metadata: d, metadataUpdatedAt: f, isLoading: p } = J(e), m = G(), h = A(() => F({
|
|
228
233
|
service: t,
|
|
229
234
|
target: n,
|
|
230
235
|
limitedKeys: r,
|
|
@@ -234,19 +239,19 @@ function We(e) {
|
|
|
234
239
|
n,
|
|
235
240
|
r,
|
|
236
241
|
o
|
|
237
|
-
]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v =
|
|
242
|
+
]), g = l.getQueryData(h), _ = m.data?.byEntityName[n], v = He({
|
|
238
243
|
update: _,
|
|
239
244
|
metadataUpdatedAt: f,
|
|
240
245
|
updatesCoverageStartedAt: m.data?.coverageStartedAt
|
|
241
|
-
}, g), y =
|
|
242
|
-
return
|
|
246
|
+
}, g), y = Y(c, v), b = m.isError || m.isSuccess && !m.isFetching;
|
|
247
|
+
return k(() => {
|
|
243
248
|
!g || !v || l.invalidateQueries({ queryKey: h });
|
|
244
249
|
}, [
|
|
245
250
|
g,
|
|
246
251
|
l,
|
|
247
252
|
h,
|
|
248
253
|
v
|
|
249
|
-
]),
|
|
254
|
+
]), M({
|
|
250
255
|
queryKey: h,
|
|
251
256
|
queryFn: async ({ signal: e }) => {
|
|
252
257
|
let a = Date.now(), c = r ? [...r] : u.getKeys(), l = u.getKeyPairs(), d = u.getKeyPairsMap();
|
|
@@ -254,7 +259,7 @@ function We(e) {
|
|
|
254
259
|
let t = d[e];
|
|
255
260
|
t && !c.includes(t) && c.push(t);
|
|
256
261
|
}
|
|
257
|
-
let { items: p } = await
|
|
262
|
+
let { items: p } = await Le({
|
|
258
263
|
url: `/${t}/${n}`,
|
|
259
264
|
query: {
|
|
260
265
|
select: c,
|
|
@@ -264,7 +269,7 @@ function We(e) {
|
|
|
264
269
|
signal: e
|
|
265
270
|
}), m = p;
|
|
266
271
|
s && (m = p.filter(s));
|
|
267
|
-
let h =
|
|
272
|
+
let h = Ce(m, l, i, !0), g = l.map((e) => ({
|
|
268
273
|
codeKey: e.codeKey,
|
|
269
274
|
count: h[e.codeKey].length
|
|
270
275
|
})).sort((e, t) => e.count - t.count);
|
|
@@ -279,16 +284,16 @@ function We(e) {
|
|
|
279
284
|
};
|
|
280
285
|
},
|
|
281
286
|
enabled: !!(!p && d && t && n && b),
|
|
282
|
-
meta:
|
|
287
|
+
meta: P,
|
|
283
288
|
staleTime: 1e3 * 60 * 60 * 2,
|
|
284
289
|
gcTime: 1e3 * 60 * 60 * 1,
|
|
285
|
-
select: a === !1 ?
|
|
290
|
+
select: a === !1 ? Re : void 0
|
|
286
291
|
});
|
|
287
292
|
}
|
|
288
293
|
//#endregion
|
|
289
294
|
//#region src/odata/useODataCollection.ts
|
|
290
|
-
function
|
|
291
|
-
let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } =
|
|
295
|
+
function We({ odata: e, model: t, pageSize: n = 50 }) {
|
|
296
|
+
let { codeKey: r, maxVisibleItems: i } = t, { data: a, isLoading: o, isError: s, refetch: c } = Ue(e), l = a?.keyPairsMap[r] ?? "", u = N(), [d, f] = j(), p = xe(/* @__PURE__ */ new Map()), { itemsMap: m, separatedItems: h, orderedKeys: g } = A(() => {
|
|
292
297
|
let e = /* @__PURE__ */ new Map(), t = [], n = [];
|
|
293
298
|
if (a && a.separated[r]) {
|
|
294
299
|
n = a.separated[r];
|
|
@@ -302,7 +307,7 @@ function Ge({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
302
307
|
separatedItems: n,
|
|
303
308
|
orderedKeys: t
|
|
304
309
|
};
|
|
305
|
-
}, [a, r]), _ =
|
|
310
|
+
}, [a, r]), _ = O((e) => {
|
|
306
311
|
let t = a?.separated[r];
|
|
307
312
|
if (!t) return /* @__PURE__ */ new Map();
|
|
308
313
|
let n = /* @__PURE__ */ new Map();
|
|
@@ -314,11 +319,11 @@ function Ge({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
314
319
|
}
|
|
315
320
|
}
|
|
316
321
|
return n;
|
|
317
|
-
}, [a, r]), v =
|
|
322
|
+
}, [a, r]), v = O((e) => {
|
|
318
323
|
f(() => {
|
|
319
324
|
if (e?.length) return new Set(e.map((e) => e[r]));
|
|
320
325
|
});
|
|
321
|
-
}, [r]), y =
|
|
326
|
+
}, [r]), y = O((e, t) => {
|
|
322
327
|
if (!g.length) return [];
|
|
323
328
|
let n = i, a = /* @__PURE__ */ new Set(), o = [];
|
|
324
329
|
if (t?.length) for (let e = 0; e < t.length; e++) a.add(t[e][r]);
|
|
@@ -338,26 +343,26 @@ function Ge({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
338
343
|
m,
|
|
339
344
|
d,
|
|
340
345
|
l
|
|
341
|
-
]), b =
|
|
346
|
+
]), b = O((e) => {
|
|
342
347
|
let t = a?.separated[r] || [], i = e * n, o = i + n;
|
|
343
348
|
return t.slice(i, o);
|
|
344
349
|
}, [
|
|
345
350
|
a,
|
|
346
351
|
n,
|
|
347
352
|
r
|
|
348
|
-
]), x =
|
|
353
|
+
]), x = O((e, t) => {
|
|
349
354
|
if (!a) return [];
|
|
350
355
|
let n = new Set(t);
|
|
351
356
|
return a.items.filter((t) => n.has(t[e]));
|
|
352
|
-
}, [a]), S =
|
|
357
|
+
}, [a]), S = O((e, t, n = 200) => {
|
|
353
358
|
p.current.has(e) && clearTimeout(p.current.get(e));
|
|
354
359
|
let r = setTimeout(t, n);
|
|
355
360
|
p.current.set(e, r);
|
|
356
|
-
}, []), C =
|
|
361
|
+
}, []), C = O(() => {
|
|
357
362
|
for (let e of p.current.values()) clearTimeout(e);
|
|
358
363
|
p.current.clear();
|
|
359
364
|
}, []);
|
|
360
|
-
return
|
|
365
|
+
return A(() => () => {
|
|
361
366
|
C();
|
|
362
367
|
}, [C]), {
|
|
363
368
|
data: a,
|
|
@@ -375,20 +380,20 @@ function Ge({ odata: e, model: t, pageSize: n = 50 }) {
|
|
|
375
380
|
separatedItems: h,
|
|
376
381
|
orderedKeys: g,
|
|
377
382
|
refetch: c,
|
|
378
|
-
invalidate: () => u.invalidateQueries({ queryKey:
|
|
383
|
+
invalidate: () => u.invalidateQueries({ queryKey: F(e) }),
|
|
379
384
|
totalCount: a?.separated[r]?.length || 0,
|
|
380
385
|
pageSize: n
|
|
381
386
|
};
|
|
382
387
|
}
|
|
383
388
|
//#endregion
|
|
384
389
|
//#region src/odata/useODataCollectionChains.ts
|
|
385
|
-
function
|
|
386
|
-
let t =
|
|
387
|
-
return
|
|
390
|
+
function Ge(e) {
|
|
391
|
+
let t = N(), [n, r] = j({}), i = A(() => e.map((e) => F(e)), [e]);
|
|
392
|
+
return k(() => {
|
|
388
393
|
function n() {
|
|
389
394
|
let n = {};
|
|
390
395
|
for (let r of e) {
|
|
391
|
-
let e =
|
|
396
|
+
let e = F(r), i = t.getQueryData(e);
|
|
392
397
|
i?.chain && (n[`${r.service}.${r.target}`] = i.chain);
|
|
393
398
|
}
|
|
394
399
|
r((e) => Object.keys(e).length === Object.keys(n).length && Object.entries(n).every(([t, n]) => e[t] === n) ? e : n);
|
|
@@ -407,9 +412,9 @@ function Ke(e) {
|
|
|
407
412
|
}
|
|
408
413
|
//#endregion
|
|
409
414
|
//#region src/odata/useODataCollectionModel.ts
|
|
410
|
-
function
|
|
411
|
-
let [t] =
|
|
412
|
-
let t =
|
|
415
|
+
function Ke(e) {
|
|
416
|
+
let [t] = j(() => {
|
|
417
|
+
let t = we.getState(), { codeKey: n, maxVisibleItems: r = t.defaultMaxVisibleItems, minSearchCodeLength: i = t.defaultMinSearchCodeLength, minSearchTextLength: a = t.defaultMinSearchTextLength, searchDebounceDelay: o = t.defaultSearchDebounceDelay } = e;
|
|
413
418
|
return {
|
|
414
419
|
codeKey: n,
|
|
415
420
|
maxVisibleItems: r,
|
|
@@ -422,31 +427,31 @@ function qe(e) {
|
|
|
422
427
|
}
|
|
423
428
|
//#endregion
|
|
424
429
|
//#region src/odata/useODataTableColumns.ts
|
|
425
|
-
function
|
|
430
|
+
function qe(e, t) {
|
|
426
431
|
let n = {}, r = (e) => {
|
|
427
432
|
for (let i of e) {
|
|
428
433
|
if ("columns" in i && Array.isArray(i.columns) && i.columns.length > 0) {
|
|
429
434
|
r(i.columns);
|
|
430
435
|
continue;
|
|
431
436
|
}
|
|
432
|
-
let e =
|
|
437
|
+
let e = ke(i);
|
|
433
438
|
!e || !(e in t) || (n[e] = t[e]);
|
|
434
439
|
}
|
|
435
440
|
};
|
|
436
441
|
return r(e), n;
|
|
437
442
|
}
|
|
438
|
-
function
|
|
443
|
+
function Je(e) {
|
|
439
444
|
let { metadata: t, isLoading: n } = K(e);
|
|
440
445
|
return {
|
|
441
|
-
columns:
|
|
446
|
+
columns: A(() => t ? e.mode === "build" ? De(t.columns, {
|
|
442
447
|
resolveHeader: e.resolveHeader,
|
|
443
448
|
resolveFormatting: e.resolveFormatting
|
|
444
|
-
}) :
|
|
445
|
-
defaultColumnVisibility:
|
|
449
|
+
}) : Oe(e.columns, t.columns) : e.mode === "build" ? [] : [...e.columns], [e, t]),
|
|
450
|
+
defaultColumnVisibility: A(() => {
|
|
446
451
|
if (!t) return;
|
|
447
|
-
if (e.mode === "build") return
|
|
448
|
-
let n =
|
|
449
|
-
return
|
|
452
|
+
if (e.mode === "build") return Ee(t.columns, { resolveVisible: e.resolveVisible });
|
|
453
|
+
let n = Ee(t.columns);
|
|
454
|
+
return qe(e.columns, n);
|
|
450
455
|
}, [e, t]),
|
|
451
456
|
metadata: t,
|
|
452
457
|
isLoading: n
|
|
@@ -454,10 +459,10 @@ function Ye(e) {
|
|
|
454
459
|
}
|
|
455
460
|
//#endregion
|
|
456
461
|
//#region src/odata/odataFetchFnDev.ts
|
|
457
|
-
function
|
|
462
|
+
function Ye() {
|
|
458
463
|
return globalThis.console;
|
|
459
464
|
}
|
|
460
|
-
function
|
|
465
|
+
function Xe(e) {
|
|
461
466
|
let t = {};
|
|
462
467
|
return new Headers(e).forEach((e, n) => {
|
|
463
468
|
t[n] = e;
|
|
@@ -473,32 +478,32 @@ function Ze(e) {
|
|
|
473
478
|
}
|
|
474
479
|
}
|
|
475
480
|
}
|
|
476
|
-
function
|
|
481
|
+
function Qe(e) {
|
|
477
482
|
return e !== void 0 && !["GET", "HEAD"].includes(e.toUpperCase());
|
|
478
483
|
}
|
|
479
|
-
function
|
|
484
|
+
function $e(e) {
|
|
480
485
|
return (e.baseUrl ?? "odata") !== "" || e.path.startsWith("/sap/") || e.path.startsWith("/sap-dp0/");
|
|
481
486
|
}
|
|
482
|
-
function
|
|
487
|
+
function et(e, t) {
|
|
483
488
|
let n = t.toLowerCase();
|
|
484
489
|
return Object.keys(e).some((e) => e.toLowerCase() === n);
|
|
485
490
|
}
|
|
486
491
|
function Z(e, t, n) {
|
|
487
|
-
|
|
488
|
-
}
|
|
489
|
-
function et(e) {
|
|
490
|
-
let t = Y(e.init.headers), n = e.init.method, r = Qe(e);
|
|
491
|
-
return Z(t, "DataServiceVersion", "2.0"), Z(t, "MaxDataServiceVersion", "2.0"), Z(t, "Accept", "application/json"), t["sap-language"] = "ru", r && (t["sap-contextid-accept"] = "header"), X(n) && e.init.body && Z(t, "Content-Type", "application/json"), X(n) && r && Z(t, "x-csrf-token", "<получается отдельным GET перед реальным write-запросом>"), t;
|
|
492
|
+
et(e, t) || (e[t] = n);
|
|
492
493
|
}
|
|
493
494
|
function tt(e) {
|
|
494
|
-
|
|
495
|
+
let t = Xe(e.init.headers), n = e.init.method, r = $e(e);
|
|
496
|
+
return Z(t, "DataServiceVersion", "2.0"), Z(t, "MaxDataServiceVersion", "2.0"), Z(t, "Accept", "application/json"), t["sap-language"] = "ru", r && (t["sap-contextid-accept"] = "header"), Qe(n) && e.init.body && Z(t, "Content-Type", "application/json"), Qe(n) && r && Z(t, "x-csrf-token", "<получается отдельным GET перед реальным write-запросом>"), t;
|
|
497
|
+
}
|
|
498
|
+
function nt(e) {
|
|
499
|
+
return ce(e) ? "FunctionImport" : e.result ? "Parameterized Entity" : "Entity";
|
|
495
500
|
}
|
|
496
501
|
function Q(e, t) {
|
|
497
|
-
let n =
|
|
502
|
+
let n = Ye();
|
|
498
503
|
n.groupCollapsed(e), n.info(t), n.groupEnd();
|
|
499
504
|
}
|
|
500
|
-
function
|
|
501
|
-
let t =
|
|
505
|
+
function rt(e) {
|
|
506
|
+
let t = Ye(), n = Ze(e.request.init.body), r = Xe(e.request.init.headers), i = tt(e.request), a = {
|
|
502
507
|
method: e.request.init.method,
|
|
503
508
|
headers: r,
|
|
504
509
|
body: n,
|
|
@@ -508,7 +513,7 @@ function nt(e) {
|
|
|
508
513
|
helper: e.helperName,
|
|
509
514
|
operation: e.operation,
|
|
510
515
|
target: e.odata.target,
|
|
511
|
-
targetKind:
|
|
516
|
+
targetKind: nt(e.target),
|
|
512
517
|
service: e.odata.service,
|
|
513
518
|
realFetch: "не выполнялся"
|
|
514
519
|
}]), t.info("Итоговый URL:", e.request.fullUrl), t.info("Path без base URL:", e.request.path), t.info("Target path до query options:", e.targetPath), t.info("Query string:", e.request.queryString || "<пусто>"), t.info("Body:", n ?? "<пусто>"), t.info("Auto parse:", e.autoParse ?? !1), t.info("Transform:", e.hasTransform ? "передан, но не вызывается без ответа backend" : "не передан"), t.info("Dry-run result:", e.operation === "query" ? {
|
|
@@ -516,20 +521,20 @@ function nt(e) {
|
|
|
516
521
|
totalCount: 0
|
|
517
522
|
} : { data: void 0 }), Q("OData config", e.odata), Q("Target metadata", e.target), Q("Target params", e.params), Q("Query options", e.queryOptions), Q("RequestInit, переданный в transport", a), Q("Заголовки после transport defaults (без реального fetch)", i), t.groupEnd();
|
|
518
523
|
}
|
|
519
|
-
function
|
|
520
|
-
|
|
524
|
+
function it(e) {
|
|
525
|
+
Ae.warning(`${e}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, { title: "OData DEV helper" });
|
|
521
526
|
}
|
|
522
527
|
function $(t, n, r) {
|
|
523
528
|
let { odata: i, options: a = {}, init: o = {}, autoParse: s, swCache: c } = n, l = n.params ?? {};
|
|
524
529
|
return async ({ client: u, signal: d }) => {
|
|
525
|
-
|
|
526
|
-
let f = e(i.service, a.baseUrl), p = await
|
|
530
|
+
it(r);
|
|
531
|
+
let f = e(i.service, a.baseUrl), p = await T({
|
|
527
532
|
service: i.service,
|
|
528
533
|
baseUrl: f
|
|
529
534
|
}, u);
|
|
530
535
|
if (!p) throw Error(`Не удалось загрузить metadata OData-сервиса '${i.service}'`);
|
|
531
|
-
let m =
|
|
532
|
-
|
|
536
|
+
let m = he(p, i.target);
|
|
537
|
+
fe(m, t, i);
|
|
533
538
|
let h = ie(n.body, t), g = ae(m, t), _ = re(m, i, l, t), v = c ? {
|
|
534
539
|
...a,
|
|
535
540
|
baseUrl: f,
|
|
@@ -543,7 +548,7 @@ function $(t, n, r) {
|
|
|
543
548
|
body: h,
|
|
544
549
|
signal: d
|
|
545
550
|
});
|
|
546
|
-
return
|
|
551
|
+
return rt({
|
|
547
552
|
helperName: r,
|
|
548
553
|
operation: t,
|
|
549
554
|
odata: i,
|
|
@@ -562,25 +567,25 @@ function $(t, n, r) {
|
|
|
562
567
|
} : { data: void 0 };
|
|
563
568
|
};
|
|
564
569
|
}
|
|
565
|
-
function it(e) {
|
|
566
|
-
return __DEV__ ? $("create", e, "odataCreateFnDev") : T("create", e);
|
|
567
|
-
}
|
|
568
570
|
function at(e) {
|
|
569
|
-
return __DEV__ ? $("
|
|
571
|
+
return __DEV__ ? $("create", e, "odataCreateFnDev") : E("create", e);
|
|
570
572
|
}
|
|
571
573
|
function ot(e) {
|
|
572
|
-
return __DEV__ ? $("
|
|
574
|
+
return __DEV__ ? $("update", e, "odataUpdateFnDev") : E("update", e);
|
|
573
575
|
}
|
|
574
576
|
function st(e) {
|
|
575
|
-
return __DEV__ ? $("
|
|
577
|
+
return __DEV__ ? $("delete", e, "odataDeleteFnDev") : E("delete", e);
|
|
576
578
|
}
|
|
577
579
|
function ct(e) {
|
|
578
|
-
return __DEV__ ? $("
|
|
580
|
+
return __DEV__ ? $("read", e, "odataReadFnDev") : E("read", e);
|
|
579
581
|
}
|
|
580
582
|
function lt(e) {
|
|
581
|
-
return __DEV__ ? $("
|
|
583
|
+
return __DEV__ ? $("query", e, "odataQueryFnDev") : E("query", e);
|
|
584
|
+
}
|
|
585
|
+
function ut(e) {
|
|
586
|
+
return __DEV__ ? $("fi", e, "odataFunctionImportFnDev") : E("fi", e);
|
|
582
587
|
}
|
|
583
588
|
//#endregion
|
|
584
|
-
export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap,
|
|
589
|
+
export { h as BaseAppConfigURL, f as BaseODataDp0URL, l as BaseODataUI2URL, c as BaseODataURL, n as BaseUrlMap, z as ODATA_COLLECTION_BUST_SW_CACHE, R as ODATA_COLLECTION_DEFAULT_SW_CACHE, L as ODATA_COLLECTION_UPDATES_LOOKBACK_MS, B as ODATA_COLLECTION_UPDATES_SW_CACHE, d as SsoRequiredError, le as applyODataMetadataVersion, i as configureODataProjectAdapter, Me as createODataCollectionBaseQueryKey, F as createODataCollectionQueryKey, V as createODataCollectionUpdatesQueryKey, v as fetchBase, p as fetchDeleteFn, g as fetchJson, u as fetchJsonMutationFn, r as fetchJsonQueryFn, oe as fetchMetadata, U as fetchODataCollectionUpdates, m as fetchODataJson, _ as fetchQueryFn, Ne as flattenODataDependentServices, b as getInputUrl, T as getODataMetadataData, S as getODataProjectAdapter, a as isNoContentResponse, y as isSsoForm, t as normalizeODataServiceName, C as normalizeRelativePath, W as odataCollectionUpdatesQueryOptions, me as odataCreateFn, at as odataCreateFnDev, ue as odataDeleteFn, st as odataDeleteFnDev, D as odataFetch, se as odataFunctionImportFn, ut as odataFunctionImportFnDev, ee as odataMetadataQueryOptions, te as odataQueryFn, lt as odataQueryFnDev, de as odataReadFn, ct as odataReadFnDev, pe as odataUpdateFn, ot as odataUpdateFnDev, o as recoverSsoSession, e as resolveODataBaseUrl, Y as resolveODataCollectionSwCachePolicy, x as resolveODataSapClient, He as shouldRefreshODataCollectionCache, Pe as sortODataDependentSegmentItemsByChains, Ie as sortODataDependentServicesByChains, s as submitSsoForm, We as useODataCollection, Ge as useODataCollectionChains, Ke as useODataCollectionModel, Ue as useODataCollectionQuery, G as useODataCollectionUpdatesQuery, J as useODataEntity, K as useODataMetadata, ge as useODataMetadataQuery, _e as useODataMetadataVersionQuery, Je as useODataTableColumns };
|
|
585
590
|
|
|
586
591
|
//# sourceMappingURL=index.js.map
|
package/dist/odata/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/odata/createODataCollectionQueryKey.ts","../../src/odata/flattenODataDependentServices.ts","../../src/odata/sortODataDependentSegmentItemsByChains.ts","../../src/odata/sortODataDependentServicesByChains.ts","../../src/odata/fetchCollectionData.ts","../../src/odata/projectODataCollectionSort.ts","../../src/odata/useODataCollectionUpdatesQuery.ts","../../src/odata/useODataMetadata.ts","../../src/odata/useODataEntity.ts","../../src/odata/useODataCollectionQuery.ts","../../src/odata/useODataCollection.ts","../../src/odata/useODataCollectionChains.ts","../../src/odata/useODataCollectionModel.ts","../../src/odata/useODataTableColumns.ts","../../src/odata/odataFetchFnDev.ts"],"sourcesContent":["import { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\n/**\n * Версия формы persisted collection snapshot.\n *\n * Версия 2 отделяет прежние записи, порядок `separated` которых зависел от\n * первого consumer, от новой канонической сортировки по code.\n */\nconst ODATA_COLLECTION_QUERY_VERSION = 2;\n\nexport const createODataCollectionBaseQueryKey = () => [...odataBaseQueryKey, \"collection\"] as const;\n\nexport const createODataCollectionQueryKey = ({ service, target, limitedKeys, serverFilter }: ODataServiceCollectionConfig) =>\n\t[\n\t\t...createODataCollectionBaseQueryKey(),\n\t\t{ version: ODATA_COLLECTION_QUERY_VERSION, service, target, limitedKeys, serverFilter }\n\t] as const;\n","import type { ODataDependentBaseProps, ODataDependentSegmentItem } from \"./types\";\n\n/**\n * Разворачивает зависимые OData-сервисы в плоский список segment-level элементов.\n */\nexport function flattenODataDependentServices(services: readonly ODataDependentBaseProps[]): ODataDependentSegmentItem[] {\n\tconst out: ODataDependentSegmentItem[] = [];\n\n\tfor (const [serviceIndex, service] of services.entries()) {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\n\t\tfor (const [segmentIndex, [id, segment]] of Object.entries(service.segments).entries()) {\n\t\t\tout.push({\n\t\t\t\tid,\n\t\t\t\tserviceKey,\n\t\t\t\tserviceIndex,\n\t\t\t\tsegmentIndex,\n\t\t\t\todata: service.odata,\n\t\t\t\tsegment,\n\t\t\t\tmodel: {\n\t\t\t\t\t...service.model,\n\t\t\t\t\tcodeKey: id\n\t\t\t\t},\n\t\t\t\tpanelVisibility: segment.panelVisibility ?? \"user\"\n\t\t\t});\n\t\t}\n\t}\n\n\treturn out;\n}\n","import { ODataDependentSegmentItem } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Сортирует плоские segment-level элементы по chain-порядку\n * и опционально накладывает пользовательский override.\n */\nexport function sortODataDependentSegmentItemsByChains(\n\titems: readonly ODataDependentSegmentItem[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentSegmentItem[] {\n\tconst chainOrderByService = new Map<string, Map<string, number>>();\n\n\tfor (const [serviceKey, chain] of Object.entries(chains)) {\n\t\tchainOrderByService.set(serviceKey, new Map(chain.map((item, index) => [item.codeKey, index])));\n\t}\n\n\tconst baseOrdered = [...items]\n\t\t.map((item, index) => ({\n\t\t\titem,\n\t\t\tindex\n\t\t}))\n\t\t.sort((left, right) => {\n\t\t\tif (left.item.serviceIndex !== right.item.serviceIndex) {\n\t\t\t\treturn left.item.serviceIndex - right.item.serviceIndex;\n\t\t\t}\n\n\t\t\tconst chainOrder = chainOrderByService.get(left.item.serviceKey);\n\t\t\tconst leftChainOrder = chainOrder?.get(left.item.id);\n\t\t\tconst rightChainOrder = chainOrder?.get(right.item.id);\n\n\t\t\tif (leftChainOrder !== undefined && rightChainOrder !== undefined) {\n\t\t\t\treturn leftChainOrder - rightChainOrder;\n\t\t\t}\n\t\t\tif (leftChainOrder !== undefined) return -1;\n\t\t\tif (rightChainOrder !== undefined) return 1;\n\n\t\t\tif (left.item.segmentIndex !== right.item.segmentIndex) {\n\t\t\t\treturn left.item.segmentIndex - right.item.segmentIndex;\n\t\t\t}\n\n\t\t\treturn left.index - right.index;\n\t\t});\n\n\tif (!orderOverrideIds?.length) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst availableIds = new Set(baseOrdered.map(({ item }) => item.id));\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => availableIds.has(id));\n\tif (normalizedOverride.length === 0) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\n\treturn [...baseOrdered]\n\t\t.sort((left, right) => {\n\t\t\tconst leftOverrideRank = overrideRank.get(left.item.id);\n\t\t\tconst rightOverrideRank = overrideRank.get(right.item.id);\n\n\t\t\tif (leftOverrideRank !== undefined && rightOverrideRank !== undefined) {\n\t\t\t\treturn leftOverrideRank - rightOverrideRank;\n\t\t\t}\n\t\t\tif (leftOverrideRank !== undefined) return -1;\n\t\t\tif (rightOverrideRank !== undefined) return 1;\n\n\t\t\treturn left.index - right.index;\n\t\t})\n\t\t.map(({ item }) => item);\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { ODataDependentBaseProps } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Применяет пользовательский override порядка сегментов поверх уже рассчитанного базового порядка.\n *\n * Алгоритм:\n * 1. берёт только валидные id из `orderOverrideIds` (без дублей);\n * 2. поднимает эти id в начало в указанной последовательности;\n * 3. все остальные сегменты оставляет в исходном относительном порядке.\n */\nfunction applySegmentsOrderOverride(\n\tservices: readonly ODataDependentBaseProps[],\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tif (!orderOverrideIds?.length) return [...services];\n\n\tconst visibleIds = new Set<string>();\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tvisibleIds.add(segmentId);\n\t\t}\n\t}\n\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => visibleIds.has(id));\n\tif (normalizedOverride.length === 0) return [...services];\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\tconst fallbackRankStart = normalizedOverride.length;\n\tconst segmentRank = new Map<string, number>();\n\tlet fallbackRank = fallbackRankStart;\n\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tif (segmentRank.has(segmentId)) continue;\n\t\t\tsegmentRank.set(segmentId, overrideRank.get(segmentId) ?? fallbackRank++);\n\t\t}\n\t}\n\n\tconst withOrderedSegments = services.map((service) => {\n\t\tconst orderedEntries = Object.entries(service.segments).sort(\n\t\t\t([leftId], [rightId]) =>\n\t\t\t\t(segmentRank.get(leftId) ?? Number.MAX_SAFE_INTEGER) - (segmentRank.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t\t);\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn [...withOrderedSegments].sort((leftService, rightService) => {\n\t\tconst leftFirstSegmentId = Object.keys(leftService.segments)[0];\n\t\tconst rightFirstSegmentId = Object.keys(rightService.segments)[0];\n\t\tconst leftRank = leftFirstSegmentId ? (segmentRank.get(leftFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\t\tconst rightRank = rightFirstSegmentId ? (segmentRank.get(rightFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\n\t\treturn leftRank - rightRank;\n\t});\n}\n\n/**\n * Сортирует сегменты сервисов по chain-порядку (от меньшего к большему)\n * и опционально накладывает пользовательский override.\n *\n * Если chain недоступен, сохраняет исходный порядок сегментов.\n *\n * @deprecated функционал должен быть вырезан и оставлен только с `sortODataDependentSegmentItemsByChains`\n */\nexport function sortODataDependentServicesByChains(\n\tservices: readonly ODataDependentBaseProps[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tconst sortedByChains = services.map((service) => {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\t\tconst chain = chains[serviceKey];\n\t\tif (!chain?.length) return service;\n\n\t\tconst chainOrder = new Map(chain.map((item, index) => [item.codeKey, index]));\n\t\tconst orderedEntries = Object.entries(service.segments).sort(([leftId], [rightId]) => {\n\t\t\tconst leftOrder = chainOrder.get(leftId);\n\t\t\tconst rightOrder = chainOrder.get(rightId);\n\n\t\t\tif (leftOrder !== undefined && rightOrder !== undefined) return leftOrder - rightOrder;\n\t\t\tif (leftOrder !== undefined) return -1;\n\t\t\tif (rightOrder !== undefined) return 1;\n\t\t\treturn compareStrings(leftId, rightId);\n\t\t});\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn applySegmentsOrderOverride(sortedByChains, orderOverrideIds);\n}\n","import { type CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { odataFetch, type ODataFetchOptions } from \"./odataFetch\";\nimport { isNoContentResponse } from \"./transport\";\n\n// Тип для результата запроса справочника\ninterface ODataServiceResult<T extends CollectionItem> {\n\titems: T[];\n}\n\n/**\n * Загрузка данных справочника из OData сервиса\n */\nexport async function fetchCollectionData<T extends CollectionItem>(params: {\n\turl: string;\n\tquery?: ODataFetchOptions<T>;\n\tsignal: AbortSignal;\n}): Promise<ODataServiceResult<T>> {\n\tconst { url, query, signal } = params;\n\n\ttry {\n\t\t// Загружаем данные из OData сервиса\n\t\tconst response = await odataFetch<T, T[]>(url, query, { signal });\n\n\t\t// Считаем отсутствие данных ошибкой, ведь query запрос обязан вернуть корректное тело json\n\t\tif (isNoContentResponse(response)) {\n\t\t\tthrow new Error(\"отсутствует тело ответа\");\n\t\t}\n\n\t\tconst data = response.data;\n\n\t\t// Удаление ненужных полей.\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars\n\t\t\titems: data.map(({ ID, CNT, __metadata, __Parameters, ...item }) => item as T) /*, pairs, pairsMap */\n\t\t};\n\t} catch (error) {\n\t\tlogError(\"Ошибка загрузки справочника:\", error);\n\t\t// throw error;\n\n\t\treturn { items: [] };\n\t}\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport type { ODataCollectionResult } from \"./useODataCollectionQuery\";\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\n/**\n * Создаёт observer-проекцию канонического справочника с сортировкой по text.\n *\n * Query cache и persistence продолжают хранить один code-sorted snapshot.\n * Проекция копирует только массивы ссылок в `separated`: исходные строки,\n * объекты элементов, `items`, `chain` и metadata остаются общими.\n */\nexport function projectODataCollectionSortByText<T extends CollectionItem>(source: ODataCollectionResult<T>): ODataCollectionResult<T> {\n\tlet hasProjectedLevel = false;\n\tconst separated = Object.fromEntries(\n\t\tObject.entries(source.separated).map(([codeKey, items]) => {\n\t\t\tconst textKey = source.keyPairsMap[codeKey];\n\t\t\tif (!textKey || items.length < 2) {\n\t\t\t\treturn [codeKey, items];\n\t\t\t}\n\n\t\t\thasProjectedLevel = true;\n\t\t\treturn [codeKey, [...items].sort((left, right) => compareStrings(String(left[textKey] ?? \"\"), String(right[textKey] ?? \"\")))];\n\t\t})\n\t) as Record<string, T[]>;\n\n\tif (!hasProjectedLevel) {\n\t\treturn source;\n\t}\n\n\treturn {\n\t\t...source,\n\t\tseparated\n\t};\n}\n","import { parseDate } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { queryOptions, useQuery } from \"@tanstack/react-query\";\n\nimport { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { odataFetch } from \"./odataFetch\";\nimport { getODataProjectAdapter, resolveODataBaseUrl } from \"./odataProjectAdapter\";\n\nconst COLLECTION_UPDATES_BUILD_ID = __APP_BUILD_ID__;\nconst COLLECTION_UPDATES_STALE_TIME = 1000 * 60 * 60 * 4;\nexport const ODATA_COLLECTION_UPDATES_LOOKBACK_MS = 1000 * 60 * 60 * 24 * 7;\nexport const ODATA_COLLECTION_DEFAULT_SW_CACHE = \"ttl=forever;name=ref\";\nexport const ODATA_COLLECTION_BUST_SW_CACHE = \"bust=forever;name=ref\";\nexport const ODATA_COLLECTION_UPDATES_SW_CACHE = \"ttl=4h;name=ref-updates\";\n\ninterface ODataCollectionUpdateRecord {\n\tentityName: string;\n\tlastChanged: string;\n}\n\nexport interface ODataCollectionUpdateItem extends ODataCollectionUpdateRecord {\n\tlastChangedAt: Date | null;\n}\n\nexport interface ODataCollectionUpdatesResult {\n\titems: ODataCollectionUpdateItem[];\n\tbyEntityName: Record<string, ODataCollectionUpdateItem>;\n\tfetchedAt: number;\n\tcoverageStartedAt: number;\n}\n\nexport interface ODataCollectionUpdatesOptions {\n\tstaleTime?: number;\n}\n\nexport const createODataCollectionUpdatesQueryKey = () =>\n\t[...odataBaseQueryKey, \"collection-updates\", { buildId: COLLECTION_UPDATES_BUILD_ID }] as const;\n\nfunction normalizeCollectionUpdateRecord(record: ODataCollectionUpdateRecord): ODataCollectionUpdateItem {\n\treturn {\n\t\t...record,\n\t\tlastChangedAt: parseDate(record.lastChanged)\n\t};\n}\n\nfunction normalizeCollectionUpdates(records: ODataCollectionUpdateRecord[], fetchedAt: number): ODataCollectionUpdatesResult {\n\tconst items = records.map(normalizeCollectionUpdateRecord);\n\tconst byEntityName = items.reduce<Record<string, ODataCollectionUpdateItem>>((acc, item) => {\n\t\tif (item.entityName) {\n\t\t\tacc[item.entityName] = item;\n\t\t}\n\n\t\treturn acc;\n\t}, {});\n\n\treturn { items, byEntityName, fetchedAt, coverageStartedAt: fetchedAt - ODATA_COLLECTION_UPDATES_LOOKBACK_MS };\n}\n\n/**\n * Загружает компактный список справочников, изменённых за последние 7 дней.\n * Сам список живёт отдельно от данных справочников и управляет их точечной инвалидацией.\n */\nexport function fetchODataCollectionUpdates() {\n\treturn async ({ signal }: { signal: AbortSignal }): Promise<ODataCollectionUpdatesResult> => {\n\t\tconst requestStartedAt = Date.now();\n\t\tconst endpoint = getODataProjectAdapter().collectionUpdates;\n\t\tif (!endpoint) return normalizeCollectionUpdates([], requestStartedAt);\n\n\t\tconst response = await odataFetch<ODataCollectionUpdateRecord, ODataCollectionUpdateRecord[]>(\n\t\t\t`/${endpoint.service}/${endpoint.target}`,\n\t\t\t{\n\t\t\t\tbaseUrl: resolveODataBaseUrl(endpoint.service, endpoint.baseUrl),\n\t\t\t\tswCache: ODATA_COLLECTION_UPDATES_SW_CACHE\n\t\t\t},\n\t\t\t{ signal }\n\t\t);\n\n\t\treturn normalizeCollectionUpdates(response.data, Math.max(requestStartedAt, Date.now()));\n\t};\n}\n\n/**\n * Описывает общий TanStack Query со списком обновлённых справочников.\n * Query сохраняется в IndexedDB и дополнительно кешируется Service Worker на короткий TTL.\n *\n * При отсутствии endpoint queryFn возвращает пустой успешный результат без сетевого запроса.\n * Query должен оставаться активным, потому что зависимые справочники ждут его завершения.\n */\nexport const odataCollectionUpdatesQueryOptions = (options: ODataCollectionUpdatesOptions = {}) =>\n\tqueryOptions({\n\t\tqueryKey: createODataCollectionUpdatesQueryKey(),\n\t\tqueryFn: fetchODataCollectionUpdates(),\n\t\tmeta: persistedQueryMeta,\n\t\tstaleTime: options.staleTime ?? COLLECTION_UPDATES_STALE_TIME,\n\t\tgcTime: Infinity\n\t});\n\nexport function useODataCollectionUpdatesQuery(options: ODataCollectionUpdatesOptions = {}) {\n\treturn useQuery(odataCollectionUpdatesQueryOptions(options));\n}\n","import { useODataMetadataQuery } from \"./useODataMetadataQuery\";\n\nimport type { ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Возвращает metadata конкретной OData-сущности по имени сервиса и сущности.\n *\n * Хук не добавляет собственную бизнес-логику и служит публичной тонкой\n * прослойкой над `useODataMetadataQuery(...)`.\n */\nexport function useODataMetadata(odata: ODataServiceConfig) {\n\tconst { data, dataUpdatedAt = 0, isLoading, isLoadingError } = useODataMetadataQuery({ service: odata.service });\n\tconst metadata = data?.entities[odata.target];\n\n\tif (!isLoading && !metadata && data?.functionImports[odata.target]) {\n\t\tthrow new Error(`OData target '${odata.target}' является FunctionImport и не может использоваться как сущность`);\n\t}\n\n\tif (isLoadingError) {\n\t\tthrow new Error(`Ошибка загрузки метаданных сервиса ${odata.service}`);\n\t}\n\n\treturn { metadata, metadataUpdatedAt: dataUpdatedAt, isLoading };\n}\n","import { useMemo } from \"react\";\n\nimport { buildEntityPath, type ODataServiceConfig, type ODataValue } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nconst throwErrorText = \"Использование actions недопустимо до окончания загрузки metadata\";\n\n// function throwNoMetadata() {\n// \tif (__DEV__) {\n// \t\tthrow new Error(throwErrorText);\n// \t}\n// \treturn undefined;\n// }\n\nexport type ODataEntity = Omit<ReturnType<typeof useODataEntity>, \"isLoading\">;\n\nexport function useODataEntity(odata: ODataServiceConfig) {\n\tconst { metadata, metadataUpdatedAt, isLoading } = useODataMetadata(odata);\n\n\tconst actions = useMemo(() => {\n\t\tconst getEntityPath = (values: Record<string, ODataValue> = {}) => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn buildEntityPath(metadata, odata, values);\n\t\t};\n\t\tconst getKeys = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns?.map((c) => c.id);\n\t\t};\n\t\tconst getKeyPairs = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns\n\t\t\t\t?.filter((c) => c.semanticType === \"code\" && c.linkedColumnId)\n\t\t\t\t.map((c) => ({ codeKey: c.id, textKey: c.linkedColumnId }) as CollectionPair);\n\t\t};\n\t\tconst getKeyPairsMap = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\tconst pairs: Record<string, string> = {};\n\n\t\t\tfor (const column of metadata.columns ?? []) {\n\t\t\t\tif (column.semanticType === \"code\" && column.linkedColumnId) {\n\t\t\t\t\tpairs[column.id] = column.linkedColumnId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pairs;\n\t\t};\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Получить строку запроса `/service/entity(parameters)/Results`\n\t\t\t */\n\t\t\tgetEntityPath,\n\t\t\t/**\n\t\t\t * Получить все ключи сущности\n\t\t\t */\n\t\t\tgetKeys,\n\t\t\t/**\n\t\t\t * Получить список ключей в формате `{ codeKey, textKey }`\n\t\t\t */\n\t\t\tgetKeyPairs,\n\t\t\t/**\n\t\t\t * Получить словать ключей в формате `{ code: text }`\n\t\t\t */\n\t\t\tgetKeyPairsMap\n\t\t};\n\t}, [odata, metadata]);\n\n\treturn { config: odata, metadata, metadataUpdatedAt, isLoading, actions };\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { buildSeparatedArrays, type CollectionItem, type CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { useQuery, useQueryClient, UseQueryResult } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { fetchCollectionData } from \"./fetchCollectionData\";\nimport { projectODataCollectionSortByText } from \"./projectODataCollectionSort\";\nimport { ODataCollectionConfig } from \"./types\";\nimport {\n\tODATA_COLLECTION_BUST_SW_CACHE,\n\tODATA_COLLECTION_DEFAULT_SW_CACHE,\n\tODataCollectionUpdateItem,\n\tuseODataCollectionUpdatesQuery\n} from \"./useODataCollectionUpdatesQuery\";\nimport { useODataEntity } from \"./useODataEntity\";\n\nexport interface ODataCollectionResult<T extends CollectionItem> {\n\titems: T[];\n\tkeyPairs: CollectionPair[];\n\tkeyPairsMap: Record<string, string>;\n\t/**\n\t * Массивы элементов по уровням справочника.\n\t *\n\t * Query cache хранит канонический порядок по code, а конкретный observer\n\t * может получить проекцию по text. Один snapshot при этом переиспользуется\n\t * ракурсами с разными `sortByCode`.\n\t */\n\tseparated: Record<string, T[]>;\n\tchain: { codeKey: string; count: number }[];\n\tcount: number;\n\tcacheUpdatedAt: number;\n}\n\ninterface ODataCollectionCacheRefreshContext {\n\tupdate?: ODataCollectionUpdateItem;\n\tmetadataUpdatedAt?: number;\n\tupdatesCoverageStartedAt?: number;\n}\n\nexport function resolveODataCollectionSwCachePolicy(swCache: string, shouldBust: boolean) {\n\tif (!shouldBust) return swCache;\n\n\tconst normalized = swCache.trim().toLowerCase();\n\tif (normalized === \"off\" || normalized.startsWith(\"bust=\")) return swCache;\n\tif (normalized.startsWith(\"ttl=\")) return swCache.replace(/^\\s*ttl=/i, \"bust=\");\n\n\treturn ODATA_COLLECTION_BUST_SW_CACHE;\n}\n\nfunction isUsableTimestamp(value: number | undefined): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Определяет, нужно ли обновить конкретный справочник по списку изменений.\n * Сравнение идёт с cacheUpdatedAt, который сохраняется вместе с данными справочника.\n */\nexport function shouldRefreshODataCollectionCache<T extends CollectionItem>(\n\tcontext: ODataCollectionCacheRefreshContext,\n\tcachedData: ODataCollectionResult<T> | undefined\n) {\n\tconst cacheUpdatedAt = cachedData?.cacheUpdatedAt ?? 0;\n\tconst updateChangedAt = context.update?.lastChangedAt?.getTime();\n\n\tif (isUsableTimestamp(updateChangedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (updateChangedAt > cacheUpdatedAt) return true;\n\t}\n\n\tif (isUsableTimestamp(context.metadataUpdatedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (context.metadataUpdatedAt > cacheUpdatedAt) return true;\n\t}\n\n\t/**\n\t * Бэкенд отдаёт список изменений справочников только за последнюю неделю.\n\t * Если локальный справочник старше этого окна, отсутствие target в списке\n\t * больше не доказывает актуальность, поэтому обновляем только открытый справочник.\n\t */\n\tif (isUsableTimestamp(context.updatesCoverageStartedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (cacheUpdatedAt < context.updatesCoverageStartedAt) return true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Универсальный хук для получения данных из OData сервиса.\n * Заменяет функционал TextDataService из SAP UI5.\n */\nexport function useODataCollectionQuery<T extends CollectionItem>(odata: ODataCollectionConfig): UseQueryResult<ODataCollectionResult<T>> {\n\tconst {\n\t\tservice,\n\t\ttarget,\n\t\tlimitedKeys,\n\t\texcludeEmpty,\n\t\tsortByCode,\n\t\tserverFilter,\n\t\tclientFilter,\n\t\tswCache = ODATA_COLLECTION_DEFAULT_SW_CACHE\n\t} = odata;\n\tconst queryClient = useQueryClient();\n\tconst { actions, metadata, metadataUpdatedAt, isLoading } = useODataEntity(odata);\n\tconst updatesQuery = useODataCollectionUpdatesQuery();\n\n\tconst queryKey = useMemo(\n\t\t() => createODataCollectionQueryKey({ service, target, limitedKeys, serverFilter }),\n\t\t[service, target, limitedKeys, serverFilter]\n\t);\n\tconst cachedData = queryClient.getQueryData<ODataCollectionResult<T>>(queryKey);\n\tconst collectionUpdate = updatesQuery.data?.byEntityName[target];\n\tconst shouldBustCollectionCache = shouldRefreshODataCollectionCache(\n\t\t{\n\t\t\tupdate: collectionUpdate,\n\t\t\tmetadataUpdatedAt,\n\t\t\tupdatesCoverageStartedAt: updatesQuery.data?.coverageStartedAt\n\t\t},\n\t\tcachedData\n\t);\n\tconst effectiveSwCache = resolveODataCollectionSwCachePolicy(swCache, shouldBustCollectionCache);\n\tconst updatesReady = updatesQuery.isError || (updatesQuery.isSuccess && !updatesQuery.isFetching);\n\n\tuseEffect(() => {\n\t\tif (!cachedData || !shouldBustCollectionCache) return;\n\n\t\tvoid queryClient.invalidateQueries({ queryKey });\n\t}, [cachedData, queryClient, queryKey, shouldBustCollectionCache]);\n\n\treturn useQuery({\n\t\tqueryKey,\n\t\tqueryFn: async ({ signal }) => {\n\t\t\tconst requestStartedAt = Date.now();\n\t\t\tconst selectKeys = limitedKeys ? [...limitedKeys] : actions.getKeys();\n\t\t\tconst keyPairs = actions.getKeyPairs();\n\t\t\tconst keyPairsMap = actions.getKeyPairsMap();\n\n\t\t\tif (limitedKeys) {\n\t\t\t\tfor (const k of limitedKeys) {\n\t\t\t\t\tconst keyText = keyPairsMap[k];\n\t\t\t\t\tif (keyText && !selectKeys.includes(keyText)) {\n\t\t\t\t\t\tselectKeys.push(keyText);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { items } = await fetchCollectionData<T>({\n\t\t\t\turl: `/${service}/${target}`,\n\t\t\t\tquery: {\n\t\t\t\t\tselect: selectKeys,\n\t\t\t\t\texpression: serverFilter,\n\t\t\t\t\tswCache: effectiveSwCache\n\t\t\t\t},\n\t\t\t\tsignal\n\t\t\t});\n\n\t\t\tlet filterdItems = items;\n\t\t\tif (clientFilter) {\n\t\t\t\tfilterdItems = items.filter(clientFilter);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Query cache хранит единую каноническую проекцию справочника.\n\t\t\t *\n\t\t\t * Сортировка конкретного контрола применяется observer-проекцией ниже,\n\t\t\t * чтобы два ракурса с разными `sortByCode` переиспользовали один snapshot,\n\t\t\t * а не конкурировали за его порядок и не дублировали всю коллекцию в памяти.\n\t\t\t */\n\t\t\tconst separated = buildSeparatedArrays<T>(filterdItems, keyPairs, excludeEmpty, true);\n\n\t\t\t// Рассчитать порядок от меньшего к большему\n\t\t\tconst chain = keyPairs\n\t\t\t\t.map((pair) => ({ codeKey: pair.codeKey, count: separated[pair.codeKey].length }))\n\t\t\t\t.sort((a, b) => a.count - b.count);\n\n\t\t\treturn {\n\t\t\t\titems: filterdItems,\n\t\t\t\tkeyPairs,\n\t\t\t\tkeyPairsMap,\n\t\t\t\tseparated,\n\t\t\t\tchain,\n\t\t\t\tcount: filterdItems.length,\n\t\t\t\tcacheUpdatedAt: Math.max(requestStartedAt, Date.now(), collectionUpdate?.lastChangedAt?.getTime() ?? 0, metadataUpdatedAt)\n\t\t\t};\n\t\t},\n\t\tenabled: Boolean(!isLoading && metadata && service && target && updatesReady),\n\t\tmeta: persistedQueryMeta,\n\t\t/**\n\t\t * Клиентский кеш можно держать не долго, чтобы он мог чаще дергать SW\n\t\t */\n\t\tstaleTime: 1000 * 60 * 60 * 2,\n\t\t/**\n\t\t * Если справочник не используется более часа, то можно из памяти выгрузить.\n\t\t */\n\t\tgcTime: 1000 * 60 * 60 * 1,\n\t\t/**\n\t\t * Сортировка является представлением observer, а не identity Query.\n\t\t * TanStack мемоизирует select-проекцию и не сохраняет её в общий cache.\n\t\t */\n\t\tselect: sortByCode === false ? projectODataCollectionSortByText<T> : undefined\n\t});\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataCollectionConfig, ODataCollectionModel } from \"./types\";\nimport { useODataCollectionQuery } from \"./useODataCollectionQuery\";\n\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\ninterface UseODataCollectionProps {\n\todata: ODataCollectionConfig;\n\tmodel: Required<ODataCollectionModel>;\n\n\t/**\n\t * Размер страницы для виртуализации.\n\t */\n\tpageSize?: number;\n\n\tfilter?: (item: CollectionItem) => boolean;\n}\n\nexport function useODataCollection({\n\todata,\n\tmodel,\n\t// filter,\n\tpageSize = 50\n}: UseODataCollectionProps) {\n\tconst { codeKey, maxVisibleItems } = model;\n\tconst { data: rawData, isLoading, isError, refetch } = useODataCollectionQuery(odata);\n\n\tconst textKey = rawData?.keyPairsMap[codeKey] ?? \"\";\n\n\t// Клиент для инвалидации запросов\n\tconst queryClient = useQueryClient();\n\n\tconst [filteredKeys, setFilteredKeys] = useState<Set<string>>();\n\n\tconst debounceTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n\t/**\n\t * itemsMap - индекс элементов для быстрого поиска\n\t * orderedKeys - упорядоченный список ключей для сохранения порядка\n\t */\n\tconst { itemsMap, separatedItems, orderedKeys } = useMemo(() => {\n\t\tconst itemsMap = new Map<string, CollectionItem>();\n\t\tconst orderedKeys = [] as string[];\n\t\tlet separatedItems: CollectionItem[] = [];\n\n\t\tif (rawData && rawData.separated[codeKey]) {\n\t\t\tseparatedItems = rawData.separated[codeKey];\n\n\t\t\tfor (const item of separatedItems) {\n\t\t\t\tconst key = item[codeKey];\n\t\t\t\tif (key) {\n\t\t\t\t\titemsMap.set(key, item);\n\t\t\t\t\torderedKeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { itemsMap, separatedItems, orderedKeys };\n\t}, [rawData, codeKey]);\n\n\t// Создание индекса поиска для текстовых полей\n\tconst buildSearchIndex = useCallback(\n\t\t(field: string) => {\n\t\t\tconst items = rawData?.separated[codeKey];\n\n\t\t\tif (!items) {\n\t\t\t\treturn new Map<string, Set<string>>();\n\t\t\t}\n\n\t\t\tconst index = new Map<string, Set<string>>();\n\n\t\t\t// Создаем индекс по префиксам для быстрого поиска\n\t\t\tfor (const item of items) {\n\t\t\t\tconst value = item[field]?.toLowerCase();\n\t\t\t\tif (!value) continue;\n\n\t\t\t\t// Индексируем по префиксам длиной 1-5 символов\n\t\t\t\tfor (let i = 1; i <= Math.min(5, value.length); i++) {\n\t\t\t\t\tconst prefix = value.substring(0, i);\n\t\t\t\t\tif (!index.has(prefix)) {\n\t\t\t\t\t\tindex.set(prefix, new Set<string>());\n\t\t\t\t\t}\n\t\t\t\t\tindex.get(prefix)!.add(item[codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn index;\n\t\t},\n\t\t[rawData, codeKey]\n\t);\n\n\t/**\n\t * Устанавливает несколько фильтров зависимостей.\n\t *\n\t * Сформированный список ключей пойдёт в фильтрацию элементов текущей коллекции по `codeKey`\n\t */\n\tconst setFilteredItems = useCallback(\n\t\t(filters: CollectionItem[] | undefined) => {\n\t\t\tsetFilteredKeys(() => {\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\treturn new Set(filters.map((item) => item[codeKey]));\n\t\t\t\t}\n\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t},\n\t\t[codeKey]\n\t);\n\n\tconst getItems = useCallback(\n\t\t(\n\t\t\tpredicate?: (codeValue: string, textValue: string) => boolean,\n\t\t\tcurrentSelectedKeys?: readonly CollectionItem[]\n\t\t): CollectionItem[] => {\n\t\t\tif (!orderedKeys.length) return [];\n\n\t\t\tconst limit = maxVisibleItems;\n\t\t\tconst selectedKeysSet = new Set<string>();\n\t\t\tconst resultItems: CollectionItem[] = [];\n\n\t\t\tif (currentSelectedKeys?.length) {\n\t\t\t\t// Быстрое заполнение Set без создания временного массива\n\t\t\t\tfor (let i = 0; i < currentSelectedKeys.length; i++) {\n\t\t\t\t\tselectedKeysSet.add(currentSelectedKeys[i][codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet count = 0;\n\n\t\t\tconst existsDependencies = filteredKeys && filteredKeys.size > 0;\n\n\t\t\t// Единый проход с ранним выходом по лимиту\n\t\t\tfor (const key of orderedKeys) {\n\t\t\t\tif (count >= limit) break;\n\n\t\t\t\tconst item = itemsMap.get(key);\n\t\t\t\tif (!item) continue;\n\n\t\t\t\t// Проверка на исключение выбранных ключей\n\t\t\t\tif (selectedKeysSet.size > 0 && selectedKeysSet.has(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemCode = item[codeKey];\n\n\t\t\t\tif (existsDependencies && !filteredKeys.has(itemCode)) continue;\n\n\t\t\t\t// Проверка внешнего предиката\n\t\t\t\tif (predicate && !predicate(itemCode, item[textKey])) continue;\n\n\t\t\t\tresultItems.push(item);\n\t\t\t\tcount++;\n\t\t\t}\n\n\t\t\treturn resultItems;\n\t\t},\n\t\t[orderedKeys, maxVisibleItems, codeKey, itemsMap, filteredKeys, textKey]\n\t);\n\n\t/**\n\t * Получает страницу данных для виртуализации.\n\t */\n\tconst getPage = useCallback(\n\t\t(pageIndex: number): CollectionItem[] => {\n\t\t\tconst allItems = rawData?.separated[codeKey] || [];\n\t\t\tconst start = pageIndex * pageSize;\n\t\t\tconst end = start + pageSize;\n\t\t\treturn allItems.slice(start, end);\n\t\t},\n\t\t[rawData, pageSize, codeKey]\n\t);\n\n\t/**\n\t * Находит несколько элементов по ключам.\n\t */\n\tconst findSourceItemsByKeys = useCallback(\n\t\t(key: string, keys: string[]) => {\n\t\t\tif (!rawData) return [];\n\n\t\t\tconst keysSet = new Set<string>(keys);\n\t\t\treturn rawData.items.filter((item) => keysSet.has(item[key]));\n\t\t},\n\t\t[rawData]\n\t);\n\n\t/**\n\t * Дебаунсинг для частых операций.\n\t */\n\tconst debounce = useCallback((key: string, fn: () => void, delay: number = 200) => {\n\t\t// Очищаем предыдущий таймер\n\t\tif (debounceTimers.current.has(key)) {\n\t\t\tclearTimeout(debounceTimers.current.get(key)!);\n\t\t}\n\n\t\t// Устанавливаем новый таймер\n\t\tconst timer = setTimeout(fn, delay);\n\t\tdebounceTimers.current.set(key, timer);\n\t}, []);\n\n\t/**\n\t * Очищает все дебаунс таймеры.\n\t */\n\tconst clearDebounceTimers = useCallback(() => {\n\t\tfor (const timer of debounceTimers.current.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tdebounceTimers.current.clear();\n\t}, []);\n\n\t// Очистка таймеров при размонтировании\n\tuseMemo(() => {\n\t\treturn () => {\n\t\t\tclearDebounceTimers();\n\t\t};\n\t}, [clearDebounceTimers]);\n\n\treturn {\n\t\t// Состояние данных\n\t\tdata: rawData,\n\t\tisLoading,\n\t\tisError,\n\n\t\tcodeKey,\n\t\ttextKey,\n\n\t\t// Функции для работы с коллекцией\n\t\tgetItems,\n\t\tfindSourceItemsByKeys,\n\t\tsetFilteredItems,\n\t\tgetPage,\n\t\tbuildSearchIndex,\n\t\tdebounce,\n\n\t\t// Вспомогательные данные\n\t\titemsMap,\n\t\tseparatedItems,\n\t\torderedKeys,\n\n\t\t// Управление запросом\n\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\trefetch,\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\tinvalidate: () => queryClient.invalidateQueries({ queryKey: createODataCollectionQueryKey(odata) }),\n\n\t\t// Метаданные для виртуализации\n\t\ttotalCount: rawData?.separated[codeKey]?.length || 0,\n\t\tpageSize\n\t};\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport { Query, useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Используется для получения последовательностей кодов.\n */\nexport function useODataCollectionChains(params: ODataServiceCollectionConfig[]) {\n\tconst queryClient = useQueryClient();\n\tconst [chains, setChains] = useState<ODataChainsMap>({});\n\n\tconst trackedKeys = useMemo(() => params.map((p) => createODataCollectionQueryKey(p)), [params]);\n\n\tuseEffect(() => {\n\t\tfunction updateChains() {\n\t\t\tconst newChains: ODataChainsMap = {};\n\n\t\t\tfor (const p of params) {\n\t\t\t\tconst key = createODataCollectionQueryKey(p);\n\t\t\t\tconst cached = queryClient.getQueryData<{ chain: { codeKey: string; count: number }[] }>(key);\n\t\t\t\tif (cached?.chain) {\n\t\t\t\t\tnewChains[`${p.service}.${p.target}`] = cached.chain;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetChains((prev) => {\n\t\t\t\t// не обновлять стейт, если данные не изменились (во избежание лишних рендеров)\n\t\t\t\tconst same =\n\t\t\t\t\tObject.keys(prev).length === Object.keys(newChains).length &&\n\t\t\t\t\tObject.entries(newChains).every(([k, v]) => prev[k] === v);\n\t\t\t\treturn same ? prev : newChains;\n\t\t\t});\n\t\t}\n\n\t\t// Первичная загрузка (на случай, если данные уже в кэше)\n\t\tupdateChains();\n\n\t\t// Подписка на изменения кэша\n\t\tconst unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n\t\t\t// Проверяем, затрагивает ли событие один из наших trackedKeys\n\t\t\tif (event?.query) {\n\t\t\t\tconst query = event.query as Query;\n\t\t\t\tconst isTracked = trackedKeys.some((key) => JSON.stringify(key) === JSON.stringify(query.queryKey));\n\t\t\t\tif (isTracked) {\n\t\t\t\t\tupdateChains();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn unsubscribe;\n\t}, [params, queryClient, trackedKeys]);\n\n\treturn chains;\n}\n","import { useState } from \"react\";\n\nimport { useODataCollectionStore } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { ODataCollectionModel } from \"./types\";\n\nexport function useODataCollectionModel(model: ODataCollectionModel): Required<ODataCollectionModel> {\n\t// NOTE: без подписки, потому что эти данные в рантайме не предполагается изменять в ближайшее время.\n\n\t// const defaultMaxVisibleItems = odataCollectionConfig.useMaxVisibleItems();\n\t// const defaultMinSearchCodeLength = odataCollectionConfig.useMinSearchCodeLength();\n\t// const defaultMinSearchTextLength = odataCollectionConfig.useMinSearchTextLength();\n\t// const defaultSearchDebounceDelay = odataCollectionConfig.useSearchDebounce();\n\n\tconst [stableModel] = useState(() => {\n\t\tconst defaultState = useODataCollectionStore.getState();\n\n\t\tconst {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems = defaultState.defaultMaxVisibleItems,\n\t\t\tminSearchCodeLength = defaultState.defaultMinSearchCodeLength,\n\t\t\tminSearchTextLength = defaultState.defaultMinSearchTextLength,\n\t\t\tsearchDebounceDelay = defaultState.defaultSearchDebounceDelay\n\t\t} = model;\n\t\treturn {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems,\n\t\t\tminSearchCodeLength,\n\t\t\tminSearchTextLength,\n\t\t\tsearchDebounceDelay\n\t\t};\n\t});\n\n\treturn stableModel;\n}\n","import { useMemo } from \"react\";\n\nimport {\n\ttype TableColumnDef,\n\ttype TableColumnFormattingMetaInput,\n\tcreateTableColumnVisibilityFromODataMetadata,\n\tcreateTableColumnsFromODataMetadata,\n\tenrichTableColumnsWithODataFormatting,\n\tresolveStableColumnId\n} from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { EntityColumnProperty, EntityMetadata, ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Собирает visibility-state только для тех leaf-колонок, которые сопоставились с metadata.\n */\nfunction collectMatchedColumnVisibility<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tvisibilityById: Readonly<Record<string, boolean>>\n): Record<string, boolean> {\n\tconst matchedVisibility: Record<string, boolean> = {};\n\n\tconst visitLeafColumns = (nestedColumns: readonly TableColumnDef<TData>[]) => {\n\t\tfor (const column of nestedColumns) {\n\t\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\t\tvisitLeafColumns(column.columns as TableColumnDef<TData>[]);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst columnId = resolveStableColumnId(column);\n\t\t\tif (!columnId || !(columnId in visibilityById)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatchedVisibility[columnId] = visibilityById[columnId];\n\t\t}\n\t};\n\n\tvisitLeafColumns(columns);\n\n\treturn matchedVisibility;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `build`.\n */\nexport interface UseODataTableColumnsBuildConfig extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим генерации колонок только по metadata.\n\t */\n\tmode: \"build\";\n\t/**\n\t * Позволяет определить видимость колонки при генерации.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n\t/**\n\t * Позволяет переопределить заголовок колонки при генерации.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `enrich`.\n */\nexport interface UseODataTableColumnsEnrichConfig<TData extends object> extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим обогащения уже существующих колонок.\n\t */\n\tmode: \"enrich\";\n\t/**\n\t * Существующий набор колонок для дозаполнения `meta.formatting.role/type`.\n\t */\n\tcolumns: readonly TableColumnDef<TData>[];\n}\n\n/**\n * Универсальный конфиг hook-адаптера колонок.\n */\nexport type UseODataTableColumnsConfig<TData extends object = Record<string, unknown>> =\n\tUseODataTableColumnsBuildConfig | UseODataTableColumnsEnrichConfig<TData>;\n\n/**\n * Результат работы hook-адаптера колонок.\n */\nexport interface UseODataTableColumnsResult<TData extends object> {\n\t/**\n\t * Итоговый набор колонок для `Table` или `TreeTable`.\n\t */\n\tcolumns: TableColumnDef<TData>[];\n\t/**\n\t * Стартовая карта видимости колонок для TanStack Table.\n\t */\n\tdefaultColumnVisibility: Record<string, boolean> | undefined;\n\t/**\n\t * Метаданные сущности, если они уже загружены.\n\t */\n\tmetadata: EntityMetadata | undefined;\n\t/**\n\t * Признак загрузки metadata.\n\t */\n\tisLoading: boolean;\n}\n\n/**\n * Возвращает колонки для `Table`/`TreeTable` на основе OData metadata.\n *\n * В режиме `build` генерирует базовый набор колонок из `metadata.columns`.\n * В режиме `enrich` дозаполняет уже существующие колонки typed-formatting контекстом.\n */\nexport function useODataTableColumns<TData extends object = Record<string, unknown>>(\n\tconfig: UseODataTableColumnsConfig<TData>\n): UseODataTableColumnsResult<TData> {\n\tconst { metadata, isLoading } = useODataMetadata(config);\n\n\tconst columns = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn config.mode === \"build\" ? [] : [...config.columns];\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnsFromODataMetadata<TData>(metadata.columns, {\n\t\t\t\tresolveHeader: config.resolveHeader,\n\t\t\t\tresolveFormatting: config.resolveFormatting\n\t\t\t});\n\t\t}\n\n\t\treturn enrichTableColumnsWithODataFormatting(config.columns, metadata.columns);\n\t}, [config, metadata]);\n\n\tconst defaultColumnVisibility = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnVisibilityFromODataMetadata(metadata.columns, {\n\t\t\t\tresolveVisible: config.resolveVisible\n\t\t\t});\n\t\t}\n\n\t\tconst visibilityById = createTableColumnVisibilityFromODataMetadata(metadata.columns);\n\n\t\treturn collectMatchedColumnVisibility(config.columns, visibilityById);\n\t}, [config, metadata]);\n\n\treturn {\n\t\tcolumns,\n\t\tdefaultColumnVisibility,\n\t\tmetadata,\n\t\tisLoading\n\t};\n}\n","import { notify } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { QueryClient } from \"@tanstack/react-query\";\n\nimport { buildODataFetchRequest, ODataFetchRequestPreview } from \"./odataFetch\";\nimport {\n\tODataArrayOperationMethod,\n\tODataCreateFnOptions,\n\tODataDeleteFnOptions,\n\todataFetchFn,\n\tODataFetchFnImplementationArgs,\n\tODataFetchFnRequest,\n\tODataFetchFnRunner,\n\tODataFetchFnSharedOptions,\n\tODataFunctionImportFnOptions,\n\tODataQueryArrayTransform,\n\tODataQueryFnOptions,\n\tODataQuerySingleTransform,\n\tODataReadFnOptions,\n\tODataSingleFetchFnRequest,\n\tODataSingleOperationMethod,\n\tODataSingleTransform,\n\tODataUpdateFnOptions\n} from \"./odataFetchFn\";\nimport {\n\tbuildTargetPath,\n\tisFunctionImportMetadata,\n\tresolveODataTarget,\n\tresolveRequestBody,\n\tresolveRequestMethod,\n\tvalidateODataOperation\n} from \"./odataFetchFnHelpers\";\nimport { resolveODataBaseUrl } from \"./transport\";\nimport { getODataMetadataData } from \"./useODataMetadataQuery\";\n\nimport type {\n\tODataOperationMethod,\n\tODataServiceConfig,\n\tODataTargetMetadata,\n\tUnwrappedODataParameters,\n\tWrappedODataParameters\n} from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\ntype ODataDevHelperName =\n\t| \"odataFetchFnDev\"\n\t| \"odataCreateFnDev\"\n\t| \"odataUpdateFnDev\"\n\t| \"odataDeleteFnDev\"\n\t| \"odataReadFnDev\"\n\t| \"odataQueryFnDev\"\n\t| \"odataFunctionImportFnDev\";\n\ntype ODataFetchFnDevOptions<I> = ODataFetchFnSharedOptions<I> & {\n\tparams?: WrappedODataParameters;\n\tbody?: unknown;\n\ttransform?: unknown;\n};\n\ntype ODataDevRequestLogInfo = {\n\thelperName: ODataDevHelperName;\n\toperation: ODataOperationMethod;\n\todata: ODataServiceConfig;\n\ttarget: ODataTargetMetadata;\n\ttargetPath: string;\n\trequest: ODataFetchRequestPreview;\n\trequestMethod: string;\n\tparams: WrappedODataParameters;\n\tqueryOptions: unknown;\n\tbody: string | undefined;\n\tautoParse: boolean | undefined;\n\thasTransform: boolean;\n};\n\nfunction getConsole() {\n\treturn globalThis.console;\n}\n\nfunction headersToRecord(headers: HeadersInit | undefined) {\n\tconst result: Record<string, string> = {};\n\tnew Headers(headers).forEach((value, key) => {\n\t\tresult[key] = value;\n\t});\n\n\treturn result;\n}\n\nfunction parseRequestBodyForLog(body: BodyInit | null | undefined): unknown {\n\tif (body === undefined || body === null) return undefined;\n\tif (typeof body !== \"string\") return body;\n\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\treturn parsed;\n\t} catch {\n\t\treturn body;\n\t}\n}\n\nfunction isWriteRequest(method: string | undefined) {\n\treturn method !== undefined && ![\"GET\", \"HEAD\"].includes(method.toUpperCase());\n}\n\nfunction isSapRequestPreview(request: ODataFetchRequestPreview) {\n\tconst baseUrl = request.baseUrl ?? \"odata\";\n\tif (baseUrl !== \"\") return true;\n\n\treturn request.path.startsWith(\"/sap/\") || request.path.startsWith(\"/sap-dp0/\");\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string) {\n\tconst normalizedName = name.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedName);\n}\n\nfunction setDefaultHeader(headers: Record<string, string>, name: string, value: string) {\n\tif (hasHeader(headers, name)) return;\n\theaders[name] = value;\n}\n\nfunction buildTransportHeadersPreview(request: ODataFetchRequestPreview) {\n\tconst headers = headersToRecord(request.init.headers);\n\tconst method = request.init.method;\n\tconst sapRequest = isSapRequestPreview(request);\n\n\tsetDefaultHeader(headers, \"DataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"MaxDataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"Accept\", \"application/json\");\n\n\theaders[\"sap-language\"] = \"ru\";\n\n\tif (sapRequest) {\n\t\theaders[\"sap-contextid-accept\"] = \"header\";\n\t}\n\n\tif (isWriteRequest(method) && request.init.body) {\n\t\tsetDefaultHeader(headers, \"Content-Type\", \"application/json\");\n\t}\n\n\tif (isWriteRequest(method) && sapRequest) {\n\t\tsetDefaultHeader(headers, \"x-csrf-token\", \"<получается отдельным GET перед реальным write-запросом>\");\n\t}\n\n\treturn headers;\n}\n\nfunction getTargetKind(target: ODataTargetMetadata) {\n\tif (isFunctionImportMetadata(target)) return \"FunctionImport\";\n\treturn target.result ? \"Parameterized Entity\" : \"Entity\";\n}\n\nfunction logObjectSection(title: string, value: unknown) {\n\tconst logger = getConsole();\n\tlogger.groupCollapsed(title);\n\tlogger.info(value);\n\tlogger.groupEnd();\n}\n\nfunction logODataDevRequest(info: ODataDevRequestLogInfo) {\n\tconst logger = getConsole();\n\tconst bodyPreview = parseRequestBodyForLog(info.request.init.body);\n\tconst initHeaders = headersToRecord(info.request.init.headers);\n\tconst transportHeaders = buildTransportHeadersPreview(info.request);\n\tconst requestInitPreview = {\n\t\tmethod: info.request.init.method,\n\t\theaders: initHeaders,\n\t\tbody: bodyPreview,\n\t\thasSignal: Boolean(info.request.init.signal)\n\t};\n\n\tlogger.groupCollapsed(`[OData DEV] ${info.requestMethod} ${info.request.fullUrl}`);\n\tlogger.table([\n\t\t{\n\t\t\thelper: info.helperName,\n\t\t\toperation: info.operation,\n\t\t\ttarget: info.odata.target,\n\t\t\ttargetKind: getTargetKind(info.target),\n\t\t\tservice: info.odata.service,\n\t\t\trealFetch: \"не выполнялся\"\n\t\t}\n\t]);\n\tlogger.info(\"Итоговый URL:\", info.request.fullUrl);\n\tlogger.info(\"Path без base URL:\", info.request.path);\n\tlogger.info(\"Target path до query options:\", info.targetPath);\n\tlogger.info(\"Query string:\", info.request.queryString || \"<пусто>\");\n\tlogger.info(\"Body:\", bodyPreview ?? \"<пусто>\");\n\tlogger.info(\"Auto parse:\", info.autoParse ?? false);\n\tlogger.info(\"Transform:\", info.hasTransform ? \"передан, но не вызывается без ответа backend\" : \"не передан\");\n\tlogger.info(\"Dry-run result:\", info.operation === \"query\" ? { data: [], totalCount: 0 } : { data: undefined });\n\tlogObjectSection(\"OData config\", info.odata);\n\tlogObjectSection(\"Target metadata\", info.target);\n\tlogObjectSection(\"Target params\", info.params);\n\tlogObjectSection(\"Query options\", info.queryOptions);\n\tlogObjectSection(\"RequestInit, переданный в transport\", requestInitPreview);\n\tlogObjectSection(\"Заголовки после transport defaults (без реального fetch)\", transportHeaders);\n\tlogger.groupEnd();\n}\n\nfunction notifyODataDevHelperCall(helperName: ODataDevHelperName) {\n\tnotify.warning(`${helperName}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, {\n\t\ttitle: \"OData DEV helper\"\n\t});\n}\n\nfunction createODataFetchFnDevRunner<I>(\n\tmethod: ODataOperationMethod,\n\topts: ODataFetchFnDevOptions<I>,\n\thelperName: ODataDevHelperName\n): ODataFetchFnRunner<unknown> {\n\tconst { odata, options = {}, init = {}, autoParse, swCache } = opts;\n\tconst params = opts.params ?? {};\n\n\treturn async ({ client, signal }: { client: QueryClient; signal?: AbortSignal }) => {\n\t\tnotifyODataDevHelperCall(helperName);\n\n\t\tconst baseUrl = resolveODataBaseUrl(odata.service, options.baseUrl);\n\t\tconst serviceMetadata = await getODataMetadataData({ service: odata.service, baseUrl }, client);\n\t\tif (!serviceMetadata) {\n\t\t\tthrow new Error(`Не удалось загрузить metadata OData-сервиса '${odata.service}'`);\n\t\t}\n\n\t\tconst target = resolveODataTarget(serviceMetadata, odata.target);\n\n\t\tvalidateODataOperation(target, method, odata);\n\n\t\tconst body = resolveRequestBody(opts.body, method);\n\t\tconst requestMethod = resolveRequestMethod(target, method);\n\t\tconst targetPath = buildTargetPath(target, odata, params, method);\n\n\t\tconst queryOptions = swCache ? { ...options, baseUrl, swCache } : { ...options, baseUrl };\n\t\tconst requestInit = { ...init, method: requestMethod, body, signal };\n\t\tconst request = buildODataFetchRequest(targetPath, queryOptions, requestInit);\n\n\t\tlogODataDevRequest({\n\t\t\thelperName,\n\t\t\toperation: method,\n\t\t\todata,\n\t\t\ttarget,\n\t\t\ttargetPath,\n\t\t\trequest,\n\t\t\trequestMethod,\n\t\t\tparams,\n\t\t\tqueryOptions,\n\t\t\tbody,\n\t\t\tautoParse,\n\t\t\thasTransform: Boolean(opts.transform)\n\t\t});\n\n\t\tif (method === \"query\") {\n\t\t\treturn { data: [], totalCount: 0 };\n\t\t}\n\n\t\treturn { data: undefined };\n\t};\n}\n\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }): ODataFetchFnRunner<O[]>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, I, P> & { transform?: undefined }): ODataFetchFnRunner<I[]>;\nexport function odataFetchFnDev<\n\tI,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataSingleOperationMethod = ODataSingleOperationMethod\n>(method: M, opts: ODataSingleFetchFnRequest<M, I, I, T, P> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataFetchFnDev<I, O = I, T = I, M extends ODataSingleOperationMethod = ODataSingleOperationMethod>(\n\tmethod: M,\n\topts: ODataSingleFetchFnRequest<M, I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataOperationMethod = ODataOperationMethod\n>(method: M, opts: ODataFetchFnRequest<M, I, O, T, P>): ODataFetchFnRunner<unknown>;\nexport function odataFetchFnDev(...args: ODataFetchFnImplementationArgs): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\tswitch (args[0]) {\n\t\t\tcase \"create\": {\n\t\t\t\treturn odataFetchFn(\"create\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn odataFetchFn(\"update\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"delete\": {\n\t\t\t\treturn odataFetchFn(\"delete\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"read\": {\n\t\t\t\treturn odataFetchFn(\"read\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"query\": {\n\t\t\t\treturn odataFetchFn(\"query\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"fi\": {\n\t\t\t\treturn odataFetchFn(\"fi\", args[1]);\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst checker: never = args[0];\n\t\t\t\tvoid checker;\n\n\t\t\t\tthrow new Error(\"Неподдерживаемая OData operation в odataFetchFnDev\");\n\t\t\t}\n\t\t}\n\t}\n\n\tconst [method, opts] = args;\n\treturn createODataFetchFnDevRunner(method, opts, \"odataFetchFnDev\");\n}\n\nexport function odataCreateFnDev<I, T = I>(opts: ODataCreateFnOptions<I, I, T> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataCreateFnDev<I, O = I, T = I>(\n\topts: ODataCreateFnOptions<I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataCreateFnDev<I, O = I, T = I>(opts: ODataCreateFnOptions<I, O, T>): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, never, \"create\">(\"create\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"create\", opts, \"odataCreateFnDev\");\n}\n\nexport function odataUpdateFnDev<I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, I, T, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, P, \"update\">(\"update\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"update\", opts, \"odataUpdateFnDev\");\n}\n\nexport function odataDeleteFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"delete\">(\"delete\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"delete\", opts, \"odataDeleteFnDev\");\n}\n\nexport function odataReadFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"read\">(\"read\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"read\", opts, \"odataReadFnDev\");\n}\n\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }\n): ODataFetchFnRunner<O[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform?: undefined }\n): ODataFetchFnRunner<I[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, void, P, \"query\">(\"query\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"query\", opts, \"odataQueryFnDev\");\n}\n\nexport function odataFunctionImportFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"fi\">(\"fi\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"fi\", opts, \"odataFunctionImportFnDev\");\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/odata/createODataCollectionQueryKey.ts","../../src/odata/flattenODataDependentServices.ts","../../src/odata/sortODataDependentSegmentItemsByChains.ts","../../src/odata/sortODataDependentServicesByChains.ts","../../src/odata/fetchCollectionData.ts","../../src/odata/projectODataCollectionSort.ts","../../src/odata/useODataCollectionUpdatesQuery.ts","../../src/odata/useODataMetadata.ts","../../src/odata/useODataEntity.ts","../../src/odata/useODataCollectionQuery.ts","../../src/odata/useODataCollection.ts","../../src/odata/useODataCollectionChains.ts","../../src/odata/useODataCollectionModel.ts","../../src/odata/useODataTableColumns.ts","../../src/odata/odataFetchFnDev.ts"],"sourcesContent":["import { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\n/**\n * Версия формы persisted collection snapshot.\n *\n * Версия 2 отделяет прежние записи, порядок `separated` которых зависел от\n * первого consumer, от новой канонической сортировки по code.\n */\nconst ODATA_COLLECTION_QUERY_VERSION = 2;\n\nexport const createODataCollectionBaseQueryKey = () => [...odataBaseQueryKey, \"collection\"] as const;\n\nexport const createODataCollectionQueryKey = ({ service, target, limitedKeys, serverFilter }: ODataServiceCollectionConfig) =>\n\t[\n\t\t...createODataCollectionBaseQueryKey(),\n\t\t{ version: ODATA_COLLECTION_QUERY_VERSION, service, target, limitedKeys, serverFilter }\n\t] as const;\n","import type { ODataDependentBaseProps, ODataDependentSegmentItem } from \"./types\";\n\n/**\n * Разворачивает зависимые OData-сервисы в плоский список segment-level элементов.\n */\nexport function flattenODataDependentServices(services: readonly ODataDependentBaseProps[]): ODataDependentSegmentItem[] {\n\tconst out: ODataDependentSegmentItem[] = [];\n\n\tfor (const [serviceIndex, service] of services.entries()) {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\n\t\tfor (const [segmentIndex, [id, segment]] of Object.entries(service.segments).entries()) {\n\t\t\tout.push({\n\t\t\t\tid,\n\t\t\t\tserviceKey,\n\t\t\t\tserviceIndex,\n\t\t\t\tsegmentIndex,\n\t\t\t\todata: service.odata,\n\t\t\t\tsegment,\n\t\t\t\tmodel: {\n\t\t\t\t\t...service.model,\n\t\t\t\t\tcodeKey: id\n\t\t\t\t},\n\t\t\t\tpanelVisibility: segment.panelVisibility ?? \"user\"\n\t\t\t});\n\t\t}\n\t}\n\n\treturn out;\n}\n","import { ODataDependentSegmentItem } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Сортирует плоские segment-level элементы по chain-порядку\n * и опционально накладывает пользовательский override.\n */\nexport function sortODataDependentSegmentItemsByChains(\n\titems: readonly ODataDependentSegmentItem[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentSegmentItem[] {\n\tconst chainOrderByService = new Map<string, Map<string, number>>();\n\n\tfor (const [serviceKey, chain] of Object.entries(chains)) {\n\t\tchainOrderByService.set(serviceKey, new Map(chain.map((item, index) => [item.codeKey, index])));\n\t}\n\n\tconst baseOrdered = [...items]\n\t\t.map((item, index) => ({\n\t\t\titem,\n\t\t\tindex\n\t\t}))\n\t\t.sort((left, right) => {\n\t\t\tif (left.item.serviceIndex !== right.item.serviceIndex) {\n\t\t\t\treturn left.item.serviceIndex - right.item.serviceIndex;\n\t\t\t}\n\n\t\t\tconst chainOrder = chainOrderByService.get(left.item.serviceKey);\n\t\t\tconst leftChainOrder = chainOrder?.get(left.item.id);\n\t\t\tconst rightChainOrder = chainOrder?.get(right.item.id);\n\n\t\t\tif (leftChainOrder !== undefined && rightChainOrder !== undefined) {\n\t\t\t\treturn leftChainOrder - rightChainOrder;\n\t\t\t}\n\t\t\tif (leftChainOrder !== undefined) return -1;\n\t\t\tif (rightChainOrder !== undefined) return 1;\n\n\t\t\tif (left.item.segmentIndex !== right.item.segmentIndex) {\n\t\t\t\treturn left.item.segmentIndex - right.item.segmentIndex;\n\t\t\t}\n\n\t\t\treturn left.index - right.index;\n\t\t});\n\n\tif (!orderOverrideIds?.length) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst availableIds = new Set(baseOrdered.map(({ item }) => item.id));\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => availableIds.has(id));\n\tif (normalizedOverride.length === 0) {\n\t\treturn baseOrdered.map(({ item }) => item);\n\t}\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\n\treturn [...baseOrdered]\n\t\t.sort((left, right) => {\n\t\t\tconst leftOverrideRank = overrideRank.get(left.item.id);\n\t\t\tconst rightOverrideRank = overrideRank.get(right.item.id);\n\n\t\t\tif (leftOverrideRank !== undefined && rightOverrideRank !== undefined) {\n\t\t\t\treturn leftOverrideRank - rightOverrideRank;\n\t\t\t}\n\t\t\tif (leftOverrideRank !== undefined) return -1;\n\t\t\tif (rightOverrideRank !== undefined) return 1;\n\n\t\t\treturn left.index - right.index;\n\t\t})\n\t\t.map(({ item }) => item);\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { ODataDependentBaseProps } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Применяет пользовательский override порядка сегментов поверх уже рассчитанного базового порядка.\n *\n * Алгоритм:\n * 1. берёт только валидные id из `orderOverrideIds` (без дублей);\n * 2. поднимает эти id в начало в указанной последовательности;\n * 3. все остальные сегменты оставляет в исходном относительном порядке.\n */\nfunction applySegmentsOrderOverride(\n\tservices: readonly ODataDependentBaseProps[],\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tif (!orderOverrideIds?.length) return [...services];\n\n\tconst visibleIds = new Set<string>();\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tvisibleIds.add(segmentId);\n\t\t}\n\t}\n\n\tconst normalizedOverride = [...new Set(orderOverrideIds)].filter((id) => visibleIds.has(id));\n\tif (normalizedOverride.length === 0) return [...services];\n\n\tconst overrideRank = new Map(normalizedOverride.map((id, index) => [id, index]));\n\tconst fallbackRankStart = normalizedOverride.length;\n\tconst segmentRank = new Map<string, number>();\n\tlet fallbackRank = fallbackRankStart;\n\n\tfor (const service of services) {\n\t\tfor (const segmentId of Object.keys(service.segments)) {\n\t\t\tif (segmentRank.has(segmentId)) continue;\n\t\t\tsegmentRank.set(segmentId, overrideRank.get(segmentId) ?? fallbackRank++);\n\t\t}\n\t}\n\n\tconst withOrderedSegments = services.map((service) => {\n\t\tconst orderedEntries = Object.entries(service.segments).sort(\n\t\t\t([leftId], [rightId]) =>\n\t\t\t\t(segmentRank.get(leftId) ?? Number.MAX_SAFE_INTEGER) - (segmentRank.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t\t);\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn [...withOrderedSegments].sort((leftService, rightService) => {\n\t\tconst leftFirstSegmentId = Object.keys(leftService.segments)[0];\n\t\tconst rightFirstSegmentId = Object.keys(rightService.segments)[0];\n\t\tconst leftRank = leftFirstSegmentId ? (segmentRank.get(leftFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\t\tconst rightRank = rightFirstSegmentId ? (segmentRank.get(rightFirstSegmentId) ?? Number.MAX_SAFE_INTEGER) : Number.MAX_SAFE_INTEGER;\n\n\t\treturn leftRank - rightRank;\n\t});\n}\n\n/**\n * Сортирует сегменты сервисов по chain-порядку (от меньшего к большему)\n * и опционально накладывает пользовательский override.\n *\n * Если chain недоступен, сохраняет исходный порядок сегментов.\n *\n * @deprecated функционал должен быть вырезан и оставлен только с `sortODataDependentSegmentItemsByChains`\n */\nexport function sortODataDependentServicesByChains(\n\tservices: readonly ODataDependentBaseProps[],\n\tchains: ODataChainsMap,\n\torderOverrideIds?: readonly string[]\n): ODataDependentBaseProps[] {\n\tconst sortedByChains = services.map((service) => {\n\t\tconst serviceKey = `${service.odata.service}.${service.odata.target}`;\n\t\tconst chain = chains[serviceKey];\n\t\tif (!chain?.length) return service;\n\n\t\tconst chainOrder = new Map(chain.map((item, index) => [item.codeKey, index]));\n\t\tconst orderedEntries = Object.entries(service.segments).sort(([leftId], [rightId]) => {\n\t\t\tconst leftOrder = chainOrder.get(leftId);\n\t\t\tconst rightOrder = chainOrder.get(rightId);\n\n\t\t\tif (leftOrder !== undefined && rightOrder !== undefined) return leftOrder - rightOrder;\n\t\t\tif (leftOrder !== undefined) return -1;\n\t\t\tif (rightOrder !== undefined) return 1;\n\t\t\treturn compareStrings(leftId, rightId);\n\t\t});\n\n\t\treturn {\n\t\t\t...service,\n\t\t\tsegments: Object.fromEntries(orderedEntries)\n\t\t};\n\t});\n\n\treturn applySegmentsOrderOverride(sortedByChains, orderOverrideIds);\n}\n","import { type CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { logError } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { odataFetch, type ODataFetchOptions } from \"./odataFetch\";\nimport { isNoContentResponse } from \"./transport\";\n\n// Тип для результата запроса справочника\ninterface ODataServiceResult<T extends CollectionItem> {\n\titems: T[];\n}\n\n/**\n * Загрузка данных справочника из OData сервиса\n */\nexport async function fetchCollectionData<T extends CollectionItem>(params: {\n\turl: string;\n\tquery?: ODataFetchOptions<T>;\n\tsignal: AbortSignal;\n}): Promise<ODataServiceResult<T>> {\n\tconst { url, query, signal } = params;\n\n\ttry {\n\t\t// Загружаем данные из OData сервиса\n\t\tconst response = await odataFetch<T, T[]>(url, query, { signal });\n\n\t\t// Считаем отсутствие данных ошибкой, ведь query запрос обязан вернуть корректное тело json\n\t\tif (isNoContentResponse(response)) {\n\t\t\tthrow new Error(\"отсутствует тело ответа\");\n\t\t}\n\n\t\tconst data = response.data;\n\n\t\t// Удаление ненужных полей.\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars\n\t\t\titems: data.map(({ ID, CNT, __metadata, __Parameters, ...item }) => item as T) /*, pairs, pairsMap */\n\t\t};\n\t} catch (error) {\n\t\tlogError(\"Ошибка загрузки справочника:\", error);\n\t\t// throw error;\n\n\t\treturn { items: [] };\n\t}\n}\n","import { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport type { ODataCollectionResult } from \"./useODataCollectionQuery\";\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\n/**\n * Разделяет одну text-проекцию между всеми observer одного Query snapshot.\n *\n * WeakMap не удерживает выгруженный Query в памяти. Пока snapshot активен,\n * дополнительные ракурсы переиспользуют уже отсортированные массивы ссылок\n * вместо повторной сортировки и отдельной копии массивов для каждого observer.\n */\nconst textProjectionBySource = new WeakMap<ODataCollectionResult<CollectionItem>, ODataCollectionResult<CollectionItem>>();\n\n/**\n * Создаёт observer-проекцию канонического справочника с сортировкой по text.\n *\n * Query cache и persistence продолжают хранить один code-sorted snapshot.\n * Проекция копирует только массивы ссылок в `separated`: исходные строки,\n * объекты элементов, `items`, `chain` и metadata остаются общими.\n */\nexport function projectODataCollectionSortByText<T extends CollectionItem>(source: ODataCollectionResult<T>): ODataCollectionResult<T> {\n\tconst cachedProjection = textProjectionBySource.get(source);\n\tif (cachedProjection) {\n\t\treturn cachedProjection as ODataCollectionResult<T>;\n\t}\n\n\tlet hasProjectedLevel = false;\n\tconst separated = Object.fromEntries(\n\t\tObject.entries(source.separated).map(([codeKey, items]) => {\n\t\t\tconst textKey = source.keyPairsMap[codeKey];\n\t\t\tif (!textKey || items.length < 2) {\n\t\t\t\treturn [codeKey, items];\n\t\t\t}\n\n\t\t\thasProjectedLevel = true;\n\t\t\treturn [codeKey, [...items].sort((left, right) => compareStrings(String(left[textKey] ?? \"\"), String(right[textKey] ?? \"\")))];\n\t\t})\n\t) as Record<string, T[]>;\n\n\tif (!hasProjectedLevel) {\n\t\treturn source;\n\t}\n\n\tconst projection = {\n\t\t...source,\n\t\tseparated\n\t};\n\ttextProjectionBySource.set(source, projection);\n\n\treturn projection;\n}\n","import { parseDate } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { queryOptions, useQuery } from \"@tanstack/react-query\";\n\nimport { odataBaseQueryKey } from \"./odataBaseQueryKey\";\nimport { odataFetch } from \"./odataFetch\";\nimport { getODataProjectAdapter, resolveODataBaseUrl } from \"./odataProjectAdapter\";\n\nconst COLLECTION_UPDATES_BUILD_ID = __APP_BUILD_ID__;\nconst COLLECTION_UPDATES_STALE_TIME = 1000 * 60 * 60 * 4;\nexport const ODATA_COLLECTION_UPDATES_LOOKBACK_MS = 1000 * 60 * 60 * 24 * 7;\nexport const ODATA_COLLECTION_DEFAULT_SW_CACHE = \"ttl=forever;name=ref\";\nexport const ODATA_COLLECTION_BUST_SW_CACHE = \"bust=forever;name=ref\";\nexport const ODATA_COLLECTION_UPDATES_SW_CACHE = \"ttl=4h;name=ref-updates\";\n\ninterface ODataCollectionUpdateRecord {\n\tentityName: string;\n\tlastChanged: string;\n}\n\nexport interface ODataCollectionUpdateItem extends ODataCollectionUpdateRecord {\n\tlastChangedAt: Date | null;\n}\n\nexport interface ODataCollectionUpdatesResult {\n\titems: ODataCollectionUpdateItem[];\n\tbyEntityName: Record<string, ODataCollectionUpdateItem>;\n\tfetchedAt: number;\n\tcoverageStartedAt: number;\n}\n\nexport interface ODataCollectionUpdatesOptions {\n\tstaleTime?: number;\n}\n\nexport const createODataCollectionUpdatesQueryKey = () =>\n\t[...odataBaseQueryKey, \"collection-updates\", { buildId: COLLECTION_UPDATES_BUILD_ID }] as const;\n\nfunction normalizeCollectionUpdateRecord(record: ODataCollectionUpdateRecord): ODataCollectionUpdateItem {\n\treturn {\n\t\t...record,\n\t\tlastChangedAt: parseDate(record.lastChanged)\n\t};\n}\n\nfunction normalizeCollectionUpdates(records: ODataCollectionUpdateRecord[], fetchedAt: number): ODataCollectionUpdatesResult {\n\tconst items = records.map(normalizeCollectionUpdateRecord);\n\tconst byEntityName = items.reduce<Record<string, ODataCollectionUpdateItem>>((acc, item) => {\n\t\tif (item.entityName) {\n\t\t\tacc[item.entityName] = item;\n\t\t}\n\n\t\treturn acc;\n\t}, {});\n\n\treturn { items, byEntityName, fetchedAt, coverageStartedAt: fetchedAt - ODATA_COLLECTION_UPDATES_LOOKBACK_MS };\n}\n\n/**\n * Загружает компактный список справочников, изменённых за последние 7 дней.\n * Сам список живёт отдельно от данных справочников и управляет их точечной инвалидацией.\n */\nexport function fetchODataCollectionUpdates() {\n\treturn async ({ signal }: { signal: AbortSignal }): Promise<ODataCollectionUpdatesResult> => {\n\t\tconst requestStartedAt = Date.now();\n\t\tconst endpoint = getODataProjectAdapter().collectionUpdates;\n\t\tif (!endpoint) return normalizeCollectionUpdates([], requestStartedAt);\n\n\t\tconst response = await odataFetch<ODataCollectionUpdateRecord, ODataCollectionUpdateRecord[]>(\n\t\t\t`/${endpoint.service}/${endpoint.target}`,\n\t\t\t{\n\t\t\t\tbaseUrl: resolveODataBaseUrl(endpoint.service, endpoint.baseUrl),\n\t\t\t\tswCache: ODATA_COLLECTION_UPDATES_SW_CACHE\n\t\t\t},\n\t\t\t{ signal }\n\t\t);\n\n\t\treturn normalizeCollectionUpdates(response.data, Math.max(requestStartedAt, Date.now()));\n\t};\n}\n\n/**\n * Описывает общий TanStack Query со списком обновлённых справочников.\n * Query сохраняется в IndexedDB и дополнительно кешируется Service Worker на короткий TTL.\n *\n * При отсутствии endpoint queryFn возвращает пустой успешный результат без сетевого запроса.\n * Query должен оставаться активным, потому что зависимые справочники ждут его завершения.\n */\nexport const odataCollectionUpdatesQueryOptions = (options: ODataCollectionUpdatesOptions = {}) =>\n\tqueryOptions({\n\t\tqueryKey: createODataCollectionUpdatesQueryKey(),\n\t\tqueryFn: fetchODataCollectionUpdates(),\n\t\tmeta: persistedQueryMeta,\n\t\tstaleTime: options.staleTime ?? COLLECTION_UPDATES_STALE_TIME,\n\t\tgcTime: Infinity\n\t});\n\nexport function useODataCollectionUpdatesQuery(options: ODataCollectionUpdatesOptions = {}) {\n\treturn useQuery(odataCollectionUpdatesQueryOptions(options));\n}\n","import { useODataMetadataQuery } from \"./useODataMetadataQuery\";\n\nimport type { ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Возвращает metadata конкретной OData-сущности по имени сервиса и сущности.\n *\n * Хук не добавляет собственную бизнес-логику и служит публичной тонкой\n * прослойкой над `useODataMetadataQuery(...)`.\n */\nexport function useODataMetadata(odata: ODataServiceConfig) {\n\tconst { data, dataUpdatedAt = 0, isLoading, isLoadingError } = useODataMetadataQuery({ service: odata.service });\n\tconst metadata = data?.entities[odata.target];\n\n\tif (!isLoading && !metadata && data?.functionImports[odata.target]) {\n\t\tthrow new Error(`OData target '${odata.target}' является FunctionImport и не может использоваться как сущность`);\n\t}\n\n\tif (isLoadingError) {\n\t\tthrow new Error(`Ошибка загрузки метаданных сервиса ${odata.service}`);\n\t}\n\n\treturn { metadata, metadataUpdatedAt: dataUpdatedAt, isLoading };\n}\n","import { useMemo } from \"react\";\n\nimport { buildEntityPath, type ODataServiceConfig, type ODataValue } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nconst throwErrorText = \"Использование actions недопустимо до окончания загрузки metadata\";\n\n// function throwNoMetadata() {\n// \tif (__DEV__) {\n// \t\tthrow new Error(throwErrorText);\n// \t}\n// \treturn undefined;\n// }\n\nexport type ODataEntity = Omit<ReturnType<typeof useODataEntity>, \"isLoading\">;\n\nexport function useODataEntity(odata: ODataServiceConfig) {\n\tconst { metadata, metadataUpdatedAt, isLoading } = useODataMetadata(odata);\n\n\tconst actions = useMemo(() => {\n\t\tconst getEntityPath = (values: Record<string, ODataValue> = {}) => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn buildEntityPath(metadata, odata, values);\n\t\t};\n\t\tconst getKeys = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns?.map((c) => c.id);\n\t\t};\n\t\tconst getKeyPairs = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\treturn metadata.columns\n\t\t\t\t?.filter((c) => c.semanticType === \"code\" && c.linkedColumnId)\n\t\t\t\t.map((c) => ({ codeKey: c.id, textKey: c.linkedColumnId }) as CollectionPair);\n\t\t};\n\t\tconst getKeyPairsMap = () => {\n\t\t\tif (!metadata) throw new Error(throwErrorText);\n\t\t\tconst pairs: Record<string, string> = {};\n\n\t\t\tfor (const column of metadata.columns ?? []) {\n\t\t\t\tif (column.semanticType === \"code\" && column.linkedColumnId) {\n\t\t\t\t\tpairs[column.id] = column.linkedColumnId;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn pairs;\n\t\t};\n\n\t\treturn {\n\t\t\t/**\n\t\t\t * Получить строку запроса `/service/entity(parameters)/Results`\n\t\t\t */\n\t\t\tgetEntityPath,\n\t\t\t/**\n\t\t\t * Получить все ключи сущности\n\t\t\t */\n\t\t\tgetKeys,\n\t\t\t/**\n\t\t\t * Получить список ключей в формате `{ codeKey, textKey }`\n\t\t\t */\n\t\t\tgetKeyPairs,\n\t\t\t/**\n\t\t\t * Получить словать ключей в формате `{ code: text }`\n\t\t\t */\n\t\t\tgetKeyPairsMap\n\t\t};\n\t}, [odata, metadata]);\n\n\treturn { config: odata, metadata, metadataUpdatedAt, isLoading, actions };\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { buildSeparatedArrays, type CollectionItem, type CollectionPair } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { persistedQueryMeta } from \"@ryuzaki13/react-foundation-lib/query-client\";\nimport { useQuery, useQueryClient, UseQueryResult } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { fetchCollectionData } from \"./fetchCollectionData\";\nimport { projectODataCollectionSortByText } from \"./projectODataCollectionSort\";\nimport { ODataCollectionConfig } from \"./types\";\nimport {\n\tODATA_COLLECTION_BUST_SW_CACHE,\n\tODATA_COLLECTION_DEFAULT_SW_CACHE,\n\tODataCollectionUpdateItem,\n\tuseODataCollectionUpdatesQuery\n} from \"./useODataCollectionUpdatesQuery\";\nimport { useODataEntity } from \"./useODataEntity\";\n\nexport interface ODataCollectionResult<T extends CollectionItem> {\n\titems: T[];\n\tkeyPairs: CollectionPair[];\n\tkeyPairsMap: Record<string, string>;\n\t/**\n\t * Массивы элементов по уровням справочника.\n\t *\n\t * Query cache хранит канонический порядок по code, а конкретный observer\n\t * может получить проекцию по text. Один snapshot при этом переиспользуется\n\t * ракурсами с разными `sortByCode`.\n\t */\n\tseparated: Record<string, T[]>;\n\tchain: { codeKey: string; count: number }[];\n\tcount: number;\n\tcacheUpdatedAt: number;\n}\n\ninterface ODataCollectionCacheRefreshContext {\n\tupdate?: ODataCollectionUpdateItem;\n\tmetadataUpdatedAt?: number;\n\tupdatesCoverageStartedAt?: number;\n}\n\nexport function resolveODataCollectionSwCachePolicy(swCache: string, shouldBust: boolean) {\n\tif (!shouldBust) return swCache;\n\n\tconst normalized = swCache.trim().toLowerCase();\n\tif (normalized === \"off\" || normalized.startsWith(\"bust=\")) return swCache;\n\tif (normalized.startsWith(\"ttl=\")) return swCache.replace(/^\\s*ttl=/i, \"bust=\");\n\n\treturn ODATA_COLLECTION_BUST_SW_CACHE;\n}\n\nfunction isUsableTimestamp(value: number | undefined): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\n/**\n * Определяет, нужно ли обновить конкретный справочник по списку изменений.\n * Сравнение идёт с cacheUpdatedAt, который сохраняется вместе с данными справочника.\n */\nexport function shouldRefreshODataCollectionCache<T extends CollectionItem>(\n\tcontext: ODataCollectionCacheRefreshContext,\n\tcachedData: ODataCollectionResult<T> | undefined\n) {\n\tconst cacheUpdatedAt = cachedData?.cacheUpdatedAt ?? 0;\n\tconst updateChangedAt = context.update?.lastChangedAt?.getTime();\n\n\tif (isUsableTimestamp(updateChangedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (updateChangedAt > cacheUpdatedAt) return true;\n\t}\n\n\tif (isUsableTimestamp(context.metadataUpdatedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (context.metadataUpdatedAt > cacheUpdatedAt) return true;\n\t}\n\n\t/**\n\t * Бэкенд отдаёт список изменений справочников только за последнюю неделю.\n\t * Если локальный справочник старше этого окна, отсутствие target в списке\n\t * больше не доказывает актуальность, поэтому обновляем только открытый справочник.\n\t */\n\tif (isUsableTimestamp(context.updatesCoverageStartedAt)) {\n\t\tif (!cachedData || !cacheUpdatedAt) return true;\n\t\tif (cacheUpdatedAt < context.updatesCoverageStartedAt) return true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Универсальный хук для получения данных из OData сервиса.\n * Заменяет функционал TextDataService из SAP UI5.\n */\nexport function useODataCollectionQuery<T extends CollectionItem>(odata: ODataCollectionConfig): UseQueryResult<ODataCollectionResult<T>> {\n\tconst {\n\t\tservice,\n\t\ttarget,\n\t\tlimitedKeys,\n\t\texcludeEmpty,\n\t\tsortByCode,\n\t\tserverFilter,\n\t\tclientFilter,\n\t\tswCache = ODATA_COLLECTION_DEFAULT_SW_CACHE\n\t} = odata;\n\tconst queryClient = useQueryClient();\n\tconst { actions, metadata, metadataUpdatedAt, isLoading } = useODataEntity(odata);\n\tconst updatesQuery = useODataCollectionUpdatesQuery();\n\n\tconst queryKey = useMemo(\n\t\t() => createODataCollectionQueryKey({ service, target, limitedKeys, serverFilter }),\n\t\t[service, target, limitedKeys, serverFilter]\n\t);\n\tconst cachedData = queryClient.getQueryData<ODataCollectionResult<T>>(queryKey);\n\tconst collectionUpdate = updatesQuery.data?.byEntityName[target];\n\tconst shouldBustCollectionCache = shouldRefreshODataCollectionCache(\n\t\t{\n\t\t\tupdate: collectionUpdate,\n\t\t\tmetadataUpdatedAt,\n\t\t\tupdatesCoverageStartedAt: updatesQuery.data?.coverageStartedAt\n\t\t},\n\t\tcachedData\n\t);\n\tconst effectiveSwCache = resolveODataCollectionSwCachePolicy(swCache, shouldBustCollectionCache);\n\tconst updatesReady = updatesQuery.isError || (updatesQuery.isSuccess && !updatesQuery.isFetching);\n\n\tuseEffect(() => {\n\t\tif (!cachedData || !shouldBustCollectionCache) return;\n\n\t\tvoid queryClient.invalidateQueries({ queryKey });\n\t}, [cachedData, queryClient, queryKey, shouldBustCollectionCache]);\n\n\treturn useQuery({\n\t\tqueryKey,\n\t\tqueryFn: async ({ signal }) => {\n\t\t\tconst requestStartedAt = Date.now();\n\t\t\tconst selectKeys = limitedKeys ? [...limitedKeys] : actions.getKeys();\n\t\t\tconst keyPairs = actions.getKeyPairs();\n\t\t\tconst keyPairsMap = actions.getKeyPairsMap();\n\n\t\t\tif (limitedKeys) {\n\t\t\t\tfor (const k of limitedKeys) {\n\t\t\t\t\tconst keyText = keyPairsMap[k];\n\t\t\t\t\tif (keyText && !selectKeys.includes(keyText)) {\n\t\t\t\t\t\tselectKeys.push(keyText);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst { items } = await fetchCollectionData<T>({\n\t\t\t\turl: `/${service}/${target}`,\n\t\t\t\tquery: {\n\t\t\t\t\tselect: selectKeys,\n\t\t\t\t\texpression: serverFilter,\n\t\t\t\t\tswCache: effectiveSwCache\n\t\t\t\t},\n\t\t\t\tsignal\n\t\t\t});\n\n\t\t\tlet filterdItems = items;\n\t\t\tif (clientFilter) {\n\t\t\t\tfilterdItems = items.filter(clientFilter);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Query cache хранит единую каноническую проекцию справочника.\n\t\t\t *\n\t\t\t * Сортировка конкретного контрола применяется observer-проекцией ниже,\n\t\t\t * чтобы два ракурса с разными `sortByCode` переиспользовали один snapshot,\n\t\t\t * а не конкурировали за его порядок и не дублировали всю коллекцию в памяти.\n\t\t\t */\n\t\t\tconst separated = buildSeparatedArrays<T>(filterdItems, keyPairs, excludeEmpty, true);\n\n\t\t\t// Рассчитать порядок от меньшего к большему\n\t\t\tconst chain = keyPairs\n\t\t\t\t.map((pair) => ({ codeKey: pair.codeKey, count: separated[pair.codeKey].length }))\n\t\t\t\t.sort((a, b) => a.count - b.count);\n\n\t\t\treturn {\n\t\t\t\titems: filterdItems,\n\t\t\t\tkeyPairs,\n\t\t\t\tkeyPairsMap,\n\t\t\t\tseparated,\n\t\t\t\tchain,\n\t\t\t\tcount: filterdItems.length,\n\t\t\t\tcacheUpdatedAt: Math.max(requestStartedAt, Date.now(), collectionUpdate?.lastChangedAt?.getTime() ?? 0, metadataUpdatedAt)\n\t\t\t};\n\t\t},\n\t\tenabled: Boolean(!isLoading && metadata && service && target && updatesReady),\n\t\tmeta: persistedQueryMeta,\n\t\t/**\n\t\t * Клиентский кеш можно держать не долго, чтобы он мог чаще дергать SW\n\t\t */\n\t\tstaleTime: 1000 * 60 * 60 * 2,\n\t\t/**\n\t\t * Если справочник не используется более часа, то можно из памяти выгрузить.\n\t\t */\n\t\tgcTime: 1000 * 60 * 60 * 1,\n\t\t/**\n\t\t * Сортировка является представлением observer, а не identity Query.\n\t\t * TanStack мемоизирует select-проекцию и не сохраняет её в общий cache.\n\t\t */\n\t\tselect: sortByCode === false ? projectODataCollectionSortByText<T> : undefined\n\t});\n}\n","import { useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataCollectionConfig, ODataCollectionModel } from \"./types\";\nimport { useODataCollectionQuery } from \"./useODataCollectionQuery\";\n\nimport type { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\n\ninterface UseODataCollectionProps {\n\todata: ODataCollectionConfig;\n\tmodel: Required<ODataCollectionModel>;\n\n\t/**\n\t * Размер страницы для виртуализации.\n\t */\n\tpageSize?: number;\n\n\tfilter?: (item: CollectionItem) => boolean;\n}\n\nexport function useODataCollection({\n\todata,\n\tmodel,\n\t// filter,\n\tpageSize = 50\n}: UseODataCollectionProps) {\n\tconst { codeKey, maxVisibleItems } = model;\n\tconst { data: rawData, isLoading, isError, refetch } = useODataCollectionQuery(odata);\n\n\tconst textKey = rawData?.keyPairsMap[codeKey] ?? \"\";\n\n\t// Клиент для инвалидации запросов\n\tconst queryClient = useQueryClient();\n\n\tconst [filteredKeys, setFilteredKeys] = useState<Set<string>>();\n\n\tconst debounceTimers = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n\t/**\n\t * itemsMap - индекс элементов для быстрого поиска\n\t * orderedKeys - упорядоченный список ключей для сохранения порядка\n\t */\n\tconst { itemsMap, separatedItems, orderedKeys } = useMemo(() => {\n\t\tconst itemsMap = new Map<string, CollectionItem>();\n\t\tconst orderedKeys = [] as string[];\n\t\tlet separatedItems: CollectionItem[] = [];\n\n\t\tif (rawData && rawData.separated[codeKey]) {\n\t\t\tseparatedItems = rawData.separated[codeKey];\n\n\t\t\tfor (const item of separatedItems) {\n\t\t\t\tconst key = item[codeKey];\n\t\t\t\tif (key) {\n\t\t\t\t\titemsMap.set(key, item);\n\t\t\t\t\torderedKeys.push(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { itemsMap, separatedItems, orderedKeys };\n\t}, [rawData, codeKey]);\n\n\t// Создание индекса поиска для текстовых полей\n\tconst buildSearchIndex = useCallback(\n\t\t(field: string) => {\n\t\t\tconst items = rawData?.separated[codeKey];\n\n\t\t\tif (!items) {\n\t\t\t\treturn new Map<string, Set<string>>();\n\t\t\t}\n\n\t\t\tconst index = new Map<string, Set<string>>();\n\n\t\t\t// Создаем индекс по префиксам для быстрого поиска\n\t\t\tfor (const item of items) {\n\t\t\t\tconst value = item[field]?.toLowerCase();\n\t\t\t\tif (!value) continue;\n\n\t\t\t\t// Индексируем по префиксам длиной 1-5 символов\n\t\t\t\tfor (let i = 1; i <= Math.min(5, value.length); i++) {\n\t\t\t\t\tconst prefix = value.substring(0, i);\n\t\t\t\t\tif (!index.has(prefix)) {\n\t\t\t\t\t\tindex.set(prefix, new Set<string>());\n\t\t\t\t\t}\n\t\t\t\t\tindex.get(prefix)!.add(item[codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn index;\n\t\t},\n\t\t[rawData, codeKey]\n\t);\n\n\t/**\n\t * Устанавливает несколько фильтров зависимостей.\n\t *\n\t * Сформированный список ключей пойдёт в фильтрацию элементов текущей коллекции по `codeKey`\n\t */\n\tconst setFilteredItems = useCallback(\n\t\t(filters: CollectionItem[] | undefined) => {\n\t\t\tsetFilteredKeys(() => {\n\t\t\t\tif (filters?.length) {\n\t\t\t\t\treturn new Set(filters.map((item) => item[codeKey]));\n\t\t\t\t}\n\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t},\n\t\t[codeKey]\n\t);\n\n\tconst getItems = useCallback(\n\t\t(\n\t\t\tpredicate?: (codeValue: string, textValue: string) => boolean,\n\t\t\tcurrentSelectedKeys?: readonly CollectionItem[]\n\t\t): CollectionItem[] => {\n\t\t\tif (!orderedKeys.length) return [];\n\n\t\t\tconst limit = maxVisibleItems;\n\t\t\tconst selectedKeysSet = new Set<string>();\n\t\t\tconst resultItems: CollectionItem[] = [];\n\n\t\t\tif (currentSelectedKeys?.length) {\n\t\t\t\t// Быстрое заполнение Set без создания временного массива\n\t\t\t\tfor (let i = 0; i < currentSelectedKeys.length; i++) {\n\t\t\t\t\tselectedKeysSet.add(currentSelectedKeys[i][codeKey]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet count = 0;\n\n\t\t\tconst existsDependencies = filteredKeys && filteredKeys.size > 0;\n\n\t\t\t// Единый проход с ранним выходом по лимиту\n\t\t\tfor (const key of orderedKeys) {\n\t\t\t\tif (count >= limit) break;\n\n\t\t\t\tconst item = itemsMap.get(key);\n\t\t\t\tif (!item) continue;\n\n\t\t\t\t// Проверка на исключение выбранных ключей\n\t\t\t\tif (selectedKeysSet.size > 0 && selectedKeysSet.has(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemCode = item[codeKey];\n\n\t\t\t\tif (existsDependencies && !filteredKeys.has(itemCode)) continue;\n\n\t\t\t\t// Проверка внешнего предиката\n\t\t\t\tif (predicate && !predicate(itemCode, item[textKey])) continue;\n\n\t\t\t\tresultItems.push(item);\n\t\t\t\tcount++;\n\t\t\t}\n\n\t\t\treturn resultItems;\n\t\t},\n\t\t[orderedKeys, maxVisibleItems, codeKey, itemsMap, filteredKeys, textKey]\n\t);\n\n\t/**\n\t * Получает страницу данных для виртуализации.\n\t */\n\tconst getPage = useCallback(\n\t\t(pageIndex: number): CollectionItem[] => {\n\t\t\tconst allItems = rawData?.separated[codeKey] || [];\n\t\t\tconst start = pageIndex * pageSize;\n\t\t\tconst end = start + pageSize;\n\t\t\treturn allItems.slice(start, end);\n\t\t},\n\t\t[rawData, pageSize, codeKey]\n\t);\n\n\t/**\n\t * Находит несколько элементов по ключам.\n\t */\n\tconst findSourceItemsByKeys = useCallback(\n\t\t(key: string, keys: string[]) => {\n\t\t\tif (!rawData) return [];\n\n\t\t\tconst keysSet = new Set<string>(keys);\n\t\t\treturn rawData.items.filter((item) => keysSet.has(item[key]));\n\t\t},\n\t\t[rawData]\n\t);\n\n\t/**\n\t * Дебаунсинг для частых операций.\n\t */\n\tconst debounce = useCallback((key: string, fn: () => void, delay: number = 200) => {\n\t\t// Очищаем предыдущий таймер\n\t\tif (debounceTimers.current.has(key)) {\n\t\t\tclearTimeout(debounceTimers.current.get(key)!);\n\t\t}\n\n\t\t// Устанавливаем новый таймер\n\t\tconst timer = setTimeout(fn, delay);\n\t\tdebounceTimers.current.set(key, timer);\n\t}, []);\n\n\t/**\n\t * Очищает все дебаунс таймеры.\n\t */\n\tconst clearDebounceTimers = useCallback(() => {\n\t\tfor (const timer of debounceTimers.current.values()) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t\tdebounceTimers.current.clear();\n\t}, []);\n\n\t// Очистка таймеров при размонтировании\n\tuseMemo(() => {\n\t\treturn () => {\n\t\t\tclearDebounceTimers();\n\t\t};\n\t}, [clearDebounceTimers]);\n\n\treturn {\n\t\t// Состояние данных\n\t\tdata: rawData,\n\t\tisLoading,\n\t\tisError,\n\n\t\tcodeKey,\n\t\ttextKey,\n\n\t\t// Функции для работы с коллекцией\n\t\tgetItems,\n\t\tfindSourceItemsByKeys,\n\t\tsetFilteredItems,\n\t\tgetPage,\n\t\tbuildSearchIndex,\n\t\tdebounce,\n\n\t\t// Вспомогательные данные\n\t\titemsMap,\n\t\tseparatedItems,\n\t\torderedKeys,\n\n\t\t// Управление запросом\n\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\trefetch,\n\t\t/**\n\t\t * @deprecated нужен только на этапе проектирования, скоро будет удален\n\t\t */\n\t\tinvalidate: () => queryClient.invalidateQueries({ queryKey: createODataCollectionQueryKey(odata) }),\n\n\t\t// Метаданные для виртуализации\n\t\ttotalCount: rawData?.separated[codeKey]?.length || 0,\n\t\tpageSize\n\t};\n}\n","import { useEffect, useMemo, useState } from \"react\";\n\nimport { Query, useQueryClient } from \"@tanstack/react-query\";\n\nimport { createODataCollectionQueryKey } from \"./createODataCollectionQueryKey\";\nimport { ODataServiceCollectionConfig } from \"./types\";\n\nimport type { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Используется для получения последовательностей кодов.\n */\nexport function useODataCollectionChains(params: ODataServiceCollectionConfig[]) {\n\tconst queryClient = useQueryClient();\n\tconst [chains, setChains] = useState<ODataChainsMap>({});\n\n\tconst trackedKeys = useMemo(() => params.map((p) => createODataCollectionQueryKey(p)), [params]);\n\n\tuseEffect(() => {\n\t\tfunction updateChains() {\n\t\t\tconst newChains: ODataChainsMap = {};\n\n\t\t\tfor (const p of params) {\n\t\t\t\tconst key = createODataCollectionQueryKey(p);\n\t\t\t\tconst cached = queryClient.getQueryData<{ chain: { codeKey: string; count: number }[] }>(key);\n\t\t\t\tif (cached?.chain) {\n\t\t\t\t\tnewChains[`${p.service}.${p.target}`] = cached.chain;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsetChains((prev) => {\n\t\t\t\t// не обновлять стейт, если данные не изменились (во избежание лишних рендеров)\n\t\t\t\tconst same =\n\t\t\t\t\tObject.keys(prev).length === Object.keys(newChains).length &&\n\t\t\t\t\tObject.entries(newChains).every(([k, v]) => prev[k] === v);\n\t\t\t\treturn same ? prev : newChains;\n\t\t\t});\n\t\t}\n\n\t\t// Первичная загрузка (на случай, если данные уже в кэше)\n\t\tupdateChains();\n\n\t\t// Подписка на изменения кэша\n\t\tconst unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n\t\t\t// Проверяем, затрагивает ли событие один из наших trackedKeys\n\t\t\tif (event?.query) {\n\t\t\t\tconst query = event.query as Query;\n\t\t\t\tconst isTracked = trackedKeys.some((key) => JSON.stringify(key) === JSON.stringify(query.queryKey));\n\t\t\t\tif (isTracked) {\n\t\t\t\t\tupdateChains();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn unsubscribe;\n\t}, [params, queryClient, trackedKeys]);\n\n\treturn chains;\n}\n","import { useState } from \"react\";\n\nimport { useODataCollectionStore } from \"@ryuzaki13/react-foundation-lib/odata\";\n\nimport { ODataCollectionModel } from \"./types\";\n\nexport function useODataCollectionModel(model: ODataCollectionModel): Required<ODataCollectionModel> {\n\t// NOTE: без подписки, потому что эти данные в рантайме не предполагается изменять в ближайшее время.\n\n\t// const defaultMaxVisibleItems = odataCollectionConfig.useMaxVisibleItems();\n\t// const defaultMinSearchCodeLength = odataCollectionConfig.useMinSearchCodeLength();\n\t// const defaultMinSearchTextLength = odataCollectionConfig.useMinSearchTextLength();\n\t// const defaultSearchDebounceDelay = odataCollectionConfig.useSearchDebounce();\n\n\tconst [stableModel] = useState(() => {\n\t\tconst defaultState = useODataCollectionStore.getState();\n\n\t\tconst {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems = defaultState.defaultMaxVisibleItems,\n\t\t\tminSearchCodeLength = defaultState.defaultMinSearchCodeLength,\n\t\t\tminSearchTextLength = defaultState.defaultMinSearchTextLength,\n\t\t\tsearchDebounceDelay = defaultState.defaultSearchDebounceDelay\n\t\t} = model;\n\t\treturn {\n\t\t\tcodeKey,\n\t\t\tmaxVisibleItems,\n\t\t\tminSearchCodeLength,\n\t\t\tminSearchTextLength,\n\t\t\tsearchDebounceDelay\n\t\t};\n\t});\n\n\treturn stableModel;\n}\n","import { useMemo } from \"react\";\n\nimport {\n\ttype TableColumnDef,\n\ttype TableColumnFormattingMetaInput,\n\tcreateTableColumnVisibilityFromODataMetadata,\n\tcreateTableColumnsFromODataMetadata,\n\tenrichTableColumnsWithODataFormatting,\n\tresolveStableColumnId\n} from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { useODataMetadata } from \"./useODataMetadata\";\n\nimport type { EntityColumnProperty, EntityMetadata, ODataServiceConfig } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\n/**\n * Собирает visibility-state только для тех leaf-колонок, которые сопоставились с metadata.\n */\nfunction collectMatchedColumnVisibility<TData extends object>(\n\tcolumns: readonly TableColumnDef<TData>[],\n\tvisibilityById: Readonly<Record<string, boolean>>\n): Record<string, boolean> {\n\tconst matchedVisibility: Record<string, boolean> = {};\n\n\tconst visitLeafColumns = (nestedColumns: readonly TableColumnDef<TData>[]) => {\n\t\tfor (const column of nestedColumns) {\n\t\t\tif (\"columns\" in column && Array.isArray(column.columns) && column.columns.length > 0) {\n\t\t\t\tvisitLeafColumns(column.columns as TableColumnDef<TData>[]);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst columnId = resolveStableColumnId(column);\n\t\t\tif (!columnId || !(columnId in visibilityById)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tmatchedVisibility[columnId] = visibilityById[columnId];\n\t\t}\n\t};\n\n\tvisitLeafColumns(columns);\n\n\treturn matchedVisibility;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `build`.\n */\nexport interface UseODataTableColumnsBuildConfig extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим генерации колонок только по metadata.\n\t */\n\tmode: \"build\";\n\t/**\n\t * Позволяет определить видимость колонки при генерации.\n\t */\n\tresolveVisible?: (column: EntityColumnProperty) => boolean;\n\t/**\n\t * Позволяет переопределить заголовок колонки при генерации.\n\t */\n\tresolveHeader?: (column: EntityColumnProperty) => string;\n\t/**\n\t * Позволяет сразу навесить formatting-конфиг на generated column.\n\t */\n\tresolveFormatting?: (column: EntityColumnProperty) => TableColumnFormattingMetaInput | undefined;\n}\n\n/**\n * Конфиг hook-адаптера колонок в режиме `enrich`.\n */\nexport interface UseODataTableColumnsEnrichConfig<TData extends object> extends Pick<ODataServiceConfig, \"service\" | \"target\"> {\n\t/**\n\t * Режим обогащения уже существующих колонок.\n\t */\n\tmode: \"enrich\";\n\t/**\n\t * Существующий набор колонок для дозаполнения `meta.formatting.role/type`.\n\t */\n\tcolumns: readonly TableColumnDef<TData>[];\n}\n\n/**\n * Универсальный конфиг hook-адаптера колонок.\n */\nexport type UseODataTableColumnsConfig<TData extends object = Record<string, unknown>> =\n\tUseODataTableColumnsBuildConfig | UseODataTableColumnsEnrichConfig<TData>;\n\n/**\n * Результат работы hook-адаптера колонок.\n */\nexport interface UseODataTableColumnsResult<TData extends object> {\n\t/**\n\t * Итоговый набор колонок для `Table` или `TreeTable`.\n\t */\n\tcolumns: TableColumnDef<TData>[];\n\t/**\n\t * Стартовая карта видимости колонок для TanStack Table.\n\t */\n\tdefaultColumnVisibility: Record<string, boolean> | undefined;\n\t/**\n\t * Метаданные сущности, если они уже загружены.\n\t */\n\tmetadata: EntityMetadata | undefined;\n\t/**\n\t * Признак загрузки metadata.\n\t */\n\tisLoading: boolean;\n}\n\n/**\n * Возвращает колонки для `Table`/`TreeTable` на основе OData metadata.\n *\n * В режиме `build` генерирует базовый набор колонок из `metadata.columns`.\n * В режиме `enrich` дозаполняет уже существующие колонки typed-formatting контекстом.\n */\nexport function useODataTableColumns<TData extends object = Record<string, unknown>>(\n\tconfig: UseODataTableColumnsConfig<TData>\n): UseODataTableColumnsResult<TData> {\n\tconst { metadata, isLoading } = useODataMetadata(config);\n\n\tconst columns = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn config.mode === \"build\" ? [] : [...config.columns];\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnsFromODataMetadata<TData>(metadata.columns, {\n\t\t\t\tresolveHeader: config.resolveHeader,\n\t\t\t\tresolveFormatting: config.resolveFormatting\n\t\t\t});\n\t\t}\n\n\t\treturn enrichTableColumnsWithODataFormatting(config.columns, metadata.columns);\n\t}, [config, metadata]);\n\n\tconst defaultColumnVisibility = useMemo(() => {\n\t\tif (!metadata) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (config.mode === \"build\") {\n\t\t\treturn createTableColumnVisibilityFromODataMetadata(metadata.columns, {\n\t\t\t\tresolveVisible: config.resolveVisible\n\t\t\t});\n\t\t}\n\n\t\tconst visibilityById = createTableColumnVisibilityFromODataMetadata(metadata.columns);\n\n\t\treturn collectMatchedColumnVisibility(config.columns, visibilityById);\n\t}, [config, metadata]);\n\n\treturn {\n\t\tcolumns,\n\t\tdefaultColumnVisibility,\n\t\tmetadata,\n\t\tisLoading\n\t};\n}\n","import { notify } from \"@ryuzaki13/react-foundation-lib/notifications\";\nimport { QueryClient } from \"@tanstack/react-query\";\n\nimport { buildODataFetchRequest, ODataFetchRequestPreview } from \"./odataFetch\";\nimport {\n\tODataArrayOperationMethod,\n\tODataCreateFnOptions,\n\tODataDeleteFnOptions,\n\todataFetchFn,\n\tODataFetchFnImplementationArgs,\n\tODataFetchFnRequest,\n\tODataFetchFnRunner,\n\tODataFetchFnSharedOptions,\n\tODataFunctionImportFnOptions,\n\tODataQueryArrayTransform,\n\tODataQueryFnOptions,\n\tODataQuerySingleTransform,\n\tODataReadFnOptions,\n\tODataSingleFetchFnRequest,\n\tODataSingleOperationMethod,\n\tODataSingleTransform,\n\tODataUpdateFnOptions\n} from \"./odataFetchFn\";\nimport {\n\tbuildTargetPath,\n\tisFunctionImportMetadata,\n\tresolveODataTarget,\n\tresolveRequestBody,\n\tresolveRequestMethod,\n\tvalidateODataOperation\n} from \"./odataFetchFnHelpers\";\nimport { resolveODataBaseUrl } from \"./transport\";\nimport { getODataMetadataData } from \"./useODataMetadataQuery\";\n\nimport type {\n\tODataOperationMethod,\n\tODataServiceConfig,\n\tODataTargetMetadata,\n\tUnwrappedODataParameters,\n\tWrappedODataParameters\n} from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\ntype ODataDevHelperName =\n\t| \"odataFetchFnDev\"\n\t| \"odataCreateFnDev\"\n\t| \"odataUpdateFnDev\"\n\t| \"odataDeleteFnDev\"\n\t| \"odataReadFnDev\"\n\t| \"odataQueryFnDev\"\n\t| \"odataFunctionImportFnDev\";\n\ntype ODataFetchFnDevOptions<I> = ODataFetchFnSharedOptions<I> & {\n\tparams?: WrappedODataParameters;\n\tbody?: unknown;\n\ttransform?: unknown;\n};\n\ntype ODataDevRequestLogInfo = {\n\thelperName: ODataDevHelperName;\n\toperation: ODataOperationMethod;\n\todata: ODataServiceConfig;\n\ttarget: ODataTargetMetadata;\n\ttargetPath: string;\n\trequest: ODataFetchRequestPreview;\n\trequestMethod: string;\n\tparams: WrappedODataParameters;\n\tqueryOptions: unknown;\n\tbody: string | undefined;\n\tautoParse: boolean | undefined;\n\thasTransform: boolean;\n};\n\nfunction getConsole() {\n\treturn globalThis.console;\n}\n\nfunction headersToRecord(headers: HeadersInit | undefined) {\n\tconst result: Record<string, string> = {};\n\tnew Headers(headers).forEach((value, key) => {\n\t\tresult[key] = value;\n\t});\n\n\treturn result;\n}\n\nfunction parseRequestBodyForLog(body: BodyInit | null | undefined): unknown {\n\tif (body === undefined || body === null) return undefined;\n\tif (typeof body !== \"string\") return body;\n\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(body);\n\t\treturn parsed;\n\t} catch {\n\t\treturn body;\n\t}\n}\n\nfunction isWriteRequest(method: string | undefined) {\n\treturn method !== undefined && ![\"GET\", \"HEAD\"].includes(method.toUpperCase());\n}\n\nfunction isSapRequestPreview(request: ODataFetchRequestPreview) {\n\tconst baseUrl = request.baseUrl ?? \"odata\";\n\tif (baseUrl !== \"\") return true;\n\n\treturn request.path.startsWith(\"/sap/\") || request.path.startsWith(\"/sap-dp0/\");\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string) {\n\tconst normalizedName = name.toLowerCase();\n\treturn Object.keys(headers).some((key) => key.toLowerCase() === normalizedName);\n}\n\nfunction setDefaultHeader(headers: Record<string, string>, name: string, value: string) {\n\tif (hasHeader(headers, name)) return;\n\theaders[name] = value;\n}\n\nfunction buildTransportHeadersPreview(request: ODataFetchRequestPreview) {\n\tconst headers = headersToRecord(request.init.headers);\n\tconst method = request.init.method;\n\tconst sapRequest = isSapRequestPreview(request);\n\n\tsetDefaultHeader(headers, \"DataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"MaxDataServiceVersion\", \"2.0\");\n\tsetDefaultHeader(headers, \"Accept\", \"application/json\");\n\n\theaders[\"sap-language\"] = \"ru\";\n\n\tif (sapRequest) {\n\t\theaders[\"sap-contextid-accept\"] = \"header\";\n\t}\n\n\tif (isWriteRequest(method) && request.init.body) {\n\t\tsetDefaultHeader(headers, \"Content-Type\", \"application/json\");\n\t}\n\n\tif (isWriteRequest(method) && sapRequest) {\n\t\tsetDefaultHeader(headers, \"x-csrf-token\", \"<получается отдельным GET перед реальным write-запросом>\");\n\t}\n\n\treturn headers;\n}\n\nfunction getTargetKind(target: ODataTargetMetadata) {\n\tif (isFunctionImportMetadata(target)) return \"FunctionImport\";\n\treturn target.result ? \"Parameterized Entity\" : \"Entity\";\n}\n\nfunction logObjectSection(title: string, value: unknown) {\n\tconst logger = getConsole();\n\tlogger.groupCollapsed(title);\n\tlogger.info(value);\n\tlogger.groupEnd();\n}\n\nfunction logODataDevRequest(info: ODataDevRequestLogInfo) {\n\tconst logger = getConsole();\n\tconst bodyPreview = parseRequestBodyForLog(info.request.init.body);\n\tconst initHeaders = headersToRecord(info.request.init.headers);\n\tconst transportHeaders = buildTransportHeadersPreview(info.request);\n\tconst requestInitPreview = {\n\t\tmethod: info.request.init.method,\n\t\theaders: initHeaders,\n\t\tbody: bodyPreview,\n\t\thasSignal: Boolean(info.request.init.signal)\n\t};\n\n\tlogger.groupCollapsed(`[OData DEV] ${info.requestMethod} ${info.request.fullUrl}`);\n\tlogger.table([\n\t\t{\n\t\t\thelper: info.helperName,\n\t\t\toperation: info.operation,\n\t\t\ttarget: info.odata.target,\n\t\t\ttargetKind: getTargetKind(info.target),\n\t\t\tservice: info.odata.service,\n\t\t\trealFetch: \"не выполнялся\"\n\t\t}\n\t]);\n\tlogger.info(\"Итоговый URL:\", info.request.fullUrl);\n\tlogger.info(\"Path без base URL:\", info.request.path);\n\tlogger.info(\"Target path до query options:\", info.targetPath);\n\tlogger.info(\"Query string:\", info.request.queryString || \"<пусто>\");\n\tlogger.info(\"Body:\", bodyPreview ?? \"<пусто>\");\n\tlogger.info(\"Auto parse:\", info.autoParse ?? false);\n\tlogger.info(\"Transform:\", info.hasTransform ? \"передан, но не вызывается без ответа backend\" : \"не передан\");\n\tlogger.info(\"Dry-run result:\", info.operation === \"query\" ? { data: [], totalCount: 0 } : { data: undefined });\n\tlogObjectSection(\"OData config\", info.odata);\n\tlogObjectSection(\"Target metadata\", info.target);\n\tlogObjectSection(\"Target params\", info.params);\n\tlogObjectSection(\"Query options\", info.queryOptions);\n\tlogObjectSection(\"RequestInit, переданный в transport\", requestInitPreview);\n\tlogObjectSection(\"Заголовки после transport defaults (без реального fetch)\", transportHeaders);\n\tlogger.groupEnd();\n}\n\nfunction notifyODataDevHelperCall(helperName: ODataDevHelperName) {\n\tnotify.warning(`${helperName}: DEV dry-run OData запроса. Реальный запрос не выполняется, payload выведен в console.`, {\n\t\ttitle: \"OData DEV helper\"\n\t});\n}\n\nfunction createODataFetchFnDevRunner<I>(\n\tmethod: ODataOperationMethod,\n\topts: ODataFetchFnDevOptions<I>,\n\thelperName: ODataDevHelperName\n): ODataFetchFnRunner<unknown> {\n\tconst { odata, options = {}, init = {}, autoParse, swCache } = opts;\n\tconst params = opts.params ?? {};\n\n\treturn async ({ client, signal }: { client: QueryClient; signal?: AbortSignal }) => {\n\t\tnotifyODataDevHelperCall(helperName);\n\n\t\tconst baseUrl = resolveODataBaseUrl(odata.service, options.baseUrl);\n\t\tconst serviceMetadata = await getODataMetadataData({ service: odata.service, baseUrl }, client);\n\t\tif (!serviceMetadata) {\n\t\t\tthrow new Error(`Не удалось загрузить metadata OData-сервиса '${odata.service}'`);\n\t\t}\n\n\t\tconst target = resolveODataTarget(serviceMetadata, odata.target);\n\n\t\tvalidateODataOperation(target, method, odata);\n\n\t\tconst body = resolveRequestBody(opts.body, method);\n\t\tconst requestMethod = resolveRequestMethod(target, method);\n\t\tconst targetPath = buildTargetPath(target, odata, params, method);\n\n\t\tconst queryOptions = swCache ? { ...options, baseUrl, swCache } : { ...options, baseUrl };\n\t\tconst requestInit = { ...init, method: requestMethod, body, signal };\n\t\tconst request = buildODataFetchRequest(targetPath, queryOptions, requestInit);\n\n\t\tlogODataDevRequest({\n\t\t\thelperName,\n\t\t\toperation: method,\n\t\t\todata,\n\t\t\ttarget,\n\t\t\ttargetPath,\n\t\t\trequest,\n\t\t\trequestMethod,\n\t\t\tparams,\n\t\t\tqueryOptions,\n\t\t\tbody,\n\t\t\tautoParse,\n\t\t\thasTransform: Boolean(opts.transform)\n\t\t});\n\n\t\tif (method === \"query\") {\n\t\t\treturn { data: [], totalCount: 0 };\n\t\t}\n\n\t\treturn { data: undefined };\n\t};\n}\n\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }): ODataFetchFnRunner<O[]>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataArrayOperationMethod = ODataArrayOperationMethod\n>(method: M, opts: ODataQueryFnOptions<I, I, P> & { transform?: undefined }): ODataFetchFnRunner<I[]>;\nexport function odataFetchFnDev<\n\tI,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataSingleOperationMethod = ODataSingleOperationMethod\n>(method: M, opts: ODataSingleFetchFnRequest<M, I, I, T, P> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataFetchFnDev<I, O = I, T = I, M extends ODataSingleOperationMethod = ODataSingleOperationMethod>(\n\tmethod: M,\n\topts: ODataSingleFetchFnRequest<M, I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFetchFnDev<\n\tI,\n\tO = I,\n\tT = I,\n\tP extends UnwrappedODataParameters = UnwrappedODataParameters,\n\tM extends ODataOperationMethod = ODataOperationMethod\n>(method: M, opts: ODataFetchFnRequest<M, I, O, T, P>): ODataFetchFnRunner<unknown>;\nexport function odataFetchFnDev(...args: ODataFetchFnImplementationArgs): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\tswitch (args[0]) {\n\t\t\tcase \"create\": {\n\t\t\t\treturn odataFetchFn(\"create\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"update\": {\n\t\t\t\treturn odataFetchFn(\"update\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"delete\": {\n\t\t\t\treturn odataFetchFn(\"delete\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"read\": {\n\t\t\t\treturn odataFetchFn(\"read\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"query\": {\n\t\t\t\treturn odataFetchFn(\"query\", args[1]);\n\t\t\t}\n\n\t\t\tcase \"fi\": {\n\t\t\t\treturn odataFetchFn(\"fi\", args[1]);\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst checker: never = args[0];\n\t\t\t\tvoid checker;\n\n\t\t\t\tthrow new Error(\"Неподдерживаемая OData operation в odataFetchFnDev\");\n\t\t\t}\n\t\t}\n\t}\n\n\tconst [method, opts] = args;\n\treturn createODataFetchFnDevRunner(method, opts, \"odataFetchFnDev\");\n}\n\nexport function odataCreateFnDev<I, T = I>(opts: ODataCreateFnOptions<I, I, T> & { transform?: undefined }): ODataFetchFnRunner<I>;\nexport function odataCreateFnDev<I, O = I, T = I>(\n\topts: ODataCreateFnOptions<I, O, T> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataCreateFnDev<I, O = I, T = I>(opts: ODataCreateFnOptions<I, O, T>): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, never, \"create\">(\"create\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"create\", opts, \"odataCreateFnDev\");\n}\n\nexport function odataUpdateFnDev<I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, I, T, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataUpdateFnDev<I, O = I, T = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataUpdateFnOptions<I, O, T, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, T, P, \"update\">(\"update\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"update\", opts, \"odataUpdateFnDev\");\n}\n\nexport function odataDeleteFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataDeleteFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataDeleteFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"delete\">(\"delete\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"delete\", opts, \"odataDeleteFnDev\");\n}\n\nexport function odataReadFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataReadFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataReadFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"read\">(\"read\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"read\", opts, \"odataReadFnDev\");\n}\n\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQueryArrayTransform<I, O> }\n): ODataFetchFnRunner<O[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform: ODataQuerySingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P> & { transform?: undefined }\n): ODataFetchFnRunner<I[]>;\nexport function odataQueryFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataQueryFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, void, P, \"query\">(\"query\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"query\", opts, \"odataQueryFnDev\");\n}\n\nexport function odataFunctionImportFnDev<I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, I, P> & { transform?: undefined }\n): ODataFetchFnRunner<I>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P> & { transform: ODataSingleTransform<I, O> }\n): ODataFetchFnRunner<O>;\nexport function odataFunctionImportFnDev<I, O = I, P extends UnwrappedODataParameters = UnwrappedODataParameters>(\n\topts: ODataFunctionImportFnOptions<I, O, P>\n): ODataFetchFnRunner<unknown> {\n\tif (!__DEV__) {\n\t\treturn odataFetchFn<I, O, I, P, \"fi\">(\"fi\", opts);\n\t}\n\n\treturn createODataFetchFnDevRunner<I>(\"fi\", opts, \"odataFunctionImportFnDev\");\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectODataCollectionSort.d.ts","sourceRoot":"","sources":["../../src/odata/projectODataCollectionSort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"projectODataCollectionSort.d.ts","sourceRoot":"","sources":["../../src/odata/projectODataCollectionSort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAW5E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,CAAC,SAAS,cAAc,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC,CAAC,CA8BrI"}
|