@web-ts-toolkit/access-router-client 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +258 -14
- package/index.d.mts +453 -85
- package/index.d.ts +453 -85
- package/index.js +1133 -368
- package/index.mjs +1133 -368
- package/llms.txt +39 -5
- package/package.json +11 -4
package/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var index_exports = {};
|
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
CustomHeaders: () => CustomHeaders,
|
|
33
33
|
DataService: () => DataService,
|
|
34
|
+
MissingPersistenceIdentityError: () => MissingPersistenceIdentityError,
|
|
34
35
|
Model: () => Model,
|
|
35
36
|
ModelService: () => ModelService,
|
|
36
37
|
Service: () => Service,
|
|
@@ -44,46 +45,163 @@ module.exports = __toCommonJS(index_exports);
|
|
|
44
45
|
|
|
45
46
|
// src/adapter.ts
|
|
46
47
|
var import_axios8 = __toESM(require("axios"));
|
|
47
|
-
var import_utils7 = require("@web-ts-toolkit/utils");
|
|
48
48
|
|
|
49
49
|
// src/services/model-service.ts
|
|
50
|
-
var
|
|
51
|
-
var import_utils5 = require("@web-ts-toolkit/utils");
|
|
50
|
+
var import_axios6 = require("axios");
|
|
52
51
|
|
|
53
52
|
// src/model.ts
|
|
54
53
|
var import_utils = require("@web-ts-toolkit/utils");
|
|
54
|
+
var MissingPersistenceIdentityError = class extends Error {
|
|
55
|
+
constructor(message) {
|
|
56
|
+
super(message);
|
|
57
|
+
this.name = "MissingPersistenceIdentityError";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
55
60
|
var Model = class _Model {
|
|
56
|
-
constructor(data, adapter) {
|
|
61
|
+
constructor(data, adapter, persistenceId, fromExisting) {
|
|
57
62
|
this.modifiedPaths = /* @__PURE__ */ new Set();
|
|
63
|
+
this._persistenceId = persistenceId;
|
|
64
|
+
this._fromExisting = fromExisting ?? false;
|
|
58
65
|
this._snapshot = (0, import_utils.cloneDeep)(data);
|
|
59
66
|
this.defineHiddenDataProp((0, import_utils.cloneDeep)(data));
|
|
60
67
|
this.defineHiddenAdapterProp(adapter);
|
|
61
68
|
this.definePublicDataProps();
|
|
62
69
|
this.initializeDirtyState();
|
|
63
70
|
}
|
|
64
|
-
static create(data, adapter) {
|
|
65
|
-
return new _Model(data, adapter);
|
|
66
|
-
}
|
|
71
|
+
static create(data, adapter, persistenceId, fromExisting) {
|
|
72
|
+
return new _Model(data, adapter, persistenceId, fromExisting);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Persists the currently dirty paths to the server, then merges the
|
|
76
|
+
* server's response back into local state.
|
|
77
|
+
*
|
|
78
|
+
* Concurrency contract:
|
|
79
|
+
*
|
|
80
|
+
* 1. Submitted paths and their values are snapshotted before the request
|
|
81
|
+
* starts, so an in-flight response cannot wipe edits that were made
|
|
82
|
+
* while the request was pending.
|
|
83
|
+
* 2. On success, a submitted path is cleared from `modifiedPaths` only if
|
|
84
|
+
* its current local value still equals the submitted value — i.e. the
|
|
85
|
+
* user has not concurrently re-edited it to a different value.
|
|
86
|
+
* 3. Server-returned values overwrite local values for paths the user did
|
|
87
|
+
* NOT concurrently re-modify during the in-flight save; for paths the
|
|
88
|
+
* user did concurrently re-modify, the local value is preserved and
|
|
89
|
+
* the dirty flag is retained so the concurrent edit is resubmitted on
|
|
90
|
+
* the next `save()`. (Deterministic conflict rule: the newer local
|
|
91
|
+
* edit wins for the same path; the server value becomes its reset
|
|
92
|
+
* baseline without replacing the newer local value.)
|
|
93
|
+
* 4. On failure, no dirty state is cleared and no local value is
|
|
94
|
+
* overwritten; the caller can retry `save()` with the same set.
|
|
95
|
+
* 5. The return value echoes `{ ...result, data }` where `data` is a
|
|
96
|
+
* refreshed `Model` snapshot of the post-save local state (or `null`
|
|
97
|
+
* on failure), matching `ModelResponse<T, TData>`.
|
|
98
|
+
*
|
|
99
|
+
* Persistence identity (ARC-21): create-vs-update is resolved from a
|
|
100
|
+
* captured persistence identity rather than from the projected `_data`
|
|
101
|
+
* payload alone, so a read that strips `_id` (e.g. `select: { name: 1,
|
|
102
|
+
* _id: 0 }`) cannot turn a subsequent `save()` into a silent create of
|
|
103
|
+
* a duplicate. When `_data._id` is present it takes precedence so callers
|
|
104
|
+
* can still deliberately aim `_id` at a bogus id to observe a failing
|
|
105
|
+
* save. When neither `_data._id` nor a captured persistence identity is
|
|
106
|
+
* available (e.g. `readAdvancedFilter` with an `_id`-excluding
|
|
107
|
+
* projection), `save()` throws `MissingPersistenceIdentityError` instead
|
|
108
|
+
* of POSTing a new document.
|
|
109
|
+
*/
|
|
67
110
|
async save(reqConfig) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
const submittedPaths = new Set(this.modifiedPaths);
|
|
112
|
+
const submittedValues = {};
|
|
113
|
+
for (const path of submittedPaths) {
|
|
114
|
+
submittedValues[path] = (0, import_utils.cloneDeep)((0, import_utils.get)(this._data, path));
|
|
115
|
+
}
|
|
116
|
+
const submittedData = this.prepareData();
|
|
117
|
+
const persistenceId = this._data._id ?? this._persistenceId;
|
|
118
|
+
if (persistenceId == null && this._fromExisting) {
|
|
119
|
+
throw new MissingPersistenceIdentityError(
|
|
120
|
+
"Model.save() cannot determine create-vs-update without a persistence identity. A read of an existing document produced a Model whose projection strips `_id` and no identity was captured at read time. Use `read(id)` / `readAdvanced(id, ...)` (which capture the identifier as a persistence identity), or include `_id` in the projection."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const isCreate = persistenceId == null;
|
|
124
|
+
const result = isCreate ? await this._service.create(submittedData, null, reqConfig) : await this._service.update(String(persistenceId), submittedData, { returningAll: false }, reqConfig);
|
|
125
|
+
if (!result.success) {
|
|
126
|
+
return { ...result, data: null };
|
|
127
|
+
}
|
|
128
|
+
const isConcurrentEdit = (path) => {
|
|
129
|
+
if (!submittedPaths.has(path)) {
|
|
130
|
+
return this.modifiedPaths.has(path);
|
|
131
|
+
}
|
|
132
|
+
const current = (0, import_utils.get)(this._data, path);
|
|
133
|
+
const submitted = submittedValues[path];
|
|
134
|
+
return !(0, import_utils.isEqual)(current, submitted);
|
|
135
|
+
};
|
|
136
|
+
const serverData = result.raw ?? {};
|
|
137
|
+
for (const key of Object.keys(serverData)) {
|
|
138
|
+
const normKey = this.normalizePath(key);
|
|
139
|
+
if (normKey === "_id") continue;
|
|
140
|
+
if (isConcurrentEdit(normKey)) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const serverValue = serverData[key];
|
|
144
|
+
const before = (0, import_utils.get)(this._data, normKey);
|
|
145
|
+
if (!(0, import_utils.isEqual)(before, serverValue)) {
|
|
146
|
+
this._data[normKey] = serverValue;
|
|
147
|
+
}
|
|
148
|
+
this.modifiedPaths.delete(normKey);
|
|
73
149
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
150
|
+
for (const path of submittedPaths) {
|
|
151
|
+
if (!isConcurrentEdit(path)) {
|
|
152
|
+
this.modifiedPaths.delete(path);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (isCreate && serverData._id != null) {
|
|
156
|
+
this._data._id = String(serverData._id);
|
|
157
|
+
this.modifiedPaths.delete("_id");
|
|
158
|
+
}
|
|
159
|
+
const latestId = this._data._id ?? (serverData._id != null ? String(serverData._id) : void 0);
|
|
160
|
+
if (latestId != null) {
|
|
161
|
+
this._persistenceId = latestId;
|
|
162
|
+
}
|
|
163
|
+
const nextSnapshot = Array.isArray(this._snapshot) ? [] : {};
|
|
164
|
+
const dataRecord = this._data;
|
|
165
|
+
for (const key of Object.keys(dataRecord)) {
|
|
166
|
+
const normKey = this.normalizePath(key);
|
|
167
|
+
if (this.modifiedPaths.has(normKey)) {
|
|
168
|
+
if (submittedPaths.has(normKey)) {
|
|
169
|
+
nextSnapshot[key] = (0, import_utils.cloneDeep)((0, import_utils.hasOwn)(serverData, key) ? serverData[key] : submittedValues[normKey]);
|
|
170
|
+
} else {
|
|
171
|
+
nextSnapshot[key] = (0, import_utils.cloneDeep)(this._snapshot[key]);
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
nextSnapshot[key] = (0, import_utils.cloneDeep)(dataRecord[key]);
|
|
175
|
+
}
|
|
78
176
|
}
|
|
177
|
+
this._snapshot = nextSnapshot;
|
|
178
|
+
this.definePublicDataProps();
|
|
79
179
|
return {
|
|
80
180
|
...result,
|
|
81
|
-
|
|
181
|
+
// The post-save snapshot is always an existing document, so propagate
|
|
182
|
+
// `_fromExisting=true` plus the refreshed persistence identity so the
|
|
183
|
+
// returned wrapper cannot later silently create a duplicate. (If the
|
|
184
|
+
// caller intends a fresh draft, they construct `new Model({...}, s)`
|
|
185
|
+
// directly — `${_fromExisting}` defaults to `false` there.)
|
|
186
|
+
data: _Model.create(this._data, this._service, this._persistenceId, true)
|
|
82
187
|
};
|
|
83
188
|
}
|
|
84
189
|
isDirty(path) {
|
|
85
190
|
return path ? this.modifiedPaths.has(this.normalizePath(String(path))) : this.modifiedPaths.size > 0;
|
|
86
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Marks a path dirty and skips snapshot reconciliation. This is the
|
|
194
|
+
* explicit "include this path on the next save()" escape hatch: even when
|
|
195
|
+
* the effective value still equals the snapshot, the path stays dirty so
|
|
196
|
+
* callers can force a field to be re-sent to the server (e.g., to retrigger
|
|
197
|
+
* server-side defaults or to re-submit a value that another client may
|
|
198
|
+
* have reverted).
|
|
199
|
+
*
|
|
200
|
+
* For implicit writes that reconcile against the snapshot automatically
|
|
201
|
+
* (reverting a field to its baseline clears the dirty flag), use `set()`,
|
|
202
|
+
* `assign(...)`, or direct property assignment — those entry points all
|
|
203
|
+
* run `reconcilePath` after the write.
|
|
204
|
+
*/
|
|
87
205
|
markModified(path) {
|
|
88
206
|
this.trackModified(String(path));
|
|
89
207
|
return this;
|
|
@@ -99,6 +217,7 @@ var Model = class _Model {
|
|
|
99
217
|
(0, import_utils.set)(this._data, path, value);
|
|
100
218
|
this.trackModified(path);
|
|
101
219
|
this.definePublicDataProps();
|
|
220
|
+
this.reconcilePath(this.normalizePath(path));
|
|
102
221
|
return this;
|
|
103
222
|
}
|
|
104
223
|
assign(partial) {
|
|
@@ -111,6 +230,9 @@ var Model = class _Model {
|
|
|
111
230
|
}
|
|
112
231
|
}
|
|
113
232
|
this.definePublicDataProps();
|
|
233
|
+
for (let x = 0; x < keys.length; x++) {
|
|
234
|
+
this.reconcilePath(this.normalizePath(String(keys[x])));
|
|
235
|
+
}
|
|
114
236
|
return this;
|
|
115
237
|
}
|
|
116
238
|
reset() {
|
|
@@ -124,10 +246,6 @@ var Model = class _Model {
|
|
|
124
246
|
toJSON() {
|
|
125
247
|
return this.toObject();
|
|
126
248
|
}
|
|
127
|
-
updateModel(data) {
|
|
128
|
-
(0, import_utils.assign)(this._data, data);
|
|
129
|
-
this.definePublicDataProps();
|
|
130
|
-
}
|
|
131
249
|
replaceData(data) {
|
|
132
250
|
const nextData = (0, import_utils.cloneDeep)(data);
|
|
133
251
|
const currentKeys = Object.keys(this._data);
|
|
@@ -141,7 +259,7 @@ var Model = class _Model {
|
|
|
141
259
|
this.definePublicDataProps();
|
|
142
260
|
}
|
|
143
261
|
initializeDirtyState() {
|
|
144
|
-
if (this._data._id) {
|
|
262
|
+
if (this._fromExisting || this._data._id) {
|
|
145
263
|
return;
|
|
146
264
|
}
|
|
147
265
|
const keys = Object.keys(this._data);
|
|
@@ -165,6 +283,7 @@ var Model = class _Model {
|
|
|
165
283
|
}
|
|
166
284
|
this.trackModified(keystr);
|
|
167
285
|
target[key] = value;
|
|
286
|
+
this.reconcilePath(this.normalizePath(keystr));
|
|
168
287
|
return true;
|
|
169
288
|
}
|
|
170
289
|
}),
|
|
@@ -200,6 +319,25 @@ var Model = class _Model {
|
|
|
200
319
|
normalizePath(path) {
|
|
201
320
|
return path.split(".")[0];
|
|
202
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Removes `path` from the dirty set when its current top-level value deeply
|
|
324
|
+
* equals the snapshot baseline. Used uniformly by `set()`, `assign()`,
|
|
325
|
+
* public property setters (via the proxy), and `markModified()` so all
|
|
326
|
+
* entry points share the same tracking rule.
|
|
327
|
+
*
|
|
328
|
+
* Note: `_id` is intentionally never reconciled away here — it is excluded
|
|
329
|
+
* from `initializeDirtyState` and managed explicitly during `save()`
|
|
330
|
+
* reconciliation.
|
|
331
|
+
*/
|
|
332
|
+
reconcilePath(path) {
|
|
333
|
+
if (path === "_id") return;
|
|
334
|
+
if (!this.modifiedPaths.has(path)) return;
|
|
335
|
+
const current = this._data[path];
|
|
336
|
+
const base = this._snapshot[path];
|
|
337
|
+
if ((0, import_utils.isEqual)(current, base)) {
|
|
338
|
+
this.modifiedPaths.delete(path);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
203
341
|
};
|
|
204
342
|
|
|
205
343
|
// src/services/service.ts
|
|
@@ -210,14 +348,13 @@ var CACHE_HEADER = "x-axios-cache";
|
|
|
210
348
|
|
|
211
349
|
// src/services/wrap.ts
|
|
212
350
|
var import_axios = require("axios");
|
|
213
|
-
var import_utils3 = require("@web-ts-toolkit/utils");
|
|
214
351
|
|
|
215
352
|
// src/helpers.ts
|
|
216
353
|
var import_utils2 = require("@web-ts-toolkit/utils");
|
|
217
354
|
function replaceSubQuery(filter) {
|
|
218
355
|
if (!(0, import_utils2.isPlainObject)(filter)) return filter;
|
|
219
356
|
const ret = (0, import_utils2.mapValues)(filter, (val) => {
|
|
220
|
-
if (val && val.__op && val.__query) {
|
|
357
|
+
if ((0, import_utils2.isPlainObject)(val) && "__op" in val && val.__op && "__query" in val && val.__query) {
|
|
221
358
|
return {
|
|
222
359
|
$$sq: val.__query
|
|
223
360
|
};
|
|
@@ -232,16 +369,20 @@ function replaceSubQuery(filter) {
|
|
|
232
369
|
});
|
|
233
370
|
return ret;
|
|
234
371
|
}
|
|
372
|
+
function encodePathSegment(value) {
|
|
373
|
+
if (value === void 0 || value === null) return "";
|
|
374
|
+
return encodeURIComponent(String(value));
|
|
375
|
+
}
|
|
235
376
|
function template(templateString, data) {
|
|
236
377
|
return templateString.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
237
|
-
return data[key] !== void 0 ? data[key] : match;
|
|
378
|
+
return data[key] !== void 0 ? encodePathSegment(data[key]) : match;
|
|
238
379
|
});
|
|
239
380
|
}
|
|
240
381
|
function getWrapContext(url, options, config) {
|
|
241
382
|
const { queryParams, pathParams } = options ?? {};
|
|
242
383
|
const finalUrl = pathParams ? template(url, pathParams) : url;
|
|
243
|
-
|
|
244
|
-
return { finalUrl, finalConfig
|
|
384
|
+
const finalConfig = queryParams && config ? { ...config, params: queryParams } : queryParams && !config ? { params: queryParams } : config;
|
|
385
|
+
return { finalUrl, finalConfig };
|
|
245
386
|
}
|
|
246
387
|
|
|
247
388
|
// src/services/wrap.ts
|
|
@@ -251,10 +392,12 @@ function resolveUrl(basePath, url) {
|
|
|
251
392
|
return basePath ? `${removeTrailingSlash(basePath)}/${removeLeadingSlash(url)}` : url;
|
|
252
393
|
}
|
|
253
394
|
function prepareConfig(defaultConfig, cacheValue, requestConfig) {
|
|
254
|
-
|
|
255
|
-
|
|
395
|
+
const headerClone = new import_axios.AxiosHeaders(defaultConfig.headers);
|
|
396
|
+
headerClone.set(CACHE_HEADER, cacheValue);
|
|
397
|
+
const defaulted = { ...defaultConfig, headers: headerClone };
|
|
398
|
+
return (0, import_axios.mergeConfig)(defaulted, requestConfig);
|
|
256
399
|
}
|
|
257
|
-
function createWrapHelper(
|
|
400
|
+
function createWrapHelper(axios3, basePath) {
|
|
258
401
|
return {
|
|
259
402
|
wrapGet: (url, defaultConfig = {}) => {
|
|
260
403
|
const _url = resolveUrl(basePath, url);
|
|
@@ -264,7 +407,7 @@ function createWrapHelper(axios2, basePath) {
|
|
|
264
407
|
options,
|
|
265
408
|
prepareConfig(defaultConfig, "true", requestConfig)
|
|
266
409
|
);
|
|
267
|
-
return
|
|
410
|
+
return axios3.get(finalUrl, finalConfig);
|
|
268
411
|
};
|
|
269
412
|
},
|
|
270
413
|
wrapPost: (url, defaultConfig = {}) => {
|
|
@@ -275,7 +418,7 @@ function createWrapHelper(axios2, basePath) {
|
|
|
275
418
|
options,
|
|
276
419
|
prepareConfig(defaultConfig, "false", requestConfig)
|
|
277
420
|
);
|
|
278
|
-
return
|
|
421
|
+
return axios3.post(finalUrl, data, finalConfig);
|
|
279
422
|
};
|
|
280
423
|
},
|
|
281
424
|
wrapPut: (url, defaultConfig = {}) => {
|
|
@@ -286,7 +429,7 @@ function createWrapHelper(axios2, basePath) {
|
|
|
286
429
|
options,
|
|
287
430
|
prepareConfig(defaultConfig, "false", requestConfig)
|
|
288
431
|
);
|
|
289
|
-
return
|
|
432
|
+
return axios3.put(finalUrl, data, finalConfig);
|
|
290
433
|
};
|
|
291
434
|
},
|
|
292
435
|
wrapPatch: (url, defaultConfig = {}) => {
|
|
@@ -297,7 +440,7 @@ function createWrapHelper(axios2, basePath) {
|
|
|
297
440
|
options,
|
|
298
441
|
prepareConfig(defaultConfig, "false", requestConfig)
|
|
299
442
|
);
|
|
300
|
-
return
|
|
443
|
+
return axios3.patch(finalUrl, data, finalConfig);
|
|
301
444
|
};
|
|
302
445
|
},
|
|
303
446
|
wrapDelete: (url, defaultConfig = {}) => {
|
|
@@ -308,7 +451,7 @@ function createWrapHelper(axios2, basePath) {
|
|
|
308
451
|
options,
|
|
309
452
|
prepareConfig(defaultConfig, "false", requestConfig)
|
|
310
453
|
);
|
|
311
|
-
return
|
|
454
|
+
return axios3.delete(finalUrl, finalConfig);
|
|
312
455
|
};
|
|
313
456
|
}
|
|
314
457
|
};
|
|
@@ -358,38 +501,77 @@ var stringifyErrorPayload = (value) => {
|
|
|
358
501
|
return String(value);
|
|
359
502
|
}
|
|
360
503
|
};
|
|
504
|
+
function finalizeOperationResult({
|
|
505
|
+
success,
|
|
506
|
+
raw,
|
|
507
|
+
status,
|
|
508
|
+
headers = {},
|
|
509
|
+
message,
|
|
510
|
+
totalCount
|
|
511
|
+
}) {
|
|
512
|
+
if (success) {
|
|
513
|
+
return {
|
|
514
|
+
success: true,
|
|
515
|
+
raw,
|
|
516
|
+
data: raw,
|
|
517
|
+
message: "",
|
|
518
|
+
status,
|
|
519
|
+
headers,
|
|
520
|
+
...totalCount == null ? {} : { totalCount }
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return {
|
|
524
|
+
success: false,
|
|
525
|
+
raw,
|
|
526
|
+
data: null,
|
|
527
|
+
message: message ?? stringifyErrorPayload(raw),
|
|
528
|
+
status,
|
|
529
|
+
headers,
|
|
530
|
+
...totalCount == null ? {} : { totalCount }
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
var normalizeTransportFailure = (error) => {
|
|
534
|
+
const transportError = error && typeof error === "object" ? error : {};
|
|
535
|
+
let raw = null;
|
|
536
|
+
let status = 0;
|
|
537
|
+
let headers = {};
|
|
538
|
+
let message;
|
|
539
|
+
if (transportError.response) {
|
|
540
|
+
status = transportError.response.status;
|
|
541
|
+
headers = transportError.response.headers;
|
|
542
|
+
raw = transportError.response.data;
|
|
543
|
+
} else if (transportError.request) {
|
|
544
|
+
message = "The server is not responding";
|
|
545
|
+
} else {
|
|
546
|
+
message = transportError.message;
|
|
547
|
+
}
|
|
548
|
+
return finalizeOperationResult({ success: false, raw, status, headers, message });
|
|
549
|
+
};
|
|
361
550
|
var Service = class {
|
|
362
|
-
constructor(
|
|
363
|
-
this._axios =
|
|
551
|
+
constructor(axios3, basePath, throwOnError = false) {
|
|
552
|
+
this._axios = axios3;
|
|
364
553
|
this._basePath = basePath;
|
|
365
|
-
this._wrap = createWrapHelper(
|
|
554
|
+
this._wrap = createWrapHelper(axios3, basePath);
|
|
555
|
+
this._throwOnError = throwOnError;
|
|
366
556
|
}
|
|
367
557
|
handleSuccess(res, extra = {}) {
|
|
368
|
-
return {
|
|
558
|
+
return {
|
|
559
|
+
...finalizeOperationResult({
|
|
560
|
+
success: true,
|
|
561
|
+
raw: res.data,
|
|
562
|
+
status: res.status,
|
|
563
|
+
headers: res.headers
|
|
564
|
+
}),
|
|
565
|
+
...extra
|
|
566
|
+
};
|
|
369
567
|
}
|
|
370
568
|
// See https://axios-http.com/docs/handling-errors
|
|
371
569
|
handleError(error) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
status: 0,
|
|
378
|
-
headers: {}
|
|
379
|
-
};
|
|
380
|
-
if (error.response) {
|
|
381
|
-
result.status = error.response.status;
|
|
382
|
-
result.headers = error.response.headers;
|
|
383
|
-
const responseData = error.response.data;
|
|
384
|
-
result.raw = responseData;
|
|
385
|
-
result.data = responseData;
|
|
386
|
-
result.message = stringifyErrorPayload(responseData);
|
|
387
|
-
} else if (error.request) {
|
|
388
|
-
result.message = "The server is not responding";
|
|
389
|
-
} else {
|
|
390
|
-
result.message = error.message;
|
|
391
|
-
}
|
|
392
|
-
return result;
|
|
570
|
+
return normalizeTransportFailure(error);
|
|
571
|
+
}
|
|
572
|
+
/** Resolves per-call policy against the already-resolved service/adapter default. */
|
|
573
|
+
resolveThrowOnError(override) {
|
|
574
|
+
return override ?? this._throwOnError;
|
|
393
575
|
}
|
|
394
576
|
wrapGet(url, defaultAxiosRequestConfig = {}) {
|
|
395
577
|
return this._wrap.wrapGet(url, defaultAxiosRequestConfig);
|
|
@@ -406,6 +588,30 @@ var Service = class {
|
|
|
406
588
|
wrapDelete(url, defaultAxiosRequestConfig = {}) {
|
|
407
589
|
return this._wrap.wrapDelete(url, defaultAxiosRequestConfig);
|
|
408
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* Public bridge to the per-service success/failure callback pipeline and
|
|
593
|
+
* `throwOnError` policy. Adapter-internal grouping machinery calls this so
|
|
594
|
+
* that grouped entries go through the same finalization the direct path
|
|
595
|
+
* uses (`createResponseHandler`). Returns `res` unchanged on success and
|
|
596
|
+
* throws `ServiceError` when both `res.success === false` and the
|
|
597
|
+
* `throwOnError` override (or the service-level default) are enabled.
|
|
598
|
+
*/
|
|
599
|
+
applyResponseCallbacks(res, throwOnErrorOverride) {
|
|
600
|
+
const handler = this._handleCallbacks;
|
|
601
|
+
return handler ? handler(res, throwOnErrorOverride) : res;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Returns a fresh headers object that includes the package-owned
|
|
605
|
+
* `CACHE_HEADER` set to `"true"` (cache eligible) or `"false"` (bypass)
|
|
606
|
+
* according to the `ignoreCache` option. The caller's `CACHE_HEADER`
|
|
607
|
+
* value, if any, wins over the `ignoreCache` default.
|
|
608
|
+
*
|
|
609
|
+
* The input `headers` object is **never mutated**: an `AxiosHeaders`
|
|
610
|
+
* instance is cloned via `.toJSON()` before any value is set, and a
|
|
611
|
+
* plain-object headers input is shallow-copied. Reusing the same
|
|
612
|
+
* caller-owned headers across multiple requests therefore has no
|
|
613
|
+
* hidden side effects, and the order of invocations is irrelevant.
|
|
614
|
+
*/
|
|
409
615
|
updateHeaders(headers, { ignoreCache }) {
|
|
410
616
|
const cacheValue = ignoreCache ? "false" : "true";
|
|
411
617
|
if (!headers) {
|
|
@@ -413,8 +619,9 @@ var Service = class {
|
|
|
413
619
|
}
|
|
414
620
|
if (headers instanceof import_axios2.AxiosHeaders) {
|
|
415
621
|
if (headers.has(CACHE_HEADER)) return headers;
|
|
416
|
-
headers.
|
|
417
|
-
|
|
622
|
+
const cloned = new import_axios2.AxiosHeaders(headers.toJSON());
|
|
623
|
+
cloned.set(CACHE_HEADER, cacheValue);
|
|
624
|
+
return cloned;
|
|
418
625
|
}
|
|
419
626
|
if (CACHE_HEADER in headers) return headers;
|
|
420
627
|
return {
|
|
@@ -427,14 +634,397 @@ var ServiceError = class extends Error {
|
|
|
427
634
|
constructor(result) {
|
|
428
635
|
super(result.message);
|
|
429
636
|
this.name = "ServiceError";
|
|
430
|
-
this.success =
|
|
637
|
+
this.success = false;
|
|
431
638
|
this.raw = result.raw;
|
|
432
|
-
this.data =
|
|
639
|
+
this.data = null;
|
|
433
640
|
this.status = result.status;
|
|
434
641
|
this.headers = result.headers;
|
|
435
642
|
}
|
|
436
643
|
};
|
|
437
644
|
|
|
645
|
+
// src/services/interceptors.ts
|
|
646
|
+
var import_axios4 = __toESM(require("axios"));
|
|
647
|
+
|
|
648
|
+
// src/services/cache-utils.ts
|
|
649
|
+
var import_axios3 = require("axios");
|
|
650
|
+
var import_utils3 = require("@web-ts-toolkit/utils");
|
|
651
|
+
var normalizeConfigValue = (value) => {
|
|
652
|
+
if (value == null) return value;
|
|
653
|
+
if (value instanceof import_axios3.AxiosHeaders) {
|
|
654
|
+
return normalizeConfigValue(value.toJSON());
|
|
655
|
+
}
|
|
656
|
+
if (Array.isArray(value)) {
|
|
657
|
+
return value.map((item) => normalizeConfigValue(item));
|
|
658
|
+
}
|
|
659
|
+
if (typeof value === "object") {
|
|
660
|
+
return Object.entries((0, import_utils3.omitBy)(value, (item) => item === void 0)).sort(([left], [right]) => left.localeCompare(right)).reduce((acc, [key, item]) => {
|
|
661
|
+
acc[key] = normalizeConfigValue(item);
|
|
662
|
+
return acc;
|
|
663
|
+
}, {});
|
|
664
|
+
}
|
|
665
|
+
return value;
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
// src/services/interceptors.ts
|
|
669
|
+
var DEFAULT_CACHE_CAPACITY = 100;
|
|
670
|
+
var CACHEABLE_METHODS = /* @__PURE__ */ new Set(["get"]);
|
|
671
|
+
var MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "patch", "delete"]);
|
|
672
|
+
var CACHEABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set(["", "json", "text"]);
|
|
673
|
+
var SENSITIVE_CACHE_HEADERS = /* @__PURE__ */ new Set([
|
|
674
|
+
"authorization",
|
|
675
|
+
"cookie",
|
|
676
|
+
"set-cookie",
|
|
677
|
+
"proxy-authorization",
|
|
678
|
+
"www-authenticate"
|
|
679
|
+
]);
|
|
680
|
+
var cloneConfigWithCacheBypass = (config) => {
|
|
681
|
+
const baseConfig = config ?? {};
|
|
682
|
+
const next = { ...baseConfig };
|
|
683
|
+
const sourceHeaders = config?.headers;
|
|
684
|
+
if (sourceHeaders instanceof import_axios4.AxiosHeaders) {
|
|
685
|
+
next.headers = sourceHeaders.toJSON();
|
|
686
|
+
} else if (sourceHeaders && typeof sourceHeaders === "object") {
|
|
687
|
+
next.headers = { ...sourceHeaders };
|
|
688
|
+
} else {
|
|
689
|
+
next.headers = {};
|
|
690
|
+
}
|
|
691
|
+
next.headers[CACHE_HEADER] = "false";
|
|
692
|
+
return next;
|
|
693
|
+
};
|
|
694
|
+
var SimpleCache = class {
|
|
695
|
+
constructor(opts = {}) {
|
|
696
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
697
|
+
this.timers = /* @__PURE__ */ new Map();
|
|
698
|
+
this.capacity = opts.capacity !== void 0 && Number.isFinite(opts.capacity) && opts.capacity > 0 ? Math.floor(opts.capacity) : DEFAULT_CACHE_CAPACITY;
|
|
699
|
+
this.clone = opts.clone ?? defaultClone;
|
|
700
|
+
}
|
|
701
|
+
set(key, value, ttl) {
|
|
702
|
+
if (this.cache.size >= this.capacity && !this.cache.has(key)) {
|
|
703
|
+
const oldestKey = this.cache.keys().next().value;
|
|
704
|
+
if (oldestKey !== void 0) {
|
|
705
|
+
this.delete(oldestKey);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
this.cache.delete(key);
|
|
709
|
+
this.cache.set(key, value);
|
|
710
|
+
if (ttl && ttl > 0) {
|
|
711
|
+
const existing = this.timers.get(key);
|
|
712
|
+
if (existing) clearTimeout(existing);
|
|
713
|
+
const timer = setTimeout(() => {
|
|
714
|
+
this.cache.delete(key);
|
|
715
|
+
this.timers.delete(key);
|
|
716
|
+
}, ttl);
|
|
717
|
+
if (typeof timer === "object" && timer && "unref" in timer && typeof timer.unref === "function") {
|
|
718
|
+
timer.unref();
|
|
719
|
+
}
|
|
720
|
+
this.timers.set(key, timer);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
get(key) {
|
|
724
|
+
const value = this.cache.get(key);
|
|
725
|
+
if (value === void 0) {
|
|
726
|
+
return void 0;
|
|
727
|
+
}
|
|
728
|
+
this.cache.delete(key);
|
|
729
|
+
this.cache.set(key, value);
|
|
730
|
+
return this.clone(value);
|
|
731
|
+
}
|
|
732
|
+
has(key) {
|
|
733
|
+
return this.cache.has(key);
|
|
734
|
+
}
|
|
735
|
+
delete(key) {
|
|
736
|
+
const timer = this.timers.get(key);
|
|
737
|
+
if (timer) {
|
|
738
|
+
clearTimeout(timer);
|
|
739
|
+
this.timers.delete(key);
|
|
740
|
+
}
|
|
741
|
+
return this.cache.delete(key);
|
|
742
|
+
}
|
|
743
|
+
clear() {
|
|
744
|
+
for (const timer of this.timers.values()) {
|
|
745
|
+
clearTimeout(timer);
|
|
746
|
+
}
|
|
747
|
+
this.timers.clear();
|
|
748
|
+
this.cache.clear();
|
|
749
|
+
}
|
|
750
|
+
dispose() {
|
|
751
|
+
this.clear();
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
var defaultClone = (value) => {
|
|
755
|
+
if (value == null) return value;
|
|
756
|
+
try {
|
|
757
|
+
return JSON.parse(JSON.stringify(value));
|
|
758
|
+
} catch {
|
|
759
|
+
return value;
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
var CACHE_REQUEST_STATE = /* @__PURE__ */ Symbol("access-router-client.cache-request-state");
|
|
763
|
+
var CACHE_DISPOSED_ERROR = "Access router client cache was disposed while the request was in flight";
|
|
764
|
+
var setCacheRequestState = (config, state) => {
|
|
765
|
+
Object.defineProperty(config, CACHE_REQUEST_STATE, {
|
|
766
|
+
configurable: false,
|
|
767
|
+
enumerable: false,
|
|
768
|
+
writable: false,
|
|
769
|
+
value: Object.freeze(state)
|
|
770
|
+
});
|
|
771
|
+
};
|
|
772
|
+
var isUnsupportedResponseBody = (response) => {
|
|
773
|
+
const responseType = response.config?.responseType;
|
|
774
|
+
if (responseType === "stream" || responseType === "arraybuffer" || responseType === "blob" || responseType === "document") {
|
|
775
|
+
return true;
|
|
776
|
+
}
|
|
777
|
+
const data = response.data;
|
|
778
|
+
if (data == null) return false;
|
|
779
|
+
if (typeof data === "string") return false;
|
|
780
|
+
if (typeof data !== "object") return false;
|
|
781
|
+
if (Array.isArray(data)) return false;
|
|
782
|
+
try {
|
|
783
|
+
JSON.stringify(data);
|
|
784
|
+
return false;
|
|
785
|
+
} catch {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
var snapshotResponse = (response) => {
|
|
790
|
+
const headers = response.headers instanceof import_axios4.AxiosHeaders ? response.headers.toJSON() : { ...response.headers ?? {} };
|
|
791
|
+
return {
|
|
792
|
+
data: defaultClone(response.data),
|
|
793
|
+
status: response.status,
|
|
794
|
+
statusText: response.statusText,
|
|
795
|
+
headers: defaultClone(headers)
|
|
796
|
+
};
|
|
797
|
+
};
|
|
798
|
+
var serializeHeaders = (headers) => {
|
|
799
|
+
const resolvedHeaders = headers instanceof import_axios4.AxiosHeaders ? headers.toJSON() : headers;
|
|
800
|
+
const normalizedHeaders = Object.entries(resolvedHeaders ?? {}).filter(([key, value]) => {
|
|
801
|
+
const normalizedKey = key.toLowerCase();
|
|
802
|
+
return normalizedKey !== CACHE_HEADER.toLowerCase() && !SENSITIVE_CACHE_HEADERS.has(normalizedKey) && value !== void 0;
|
|
803
|
+
}).reduce((acc, [key, value]) => {
|
|
804
|
+
acc[key.toLowerCase()] = value;
|
|
805
|
+
return acc;
|
|
806
|
+
}, {});
|
|
807
|
+
return JSON.stringify(normalizeConfigValue(normalizedHeaders));
|
|
808
|
+
};
|
|
809
|
+
var hasStableCacheValue = (value, seen = /* @__PURE__ */ new Set()) => {
|
|
810
|
+
if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean")
|
|
811
|
+
return true;
|
|
812
|
+
if (typeof value !== "object") return false;
|
|
813
|
+
if (seen.has(value)) return false;
|
|
814
|
+
if (value instanceof import_axios4.AxiosHeaders) {
|
|
815
|
+
return hasStableCacheValue(value.toJSON(), seen);
|
|
816
|
+
}
|
|
817
|
+
const prototype = Object.getPrototypeOf(value);
|
|
818
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) return false;
|
|
819
|
+
seen.add(value);
|
|
820
|
+
const stable = Object.values(value).every((item) => hasStableCacheValue(item, seen));
|
|
821
|
+
seen.delete(value);
|
|
822
|
+
return stable;
|
|
823
|
+
};
|
|
824
|
+
var sameTransform = (configured, defaultValue) => {
|
|
825
|
+
const configuredList = Array.isArray(configured) ? configured : [configured];
|
|
826
|
+
const defaultList = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
|
|
827
|
+
return configuredList.length === defaultList.length && configuredList.every((item, index) => item === defaultList[index]);
|
|
828
|
+
};
|
|
829
|
+
var sameConfigIdentity = (configured, defaultValue) => {
|
|
830
|
+
if (Array.isArray(configured) && Array.isArray(defaultValue)) {
|
|
831
|
+
return configured.length === defaultValue.length && configured.every((item, index) => item === defaultValue[index]);
|
|
832
|
+
}
|
|
833
|
+
return configured === defaultValue;
|
|
834
|
+
};
|
|
835
|
+
var isCacheEligible = (config, instance) => {
|
|
836
|
+
const method = (config.method ?? "get").toLowerCase();
|
|
837
|
+
const responseType = config.responseType ?? "";
|
|
838
|
+
return CACHEABLE_METHODS.has(method) && CACHEABLE_RESPONSE_TYPES.has(responseType) && config.paramsSerializer === void 0 && config.auth === void 0 && config.signal === void 0 && config.cancelToken === void 0 && config.onDownloadProgress === void 0 && config.onUploadProgress === void 0 && sameConfigIdentity(config.adapter, instance.defaults.adapter) && sameTransform(config.transformRequest, instance.defaults.transformRequest) && sameTransform(config.transformResponse, instance.defaults.transformResponse) && hasStableCacheValue(config.params) && hasStableCacheValue(config.data) && hasStableCacheValue(config.headers);
|
|
839
|
+
};
|
|
840
|
+
function generateCacheKey(config, partition) {
|
|
841
|
+
const responseSemantics = JSON.stringify({
|
|
842
|
+
responseType: config.responseType ?? "",
|
|
843
|
+
responseEncoding: config.responseEncoding ?? "",
|
|
844
|
+
decompress: config.decompress ?? true,
|
|
845
|
+
timeout: config.timeout ?? 0,
|
|
846
|
+
maxContentLength: config.maxContentLength ?? -1,
|
|
847
|
+
maxBodyLength: config.maxBodyLength ?? -1,
|
|
848
|
+
withCredentials: Boolean(config.withCredentials),
|
|
849
|
+
transitional: normalizeConfigValue(config.transitional)
|
|
850
|
+
});
|
|
851
|
+
const key = `${config.baseURL}/${config.url}_${config.method}_${generateParamKey(config.params)}_${generateDataKey(
|
|
852
|
+
config.data
|
|
853
|
+
)}_${partition ?? ""}_${serializeHeaders(config.headers)}_${responseSemantics}`;
|
|
854
|
+
return encodeURI(key);
|
|
855
|
+
}
|
|
856
|
+
function generateParamKey(params) {
|
|
857
|
+
if (!params) return "";
|
|
858
|
+
return JSON.stringify(normalizeConfigValue(params));
|
|
859
|
+
}
|
|
860
|
+
function generateDataKey(data) {
|
|
861
|
+
if (!data) return "";
|
|
862
|
+
return typeof data === "string" ? data : JSON.stringify(normalizeConfigValue(data));
|
|
863
|
+
}
|
|
864
|
+
var resolveWithCredentials = (config, withCredentialsDefault) => {
|
|
865
|
+
if (config.withCredentials !== void 0) {
|
|
866
|
+
return Boolean(config.withCredentials);
|
|
867
|
+
}
|
|
868
|
+
return withCredentialsDefault;
|
|
869
|
+
};
|
|
870
|
+
function useCacheInterceptors(instance, policyOrTtl) {
|
|
871
|
+
const policy = typeof policyOrTtl === "number" ? { ttl: policyOrTtl } : policyOrTtl;
|
|
872
|
+
const store = new SimpleCache({ capacity: policy.capacity, clone: policy.clone });
|
|
873
|
+
const withCredentialsDefault = policy.withCredentialsDefault ?? Boolean(instance.defaults.withCredentials);
|
|
874
|
+
const inflight = /* @__PURE__ */ new Map();
|
|
875
|
+
let generation = 0;
|
|
876
|
+
let disposed = false;
|
|
877
|
+
const finalizeInflight = (slot) => {
|
|
878
|
+
if (inflight.get(slot.key) === slot) {
|
|
879
|
+
inflight.delete(slot.key);
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
const resolveInflight = (slot, response) => {
|
|
883
|
+
if (slot.settled) return;
|
|
884
|
+
slot.settled = true;
|
|
885
|
+
slot.resolve(response);
|
|
886
|
+
finalizeInflight(slot);
|
|
887
|
+
};
|
|
888
|
+
const rejectInflight = (slot, error) => {
|
|
889
|
+
if (slot.settled) return;
|
|
890
|
+
slot.settled = true;
|
|
891
|
+
slot.reject(error);
|
|
892
|
+
finalizeInflight(slot);
|
|
893
|
+
};
|
|
894
|
+
const invalidate = () => {
|
|
895
|
+
generation += 1;
|
|
896
|
+
store.clear();
|
|
897
|
+
inflight.clear();
|
|
898
|
+
};
|
|
899
|
+
instance.interceptors.request.use(
|
|
900
|
+
async (config) => {
|
|
901
|
+
if (disposed || config.headers[CACHE_HEADER] === "false" || !isCacheEligible(config, instance)) return config;
|
|
902
|
+
const isCredentialed = resolveWithCredentials(config, withCredentialsDefault);
|
|
903
|
+
const partitionKey = policy.partitionForRequest?.(config);
|
|
904
|
+
if (isCredentialed && !partitionKey) {
|
|
905
|
+
return config;
|
|
906
|
+
}
|
|
907
|
+
const key = generateCacheKey(config, partitionKey);
|
|
908
|
+
policy.onCacheKey?.(key);
|
|
909
|
+
const snapshot = store.get(key);
|
|
910
|
+
if (snapshot) {
|
|
911
|
+
setCacheRequestState(config, Object.freeze({ key, generation, role: "hit" }));
|
|
912
|
+
config.adapter = async (_config) => {
|
|
913
|
+
return {
|
|
914
|
+
data: snapshot.data,
|
|
915
|
+
status: snapshot.status,
|
|
916
|
+
statusText: snapshot.statusText,
|
|
917
|
+
headers: { ...snapshot.headers, [CACHE_HEADER]: "true" },
|
|
918
|
+
config: _config
|
|
919
|
+
};
|
|
920
|
+
};
|
|
921
|
+
return config;
|
|
922
|
+
}
|
|
923
|
+
const existing = inflight.get(key);
|
|
924
|
+
if (existing) {
|
|
925
|
+
config.adapter = async (_config) => {
|
|
926
|
+
const response = await existing.promise;
|
|
927
|
+
const shared = response;
|
|
928
|
+
return {
|
|
929
|
+
data: defaultClone(shared.data),
|
|
930
|
+
status: shared.status,
|
|
931
|
+
statusText: shared.statusText,
|
|
932
|
+
headers: { ...shared.headers, [CACHE_HEADER]: "true" },
|
|
933
|
+
config: _config
|
|
934
|
+
};
|
|
935
|
+
};
|
|
936
|
+
setCacheRequestState(config, Object.freeze({ key, generation, role: "tail", slot: existing }));
|
|
937
|
+
return config;
|
|
938
|
+
}
|
|
939
|
+
let resolvePromise;
|
|
940
|
+
let rejectPromise;
|
|
941
|
+
const inflightPromise = new Promise((resolve, reject) => {
|
|
942
|
+
resolvePromise = resolve;
|
|
943
|
+
rejectPromise = reject;
|
|
944
|
+
});
|
|
945
|
+
inflightPromise.catch(() => {
|
|
946
|
+
});
|
|
947
|
+
const slot = {
|
|
948
|
+
key,
|
|
949
|
+
generation,
|
|
950
|
+
promise: inflightPromise,
|
|
951
|
+
resolve: resolvePromise,
|
|
952
|
+
reject: rejectPromise,
|
|
953
|
+
settled: false
|
|
954
|
+
};
|
|
955
|
+
inflight.set(key, slot);
|
|
956
|
+
const nextConfig = { ...config };
|
|
957
|
+
setCacheRequestState(nextConfig, Object.freeze({ key, generation, role: "source", slot }));
|
|
958
|
+
let realAdapter = config.adapter;
|
|
959
|
+
if (realAdapter === void 0 || realAdapter === null) {
|
|
960
|
+
realAdapter = instance.defaults.adapter;
|
|
961
|
+
}
|
|
962
|
+
const dispatch = typeof realAdapter === "function" ? realAdapter : typeof import_axios4.default.getAdapter === "function" ? import_axios4.default.getAdapter(
|
|
963
|
+
realAdapter,
|
|
964
|
+
instance.defaults
|
|
965
|
+
) : void 0;
|
|
966
|
+
nextConfig.adapter = async (adapterConfig) => {
|
|
967
|
+
if (!dispatch) {
|
|
968
|
+
const response = await adapterConfig.adapter;
|
|
969
|
+
return response;
|
|
970
|
+
}
|
|
971
|
+
try {
|
|
972
|
+
const response = await dispatch(adapterConfig);
|
|
973
|
+
return response;
|
|
974
|
+
} catch (error) {
|
|
975
|
+
rejectInflight(slot, error);
|
|
976
|
+
throw error;
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
return nextConfig;
|
|
980
|
+
},
|
|
981
|
+
(error) => Promise.reject(error)
|
|
982
|
+
);
|
|
983
|
+
instance.interceptors.response.use(
|
|
984
|
+
(response) => {
|
|
985
|
+
const method = (response.config.method ?? "get").toLowerCase();
|
|
986
|
+
if (response.config.headers[CACHE_HEADER] === "false" || MUTATION_METHODS.has(method)) {
|
|
987
|
+
if (response.status >= 200 && response.status < 300) {
|
|
988
|
+
invalidate();
|
|
989
|
+
}
|
|
990
|
+
return response;
|
|
991
|
+
}
|
|
992
|
+
const state = response.config[CACHE_REQUEST_STATE];
|
|
993
|
+
if (!state || state.role !== "source" || !state.slot) {
|
|
994
|
+
return response;
|
|
995
|
+
}
|
|
996
|
+
if (response.status >= 200 && response.status < 300) {
|
|
997
|
+
if (!disposed && state.generation === generation && !isUnsupportedResponseBody(response)) {
|
|
998
|
+
store.set(state.key, snapshotResponse(response), policy.ttl);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
resolveInflight(state.slot, response);
|
|
1002
|
+
return response;
|
|
1003
|
+
},
|
|
1004
|
+
(error) => {
|
|
1005
|
+
const state = (error?.config ?? {})[CACHE_REQUEST_STATE];
|
|
1006
|
+
if (state?.role === "source" && state.slot) {
|
|
1007
|
+
rejectInflight(state.slot, error);
|
|
1008
|
+
}
|
|
1009
|
+
return Promise.reject(error);
|
|
1010
|
+
}
|
|
1011
|
+
);
|
|
1012
|
+
return {
|
|
1013
|
+
clear: invalidate,
|
|
1014
|
+
dispose: () => {
|
|
1015
|
+
if (disposed) return;
|
|
1016
|
+
disposed = true;
|
|
1017
|
+
generation += 1;
|
|
1018
|
+
store.dispose();
|
|
1019
|
+
const error = new Error(CACHE_DISPOSED_ERROR);
|
|
1020
|
+
for (const slot of inflight.values()) {
|
|
1021
|
+
rejectInflight(slot, error);
|
|
1022
|
+
}
|
|
1023
|
+
inflight.clear();
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
|
|
438
1028
|
// src/services/shared.ts
|
|
439
1029
|
var import_utils4 = require("@web-ts-toolkit/utils");
|
|
440
1030
|
|
|
@@ -451,10 +1041,118 @@ var CustomHeaders = /* @__PURE__ */ ((CustomHeaders2) => {
|
|
|
451
1041
|
})(CustomHeaders || {});
|
|
452
1042
|
|
|
453
1043
|
// src/services/shared.ts
|
|
1044
|
+
var getSubdocumentResultShape = (query) => {
|
|
1045
|
+
if (query.target !== "model") return void 0;
|
|
1046
|
+
switch (query.op) {
|
|
1047
|
+
case "subList":
|
|
1048
|
+
case "subCreate":
|
|
1049
|
+
case "subBulkUpdate":
|
|
1050
|
+
return "list";
|
|
1051
|
+
case "subRead":
|
|
1052
|
+
case "subUpdate":
|
|
1053
|
+
return "single";
|
|
1054
|
+
case "subDelete":
|
|
1055
|
+
return "scalar";
|
|
1056
|
+
default:
|
|
1057
|
+
return void 0;
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
function finalizeRootEntry(query, entry, responseHeaders, service) {
|
|
1061
|
+
const { result, message: entryMessage, statusCode, op } = entry;
|
|
1062
|
+
const success = result.success;
|
|
1063
|
+
const baseResult = finalizeOperationResult({
|
|
1064
|
+
success,
|
|
1065
|
+
raw: success ? result.data : result,
|
|
1066
|
+
status: statusCode,
|
|
1067
|
+
headers: responseHeaders,
|
|
1068
|
+
message: success ? void 0 : entryMessage
|
|
1069
|
+
});
|
|
1070
|
+
let _raw = baseResult.raw;
|
|
1071
|
+
let _data = baseResult.data;
|
|
1072
|
+
const subdocumentResultShape = getSubdocumentResultShape(query);
|
|
1073
|
+
if (!success) {
|
|
1074
|
+
_data = null;
|
|
1075
|
+
} else if (subdocumentResultShape) {
|
|
1076
|
+
if (subdocumentResultShape === "list") {
|
|
1077
|
+
const rows = result.data == null ? [] : (0, import_utils4.castArray)(result.data);
|
|
1078
|
+
_raw = rows;
|
|
1079
|
+
_data = rows;
|
|
1080
|
+
}
|
|
1081
|
+
} else if (query.target === "model") {
|
|
1082
|
+
const modelService = service;
|
|
1083
|
+
if (result.kind === "list" && Array.isArray(result.data)) {
|
|
1084
|
+
if (op === "create" && !Array.isArray(query.data) && result.data.length === 1) {
|
|
1085
|
+
_raw = result.data[0];
|
|
1086
|
+
if (modelService) {
|
|
1087
|
+
_data = Model.create(result.data[0], modelService, void 0, true);
|
|
1088
|
+
}
|
|
1089
|
+
} else if (op !== "distinct") {
|
|
1090
|
+
const rows = (0, import_utils4.castArray)(result.data);
|
|
1091
|
+
if (modelService) {
|
|
1092
|
+
_data = rows.map((item) => Model.create(item, modelService, void 0, true));
|
|
1093
|
+
} else {
|
|
1094
|
+
_data = rows;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
} else if (result.kind === "single" && (op === "new" || op === "read" || op === "update" || op === "upsert")) {
|
|
1098
|
+
if (op === "new" && result.data && typeof result.data === "object") {
|
|
1099
|
+
const { _id: _generatedId, ...draft } = result.data;
|
|
1100
|
+
void _generatedId;
|
|
1101
|
+
_raw = draft;
|
|
1102
|
+
_data = draft;
|
|
1103
|
+
}
|
|
1104
|
+
if (modelService) {
|
|
1105
|
+
const fromExisting = op !== "new";
|
|
1106
|
+
const persistenceId = op === "read" && query.target === "model" && "id" in query ? query.id : void 0;
|
|
1107
|
+
_data = Model.create(_data, modelService, persistenceId, fromExisting);
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
const isSubdocumentList = subdocumentResultShape === "list";
|
|
1112
|
+
const isModelOrDataList = !subdocumentResultShape && query.op === "list";
|
|
1113
|
+
const returnedCount = Array.isArray(_data) ? _data.length : 0;
|
|
1114
|
+
const totalCount = success && query.options?.includeCount === true ? result.totalCount ?? result.count ?? returnedCount : 0;
|
|
1115
|
+
return {
|
|
1116
|
+
success,
|
|
1117
|
+
raw: _raw,
|
|
1118
|
+
data: _data,
|
|
1119
|
+
message: baseResult.message,
|
|
1120
|
+
status: statusCode,
|
|
1121
|
+
...isSubdocumentList ? { count: success ? returnedCount : 0 } : {},
|
|
1122
|
+
...isModelOrDataList ? { totalCount } : {},
|
|
1123
|
+
headers: responseHeaders
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
function finalizeRootTransportFailure(query, error) {
|
|
1127
|
+
const failure = normalizeTransportFailure(error);
|
|
1128
|
+
const subdocumentResultShape = getSubdocumentResultShape(query);
|
|
1129
|
+
return {
|
|
1130
|
+
...failure,
|
|
1131
|
+
...subdocumentResultShape === "list" ? { count: 0 } : {},
|
|
1132
|
+
...!subdocumentResultShape && query.op === "list" ? { totalCount: 0 } : {}
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
function applyGroupCallbacks(entries, services, groupThrowOnError) {
|
|
1136
|
+
let callbackError;
|
|
1137
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1138
|
+
const svc = services[i];
|
|
1139
|
+
try {
|
|
1140
|
+
entries[i] = svc?.applyResponseCallbacks ? svc.applyResponseCallbacks(entries[i], false) : entries[i];
|
|
1141
|
+
} catch (error) {
|
|
1142
|
+
callbackError ??= error;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
if (callbackError) throw callbackError;
|
|
1146
|
+
if (groupThrowOnError) {
|
|
1147
|
+
const failure = entries.find((entry) => !entry.success);
|
|
1148
|
+
if (failure) throw new ServiceError(toResultError(failure));
|
|
1149
|
+
}
|
|
1150
|
+
return entries;
|
|
1151
|
+
}
|
|
454
1152
|
var toResultError = (result) => ({
|
|
455
1153
|
success: false,
|
|
456
1154
|
raw: result.raw ?? null,
|
|
457
|
-
data:
|
|
1155
|
+
data: null,
|
|
458
1156
|
message: result.message ?? "",
|
|
459
1157
|
status: result.status ?? 0,
|
|
460
1158
|
headers: result.headers ?? {}
|
|
@@ -470,6 +1168,10 @@ var setDefaultObjectProp = (obj, key, value) => {
|
|
|
470
1168
|
(0, import_utils4.set)(obj, key, value);
|
|
471
1169
|
}
|
|
472
1170
|
};
|
|
1171
|
+
var ensureListResultCount = (result) => {
|
|
1172
|
+
result.totalCount ??= 0;
|
|
1173
|
+
return result;
|
|
1174
|
+
};
|
|
473
1175
|
var createResponseHandler = (onSuccess, onFailure, throwOnError) => {
|
|
474
1176
|
const successHandler = onSuccess ?? import_utils4.noop;
|
|
475
1177
|
const failureHandler = onFailure ?? import_utils4.noop;
|
|
@@ -486,6 +1188,7 @@ var createResponseHandler = (onSuccess, onFailure, throwOnError) => {
|
|
|
486
1188
|
};
|
|
487
1189
|
};
|
|
488
1190
|
function processListResult(result, { includeCount, includeExtraHeaders }, wrapItem) {
|
|
1191
|
+
ensureListResultCount(result);
|
|
489
1192
|
const wrappedRows = (0, import_utils4.get)(result, "raw.data");
|
|
490
1193
|
const wrappedTotalCount = (0, import_utils4.get)(result, "raw.meta.totalCount");
|
|
491
1194
|
if (Array.isArray(wrappedRows)) {
|
|
@@ -518,11 +1221,40 @@ function processListResult(result, { includeCount, includeExtraHeaders }, wrapIt
|
|
|
518
1221
|
}
|
|
519
1222
|
|
|
520
1223
|
// src/lazy-promise.ts
|
|
1224
|
+
var STARTED_KEY = /* @__PURE__ */ Symbol("started");
|
|
1225
|
+
var executionClaims = /* @__PURE__ */ new WeakMap();
|
|
1226
|
+
var claimLazyRequest = (request, mode, owner) => {
|
|
1227
|
+
const claim = executionClaims.get(request);
|
|
1228
|
+
if (!claim) {
|
|
1229
|
+
executionClaims.set(request, { mode, owner });
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
if (mode === "grouped") {
|
|
1233
|
+
if (claim.mode === "direct") {
|
|
1234
|
+
throw new Error(
|
|
1235
|
+
"Cannot group a request that has already started execution; group() must be called before await/then/catch/finally/exec on each input"
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
throw new Error("Cannot group a request already claimed for grouped execution");
|
|
1239
|
+
}
|
|
1240
|
+
throw new Error("Cannot execute a request already claimed for grouped execution");
|
|
1241
|
+
};
|
|
1242
|
+
var releaseLazyRequestClaim = (request, owner) => {
|
|
1243
|
+
const claim = executionClaims.get(request);
|
|
1244
|
+
if (claim?.mode === "grouped" && claim.owner === owner) {
|
|
1245
|
+
executionClaims.delete(request);
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
521
1248
|
var wrapLazyPromise = (promiseFn, meta) => {
|
|
522
1249
|
let promise;
|
|
523
1250
|
const exec = () => {
|
|
524
1251
|
if (!promise) {
|
|
525
|
-
|
|
1252
|
+
try {
|
|
1253
|
+
claimLazyRequest(prom, "direct");
|
|
1254
|
+
promise = Promise.resolve().then(promiseFn);
|
|
1255
|
+
} catch (error) {
|
|
1256
|
+
promise = Promise.reject(error);
|
|
1257
|
+
}
|
|
526
1258
|
}
|
|
527
1259
|
return promise;
|
|
528
1260
|
};
|
|
@@ -545,32 +1277,62 @@ var wrapLazyPromise = (promiseFn, meta) => {
|
|
|
545
1277
|
value: "Promise",
|
|
546
1278
|
writable: false,
|
|
547
1279
|
enumerable: false,
|
|
548
|
-
configurable:
|
|
1280
|
+
configurable: false
|
|
1281
|
+
});
|
|
1282
|
+
Object.defineProperty(prom, STARTED_KEY, {
|
|
1283
|
+
get: () => executionClaims.has(prom),
|
|
1284
|
+
enumerable: false,
|
|
1285
|
+
configurable: false
|
|
549
1286
|
});
|
|
550
|
-
|
|
1287
|
+
if (meta != null) {
|
|
1288
|
+
const metaKeys = Object.keys(meta);
|
|
1289
|
+
for (let i = 0; i < metaKeys.length; i++) {
|
|
1290
|
+
const key = metaKeys[i];
|
|
1291
|
+
Object.defineProperty(prom, key, {
|
|
1292
|
+
value: meta[key],
|
|
1293
|
+
enumerable: false,
|
|
1294
|
+
writable: false,
|
|
1295
|
+
configurable: false
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
551
1299
|
return prom;
|
|
552
1300
|
};
|
|
553
1301
|
|
|
554
1302
|
// src/services/request.ts
|
|
555
1303
|
function makeRequest(execute, meta) {
|
|
556
|
-
|
|
1304
|
+
const effectiveMeta = {
|
|
1305
|
+
...meta,
|
|
1306
|
+
__throwOnError: meta.__service?.resolveThrowOnError(meta.__throwOnError) ?? Boolean(meta.__throwOnError)
|
|
1307
|
+
};
|
|
1308
|
+
return wrapLazyPromise(execute, effectiveMeta);
|
|
557
1309
|
}
|
|
558
1310
|
|
|
559
1311
|
// src/services/sub-ops.ts
|
|
560
|
-
var
|
|
1312
|
+
var import_axios5 = require("axios");
|
|
1313
|
+
var toArray = (value) => Array.isArray(value) ? value : value == null ? [] : [value];
|
|
1314
|
+
var ensureSubdocumentListCount = (result) => {
|
|
1315
|
+
result.count ??= 0;
|
|
1316
|
+
return result;
|
|
1317
|
+
};
|
|
561
1318
|
function buildSubDocumentOps(ctx, id, sub) {
|
|
562
|
-
const { axios:
|
|
563
|
-
const asS = parentService;
|
|
1319
|
+
const { axios: axios3, basePath, modelName, queryPath, handleSuccess, handleError, _handleCallbacks, parentService } = ctx;
|
|
564
1320
|
return {
|
|
565
1321
|
list: (axiosRequestConfig) => {
|
|
566
1322
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
567
1323
|
return makeRequest(
|
|
568
|
-
() =>
|
|
569
|
-
|
|
570
|
-
|
|
1324
|
+
() => axios3.get(
|
|
1325
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}`,
|
|
1326
|
+
(0, import_axios5.mergeConfig)(reqConfig, { params: {} })
|
|
1327
|
+
).then(handleSuccess).then((result) => {
|
|
1328
|
+
const rawArray = toArray(result.raw);
|
|
1329
|
+
result.raw = rawArray;
|
|
1330
|
+
result.count = rawArray.length;
|
|
1331
|
+
result.data = rawArray;
|
|
571
1332
|
return result;
|
|
572
|
-
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
1333
|
+
}).catch(handleError).then(ensureSubdocumentListCount).then((res) => _handleCallbacks(res, throwOnError)),
|
|
573
1334
|
{
|
|
1335
|
+
__throwOnError: throwOnError,
|
|
574
1336
|
__op: "listSub",
|
|
575
1337
|
__query: {
|
|
576
1338
|
target: "model",
|
|
@@ -592,14 +1354,21 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
592
1354
|
const select = args?.select;
|
|
593
1355
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
594
1356
|
return makeRequest(
|
|
595
|
-
() =>
|
|
596
|
-
|
|
597
|
-
|
|
1357
|
+
() => axios3.post(
|
|
1358
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}/${queryPath}`,
|
|
1359
|
+
{ filter, select },
|
|
1360
|
+
reqConfig
|
|
1361
|
+
).then(handleSuccess).then((result) => {
|
|
1362
|
+
const rawArray = toArray(result.raw);
|
|
1363
|
+
result.raw = rawArray;
|
|
1364
|
+
result.count = rawArray.length;
|
|
1365
|
+
result.data = rawArray;
|
|
598
1366
|
return result;
|
|
599
|
-
}).catch(handleError).then(
|
|
1367
|
+
}).catch(handleError).then(ensureSubdocumentListCount).then(
|
|
600
1368
|
(res) => _handleCallbacks(res, throwOnError)
|
|
601
1369
|
),
|
|
602
1370
|
{
|
|
1371
|
+
__throwOnError: throwOnError,
|
|
603
1372
|
__op: "listAdvancedSub",
|
|
604
1373
|
__query: {
|
|
605
1374
|
target: "model",
|
|
@@ -620,11 +1389,15 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
620
1389
|
read: (subId, axiosRequestConfig) => {
|
|
621
1390
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
622
1391
|
return makeRequest(
|
|
623
|
-
() =>
|
|
624
|
-
|
|
1392
|
+
() => axios3.get(
|
|
1393
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}/${encodePathSegment(subId)}`,
|
|
1394
|
+
(0, import_axios5.mergeConfig)(reqConfig, { params: {} })
|
|
1395
|
+
).then(handleSuccess).then((result) => {
|
|
1396
|
+
result.data = result.success ? result.raw : null;
|
|
625
1397
|
return result;
|
|
626
1398
|
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
627
1399
|
{
|
|
1400
|
+
__throwOnError: throwOnError,
|
|
628
1401
|
__op: "readSub",
|
|
629
1402
|
__query: {
|
|
630
1403
|
target: "model",
|
|
@@ -646,13 +1419,18 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
646
1419
|
const { select, populate } = args ?? {};
|
|
647
1420
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
648
1421
|
return makeRequest(
|
|
649
|
-
() =>
|
|
650
|
-
|
|
1422
|
+
() => axios3.post(
|
|
1423
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}/${encodePathSegment(subId)}/${queryPath}`,
|
|
1424
|
+
{ select, populate },
|
|
1425
|
+
reqConfig
|
|
1426
|
+
).then(handleSuccess).then((result) => {
|
|
1427
|
+
result.data = result.success ? result.raw : null;
|
|
651
1428
|
return result;
|
|
652
1429
|
}).catch(handleError).then(
|
|
653
1430
|
(res) => _handleCallbacks(res, throwOnError)
|
|
654
1431
|
),
|
|
655
1432
|
{
|
|
1433
|
+
__throwOnError: throwOnError,
|
|
656
1434
|
__op: "readAdvancedSub",
|
|
657
1435
|
__query: {
|
|
658
1436
|
target: "model",
|
|
@@ -671,13 +1449,18 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
671
1449
|
);
|
|
672
1450
|
},
|
|
673
1451
|
update: (subId, data, axiosRequestConfig) => {
|
|
674
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1452
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
675
1453
|
return makeRequest(
|
|
676
|
-
() =>
|
|
677
|
-
|
|
1454
|
+
() => axios3.patch(
|
|
1455
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}/${encodePathSegment(subId)}`,
|
|
1456
|
+
data,
|
|
1457
|
+
(0, import_axios5.mergeConfig)(reqConfig, { params: {} })
|
|
1458
|
+
).then(handleSuccess).then((result) => {
|
|
1459
|
+
result.data = result.success ? result.raw : null;
|
|
678
1460
|
return result;
|
|
679
1461
|
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
680
1462
|
{
|
|
1463
|
+
__throwOnError: throwOnError,
|
|
681
1464
|
__op: "updateSub",
|
|
682
1465
|
__query: {
|
|
683
1466
|
target: "model",
|
|
@@ -696,13 +1479,21 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
696
1479
|
);
|
|
697
1480
|
},
|
|
698
1481
|
bulkUpdate: (data, axiosRequestConfig) => {
|
|
699
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1482
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
700
1483
|
return makeRequest(
|
|
701
|
-
() =>
|
|
702
|
-
|
|
1484
|
+
() => axios3.patch(
|
|
1485
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}`,
|
|
1486
|
+
data,
|
|
1487
|
+
(0, import_axios5.mergeConfig)(reqConfig, { params: {} })
|
|
1488
|
+
).then(handleSuccess).then((result) => {
|
|
1489
|
+
const rawArray = toArray(result.raw);
|
|
1490
|
+
result.raw = rawArray;
|
|
1491
|
+
result.count = rawArray.length;
|
|
1492
|
+
result.data = rawArray;
|
|
703
1493
|
return result;
|
|
704
|
-
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
1494
|
+
}).catch(handleError).then(ensureSubdocumentListCount).then((res) => _handleCallbacks(res, throwOnError)),
|
|
705
1495
|
{
|
|
1496
|
+
__throwOnError: throwOnError,
|
|
706
1497
|
__op: "bulkUpdateSub",
|
|
707
1498
|
__query: {
|
|
708
1499
|
target: "model",
|
|
@@ -720,30 +1511,42 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
720
1511
|
);
|
|
721
1512
|
},
|
|
722
1513
|
create: (data, axiosRequestConfig) => {
|
|
723
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1514
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
724
1515
|
return makeRequest(
|
|
725
|
-
() =>
|
|
726
|
-
|
|
1516
|
+
() => axios3.post(
|
|
1517
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}`,
|
|
1518
|
+
data,
|
|
1519
|
+
(0, import_axios5.mergeConfig)(reqConfig, { params: {} })
|
|
1520
|
+
).then(handleSuccess).then((result) => {
|
|
1521
|
+
const rawArray = toArray(result.raw);
|
|
1522
|
+
result.raw = rawArray;
|
|
1523
|
+
result.count = rawArray.length;
|
|
1524
|
+
result.data = rawArray;
|
|
727
1525
|
return result;
|
|
728
|
-
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
1526
|
+
}).catch(handleError).then(ensureSubdocumentListCount).then((res) => _handleCallbacks(res, throwOnError)),
|
|
729
1527
|
{
|
|
1528
|
+
__throwOnError: throwOnError,
|
|
730
1529
|
__op: "createSub",
|
|
731
|
-
__query: { target: "model", name: modelName,
|
|
1530
|
+
__query: { target: "model", name: modelName, op: "subCreate", id, sub, data, options: {} },
|
|
732
1531
|
__requestConfig: reqConfig,
|
|
733
1532
|
__service: parentService
|
|
734
1533
|
}
|
|
735
1534
|
);
|
|
736
1535
|
},
|
|
737
1536
|
delete: (subId, axiosRequestConfig) => {
|
|
738
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1537
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
739
1538
|
return makeRequest(
|
|
740
|
-
() =>
|
|
741
|
-
|
|
1539
|
+
() => axios3.delete(
|
|
1540
|
+
`${basePath}/${encodePathSegment(id)}/${encodePathSegment(sub)}/${encodePathSegment(subId)}`,
|
|
1541
|
+
reqConfig
|
|
1542
|
+
).then(handleSuccess).then((result) => {
|
|
1543
|
+
if (result.success) result.data = result.raw;
|
|
742
1544
|
return result;
|
|
743
1545
|
}).catch(handleError).then((res) => _handleCallbacks(res, throwOnError)),
|
|
744
1546
|
{
|
|
1547
|
+
__throwOnError: throwOnError,
|
|
745
1548
|
__op: "deleteSub",
|
|
746
|
-
__query: { target: "model", name: modelName,
|
|
1549
|
+
__query: { target: "model", name: modelName, op: "subDelete", id, sub, subId },
|
|
747
1550
|
__requestConfig: reqConfig,
|
|
748
1551
|
__service: parentService
|
|
749
1552
|
}
|
|
@@ -754,8 +1557,8 @@ function buildSubDocumentOps(ctx, id, sub) {
|
|
|
754
1557
|
|
|
755
1558
|
// src/services/model-service.ts
|
|
756
1559
|
var ModelService = class extends Service {
|
|
757
|
-
constructor({ axios:
|
|
758
|
-
super(
|
|
1560
|
+
constructor({ axios: axios3, modelName, basePath, queryPath, mutationPath, onSuccess, onFailure, throwOnError }, defaults) {
|
|
1561
|
+
super(axios3, basePath, throwOnError);
|
|
759
1562
|
this._modelName = modelName;
|
|
760
1563
|
this._queryPath = queryPath;
|
|
761
1564
|
this._mutationPath = mutationPath;
|
|
@@ -803,7 +1606,7 @@ var ModelService = class extends Service {
|
|
|
803
1606
|
return makeRequest(
|
|
804
1607
|
() => this._axios.get(
|
|
805
1608
|
this._basePath,
|
|
806
|
-
(0,
|
|
1609
|
+
(0, import_axios6.mergeConfig)(reqConfig, {
|
|
807
1610
|
params: {
|
|
808
1611
|
skip,
|
|
809
1612
|
limit,
|
|
@@ -819,10 +1622,15 @@ var ModelService = class extends Service {
|
|
|
819
1622
|
return processListResult(
|
|
820
1623
|
result,
|
|
821
1624
|
{ includeCount, includeExtraHeaders },
|
|
822
|
-
|
|
1625
|
+
// ARC-21: list items come from existing documents, so mark
|
|
1626
|
+
// them as `_fromExisting=true` even if the server response
|
|
1627
|
+
// (or a custom adapter) strips `_id` — a save on such an item
|
|
1628
|
+
// must throw rather than silently re-create.
|
|
1629
|
+
(item) => Model.create(item, this, void 0, true)
|
|
823
1630
|
);
|
|
824
|
-
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1631
|
+
}).catch(this.handleError).then(ensureListResultCount).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
825
1632
|
{
|
|
1633
|
+
__throwOnError: throwOnError,
|
|
826
1634
|
__op: "list",
|
|
827
1635
|
__query: {
|
|
828
1636
|
target: "model",
|
|
@@ -831,7 +1639,7 @@ var ModelService = class extends Service {
|
|
|
831
1639
|
op: "list",
|
|
832
1640
|
filter: {},
|
|
833
1641
|
args: { skip, limit, page, pageSize },
|
|
834
|
-
options: { skim, includePermissions, includeCount
|
|
1642
|
+
options: { skim, includePermissions, includeCount },
|
|
835
1643
|
sqOptions: sq
|
|
836
1644
|
},
|
|
837
1645
|
__requestConfig: reqConfig,
|
|
@@ -884,12 +1692,18 @@ var ModelService = class extends Service {
|
|
|
884
1692
|
return processListResult(
|
|
885
1693
|
result,
|
|
886
1694
|
{ includeCount, includeExtraHeaders },
|
|
887
|
-
(item) =>
|
|
1695
|
+
(item) => (
|
|
1696
|
+
// ARC-21: listAdvanced items come from existing documents;
|
|
1697
|
+
// mark `_fromExisting=true` so a save cannot silently re-create
|
|
1698
|
+
// when a server response shape drops `_id`.
|
|
1699
|
+
Model.create(item, this, void 0, true)
|
|
1700
|
+
)
|
|
888
1701
|
);
|
|
889
|
-
}).catch(this.handleError).then(
|
|
1702
|
+
}).catch(this.handleError).then(ensureListResultCount).then(
|
|
890
1703
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
891
1704
|
),
|
|
892
1705
|
{
|
|
1706
|
+
__throwOnError: throwOnError,
|
|
893
1707
|
__op: "listAdvanced",
|
|
894
1708
|
__query: {
|
|
895
1709
|
target: "model",
|
|
@@ -898,7 +1712,7 @@ var ModelService = class extends Service {
|
|
|
898
1712
|
op: "list",
|
|
899
1713
|
filter: _filter,
|
|
900
1714
|
args: { select, sort, populate, include, skip, limit, page, pageSize, tasks },
|
|
901
|
-
options: { skim, includePermissions, includeCount,
|
|
1715
|
+
options: { skim, includePermissions, includeCount, populateAccess },
|
|
902
1716
|
sqOptions: sq
|
|
903
1717
|
},
|
|
904
1718
|
__requestConfig: reqConfig,
|
|
@@ -908,14 +1722,25 @@ var ModelService = class extends Service {
|
|
|
908
1722
|
}
|
|
909
1723
|
create(data, options, axiosRequestConfig) {
|
|
910
1724
|
const { includePermissions = this._defaults.createOptions.includePermissions ?? true } = options ?? {};
|
|
911
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
912
|
-
|
|
1725
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1726
|
+
const bulk = Array.isArray(data);
|
|
913
1727
|
return makeRequest(
|
|
914
|
-
() => this._axios.post(this._basePath, data, (0,
|
|
915
|
-
|
|
1728
|
+
() => this._axios.post(this._basePath, data, (0, import_axios6.mergeConfig)(reqConfig, { params: { include_permissions: includePermissions } })).then(this.handleSuccess).then((result) => {
|
|
1729
|
+
if (result.success) {
|
|
1730
|
+
if (bulk) {
|
|
1731
|
+
const rows = Array.isArray(result.raw) ? result.raw : [result.raw];
|
|
1732
|
+
result.raw = rows;
|
|
1733
|
+
result.data = rows.map((row) => Model.create(row, this, void 0, true));
|
|
1734
|
+
} else {
|
|
1735
|
+
result.data = Model.create(result.raw, this, void 0, true);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
916
1738
|
return result;
|
|
917
|
-
}).catch(this.handleError).then(
|
|
1739
|
+
}).catch(this.handleError).then(
|
|
1740
|
+
(res) => this._handleCallbacks(res, throwOnError)
|
|
1741
|
+
),
|
|
918
1742
|
{
|
|
1743
|
+
__throwOnError: throwOnError,
|
|
919
1744
|
__op: "create",
|
|
920
1745
|
__query: {
|
|
921
1746
|
target: "model",
|
|
@@ -937,20 +1762,27 @@ var ModelService = class extends Service {
|
|
|
937
1762
|
includePermissions = this._defaults.createAdvancedOptions.includePermissions ?? true,
|
|
938
1763
|
populateAccess = this._defaults.createAdvancedOptions.populateAccess
|
|
939
1764
|
} = options ?? {};
|
|
940
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
941
|
-
|
|
1765
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1766
|
+
const bulk = Array.isArray(data);
|
|
942
1767
|
return makeRequest(
|
|
943
1768
|
() => this._axios.post(
|
|
944
1769
|
`${this._basePath}/${this._mutationPath}`,
|
|
945
1770
|
{ data, select, populate, tasks, options: { includePermissions, populateAccess } },
|
|
946
1771
|
reqConfig
|
|
947
1772
|
).then(this.handleSuccess).then((result) => {
|
|
948
|
-
|
|
1773
|
+
if (result.success) {
|
|
1774
|
+
if (bulk) {
|
|
1775
|
+
const rows = Array.isArray(result.raw) ? result.raw : [result.raw];
|
|
1776
|
+
result.raw = rows;
|
|
1777
|
+
result.data = rows.map((row) => Model.create(row, this, void 0, true));
|
|
1778
|
+
} else {
|
|
1779
|
+
result.data = Model.create(result.raw, this, void 0, true);
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
949
1782
|
return result;
|
|
950
|
-
}).catch(this.handleError).then(
|
|
951
|
-
(res) => this._handleCallbacks(res, throwOnError)
|
|
952
|
-
),
|
|
1783
|
+
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
953
1784
|
{
|
|
1785
|
+
__throwOnError: throwOnError,
|
|
954
1786
|
__op: "createAdvanced",
|
|
955
1787
|
__query: {
|
|
956
1788
|
target: "model",
|
|
@@ -967,15 +1799,24 @@ var ModelService = class extends Service {
|
|
|
967
1799
|
);
|
|
968
1800
|
}
|
|
969
1801
|
upsert(data, options, axiosRequestConfig) {
|
|
970
|
-
const {
|
|
971
|
-
|
|
972
|
-
|
|
1802
|
+
const {
|
|
1803
|
+
returningAll = this._defaults.upsertOptions.returningAll ?? true,
|
|
1804
|
+
includePermissions = this._defaults.upsertOptions.includePermissions ?? true
|
|
1805
|
+
} = options ?? {};
|
|
1806
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
973
1807
|
return makeRequest(
|
|
974
|
-
() => this._axios.put(
|
|
975
|
-
|
|
1808
|
+
() => this._axios.put(
|
|
1809
|
+
this._basePath,
|
|
1810
|
+
data,
|
|
1811
|
+
(0, import_axios6.mergeConfig)(reqConfig, {
|
|
1812
|
+
params: { returning_all: returningAll, include_permissions: includePermissions }
|
|
1813
|
+
})
|
|
1814
|
+
).then(this.handleSuccess).then((result) => {
|
|
1815
|
+
result.data = result.success ? Model.create(result.raw, this, void 0, true) : null;
|
|
976
1816
|
return result;
|
|
977
1817
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
978
1818
|
{
|
|
1819
|
+
__throwOnError: throwOnError,
|
|
979
1820
|
__op: "upsert",
|
|
980
1821
|
__query: {
|
|
981
1822
|
target: "model",
|
|
@@ -983,7 +1824,7 @@ var ModelService = class extends Service {
|
|
|
983
1824
|
model: this._modelName,
|
|
984
1825
|
op: "upsert",
|
|
985
1826
|
data,
|
|
986
|
-
options: { returningAll }
|
|
1827
|
+
options: { returningAll, includePermissions }
|
|
987
1828
|
},
|
|
988
1829
|
__requestConfig: reqConfig,
|
|
989
1830
|
__service: this
|
|
@@ -998,8 +1839,7 @@ var ModelService = class extends Service {
|
|
|
998
1839
|
includePermissions = this._defaults.upsertAdvancedOptions.includePermissions ?? true,
|
|
999
1840
|
populateAccess = this._defaults.upsertAdvancedOptions.populateAccess
|
|
1000
1841
|
} = options ?? {};
|
|
1001
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1002
|
-
(0, import_utils5.set)(reqConfig, `headers.${CACHE_HEADER}`, "false");
|
|
1842
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1003
1843
|
return makeRequest(
|
|
1004
1844
|
() => this._axios.put(
|
|
1005
1845
|
`${this._basePath}/${this._mutationPath}`,
|
|
@@ -1012,12 +1852,13 @@ var ModelService = class extends Service {
|
|
|
1012
1852
|
},
|
|
1013
1853
|
reqConfig
|
|
1014
1854
|
).then(this.handleSuccess).then((result) => {
|
|
1015
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
1855
|
+
result.data = result.success ? Model.create(result.raw, this, void 0, true) : null;
|
|
1016
1856
|
return result;
|
|
1017
1857
|
}).catch(this.handleError).then(
|
|
1018
1858
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1019
1859
|
),
|
|
1020
1860
|
{
|
|
1861
|
+
__throwOnError: throwOnError,
|
|
1021
1862
|
__op: "upsertAdvanced",
|
|
1022
1863
|
__query: {
|
|
1023
1864
|
target: "model",
|
|
@@ -1034,14 +1875,14 @@ var ModelService = class extends Service {
|
|
|
1034
1875
|
);
|
|
1035
1876
|
}
|
|
1036
1877
|
delete(identifier, axiosRequestConfig) {
|
|
1037
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1038
|
-
(0, import_utils5.set)(reqConfig, `headers.${CACHE_HEADER}`, "false");
|
|
1878
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1039
1879
|
return makeRequest(
|
|
1040
|
-
() => this._axios.delete(`${this._basePath}/${identifier}`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1041
|
-
result.data = result.raw;
|
|
1880
|
+
() => this._axios.delete(`${this._basePath}/${encodePathSegment(identifier)}`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1881
|
+
if (result.success) result.data = result.raw;
|
|
1042
1882
|
return result;
|
|
1043
1883
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1044
1884
|
{
|
|
1885
|
+
__throwOnError: throwOnError,
|
|
1045
1886
|
__op: "delete",
|
|
1046
1887
|
__query: {
|
|
1047
1888
|
target: "model",
|
|
@@ -1056,15 +1897,17 @@ var ModelService = class extends Service {
|
|
|
1056
1897
|
);
|
|
1057
1898
|
}
|
|
1058
1899
|
new(axiosRequestConfig) {
|
|
1059
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1060
|
-
(0, import_utils5.set)(reqConfig, `headers.${CACHE_HEADER}`, "false");
|
|
1900
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1061
1901
|
return makeRequest(
|
|
1062
1902
|
() => this._axios.get(`${this._basePath}/new`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1063
|
-
|
|
1064
|
-
|
|
1903
|
+
if (result.success) {
|
|
1904
|
+
delete result.raw._id;
|
|
1905
|
+
result.data = Model.create(result.raw, this);
|
|
1906
|
+
}
|
|
1065
1907
|
return result;
|
|
1066
1908
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1067
1909
|
{
|
|
1910
|
+
__throwOnError: throwOnError,
|
|
1068
1911
|
__op: "new",
|
|
1069
1912
|
__query: {
|
|
1070
1913
|
target: "model",
|
|
@@ -1080,11 +1923,12 @@ var ModelService = class extends Service {
|
|
|
1080
1923
|
distinct(field, axiosRequestConfig) {
|
|
1081
1924
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1082
1925
|
return makeRequest(
|
|
1083
|
-
() => this._axios.get(`${this._basePath}/distinct/${field}`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1084
|
-
result.data = result.raw;
|
|
1926
|
+
() => this._axios.get(`${this._basePath}/distinct/${encodePathSegment(field)}`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1927
|
+
if (result.success) result.data = result.raw;
|
|
1085
1928
|
return result;
|
|
1086
1929
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1087
1930
|
{
|
|
1931
|
+
__throwOnError: throwOnError,
|
|
1088
1932
|
__op: "distinct",
|
|
1089
1933
|
__query: {
|
|
1090
1934
|
target: "model",
|
|
@@ -1101,11 +1945,12 @@ var ModelService = class extends Service {
|
|
|
1101
1945
|
distinctAdvanced(field, conditions, axiosRequestConfig) {
|
|
1102
1946
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1103
1947
|
return makeRequest(
|
|
1104
|
-
() => this._axios.post(`${this._basePath}/distinct/${field}`, conditions, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1105
|
-
result.data = result.raw;
|
|
1948
|
+
() => this._axios.post(`${this._basePath}/distinct/${encodePathSegment(field)}`, { filter: conditions }, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1949
|
+
if (result.success) result.data = result.raw;
|
|
1106
1950
|
return result;
|
|
1107
1951
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1108
1952
|
{
|
|
1953
|
+
__throwOnError: throwOnError,
|
|
1109
1954
|
__op: "distinctAdvanced",
|
|
1110
1955
|
__query: {
|
|
1111
1956
|
target: "model",
|
|
@@ -1124,10 +1969,11 @@ var ModelService = class extends Service {
|
|
|
1124
1969
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1125
1970
|
return makeRequest(
|
|
1126
1971
|
() => this._axios.get(`${this._basePath}/count`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1127
|
-
result.data = result.raw;
|
|
1972
|
+
if (result.success) result.data = result.raw;
|
|
1128
1973
|
return result;
|
|
1129
1974
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1130
1975
|
{
|
|
1976
|
+
__throwOnError: throwOnError,
|
|
1131
1977
|
__op: "count",
|
|
1132
1978
|
__query: {
|
|
1133
1979
|
target: "model",
|
|
@@ -1140,23 +1986,22 @@ var ModelService = class extends Service {
|
|
|
1140
1986
|
}
|
|
1141
1987
|
);
|
|
1142
1988
|
}
|
|
1143
|
-
countAdvanced(filter,
|
|
1144
|
-
const { access } = args ?? {};
|
|
1989
|
+
countAdvanced(filter, axiosRequestConfig) {
|
|
1145
1990
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1146
1991
|
return makeRequest(
|
|
1147
|
-
() => this._axios.post(`${this._basePath}/count`, { filter
|
|
1148
|
-
result.data = result.raw;
|
|
1992
|
+
() => this._axios.post(`${this._basePath}/count`, { filter }, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1993
|
+
if (result.success) result.data = result.raw;
|
|
1149
1994
|
return result;
|
|
1150
1995
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1151
1996
|
{
|
|
1997
|
+
__throwOnError: throwOnError,
|
|
1152
1998
|
__op: "countAdvanced",
|
|
1153
1999
|
__query: {
|
|
1154
2000
|
target: "model",
|
|
1155
2001
|
name: this._modelName,
|
|
1156
2002
|
model: this._modelName,
|
|
1157
2003
|
op: "count",
|
|
1158
|
-
filter
|
|
1159
|
-
options: { access }
|
|
2004
|
+
filter
|
|
1160
2005
|
},
|
|
1161
2006
|
__requestConfig: reqConfig,
|
|
1162
2007
|
__service: this
|
|
@@ -1177,15 +2022,16 @@ var ModelService = class extends Service {
|
|
|
1177
2022
|
reqConfig.headers = this.updateHeaders(reqConfig.headers, { ignoreCache });
|
|
1178
2023
|
return makeRequest(
|
|
1179
2024
|
() => this._axios.get(
|
|
1180
|
-
`${this._basePath}/${identifier}`,
|
|
1181
|
-
(0,
|
|
2025
|
+
`${this._basePath}/${encodePathSegment(identifier)}`,
|
|
2026
|
+
(0, import_axios6.mergeConfig)(reqConfig, {
|
|
1182
2027
|
params: { include_permissions: includePermissions, try_list: tryList }
|
|
1183
2028
|
})
|
|
1184
2029
|
).then(this.handleSuccess).then((result) => {
|
|
1185
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
2030
|
+
result.data = result.success ? Model.create(result.raw, this, identifier, true) : null;
|
|
1186
2031
|
return result;
|
|
1187
2032
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1188
2033
|
{
|
|
2034
|
+
__throwOnError: throwOnError,
|
|
1189
2035
|
__op: "read",
|
|
1190
2036
|
__query: {
|
|
1191
2037
|
target: "model",
|
|
@@ -1221,7 +2067,7 @@ var ModelService = class extends Service {
|
|
|
1221
2067
|
reqConfig.headers = this.updateHeaders(reqConfig.headers, { ignoreCache });
|
|
1222
2068
|
return makeRequest(
|
|
1223
2069
|
() => this._axios.post(
|
|
1224
|
-
`${this._basePath}/${this._queryPath}/${identifier}`,
|
|
2070
|
+
`${this._basePath}/${this._queryPath}/${encodePathSegment(identifier)}`,
|
|
1225
2071
|
{
|
|
1226
2072
|
select,
|
|
1227
2073
|
populate,
|
|
@@ -1231,12 +2077,13 @@ var ModelService = class extends Service {
|
|
|
1231
2077
|
},
|
|
1232
2078
|
reqConfig
|
|
1233
2079
|
).then(this.handleSuccess).then((result) => {
|
|
1234
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
2080
|
+
result.data = result.success ? Model.create(result.raw, this, identifier, true) : null;
|
|
1235
2081
|
return result;
|
|
1236
2082
|
}).catch(this.handleError).then(
|
|
1237
2083
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1238
2084
|
),
|
|
1239
2085
|
{
|
|
2086
|
+
__throwOnError: throwOnError,
|
|
1240
2087
|
__op: "readAdvanced",
|
|
1241
2088
|
__query: {
|
|
1242
2089
|
target: "model",
|
|
@@ -1286,12 +2133,13 @@ var ModelService = class extends Service {
|
|
|
1286
2133
|
},
|
|
1287
2134
|
reqConfig
|
|
1288
2135
|
).then(this.handleSuccess).then((result) => {
|
|
1289
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
2136
|
+
result.data = result.success ? Model.create(result.raw, this, void 0, true) : null;
|
|
1290
2137
|
return result;
|
|
1291
2138
|
}).catch(this.handleError).then(
|
|
1292
2139
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1293
2140
|
),
|
|
1294
2141
|
{
|
|
2142
|
+
__throwOnError: throwOnError,
|
|
1295
2143
|
__op: "readAdvancedFilter",
|
|
1296
2144
|
__query: {
|
|
1297
2145
|
target: "model",
|
|
@@ -1309,19 +2157,24 @@ var ModelService = class extends Service {
|
|
|
1309
2157
|
);
|
|
1310
2158
|
}
|
|
1311
2159
|
update(identifier, data, options, axiosRequestConfig) {
|
|
1312
|
-
const {
|
|
1313
|
-
|
|
1314
|
-
|
|
2160
|
+
const {
|
|
2161
|
+
returningAll = this._defaults.updateOptions.returningAll ?? true,
|
|
2162
|
+
includePermissions = this._defaults.updateOptions.includePermissions ?? true
|
|
2163
|
+
} = options ?? {};
|
|
2164
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1315
2165
|
return makeRequest(
|
|
1316
2166
|
() => this._axios.patch(
|
|
1317
|
-
`${this._basePath}/${identifier}`,
|
|
2167
|
+
`${this._basePath}/${encodePathSegment(identifier)}`,
|
|
1318
2168
|
data,
|
|
1319
|
-
(0,
|
|
2169
|
+
(0, import_axios6.mergeConfig)(reqConfig, {
|
|
2170
|
+
params: { returning_all: returningAll, include_permissions: includePermissions }
|
|
2171
|
+
})
|
|
1320
2172
|
).then(this.handleSuccess).then((result) => {
|
|
1321
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
2173
|
+
result.data = result.success ? Model.create(result.raw, this, void 0, true) : null;
|
|
1322
2174
|
return result;
|
|
1323
2175
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1324
2176
|
{
|
|
2177
|
+
__throwOnError: throwOnError,
|
|
1325
2178
|
__op: "update",
|
|
1326
2179
|
__query: {
|
|
1327
2180
|
target: "model",
|
|
@@ -1330,7 +2183,7 @@ var ModelService = class extends Service {
|
|
|
1330
2183
|
op: "update",
|
|
1331
2184
|
id: identifier,
|
|
1332
2185
|
data,
|
|
1333
|
-
options: { returningAll }
|
|
2186
|
+
options: { returningAll, includePermissions }
|
|
1334
2187
|
},
|
|
1335
2188
|
__requestConfig: reqConfig,
|
|
1336
2189
|
__service: this
|
|
@@ -1345,11 +2198,10 @@ var ModelService = class extends Service {
|
|
|
1345
2198
|
includePermissions = this._defaults.updateAdvancedOptions.includePermissions ?? true,
|
|
1346
2199
|
populateAccess = this._defaults.updateAdvancedOptions.populateAccess
|
|
1347
2200
|
} = options ?? {};
|
|
1348
|
-
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1349
|
-
(0, import_utils5.set)(reqConfig, `headers.${CACHE_HEADER}`, "false");
|
|
2201
|
+
const { throwOnError, ...reqConfig } = cloneConfigWithCacheBypass(axiosRequestConfig ?? {});
|
|
1350
2202
|
return makeRequest(
|
|
1351
2203
|
() => this._axios.patch(
|
|
1352
|
-
`${this._basePath}/${this._mutationPath}/${identifier}`,
|
|
2204
|
+
`${this._basePath}/${this._mutationPath}/${encodePathSegment(identifier)}`,
|
|
1353
2205
|
{
|
|
1354
2206
|
data,
|
|
1355
2207
|
select,
|
|
@@ -1359,12 +2211,13 @@ var ModelService = class extends Service {
|
|
|
1359
2211
|
},
|
|
1360
2212
|
reqConfig
|
|
1361
2213
|
).then(this.handleSuccess).then((result) => {
|
|
1362
|
-
result.data = result.success ? Model.create(result.raw, this) : null;
|
|
2214
|
+
result.data = result.success ? Model.create(result.raw, this, void 0, true) : null;
|
|
1363
2215
|
return result;
|
|
1364
2216
|
}).catch(this.handleError).then(
|
|
1365
2217
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1366
2218
|
),
|
|
1367
2219
|
{
|
|
2220
|
+
__throwOnError: throwOnError,
|
|
1368
2221
|
__op: "updateAdvanced",
|
|
1369
2222
|
__query: {
|
|
1370
2223
|
target: "model",
|
|
@@ -1411,10 +2264,10 @@ var ModelService = class extends Service {
|
|
|
1411
2264
|
};
|
|
1412
2265
|
|
|
1413
2266
|
// src/services/data-service.ts
|
|
1414
|
-
var
|
|
2267
|
+
var import_axios7 = require("axios");
|
|
1415
2268
|
var DataService = class extends Service {
|
|
1416
|
-
constructor({ axios:
|
|
1417
|
-
super(
|
|
2269
|
+
constructor({ axios: axios3, dataName, basePath, queryPath, onSuccess, onFailure, throwOnError }, defaults) {
|
|
2270
|
+
super(axios3, basePath, throwOnError);
|
|
1418
2271
|
this._dataName = dataName;
|
|
1419
2272
|
this._queryPath = queryPath;
|
|
1420
2273
|
this._defaults = defaults ?? {};
|
|
@@ -1440,7 +2293,6 @@ var DataService = class extends Service {
|
|
|
1440
2293
|
pageSize = this._defaults.listArgs.pageSize
|
|
1441
2294
|
} = args ?? {};
|
|
1442
2295
|
const {
|
|
1443
|
-
includePermissions = this._defaults.listOptions.includePermissions ?? false,
|
|
1444
2296
|
includeCount = this._defaults.listOptions.includeCount ?? false,
|
|
1445
2297
|
includeExtraHeaders = this._defaults.listOptions.includeExtraHeaders ?? false,
|
|
1446
2298
|
ignoreCache = this._defaults.listOptions.ignoreCache ?? false
|
|
@@ -1450,21 +2302,21 @@ var DataService = class extends Service {
|
|
|
1450
2302
|
return makeRequest(
|
|
1451
2303
|
() => this._axios.get(
|
|
1452
2304
|
this._basePath,
|
|
1453
|
-
(0,
|
|
2305
|
+
(0, import_axios7.mergeConfig)(reqConfig, {
|
|
1454
2306
|
params: {
|
|
1455
2307
|
skip,
|
|
1456
2308
|
limit,
|
|
1457
2309
|
page,
|
|
1458
2310
|
page_size: pageSize,
|
|
1459
|
-
include_permissions: includePermissions,
|
|
1460
2311
|
include_count: includeCount,
|
|
1461
2312
|
include_extra_headers: includeExtraHeaders
|
|
1462
2313
|
}
|
|
1463
2314
|
})
|
|
1464
2315
|
).then(this.handleSuccess).then((result) => {
|
|
1465
2316
|
return processListResult(result, { includeCount, includeExtraHeaders });
|
|
1466
|
-
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
2317
|
+
}).catch(this.handleError).then(ensureListResultCount).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1467
2318
|
{
|
|
2319
|
+
__throwOnError: throwOnError,
|
|
1468
2320
|
__op: "list",
|
|
1469
2321
|
__query: {
|
|
1470
2322
|
target: "data",
|
|
@@ -1472,7 +2324,7 @@ var DataService = class extends Service {
|
|
|
1472
2324
|
op: "list",
|
|
1473
2325
|
filter: {},
|
|
1474
2326
|
args: { skip, limit, page, pageSize },
|
|
1475
|
-
options: {
|
|
2327
|
+
options: { includeCount }
|
|
1476
2328
|
},
|
|
1477
2329
|
__requestConfig: reqConfig,
|
|
1478
2330
|
__service: this
|
|
@@ -1489,7 +2341,6 @@ var DataService = class extends Service {
|
|
|
1489
2341
|
} = args ?? {};
|
|
1490
2342
|
const select = args?.select ?? this._defaults.listAdvancedArgs.select;
|
|
1491
2343
|
const {
|
|
1492
|
-
includePermissions = this._defaults.listAdvancedOptions.includePermissions ?? false,
|
|
1493
2344
|
includeCount = this._defaults.listAdvancedOptions.includeCount ?? false,
|
|
1494
2345
|
includeExtraHeaders = this._defaults.listAdvancedOptions.includeExtraHeaders ?? false,
|
|
1495
2346
|
ignoreCache = this._defaults.listAdvancedOptions.ignoreCache ?? false
|
|
@@ -1508,7 +2359,7 @@ var DataService = class extends Service {
|
|
|
1508
2359
|
limit,
|
|
1509
2360
|
page,
|
|
1510
2361
|
pageSize,
|
|
1511
|
-
options: {
|
|
2362
|
+
options: { includeCount, includeExtraHeaders }
|
|
1512
2363
|
},
|
|
1513
2364
|
reqConfig
|
|
1514
2365
|
).then(this.handleSuccess).then((result) => {
|
|
@@ -1516,10 +2367,11 @@ var DataService = class extends Service {
|
|
|
1516
2367
|
includeCount,
|
|
1517
2368
|
includeExtraHeaders
|
|
1518
2369
|
});
|
|
1519
|
-
}).catch(this.handleError).then(
|
|
2370
|
+
}).catch(this.handleError).then(ensureListResultCount).then(
|
|
1520
2371
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1521
2372
|
),
|
|
1522
2373
|
{
|
|
2374
|
+
__throwOnError: throwOnError,
|
|
1523
2375
|
__op: "listAdvanced",
|
|
1524
2376
|
__query: {
|
|
1525
2377
|
target: "data",
|
|
@@ -1527,7 +2379,7 @@ var DataService = class extends Service {
|
|
|
1527
2379
|
op: "list",
|
|
1528
2380
|
filter: _filter,
|
|
1529
2381
|
args: { select, sort, skip, limit, page, pageSize },
|
|
1530
|
-
options: {
|
|
2382
|
+
options: { includeCount }
|
|
1531
2383
|
},
|
|
1532
2384
|
__requestConfig: reqConfig,
|
|
1533
2385
|
__service: this
|
|
@@ -1538,23 +2390,16 @@ var DataService = class extends Service {
|
|
|
1538
2390
|
// Document operations
|
|
1539
2391
|
// ---------------------------------------------------------------------------
|
|
1540
2392
|
read(identifier, options, axiosRequestConfig) {
|
|
1541
|
-
const {
|
|
1542
|
-
includePermissions = this._defaults.readOptions.includePermissions ?? true,
|
|
1543
|
-
ignoreCache = this._defaults.readOptions.ignoreCache ?? false
|
|
1544
|
-
} = options ?? {};
|
|
2393
|
+
const { ignoreCache = this._defaults.readOptions.ignoreCache ?? false } = options ?? {};
|
|
1545
2394
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1546
2395
|
reqConfig.headers = this.updateHeaders(reqConfig.headers, { ignoreCache });
|
|
1547
2396
|
return makeRequest(
|
|
1548
|
-
() => this._axios.get(
|
|
1549
|
-
|
|
1550
|
-
(0, import_axios5.mergeConfig)(reqConfig, {
|
|
1551
|
-
params: { include_permissions: includePermissions }
|
|
1552
|
-
})
|
|
1553
|
-
).then(this.handleSuccess).then((result) => {
|
|
1554
|
-
result.data = result.raw;
|
|
2397
|
+
() => this._axios.get(`${this._basePath}/${encodePathSegment(identifier)}`, reqConfig).then(this.handleSuccess).then((result) => {
|
|
2398
|
+
if (result.success) result.data = result.raw;
|
|
1555
2399
|
return result;
|
|
1556
2400
|
}).catch(this.handleError).then((res) => this._handleCallbacks(res, throwOnError)),
|
|
1557
2401
|
{
|
|
2402
|
+
__throwOnError: throwOnError,
|
|
1558
2403
|
__op: "read",
|
|
1559
2404
|
__query: {
|
|
1560
2405
|
target: "data",
|
|
@@ -1562,7 +2407,7 @@ var DataService = class extends Service {
|
|
|
1562
2407
|
op: "read",
|
|
1563
2408
|
id: identifier,
|
|
1564
2409
|
args: {},
|
|
1565
|
-
options: {
|
|
2410
|
+
options: {}
|
|
1566
2411
|
},
|
|
1567
2412
|
__requestConfig: reqConfig,
|
|
1568
2413
|
__service: this
|
|
@@ -1570,19 +2415,19 @@ var DataService = class extends Service {
|
|
|
1570
2415
|
);
|
|
1571
2416
|
}
|
|
1572
2417
|
readAdvanced(identifier, args, options, axiosRequestConfig) {
|
|
1573
|
-
const { ignoreCache = this._defaults.readAdvancedArgs.ignoreCache ?? false } = args ?? {};
|
|
1574
2418
|
const select = args?.select ?? this._defaults.readAdvancedArgs.select;
|
|
1575
|
-
const {
|
|
2419
|
+
const { ignoreCache = this._defaults.readAdvancedOptions.ignoreCache ?? false } = options ?? {};
|
|
1576
2420
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1577
2421
|
reqConfig.headers = this.updateHeaders(reqConfig.headers, { ignoreCache });
|
|
1578
2422
|
return makeRequest(
|
|
1579
|
-
() => this._axios.post(`${this._basePath}/${this._queryPath}/${identifier}`, { select }, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1580
|
-
result.data = result.raw;
|
|
2423
|
+
() => this._axios.post(`${this._basePath}/${this._queryPath}/${encodePathSegment(identifier)}`, { select }, reqConfig).then(this.handleSuccess).then((result) => {
|
|
2424
|
+
if (result.success) result.data = result.raw;
|
|
1581
2425
|
return result;
|
|
1582
2426
|
}).catch(this.handleError).then(
|
|
1583
2427
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1584
2428
|
),
|
|
1585
2429
|
{
|
|
2430
|
+
__throwOnError: throwOnError,
|
|
1586
2431
|
__op: "readAdvanced",
|
|
1587
2432
|
__query: {
|
|
1588
2433
|
target: "data",
|
|
@@ -1590,7 +2435,7 @@ var DataService = class extends Service {
|
|
|
1590
2435
|
op: "read",
|
|
1591
2436
|
id: identifier,
|
|
1592
2437
|
args: { select },
|
|
1593
|
-
options: {
|
|
2438
|
+
options: {}
|
|
1594
2439
|
},
|
|
1595
2440
|
__requestConfig: reqConfig,
|
|
1596
2441
|
__service: this
|
|
@@ -1599,19 +2444,19 @@ var DataService = class extends Service {
|
|
|
1599
2444
|
}
|
|
1600
2445
|
readAdvancedFilter(filter, args, options, axiosRequestConfig) {
|
|
1601
2446
|
const select = args?.select ?? this._defaults.readAdvancedArgs.select;
|
|
1602
|
-
const { ignoreCache = this._defaults.
|
|
1603
|
-
const { includePermissions = this._defaults.readAdvancedOptions.includePermissions ?? true } = options ?? {};
|
|
2447
|
+
const { ignoreCache = this._defaults.readAdvancedOptions.ignoreCache ?? false } = options ?? {};
|
|
1604
2448
|
const { throwOnError, ...reqConfig } = axiosRequestConfig ?? {};
|
|
1605
2449
|
reqConfig.headers = this.updateHeaders(reqConfig.headers, { ignoreCache });
|
|
1606
2450
|
const _filter = replaceSubQuery(filter);
|
|
1607
2451
|
return makeRequest(
|
|
1608
2452
|
() => this._axios.post(`${this._basePath}/${this._queryPath}/__filter`, { filter: _filter, select }, reqConfig).then(this.handleSuccess).then((result) => {
|
|
1609
|
-
result.data = result.raw;
|
|
2453
|
+
if (result.success) result.data = result.raw;
|
|
1610
2454
|
return result;
|
|
1611
2455
|
}).catch(this.handleError).then(
|
|
1612
2456
|
(res) => this._handleCallbacks(res, throwOnError)
|
|
1613
2457
|
),
|
|
1614
2458
|
{
|
|
2459
|
+
__throwOnError: throwOnError,
|
|
1615
2460
|
__op: "readAdvancedFilter",
|
|
1616
2461
|
__query: {
|
|
1617
2462
|
target: "data",
|
|
@@ -1619,7 +2464,7 @@ var DataService = class extends Service {
|
|
|
1619
2464
|
op: "read",
|
|
1620
2465
|
filter: _filter,
|
|
1621
2466
|
args: { select },
|
|
1622
|
-
options: {
|
|
2467
|
+
options: {}
|
|
1623
2468
|
},
|
|
1624
2469
|
__requestConfig: reqConfig,
|
|
1625
2470
|
__service: this
|
|
@@ -1628,132 +2473,8 @@ var DataService = class extends Service {
|
|
|
1628
2473
|
}
|
|
1629
2474
|
};
|
|
1630
2475
|
|
|
1631
|
-
// src/services/
|
|
1632
|
-
var
|
|
1633
|
-
|
|
1634
|
-
// src/services/cache-utils.ts
|
|
1635
|
-
var import_axios6 = require("axios");
|
|
1636
|
-
var import_utils6 = require("@web-ts-toolkit/utils");
|
|
1637
|
-
var normalizeConfigValue = (value) => {
|
|
1638
|
-
if (value == null) return value;
|
|
1639
|
-
if (value instanceof import_axios6.AxiosHeaders) {
|
|
1640
|
-
return normalizeConfigValue(value.toJSON());
|
|
1641
|
-
}
|
|
1642
|
-
if (Array.isArray(value)) {
|
|
1643
|
-
return value.map((item) => normalizeConfigValue(item));
|
|
1644
|
-
}
|
|
1645
|
-
if (typeof value === "object") {
|
|
1646
|
-
return Object.entries((0, import_utils6.omitBy)(value, (item) => item === void 0)).sort(([left], [right]) => left.localeCompare(right)).reduce((acc, [key, item]) => {
|
|
1647
|
-
acc[key] = normalizeConfigValue(item);
|
|
1648
|
-
return acc;
|
|
1649
|
-
}, {});
|
|
1650
|
-
}
|
|
1651
|
-
return value;
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
// src/services/interceptors.ts
|
|
1655
|
-
var SimpleCache = class {
|
|
1656
|
-
constructor() {
|
|
1657
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
1658
|
-
this.timers = /* @__PURE__ */ new Map();
|
|
1659
|
-
}
|
|
1660
|
-
set(key, value, ttl) {
|
|
1661
|
-
this.cache.set(key, value);
|
|
1662
|
-
if (ttl && ttl > 0) {
|
|
1663
|
-
const existing = this.timers.get(key);
|
|
1664
|
-
if (existing) clearTimeout(existing);
|
|
1665
|
-
this.timers.set(
|
|
1666
|
-
key,
|
|
1667
|
-
setTimeout(() => {
|
|
1668
|
-
this.cache.delete(key);
|
|
1669
|
-
this.timers.delete(key);
|
|
1670
|
-
}, ttl)
|
|
1671
|
-
);
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
get(key) {
|
|
1675
|
-
return this.cache.get(key);
|
|
1676
|
-
}
|
|
1677
|
-
has(key) {
|
|
1678
|
-
return this.cache.has(key);
|
|
1679
|
-
}
|
|
1680
|
-
delete(key) {
|
|
1681
|
-
const timer = this.timers.get(key);
|
|
1682
|
-
if (timer) {
|
|
1683
|
-
clearTimeout(timer);
|
|
1684
|
-
this.timers.delete(key);
|
|
1685
|
-
}
|
|
1686
|
-
return this.cache.delete(key);
|
|
1687
|
-
}
|
|
1688
|
-
};
|
|
1689
|
-
var IGNORED_CACHE_HEADERS = /* @__PURE__ */ new Set([
|
|
1690
|
-
"accept",
|
|
1691
|
-
"accept-encoding",
|
|
1692
|
-
"cache-control",
|
|
1693
|
-
"connection",
|
|
1694
|
-
"content-length",
|
|
1695
|
-
"content-type",
|
|
1696
|
-
"expires",
|
|
1697
|
-
"host",
|
|
1698
|
-
"pragma",
|
|
1699
|
-
"user-agent"
|
|
1700
|
-
]);
|
|
1701
|
-
var serializeHeaders = (headers) => {
|
|
1702
|
-
const resolvedHeaders = headers instanceof import_axios7.AxiosHeaders ? headers.toJSON() : headers;
|
|
1703
|
-
const normalizedHeaders = Object.entries(resolvedHeaders ?? {}).filter(([key, value]) => {
|
|
1704
|
-
const normalizedKey = key.toLowerCase();
|
|
1705
|
-
return normalizedKey !== CACHE_HEADER.toLowerCase() && !IGNORED_CACHE_HEADERS.has(normalizedKey) && value !== void 0;
|
|
1706
|
-
}).reduce((acc, [key, value]) => {
|
|
1707
|
-
acc[key.toLowerCase()] = value;
|
|
1708
|
-
return acc;
|
|
1709
|
-
}, {});
|
|
1710
|
-
return JSON.stringify(normalizeConfigValue(normalizedHeaders));
|
|
1711
|
-
};
|
|
1712
|
-
function generateCacheKey(config) {
|
|
1713
|
-
const key = `${config.baseURL}/${config.url}_${config.method}_${generateParamKey(config.params)}_${generateDataKey(
|
|
1714
|
-
config.data
|
|
1715
|
-
)}_${serializeHeaders(config.headers)}`;
|
|
1716
|
-
return encodeURI(key);
|
|
1717
|
-
}
|
|
1718
|
-
function generateParamKey(params) {
|
|
1719
|
-
if (!params) return "";
|
|
1720
|
-
return JSON.stringify(normalizeConfigValue(params));
|
|
1721
|
-
}
|
|
1722
|
-
function generateDataKey(data) {
|
|
1723
|
-
if (!data) return "";
|
|
1724
|
-
return typeof data === "string" ? data : JSON.stringify(normalizeConfigValue(data));
|
|
1725
|
-
}
|
|
1726
|
-
function useCacheInterceptors(instance, cacheTTL) {
|
|
1727
|
-
const store = new SimpleCache();
|
|
1728
|
-
instance.interceptors.request.use(
|
|
1729
|
-
async (config) => {
|
|
1730
|
-
if (config.headers[CACHE_HEADER] === "false") return config;
|
|
1731
|
-
const key = generateCacheKey(config);
|
|
1732
|
-
const cachedResponse = store.get(key);
|
|
1733
|
-
if (!cachedResponse) {
|
|
1734
|
-
return config;
|
|
1735
|
-
}
|
|
1736
|
-
config.adapter = async (_config) => {
|
|
1737
|
-
return {
|
|
1738
|
-
...cachedResponse,
|
|
1739
|
-
config: _config,
|
|
1740
|
-
headers: { ...cachedResponse.headers, [CACHE_HEADER]: "true" }
|
|
1741
|
-
};
|
|
1742
|
-
};
|
|
1743
|
-
return config;
|
|
1744
|
-
},
|
|
1745
|
-
(error) => Promise.reject(error)
|
|
1746
|
-
);
|
|
1747
|
-
instance.interceptors.response.use(
|
|
1748
|
-
(response) => {
|
|
1749
|
-
if (response.config.headers[CACHE_HEADER] === "false") return response;
|
|
1750
|
-
const key = generateCacheKey(response.config);
|
|
1751
|
-
store.set(key, response, cacheTTL);
|
|
1752
|
-
return response;
|
|
1753
|
-
},
|
|
1754
|
-
(error) => Promise.reject(error)
|
|
1755
|
-
);
|
|
1756
|
-
}
|
|
2476
|
+
// src/services/symbols.ts
|
|
2477
|
+
var ADAPTER_ID_KEY = /* @__PURE__ */ Symbol("adapterId");
|
|
1757
2478
|
|
|
1758
2479
|
// src/adapter.ts
|
|
1759
2480
|
var defaultAxiosConfig = Object.freeze({
|
|
@@ -1766,7 +2487,12 @@ var defaultAxiosConfig = Object.freeze({
|
|
|
1766
2487
|
Expires: "0"
|
|
1767
2488
|
}
|
|
1768
2489
|
});
|
|
1769
|
-
var
|
|
2490
|
+
var noopCacheController = {
|
|
2491
|
+
clear: () => {
|
|
2492
|
+
},
|
|
2493
|
+
dispose: () => {
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
1770
2496
|
var serializeRequestConfig = (config) => JSON.stringify(normalizeConfigValue(config ?? {}));
|
|
1771
2497
|
var isObjectRecord = (value) => value != null && typeof value === "object" && !Array.isArray(value);
|
|
1772
2498
|
var mergeServiceDefaults = (adapterDefaults, serviceDefaults) => {
|
|
@@ -1798,13 +2524,32 @@ function createAdapter(axiosConfig, adapterOptions) {
|
|
|
1798
2524
|
onFailure: onFailureRoot,
|
|
1799
2525
|
throwOnError: throwOnErrorRoot,
|
|
1800
2526
|
cacheTTL = 0,
|
|
2527
|
+
cachePartition,
|
|
2528
|
+
cacheCapacity,
|
|
1801
2529
|
modelDefaults: adapterModelDefaults,
|
|
1802
2530
|
dataDefaults: adapterDataDefaults
|
|
1803
2531
|
} = adapterOptions ?? {};
|
|
1804
|
-
|
|
2532
|
+
const cacheController = cacheTTL > 0 ? useCacheInterceptors(instance, {
|
|
2533
|
+
ttl: cacheTTL,
|
|
2534
|
+
capacity: cacheCapacity,
|
|
2535
|
+
withCredentialsDefault: Boolean(instance.defaults.withCredentials),
|
|
2536
|
+
partitionForRequest: cachePartition
|
|
2537
|
+
}) : noopCacheController;
|
|
1805
2538
|
const wraps = createWrapHelper(instance);
|
|
2539
|
+
const adapterId = /* @__PURE__ */ Symbol("adapter");
|
|
2540
|
+
const stampAdapterId = (service) => {
|
|
2541
|
+
Object.defineProperty(service, ADAPTER_ID_KEY, {
|
|
2542
|
+
value: adapterId,
|
|
2543
|
+
enumerable: false,
|
|
2544
|
+
writable: false,
|
|
2545
|
+
configurable: false
|
|
2546
|
+
});
|
|
2547
|
+
return service;
|
|
2548
|
+
};
|
|
1806
2549
|
return Object.freeze({
|
|
1807
2550
|
axios: instance,
|
|
2551
|
+
clearCache: cacheController.clear,
|
|
2552
|
+
disposeCache: cacheController.dispose,
|
|
1808
2553
|
createModelService: ({
|
|
1809
2554
|
modelName,
|
|
1810
2555
|
basePath,
|
|
@@ -1814,7 +2559,7 @@ function createAdapter(axiosConfig, adapterOptions) {
|
|
|
1814
2559
|
onFailure,
|
|
1815
2560
|
throwOnError
|
|
1816
2561
|
}, defaults) => {
|
|
1817
|
-
|
|
2562
|
+
const service = new ModelService(
|
|
1818
2563
|
{
|
|
1819
2564
|
axios: instance,
|
|
1820
2565
|
modelName,
|
|
@@ -1827,9 +2572,10 @@ function createAdapter(axiosConfig, adapterOptions) {
|
|
|
1827
2572
|
},
|
|
1828
2573
|
mergeServiceDefaults(adapterModelDefaults, defaults)
|
|
1829
2574
|
);
|
|
2575
|
+
return stampAdapterId(service);
|
|
1830
2576
|
},
|
|
1831
2577
|
createDataService: ({ dataName, basePath, queryPath = "__query", onSuccess, onFailure, throwOnError }, defaults) => {
|
|
1832
|
-
|
|
2578
|
+
const service = new DataService(
|
|
1833
2579
|
{
|
|
1834
2580
|
axios: instance,
|
|
1835
2581
|
dataName,
|
|
@@ -1841,6 +2587,7 @@ function createAdapter(axiosConfig, adapterOptions) {
|
|
|
1841
2587
|
},
|
|
1842
2588
|
mergeServiceDefaults(adapterDataDefaults, defaults)
|
|
1843
2589
|
);
|
|
2590
|
+
return stampAdapterId(service);
|
|
1844
2591
|
},
|
|
1845
2592
|
wrapGet: wraps.wrapGet,
|
|
1846
2593
|
wrapPost: wraps.wrapPost,
|
|
@@ -1850,55 +2597,72 @@ function createAdapter(axiosConfig, adapterOptions) {
|
|
|
1850
2597
|
group: async (...proms) => {
|
|
1851
2598
|
let sharedConfig;
|
|
1852
2599
|
let sharedConfigKey;
|
|
2600
|
+
let groupThrowOnError;
|
|
1853
2601
|
const defs = proms.map((prom, index) => {
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
2602
|
+
const service = prom.__service;
|
|
2603
|
+
if (!service || service[ADAPTER_ID_KEY] !== adapterId) {
|
|
2604
|
+
throw new Error(
|
|
2605
|
+
"Cannot group a request owned by a different adapter; create the request from this adapter's services"
|
|
2606
|
+
);
|
|
2607
|
+
}
|
|
2608
|
+
if (groupThrowOnError != null && groupThrowOnError !== prom.__throwOnError) {
|
|
2609
|
+
throw new Error("Grouped requests must share the same effective throwOnError policy");
|
|
2610
|
+
}
|
|
2611
|
+
groupThrowOnError = prom.__throwOnError;
|
|
2612
|
+
const configKey = serializeRequestConfig(prom.__requestConfig);
|
|
2613
|
+
if (sharedConfigKey != null && sharedConfigKey !== configKey) {
|
|
2614
|
+
throw new Error("Grouped requests must share the same axios request config");
|
|
1861
2615
|
}
|
|
2616
|
+
sharedConfig = prom.__requestConfig ?? {};
|
|
2617
|
+
sharedConfigKey = configKey;
|
|
1862
2618
|
const query = { ...prom.__query };
|
|
2619
|
+
if (query.target === "model") {
|
|
2620
|
+
delete query.model;
|
|
2621
|
+
}
|
|
1863
2622
|
if (prom.__query.order == null) {
|
|
1864
2623
|
query.order = index;
|
|
1865
2624
|
}
|
|
1866
2625
|
return query;
|
|
1867
2626
|
});
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
_data = (0, import_utils7.castArray)(result2.data).map((item) => Model.create(item, modelService));
|
|
1886
|
-
}
|
|
1887
|
-
} else if (result2.kind === "single" && ["new", "read", "update", "upsert"].includes(op)) {
|
|
1888
|
-
_data = Model.create(result2.data, modelService);
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
return {
|
|
1892
|
-
success,
|
|
1893
|
-
raw: _raw,
|
|
1894
|
-
data: _data,
|
|
2627
|
+
const groupOwner = /* @__PURE__ */ Symbol("group");
|
|
2628
|
+
const claimed = [];
|
|
2629
|
+
try {
|
|
2630
|
+
for (const prom of proms) {
|
|
2631
|
+
claimLazyRequest(prom, "grouped", groupOwner);
|
|
2632
|
+
claimed.push(prom);
|
|
2633
|
+
}
|
|
2634
|
+
} catch (error) {
|
|
2635
|
+
for (const prom of claimed) {
|
|
2636
|
+
releaseLazyRequestClaim(prom, groupOwner);
|
|
2637
|
+
}
|
|
2638
|
+
throw error;
|
|
2639
|
+
}
|
|
2640
|
+
const result = await instance.post(rootRouterPath, defs, sharedConfig ?? {}).then(
|
|
2641
|
+
(res) => {
|
|
2642
|
+
const rawEntries = res.data.map(({ result: result2, message, statusCode, op }) => ({
|
|
2643
|
+
result: result2,
|
|
1895
2644
|
message,
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
2645
|
+
statusCode,
|
|
2646
|
+
op
|
|
2647
|
+
}));
|
|
2648
|
+
const finalized = rawEntries.map(
|
|
2649
|
+
(rawEntry, index) => finalizeRootEntry(proms[index].__query, rawEntry, {}, proms[index].__service)
|
|
2650
|
+
);
|
|
2651
|
+
return applyGroupCallbacks(
|
|
2652
|
+
finalized,
|
|
2653
|
+
proms.map((p) => p.__service),
|
|
2654
|
+
groupThrowOnError ?? false
|
|
2655
|
+
);
|
|
2656
|
+
},
|
|
2657
|
+
(error) => {
|
|
2658
|
+
const failures = proms.map((prom) => finalizeRootTransportFailure(prom.__query, error));
|
|
2659
|
+
return applyGroupCallbacks(
|
|
2660
|
+
failures,
|
|
2661
|
+
proms.map((p) => p.__service),
|
|
2662
|
+
groupThrowOnError ?? false
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
);
|
|
1902
2666
|
return result;
|
|
1903
2667
|
}
|
|
1904
2668
|
});
|
|
@@ -1923,6 +2687,7 @@ function removeItemById(items, targetItem) {
|
|
|
1923
2687
|
0 && (module.exports = {
|
|
1924
2688
|
CustomHeaders,
|
|
1925
2689
|
DataService,
|
|
2690
|
+
MissingPersistenceIdentityError,
|
|
1926
2691
|
Model,
|
|
1927
2692
|
ModelService,
|
|
1928
2693
|
Service,
|