startgg-helper 1.0.3 → 2.0.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/package.json +1 -1
- package/src/jsUtil.js +29 -10
- package/src/query.js +39 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "startgg-helper",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
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
|
"scripts": {
|
package/src/jsUtil.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
*
|
|
3
|
-
* @param {{}} obj
|
|
4
|
-
* @param {string} path
|
|
5
|
-
* @param {*} def
|
|
6
|
-
* @returns
|
|
7
|
-
*/
|
|
8
|
-
export function deep_get(obj, path, def = null){
|
|
9
|
-
//https://stackoverflow.com/a/8817473
|
|
1
|
+
function processObjectPath(path){
|
|
10
2
|
path = path=path.split('.');
|
|
11
3
|
for (let i = 0; i < path.length; i++){
|
|
12
4
|
if (/^\d/.test(path[i])){
|
|
@@ -16,10 +8,37 @@ export function deep_get(obj, path, def = null){
|
|
|
16
8
|
}
|
|
17
9
|
}
|
|
18
10
|
}
|
|
11
|
+
return path;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param {{}} obj
|
|
17
|
+
* @param {string} path
|
|
18
|
+
* @param {*} def
|
|
19
|
+
* @returns
|
|
20
|
+
*/
|
|
21
|
+
export function deep_get(obj, path, def = null){
|
|
22
|
+
//https://stackoverflow.com/a/8817473
|
|
23
|
+
path = processObjectPath(path);
|
|
19
24
|
|
|
20
25
|
for (var i=0, len=path.length; i<len; i++){
|
|
21
26
|
obj = obj[path[i]];
|
|
22
27
|
if (obj == undefined) return def;
|
|
23
28
|
};
|
|
24
29
|
return obj;
|
|
25
|
-
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function deep_set(obj, path, value){
|
|
33
|
+
path = processObjectPath(path);
|
|
34
|
+
|
|
35
|
+
let finalName = path.pop();
|
|
36
|
+
for (let elt of path){
|
|
37
|
+
obj = obj[elt];
|
|
38
|
+
if (!(obj instanceof Object)){
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
obj[finalName] = value;
|
|
43
|
+
return true;
|
|
44
|
+
}
|
package/src/query.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GraphQLClient } from 'graphql-request';
|
|
2
|
+
import { deep_get, deep_set } from './jsUtil.js';
|
|
2
3
|
import { TimedQuerySemaphore } from './queryLimiter.js'
|
|
3
4
|
|
|
4
|
-
/**
|
|
5
|
-
* Dummy client class that's only used in the JSDoc.
|
|
6
|
-
* In a real use case, the user will have their own client class.
|
|
7
|
-
*/
|
|
8
|
-
class Client {
|
|
9
|
-
request(){}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
5
|
export class Query {
|
|
13
6
|
#schema;
|
|
14
7
|
#maxTries;
|
|
@@ -44,7 +37,7 @@ export class Query {
|
|
|
44
37
|
|
|
45
38
|
/**
|
|
46
39
|
*
|
|
47
|
-
* @param {
|
|
40
|
+
* @param {GraphQLClient} client
|
|
48
41
|
* @param {{[varName: string]: value}} params
|
|
49
42
|
* @param {number} tries How many tries in are we
|
|
50
43
|
* @param {TimedQuerySemaphore} limiter
|
|
@@ -73,7 +66,7 @@ export class Query {
|
|
|
73
66
|
|
|
74
67
|
/**
|
|
75
68
|
* Executes the query with given parameters and client
|
|
76
|
-
* @param {
|
|
69
|
+
* @param {GraphQLClient} client
|
|
77
70
|
* @param {{[varName: string]: value}} params
|
|
78
71
|
* @param {TimedQuerySemaphore} limiter
|
|
79
72
|
* @param {boolean} silentErrors
|
|
@@ -84,29 +77,43 @@ export class Query {
|
|
|
84
77
|
return await this.#execute_(client, params, 0, limiter, silentErrors, maxTries);
|
|
85
78
|
}
|
|
86
79
|
|
|
80
|
+
static IWQModes = {
|
|
81
|
+
DONT: 0,
|
|
82
|
+
INLINE: 1,
|
|
83
|
+
DUPLICATE: 2,
|
|
84
|
+
OUT: 3
|
|
85
|
+
}
|
|
86
|
+
|
|
87
87
|
/**
|
|
88
88
|
* Executes a query containing a paginated collection, repeatedly, increasing the page index each time until nothing is returned, returning an aggregation of all the pages.
|
|
89
|
-
* @param {
|
|
89
|
+
* @param {GraphQLClient} client
|
|
90
90
|
* @param {{[varName: string]: value}} params
|
|
91
91
|
* @param {string} collectionPathInQuery JSON path to the paginated collection that must aggregated in the query (JSON path : property names separated by dots)
|
|
92
92
|
* @param {TimedQuerySemaphore} limiter
|
|
93
|
-
* @param {
|
|
94
|
-
* @param {string} pageParamName Name of the query parameter that must be updated with a page index for each query
|
|
93
|
+
* @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, delay?: number, maxElements?: number, includeWholeQuery?: number}} config
|
|
95
94
|
* @param {boolean} silentErrors
|
|
96
95
|
* @param {number} maxTries
|
|
97
96
|
* @returns
|
|
98
97
|
*/
|
|
99
|
-
async executePaginated(client, params, collectionPathInQuery, limiter = null,
|
|
98
|
+
async executePaginated(client, params, collectionPathInQuery, limiter = null, config = {}, silentErrors = false, maxTries = null){
|
|
100
99
|
let result = [];
|
|
101
|
-
|
|
100
|
+
//delay = null, perPage = undefined, pageParamName = "page", perPageParamName = "perPage", silentErrors = false, maxTries = null
|
|
101
|
+
const pageParamName = config.pageParamName ?? "page";
|
|
102
|
+
const perPageParamName = config.perPageParamName ?? "perPage";
|
|
103
|
+
const perPage = config.perPage ?? params[perPageParamName];
|
|
104
|
+
const delay = config.delay;
|
|
105
|
+
const maxElements = config.maxElements ?? undefined; //eliminating null
|
|
102
106
|
|
|
103
107
|
params = Object.assign({}, params);
|
|
104
108
|
params[pageParamName] = 1;
|
|
105
|
-
params[perPageParamName] = perPage
|
|
109
|
+
params[perPageParamName] = perPage;
|
|
106
110
|
|
|
111
|
+
let data;
|
|
107
112
|
while (true){
|
|
113
|
+
if (result.length >= maxElements) break;
|
|
114
|
+
|
|
108
115
|
console.log("Querying page", params[pageParamName], `(${result.length} elements loaded)`);
|
|
109
|
-
|
|
116
|
+
data = await this.execute(client, params, limiter, silentErrors, maxTries);
|
|
110
117
|
|
|
111
118
|
if (!data) throw (this.#getLog("error", params) ?? "Request failed.") + "(in paginated execution, at page " + params[pageParamName] + ")";
|
|
112
119
|
|
|
@@ -128,6 +135,20 @@ export class Query {
|
|
|
128
135
|
await new Promise(r => setTimeout(r, delay));
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
if (maxElements) result = result.slice(0, maxElements);
|
|
139
|
+
|
|
140
|
+
if (config.includeWholeQuery == Query.IWQModes.DUPLICATE || config.includeWholeQuery == Query.IWQModes.INLINE){
|
|
141
|
+
deep_set(data, collectionPathInQuery, result);
|
|
142
|
+
} else if (config.includeWholeQuery == Query.IWQModes.OUT){
|
|
143
|
+
deep_set(data, collectionPathInQuery, null);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (config.includeWholeQuery == Query.IWQModes.DUPLICATE || config.includeWholeQuery == Query.IWQModes.OUT){
|
|
147
|
+
return [result, data]
|
|
148
|
+
} else if (config.includeWholeQuery == Query.IWQModes.INLINE){
|
|
149
|
+
return data;
|
|
150
|
+
}
|
|
151
|
+
|
|
131
152
|
return result;
|
|
132
153
|
}
|
|
133
154
|
}
|