@decaf-ts/for-fabric 0.13.9 → 0.13.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/for-fabric.cjs +1 -1
- package/lib/cjs/contracts/ContractAdapter.cjs +194 -148
- package/lib/cjs/contracts/ContractAdapter.cjs.map +1 -1
- package/lib/cjs/contracts/FabricContractRepository.cjs +10 -2
- package/lib/cjs/contracts/FabricContractRepository.cjs.map +1 -1
- package/lib/cjs/version.cjs +3 -3
- package/lib/esm/contracts/ContractAdapter.js +196 -150
- package/lib/esm/contracts/ContractAdapter.js.map +1 -1
- package/lib/esm/contracts/FabricContractRepository.js +10 -2
- package/lib/esm/contracts/FabricContractRepository.js.map +1 -1
- package/lib/esm/version.js +3 -3
- package/lib/types/contracts/ContractAdapter.d.cts +6 -3
- package/lib/types/contracts/ContractAdapter.d.mts +6 -3
- package/lib/types/shared/types.d.cts +11 -0
- package/lib/types/shared/types.d.mts +11 -0
- package/lib/types/version.d.cts +3 -3
- package/lib/types/version.d.mts +3 -3
- package/package.json +1 -1
|
@@ -120,114 +120,104 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
120
120
|
.update(FabricContractAdapter.stableStringify(relevant))
|
|
121
121
|
.digest("base64url");
|
|
122
122
|
}
|
|
123
|
-
static
|
|
124
|
-
if (typeof bookmark !== "string")
|
|
125
|
-
return undefined;
|
|
126
|
-
if (!bookmark.startsWith(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX))
|
|
127
|
-
return undefined;
|
|
128
|
-
const raw = bookmark.slice(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX.length);
|
|
129
|
-
try {
|
|
130
|
-
const parsed = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
|
|
131
|
-
if (!parsed ||
|
|
132
|
-
typeof parsed !== "object" ||
|
|
133
|
-
typeof parsed.sortField !== "string" ||
|
|
134
|
-
typeof parsed.direction !== "string" ||
|
|
135
|
-
typeof parsed.idField !== "string" ||
|
|
136
|
-
typeof parsed.lastId !== "string"
|
|
137
|
-
|| typeof parsed.queryHash !== "string") {
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
sortField: parsed.sortField,
|
|
142
|
-
direction: parsed.direction === "desc" ? "desc" : "asc",
|
|
143
|
-
idField: parsed.idField,
|
|
144
|
-
lastValue: parsed.lastValue,
|
|
145
|
-
lastId: parsed.lastId,
|
|
146
|
-
queryHash: parsed.queryHash,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
return undefined;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
static buildSyntheticPrivateBookmark(cursor) {
|
|
154
|
-
return `${FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX}${Buffer.from(JSON.stringify(cursor)).toString("base64url")}`;
|
|
155
|
-
}
|
|
156
|
-
static buildPrivateCursorSelector(selector, sortField, direction, cursor) {
|
|
123
|
+
static buildPrivateContinuationSelector(selector, sortField, direction, idField, lastValue, lastId, variant) {
|
|
157
124
|
const cmp = direction === "desc" ? "$lt" : "$gt";
|
|
158
|
-
|
|
125
|
+
const idCmp = direction === "desc" ? "$lt" : "$gt";
|
|
126
|
+
if (idField === sortField) {
|
|
159
127
|
const continuation = {
|
|
160
128
|
[sortField]: {
|
|
161
|
-
[cmp]:
|
|
129
|
+
[cmp]: lastValue,
|
|
162
130
|
},
|
|
163
131
|
};
|
|
164
|
-
if (!Object.keys(selector
|
|
132
|
+
if (!selector || !Object.keys(selector).length) {
|
|
165
133
|
return continuation;
|
|
134
|
+
}
|
|
166
135
|
return {
|
|
167
136
|
$and: [selector, continuation],
|
|
168
137
|
};
|
|
169
138
|
}
|
|
170
|
-
const
|
|
171
|
-
|
|
139
|
+
const clauses = variant === "same"
|
|
140
|
+
? [
|
|
172
141
|
{
|
|
173
142
|
[sortField]: {
|
|
174
|
-
|
|
143
|
+
$eq: lastValue,
|
|
175
144
|
},
|
|
176
145
|
},
|
|
177
146
|
{
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
$eq: cursor.lastValue,
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
[cursor.idField]: {
|
|
186
|
-
[cmp]: cursor.lastId,
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
],
|
|
147
|
+
[idField]: {
|
|
148
|
+
[idCmp]: lastId,
|
|
149
|
+
},
|
|
190
150
|
},
|
|
191
|
-
]
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
151
|
+
]
|
|
152
|
+
: [
|
|
153
|
+
{
|
|
154
|
+
[sortField]: {
|
|
155
|
+
[cmp]: lastValue,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
if (!selector || !Object.keys(selector).length) {
|
|
160
|
+
return clauses.length === 1
|
|
161
|
+
? clauses[0]
|
|
162
|
+
: {
|
|
163
|
+
$and: clauses,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
195
166
|
return {
|
|
196
|
-
$and: [selector,
|
|
167
|
+
$and: [selector, ...clauses],
|
|
197
168
|
};
|
|
198
169
|
}
|
|
199
|
-
static
|
|
200
|
-
|
|
201
|
-
|
|
170
|
+
static buildOrlessKeysetContinuationQueries(query, cursor, pageSize) {
|
|
171
|
+
const baseQuery = { ...query };
|
|
172
|
+
delete baseQuery.skip;
|
|
173
|
+
delete baseQuery.bookmark;
|
|
174
|
+
delete baseQuery.limit;
|
|
175
|
+
if (cursor.idField === cursor.sortField) {
|
|
176
|
+
const single = {
|
|
177
|
+
...baseQuery,
|
|
178
|
+
selector: FabricContractAdapter.buildPrivateContinuationSelector((baseQuery.selector || {}), cursor.sortField, cursor.direction, cursor.idField, cursor.lastValue, cursor.lastId, "same"),
|
|
179
|
+
limit: pageSize + 1,
|
|
180
|
+
};
|
|
181
|
+
return [single];
|
|
202
182
|
}
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
183
|
+
const first = {
|
|
184
|
+
...baseQuery,
|
|
185
|
+
selector: FabricContractAdapter.buildPrivateContinuationSelector((baseQuery.selector || {}), cursor.sortField, cursor.direction, cursor.idField, cursor.lastValue, cursor.lastId, "same"),
|
|
186
|
+
limit: pageSize + 1,
|
|
187
|
+
};
|
|
188
|
+
const second = {
|
|
189
|
+
...baseQuery,
|
|
190
|
+
selector: FabricContractAdapter.buildPrivateContinuationSelector((baseQuery.selector || {}), cursor.sortField, cursor.direction, cursor.idField, cursor.lastValue, cursor.lastId, "next"),
|
|
191
|
+
limit: pageSize + 1,
|
|
192
|
+
};
|
|
193
|
+
return [first, second];
|
|
194
|
+
}
|
|
195
|
+
static ensureDeterministicPrivateSort(query, tieBreaker) {
|
|
196
|
+
if (!Array.isArray(query.sort) || !query.sort.length) {
|
|
197
|
+
throw new core_1.PagingError("Private Mango pagination requires an explicit sort. Add orderBy(...) so a stable generated index can be selected.");
|
|
206
198
|
}
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
199
|
+
const direction = ((0, for_couchdb_1.getSortDirection)(query) ||
|
|
200
|
+
core_1.OrderDirection.ASC);
|
|
201
|
+
(0, for_couchdb_1.ensureDeterministicSort)(query, tieBreaker, direction);
|
|
202
|
+
const sortFields = (0, for_couchdb_1.getSortFields)(query);
|
|
203
|
+
const sortField = sortFields[0];
|
|
204
|
+
if (!sortField) {
|
|
205
|
+
throw new core_1.PagingError("Private Mango pagination requires a valid first sort field.");
|
|
211
206
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const [field, dir] = Object.entries(entry || {})[0] || [];
|
|
215
|
-
return (field === idField && String(dir || "").toLowerCase() === direction);
|
|
216
|
-
});
|
|
217
|
-
if (!hasIdTieBreaker && idField !== sortField) {
|
|
218
|
-
query.sort = [...query.sort, { [idField]: direction }];
|
|
207
|
+
if (!sortFields.includes(tieBreaker)) {
|
|
208
|
+
throw new core_1.PagingError(`Private Mango pagination requires tie-breaker sort field "${tieBreaker}".`);
|
|
219
209
|
}
|
|
220
210
|
return {
|
|
221
211
|
sortField,
|
|
222
212
|
direction: direction,
|
|
223
|
-
idField,
|
|
213
|
+
idField: tieBreaker,
|
|
224
214
|
};
|
|
225
215
|
}
|
|
226
216
|
static parsePrivateResultValue(value) {
|
|
227
217
|
try {
|
|
228
218
|
const parsed = JSON.parse(value.toString("utf8"));
|
|
229
|
-
if (!parsed || typeof parsed !== "object") {
|
|
230
|
-
throw new Error("Private query result is not
|
|
219
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
220
|
+
throw new Error("Private query result is not a JSON object");
|
|
231
221
|
}
|
|
232
222
|
return parsed;
|
|
233
223
|
}
|
|
@@ -235,6 +225,102 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
235
225
|
throw new db_decorators_1.SerializationError(`Failed to parse private query result while building bookmark: ${e}`);
|
|
236
226
|
}
|
|
237
227
|
}
|
|
228
|
+
static async executePrivateMangoPageQueries(stub, collection, queries, pageSize, log) {
|
|
229
|
+
const paged = [];
|
|
230
|
+
for (const query of queries) {
|
|
231
|
+
if (paged.length >= pageSize + 1) {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
const remaining = pageSize + 1 - paged.length;
|
|
235
|
+
const queryForExecution = {
|
|
236
|
+
...query,
|
|
237
|
+
limit: remaining,
|
|
238
|
+
};
|
|
239
|
+
delete queryForExecution.skip;
|
|
240
|
+
delete queryForExecution.bookmark;
|
|
241
|
+
log.debug(`Querying collection ${collection} for ${JSON.stringify(queryForExecution)}`);
|
|
242
|
+
const response = await stub.getPrivateDataQueryResult(collection, JSON.stringify(queryForExecution));
|
|
243
|
+
const iterator = (response.iterator ||
|
|
244
|
+
response);
|
|
245
|
+
try {
|
|
246
|
+
while (paged.length < pageSize + 1) {
|
|
247
|
+
const res = await iterator.next();
|
|
248
|
+
if (res.done)
|
|
249
|
+
break;
|
|
250
|
+
if (!res.value || !res.value.value)
|
|
251
|
+
continue;
|
|
252
|
+
paged.push({
|
|
253
|
+
key: res.value.key,
|
|
254
|
+
value: Buffer.isBuffer(res.value.value)
|
|
255
|
+
? res.value.value
|
|
256
|
+
: Buffer.from(res.value.value.toString("utf8")),
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
await iterator.close();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return paged;
|
|
265
|
+
}
|
|
266
|
+
static toFabricPaginationResponse(docs, bookmark) {
|
|
267
|
+
let idx = 0;
|
|
268
|
+
const iterator = {
|
|
269
|
+
async next() {
|
|
270
|
+
if (idx < docs.length) {
|
|
271
|
+
return {
|
|
272
|
+
value: docs[idx++],
|
|
273
|
+
done: false,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
value: undefined,
|
|
278
|
+
done: true,
|
|
279
|
+
};
|
|
280
|
+
},
|
|
281
|
+
async close() { },
|
|
282
|
+
};
|
|
283
|
+
return {
|
|
284
|
+
iterator: iterator,
|
|
285
|
+
metadata: {
|
|
286
|
+
fetchedRecordsCount: docs.length,
|
|
287
|
+
bookmark,
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
static parseSyntheticPrivateBookmark(bookmark) {
|
|
292
|
+
if (typeof bookmark !== "string")
|
|
293
|
+
return undefined;
|
|
294
|
+
if (!bookmark.startsWith(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX))
|
|
295
|
+
return undefined;
|
|
296
|
+
const raw = bookmark.slice(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX.length);
|
|
297
|
+
try {
|
|
298
|
+
const parsed = JSON.parse(Buffer.from(raw, "base64url").toString("utf8"));
|
|
299
|
+
if (!parsed ||
|
|
300
|
+
typeof parsed !== "object" ||
|
|
301
|
+
typeof parsed.sortField !== "string" ||
|
|
302
|
+
typeof parsed.direction !== "string" ||
|
|
303
|
+
typeof parsed.idField !== "string" ||
|
|
304
|
+
typeof parsed.lastId !== "string"
|
|
305
|
+
|| typeof parsed.queryHash !== "string") {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
sortField: parsed.sortField,
|
|
310
|
+
direction: parsed.direction === "desc" ? "desc" : "asc",
|
|
311
|
+
idField: parsed.idField,
|
|
312
|
+
lastValue: parsed.lastValue,
|
|
313
|
+
lastId: parsed.lastId,
|
|
314
|
+
queryHash: parsed.queryHash,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
static buildSyntheticPrivateBookmark(cursor) {
|
|
322
|
+
return `${FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX}${Buffer.from(JSON.stringify(cursor)).toString("base64url")}`;
|
|
323
|
+
}
|
|
238
324
|
getClient() {
|
|
239
325
|
throw new core_1.UnsupportedError("Client is not supported in Fabric contracts");
|
|
240
326
|
}
|
|
@@ -627,76 +713,48 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
627
713
|
}
|
|
628
714
|
case "queryResultPaginated": {
|
|
629
715
|
const [stub, rawInput, limit, skip, bookmark, ...args] = argsList;
|
|
630
|
-
const { log } = thisArg["logCtx"](args, prop);
|
|
716
|
+
const { log, ctx } = thisArg["logCtx"](args, prop);
|
|
631
717
|
if (skip !== undefined && skip !== null && Number(skip) > 0) {
|
|
632
|
-
throw new core_1.PagingError("Private
|
|
718
|
+
throw new core_1.PagingError("Private Mango pagination does not support skip/offset pagination. Use the returned synthetic bookmark instead.");
|
|
633
719
|
}
|
|
634
720
|
const pageSize = Math.max(1, Number(limit) || 250);
|
|
635
721
|
const query = { ...rawInput };
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
722
|
+
const queryInput = query;
|
|
723
|
+
const queryPkField = typeof queryInput["__pkField"] === "string" &&
|
|
724
|
+
queryInput["__pkField"].trim().length
|
|
725
|
+
? String(queryInput["__pkField"])
|
|
726
|
+
: String(ctx?.getOrUndefined("privatePaginationTieBreaker") ||
|
|
727
|
+
"id");
|
|
728
|
+
delete queryInput["__pkField"];
|
|
642
729
|
const syntheticCursor = FabricContractAdapter.parseSyntheticPrivateBookmark(bookmark);
|
|
643
730
|
if (bookmark !== undefined &&
|
|
644
731
|
bookmark !== null &&
|
|
645
732
|
bookmark !== "" &&
|
|
646
733
|
!syntheticCursor) {
|
|
647
|
-
throw new core_1.PagingError("Private
|
|
734
|
+
throw new core_1.PagingError("Private Mango pagination only supports adapter-generated synthetic bookmarks.");
|
|
735
|
+
}
|
|
736
|
+
if (!Array.isArray(query.sort) || !query.sort.length) {
|
|
737
|
+
throw new core_1.PagingError("Private Mango pagination requires an explicit sort. Add orderBy(...) so a stable generated index can be selected.");
|
|
648
738
|
}
|
|
739
|
+
const { sortField, direction: sortDirection, idField } = FabricContractAdapter.ensureDeterministicPrivateSort(query, queryPkField);
|
|
740
|
+
(0, for_couchdb_1.warnScanProneMangoOperators)(query.selector || {}, log);
|
|
649
741
|
log.debug(`Private paginated query input collection=${collection} limit=${limit} skip=${skip} bookmark=${bookmark} sortField=${sortField} direction=${sortDirection} synthetic=${Boolean(syntheticCursor)}`);
|
|
650
|
-
delete query.skip;
|
|
651
|
-
delete query.bookmark;
|
|
652
742
|
query.limit = pageSize + 1;
|
|
653
743
|
const queryHash = FabricContractAdapter.privateQueryHash(query);
|
|
654
744
|
if (syntheticCursor) {
|
|
655
745
|
if (syntheticCursor.queryHash !== queryHash) {
|
|
656
|
-
throw new core_1.PagingError("Private
|
|
657
|
-
}
|
|
658
|
-
query.selector = FabricContractAdapter.buildPrivateCursorSelector(query.selector || {}, syntheticCursor.sortField, syntheticCursor.direction, syntheticCursor);
|
|
659
|
-
}
|
|
660
|
-
log.debug(`Querying collection ${collection} for ${JSON.stringify(query)}`);
|
|
661
|
-
const response = await stub.getPrivateDataQueryResult(collection, JSON.stringify(query));
|
|
662
|
-
const iterator = (response.iterator ||
|
|
663
|
-
response);
|
|
664
|
-
const responseMetadata = response.metadata ||
|
|
665
|
-
iterator.metadata ||
|
|
666
|
-
{};
|
|
667
|
-
log.debug(`Private paginated response collection=${collection} metadata=${JSON.stringify(responseMetadata)}`);
|
|
668
|
-
log.verbose(`iterator from collection ${collection} received`);
|
|
669
|
-
const paged = [];
|
|
670
|
-
let hasMore = false;
|
|
671
|
-
try {
|
|
672
|
-
while (true) {
|
|
673
|
-
const res = await iterator.next();
|
|
674
|
-
if (res.done)
|
|
675
|
-
break;
|
|
676
|
-
if (res.value && res.value.value) {
|
|
677
|
-
const key = res.value.key;
|
|
678
|
-
if (paged.length < pageSize) {
|
|
679
|
-
paged.push({
|
|
680
|
-
key,
|
|
681
|
-
value: Buffer.isBuffer(res.value.value)
|
|
682
|
-
? res.value.value
|
|
683
|
-
: Buffer.from(res.value.value.toString("utf8")),
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
hasMore = true;
|
|
688
|
-
break; // early exit
|
|
689
|
-
}
|
|
690
|
-
}
|
|
746
|
+
throw new core_1.PagingError("Private Mango bookmark does not match the current query.");
|
|
691
747
|
}
|
|
692
748
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
749
|
+
const queries = syntheticCursor
|
|
750
|
+
? FabricContractAdapter.buildOrlessKeysetContinuationQueries(query, syntheticCursor, pageSize)
|
|
751
|
+
: [{ ...query, limit: pageSize + 1 }];
|
|
752
|
+
const paged = await FabricContractAdapter.executePrivateMangoPageQueries(stub, collection, queries, pageSize, log);
|
|
753
|
+
const hasMore = paged.length > pageSize;
|
|
754
|
+
const docs = hasMore ? paged.slice(0, pageSize) : paged;
|
|
697
755
|
let nextBookmark = "";
|
|
698
|
-
if (hasMore &&
|
|
699
|
-
const last =
|
|
756
|
+
if (hasMore && docs.length) {
|
|
757
|
+
const last = docs[docs.length - 1];
|
|
700
758
|
const lastDoc = FabricContractAdapter.parsePrivateResultValue(last.value);
|
|
701
759
|
if (!(sortField in lastDoc)) {
|
|
702
760
|
throw new core_1.PagingError(`Cannot build private pagination bookmark: sorted field "${sortField}" is missing from the last result`);
|
|
@@ -716,24 +774,7 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
716
774
|
queryHash,
|
|
717
775
|
});
|
|
718
776
|
}
|
|
719
|
-
|
|
720
|
-
let idx = 0;
|
|
721
|
-
const arrayIterator = {
|
|
722
|
-
async next() {
|
|
723
|
-
if (idx < paged.length) {
|
|
724
|
-
return { value: paged[idx++], done: false };
|
|
725
|
-
}
|
|
726
|
-
return { value: undefined, done: true };
|
|
727
|
-
},
|
|
728
|
-
async close() { },
|
|
729
|
-
};
|
|
730
|
-
return {
|
|
731
|
-
iterator: arrayIterator,
|
|
732
|
-
metadata: {
|
|
733
|
-
fetchedRecordsCount: paged.length,
|
|
734
|
-
bookmark: nextBookmark,
|
|
735
|
-
},
|
|
736
|
-
};
|
|
777
|
+
return FabricContractAdapter.toFabricPaginationResponse(docs, nextBookmark);
|
|
737
778
|
}
|
|
738
779
|
default:
|
|
739
780
|
throw new db_decorators_1.InternalError(`Unsupported method override ${String(prop)}`);
|
|
@@ -803,6 +844,8 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
803
844
|
segregated: false,
|
|
804
845
|
rebuildWithTransient: false,
|
|
805
846
|
fullySegregated: false,
|
|
847
|
+
strictPrivateMangoPagination: true,
|
|
848
|
+
privatePaginationTieBreaker: "id",
|
|
806
849
|
};
|
|
807
850
|
if (flags instanceof ContractContext_js_1.FabricContractContext || flags instanceof core_1.Context) {
|
|
808
851
|
flags = flags.toOverrides();
|
|
@@ -937,6 +980,8 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
937
980
|
const originalInput = { ...rawInput };
|
|
938
981
|
const { skip, limit } = originalInput;
|
|
939
982
|
const bookmark = originalInput["bookmark"];
|
|
983
|
+
const hasSort = Array.isArray(originalInput.sort) &&
|
|
984
|
+
originalInput.sort.length > 0;
|
|
940
985
|
const pkField = typeof originalInput["__pkField"] === "string" &&
|
|
941
986
|
originalInput["__pkField"].trim().length
|
|
942
987
|
? String(originalInput["__pkField"])
|
|
@@ -944,7 +989,8 @@ class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
|
944
989
|
const hasSkip = skip !== undefined && skip !== null && Number(skip) > 0;
|
|
945
990
|
const hasBookmark = bookmark !== undefined && bookmark !== null && bookmark !== "";
|
|
946
991
|
const paginationActive = Boolean(limit || hasSkip || hasBookmark);
|
|
947
|
-
const shouldPaginate = Boolean(paginationActive &&
|
|
992
|
+
const shouldPaginate = Boolean(paginationActive &&
|
|
993
|
+
(enableSegregates || hasSkip || hasBookmark || hasSort));
|
|
948
994
|
const baseInput = { ...originalInput };
|
|
949
995
|
delete baseInput["skip"];
|
|
950
996
|
delete baseInput["bookmark"];
|