startgg-helper 2.0.0 → 2.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/query.js +86 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "startgg-helper",
3
- "version": "2.0.0",
3
+ "version": "2.0.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
  "scripts": {
package/src/query.js CHANGED
@@ -2,6 +2,10 @@ import { GraphQLClient } from 'graphql-request';
2
2
  import { deep_get, deep_set } from './jsUtil.js';
3
3
  import { TimedQuerySemaphore } from './queryLimiter.js'
4
4
 
5
+ function isConnection(val){
6
+ return val instanceof Object && val.nodes instanceof Array
7
+ }
8
+
5
9
  export class Query {
6
10
  #schema;
7
11
  #maxTries;
@@ -84,6 +88,87 @@ export class Query {
84
88
  OUT: 3
85
89
  }
86
90
 
91
+ /**
92
+ * Executes a query containing a paginated collection (of a *Connection type) repeatedly, increasing the page index each time until nothing is returned, returning an aggregation of all the pages.
93
+ * @param {GraphQLClient} client
94
+ * @param {{[varName: string]: value}} params
95
+ * @param {string} connectionPathInQuery JSON path to the paginated collection that must aggregated in the query (JSON path : property names separated by dots)
96
+ * @param {TimedQuerySemaphore} limiter
97
+ * @param {{pageParamName?: string, perPageParamName?: string, perPage?: number, delay?: number, maxElements?: number, includeWholeQuery?: number}} config
98
+ * @param {boolean} silentErrors
99
+ * @param {number} maxTries
100
+ * @returns
101
+ */
102
+ async executePaginated(client, params, connectionPathInQuery, limiter = null, config = {}, silentErrors = false, maxTries = null){
103
+ let result = [];
104
+ //delay = null, perPage = undefined, pageParamName = "page", perPageParamName = "perPage", silentErrors = false, maxTries = null
105
+ const pageParamName = config.pageParamName ?? "page";
106
+ const perPageParamName = config.perPageParamName ?? "perPage";
107
+ const perPage = config.perPage ?? params[perPageParamName];
108
+ const delay = config.delay;
109
+ const maxElements = config.maxElements ?? undefined; //eliminating null
110
+
111
+ let currentPage = 1;
112
+
113
+ params = Object.assign({}, params);
114
+ params[pageParamName] = currentPage;
115
+ params[perPageParamName] = perPage;
116
+
117
+ let data;
118
+ while (true){
119
+ if (result.length >= maxElements) break;
120
+
121
+ console.log("Querying page", params[pageParamName], `(${result.length} elements loaded)`);
122
+ data = await this.execute(client, params, limiter, silentErrors, maxTries);
123
+
124
+ if (!data) throw (this.#getLog("error", params) ?? "Request failed.") + "(in paginated execution, at page " + params[pageParamName] + ")";
125
+
126
+ let connection = deep_get(data, connectionPathInQuery);
127
+
128
+ if (!connection) {
129
+ console.warn(`The given path ${connectionPathInQuery} does not point to anything.`);
130
+ return null;
131
+ }
132
+
133
+ if (!isConnection(connection)) throw "The given path does not point to a connection type"
134
+ console.log(connection);
135
+
136
+ let localResult = connection.nodes;
137
+ if (connection.pageInfo && connection.pageInfo.totalPages){
138
+ let totalPages = connection.pageInfo.totalPages;
139
+ if (currentPage >= totalPages) {
140
+ result = result.concat(localResult);
141
+ break;
142
+ }
143
+ } else {
144
+ if (localResult.length < 1) break;
145
+ }
146
+
147
+ result = result.concat(localResult);
148
+ currentPage++;
149
+ params[pageParamName] = currentPage;
150
+
151
+ if (delay)
152
+ await new Promise(r => setTimeout(r, delay));
153
+ }
154
+
155
+ if (maxElements) result = result.slice(0, maxElements);
156
+
157
+ if (config.includeWholeQuery == Query.IWQModes.DUPLICATE || config.includeWholeQuery == Query.IWQModes.INLINE){
158
+ deep_set(data, connectionPathInQuery + ".nodes", result);
159
+ } else if (config.includeWholeQuery == Query.IWQModes.OUT){
160
+ deep_set(data, connectionPathInQuery + ".nodes", null);
161
+ }
162
+
163
+ if (config.includeWholeQuery == Query.IWQModes.DUPLICATE || config.includeWholeQuery == Query.IWQModes.OUT){
164
+ return [result, data]
165
+ } else if (config.includeWholeQuery == Query.IWQModes.INLINE){
166
+ return data;
167
+ }
168
+
169
+ return result;
170
+ }
171
+
87
172
  /**
88
173
  * 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
174
  * @param {GraphQLClient} client
@@ -95,7 +180,7 @@ export class Query {
95
180
  * @param {number} maxTries
96
181
  * @returns
97
182
  */
98
- async executePaginated(client, params, collectionPathInQuery, limiter = null, config = {}, silentErrors = false, maxTries = null){
183
+ async executePaginatedLegacy(client, params, collectionPathInQuery, limiter = null, config = {}, silentErrors = false, maxTries = null){
99
184
  let result = [];
100
185
  //delay = null, perPage = undefined, pageParamName = "page", perPageParamName = "perPage", silentErrors = false, maxTries = null
101
186
  const pageParamName = config.pageParamName ?? "page";