startgg-helper 2.3.2 → 2.4.1
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/package.json +1 -1
- package/src/query.js +56 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "startgg-helper",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "A set of functions and classes useful to communicate with the start.gg API, using any client (YOU NEED TO PROVIDE A CLIENT YOURSELF, SEE README)",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"module": "main.js",
|
package/src/query.js
CHANGED
|
@@ -5,6 +5,17 @@ function isConnection(val){
|
|
|
5
5
|
return val instanceof Object && val.nodes instanceof Array
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
export class PageResult {
|
|
9
|
+
/**
|
|
10
|
+
* @param {any} result
|
|
11
|
+
* @param {boolean} stop
|
|
12
|
+
*/
|
|
13
|
+
constructor(result, stop){
|
|
14
|
+
this.result = result;
|
|
15
|
+
this.stop = stop;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
/**
|
|
9
20
|
* A GraphQL Document/Schema. Allows easily batch-requesting with the same schema but different parameters.
|
|
10
21
|
*/
|
|
@@ -76,7 +87,7 @@ export class Query {
|
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
/**
|
|
79
|
-
* @param {GraphQLClient} client A client object ; not provided by this package, either use startgg-helper-node (or-browser) or refer to README.md
|
|
90
|
+
* @param {GraphQLClient} client A client object ; not provided by this package, either use startgg-helper-node (or -browser) or refer to README.md
|
|
80
91
|
* @param {{[varName: string]: value}} params GraphQL variables
|
|
81
92
|
* @param {TimedQuerySemaphore} limiter A request limiter object; see TimedQuerySemaphore
|
|
82
93
|
* @param {boolean} silentErrors No effect, exists only for legacy purposes
|
|
@@ -94,6 +105,8 @@ export class Query {
|
|
|
94
105
|
OUT: 3
|
|
95
106
|
}
|
|
96
107
|
|
|
108
|
+
/** @typedef {(localResult: T[], currentResult: T[], pageIndex: number) => (T[]|PageResult|boolean)?} PageCallback*/
|
|
109
|
+
|
|
97
110
|
/**
|
|
98
111
|
* Queries a whole paginated collection (of a *Connection type). See the start.gg API doc or this package's documentation for more info about pagniated collections. This is done through executing the query repeatedly while increasing the page index each time.
|
|
99
112
|
* The target collection must be pointed to by the "path" argument, and will be agregated in a single array. The schema must have a variable (whose name can be specified in parameters) that is used as the page index of the paginated field.
|
|
@@ -103,7 +116,7 @@ export class Query {
|
|
|
103
116
|
* @param {{[varName: string]: value}} params GraphQL variables ; does not include the page index variable.
|
|
104
117
|
* @param {string} connectionPathInQuery JSON path to the paginated collection that must be aggregated in the query (JSON path : property names separated by dots, see deep_get())
|
|
105
118
|
* @param {TimedQuerySemaphore} limiter A request limiter object; see TimedQuerySemaphore
|
|
106
|
-
* @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, delay?: number, maxElements?: number, includeWholeQuery?: number, callback:
|
|
119
|
+
* @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, startingPage: number, initialData: any, delay?: number, maxElements?: number, includeWholeQuery?: number, callback: PageCallback?}} config
|
|
107
120
|
* @param config.pageParamName name of the variable representing the page index. This variable must exist in your query, and be used as an argument in a paginated collection field
|
|
108
121
|
* @param config.delay number of miliseconds to wait for between each query. No delay if absent.
|
|
109
122
|
* @param config.maxElements if present, queries will stop once this many elements have been fetched
|
|
@@ -114,15 +127,14 @@ export class Query {
|
|
|
114
127
|
* @returns See config.includeWholeQuery
|
|
115
128
|
*/
|
|
116
129
|
async executePaginated(client, params, connectionPathInQuery, limiter = null, config = {}, silentErrors = false, maxTries = null){
|
|
117
|
-
let result = [];
|
|
118
|
-
//delay = null, perPage = undefined, pageParamName = "page", perPageParamName = "perPage", silentErrors = false, maxTries = null
|
|
130
|
+
let result = config.initialData ?? [];
|
|
119
131
|
const pageParamName = config.pageParamName ?? "page";
|
|
120
132
|
const perPageParamName = config.perPageParamName ?? "perPage";
|
|
121
133
|
const perPage = config.perPage ?? params[perPageParamName];
|
|
122
134
|
const delay = config.delay;
|
|
123
135
|
const maxElements = config.maxElements ?? undefined; //eliminating null
|
|
124
136
|
|
|
125
|
-
let currentPage = 1;
|
|
137
|
+
let currentPage = config.startingPage ?? 1;
|
|
126
138
|
|
|
127
139
|
params = Object.assign({}, params);
|
|
128
140
|
params[pageParamName] = currentPage;
|
|
@@ -150,29 +162,56 @@ export class Query {
|
|
|
150
162
|
|
|
151
163
|
let localResult = connection.nodes;
|
|
152
164
|
|
|
153
|
-
if (connection.pageInfo && connection.pageInfo.totalPages){
|
|
165
|
+
if (connection.pageInfo && connection.pageInfo.totalPages){ //if the query contains pageInfo we use that to determine if we're at the last page
|
|
154
166
|
let totalPages = connection.pageInfo.totalPages;
|
|
155
|
-
if (
|
|
167
|
+
if (currentPage >= totalPages) {
|
|
156
168
|
if (config.callback){
|
|
157
|
-
let cbRes = config.callback(localResult, currentPage)
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
let cbRes = config.callback(localResult, result, currentPage)
|
|
170
|
+
|
|
171
|
+
if (cbRes instanceof PageResult){
|
|
172
|
+
if (cbRes.result){ //If the user gives us a result we take it ofc
|
|
173
|
+
result = cbRes.result;
|
|
174
|
+
} else {
|
|
175
|
+
result = result.concat(localResult);
|
|
176
|
+
}
|
|
177
|
+
} else if (cbRes && cbRes !== true) { //cbres isn't one that means something loop-control-related (it's over anyways so we don't care!)
|
|
178
|
+
result = result.concat(cbRes);
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
result = result.concat(localResult);
|
|
160
182
|
}
|
|
161
|
-
result = result.concat(localResult);
|
|
162
183
|
break;
|
|
163
184
|
}
|
|
164
|
-
} else {
|
|
185
|
+
} else { //if not, we only know when we get an empty page
|
|
165
186
|
if (localResult.length < 1) break;
|
|
166
187
|
}
|
|
167
188
|
|
|
168
189
|
if (config.callback){
|
|
169
|
-
let cbRes = config.callback(localResult, currentPage);
|
|
170
|
-
if (!cbRes) break;
|
|
171
|
-
localResult = cbRes;
|
|
172
|
-
}
|
|
190
|
+
let cbRes = config.callback(localResult, result, currentPage);
|
|
173
191
|
|
|
174
|
-
|
|
192
|
+
if (cbRes instanceof PageResult){
|
|
193
|
+
if (cbRes.result){ //If the user gives us a result we take it ofc
|
|
194
|
+
result = cbRes.result;
|
|
195
|
+
} else {
|
|
196
|
+
result = result.concat(localResult);
|
|
197
|
+
}
|
|
198
|
+
if (cbRes.stop){
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
} else if (!cbRes) { //"normal case" : basic callback that doesn't touch the flow of the pexecution, we concat and increment normally
|
|
202
|
+
result = result.concat(localResult)
|
|
203
|
+
} else if (cbRes === true){ //callback is asking us to stop by returning true
|
|
204
|
+
break;
|
|
205
|
+
} else { //callback returns a non-boolean value : it's the local result (and we increment normally)
|
|
206
|
+
result = result.concat(cbRes);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
} else {
|
|
210
|
+
result = result.concat(localResult);
|
|
211
|
+
}
|
|
212
|
+
|
|
175
213
|
currentPage++;
|
|
214
|
+
|
|
176
215
|
params[pageParamName] = currentPage;
|
|
177
216
|
|
|
178
217
|
if (delay)
|