@nftx/query
Advanced tools
Comparing version 3.6.1 to 3.7.0
@@ -6,2 +6,13 @@ # Change Log | ||
# [3.7.0](https://github.com/NFTX-project/nftxjs/compare/v3.6.2...v3.7.0) (2024-07-17) | ||
### Features | ||
* query now accepts array of urls ([c6ad594](https://github.com/NFTX-project/nftxjs/commit/c6ad59419db3dadbf426e1080b9bc083c0236203)) | ||
## [3.6.1](https://github.com/NFTX-project/nftxjs/compare/v3.6.0...v3.6.1) (2024-07-12) | ||
@@ -8,0 +19,0 @@ |
@@ -27,3 +27,3 @@ 'use strict'; | ||
const { | ||
url, | ||
url: baseUrl, | ||
data: sourceData, | ||
@@ -42,64 +42,78 @@ headers = {}, | ||
} | ||
if (!url) { | ||
const urls = Array.isArray(baseUrl) ? baseUrl : [baseUrl]; | ||
if (!urls.some(Boolean)) { | ||
throw new Error('No URL provided'); | ||
} | ||
const uri = new URL(url); | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
if (!url) { | ||
continue; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
if (Array.isArray(value)) { | ||
value.forEach(v => { | ||
if (v == null) { | ||
const uri = new URL(url); | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
if (Array.isArray(value)) { | ||
value.forEach(v => { | ||
if (v == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
}); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
} | ||
}); | ||
} | ||
} | ||
const body = method === 'GET' ? undefined : typeof sourceData === 'string' ? sourceData : stringify(sourceData); | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit | ||
}); | ||
if (response.status >= 500 && response.status <= 599 && attempt < maxAttempts) { | ||
await new Promise(res => setTimeout(res, 1000)); | ||
return query({ | ||
...args, | ||
attempt: attempt + 1 | ||
}); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
} | ||
}); | ||
} | ||
} | ||
const body = method === 'GET' ? undefined : typeof sourceData === 'string' ? sourceData : stringify(sourceData); | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit | ||
}); | ||
if (response.status >= 500 && response.status <= 599 && attempt < maxAttempts) { | ||
await new Promise(res => setTimeout(res, 1000)); | ||
return query({ | ||
...args, | ||
attempt: attempt + 1 | ||
}); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
} | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text; | ||
} | ||
} catch (e) { | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
const text = await response.text(); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text; | ||
} | ||
throw new Error(); | ||
}; | ||
@@ -174,32 +188,2 @@ var sendQuery = query; | ||
}; | ||
const queryUrls = async ({ | ||
baseUrl, | ||
query, | ||
...rest | ||
}) => { | ||
// We can be passed a single url or an array of urls | ||
// If we have an array, we'll try them in order until we get a successful response | ||
const urls = [baseUrl].flat(); | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
// Ignore empty urls (baseUrl could be undefined, or an array could've been built with missing content) | ||
if (url == null) { | ||
continue; | ||
} | ||
const data = await sendGraphQuery({ | ||
query, | ||
url, | ||
...rest | ||
}); | ||
return data; | ||
} catch (e) { | ||
// If there's been an error, we'll try the next url | ||
// if we've exhausted all urls, throw the most recent error | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
}; | ||
async function queryGraph({ | ||
@@ -215,4 +199,4 @@ query, | ||
} | ||
return queryUrls({ | ||
baseUrl: url, | ||
return sendGraphQuery({ | ||
url, | ||
query: formatQuery({ | ||
@@ -219,0 +203,0 @@ query, |
@@ -23,3 +23,3 @@ /** Processes a graphql string | ||
const { | ||
url, | ||
url: baseUrl, | ||
data: sourceData, | ||
@@ -38,64 +38,78 @@ headers = {}, | ||
} | ||
if (!url) { | ||
const urls = Array.isArray(baseUrl) ? baseUrl : [baseUrl]; | ||
if (!urls.some(Boolean)) { | ||
throw new Error('No URL provided'); | ||
} | ||
const uri = new URL(url); | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
if (!url) { | ||
continue; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
if (Array.isArray(value)) { | ||
value.forEach(v => { | ||
if (v == null) { | ||
const uri = new URL(url); | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
if (Array.isArray(value)) { | ||
value.forEach(v => { | ||
if (v == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
}); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
} | ||
}); | ||
} | ||
} | ||
const body = method === 'GET' ? undefined : typeof sourceData === 'string' ? sourceData : stringify(sourceData); | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit | ||
}); | ||
if (response.status >= 500 && response.status <= 599 && attempt < maxAttempts) { | ||
await new Promise(res => setTimeout(res, 1000)); | ||
return query({ | ||
...args, | ||
attempt: attempt + 1 | ||
}); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
} | ||
}); | ||
} | ||
} | ||
const body = method === 'GET' ? undefined : typeof sourceData === 'string' ? sourceData : stringify(sourceData); | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit | ||
}); | ||
if (response.status >= 500 && response.status <= 599 && attempt < maxAttempts) { | ||
await new Promise(res => setTimeout(res, 1000)); | ||
return query({ | ||
...args, | ||
attempt: attempt + 1 | ||
}); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
} | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text; | ||
} | ||
} catch (e) { | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
const text = await response.text(); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text; | ||
} | ||
throw new Error(); | ||
}; | ||
@@ -170,32 +184,2 @@ var sendQuery = query; | ||
}; | ||
const queryUrls = async ({ | ||
baseUrl, | ||
query, | ||
...rest | ||
}) => { | ||
// We can be passed a single url or an array of urls | ||
// If we have an array, we'll try them in order until we get a successful response | ||
const urls = [baseUrl].flat(); | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
// Ignore empty urls (baseUrl could be undefined, or an array could've been built with missing content) | ||
if (url == null) { | ||
continue; | ||
} | ||
const data = await sendGraphQuery({ | ||
query, | ||
url, | ||
...rest | ||
}); | ||
return data; | ||
} catch (e) { | ||
// If there's been an error, we'll try the next url | ||
// if we've exhausted all urls, throw the most recent error | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
}; | ||
async function queryGraph({ | ||
@@ -211,4 +195,4 @@ query, | ||
} | ||
return queryUrls({ | ||
baseUrl: url, | ||
return sendGraphQuery({ | ||
url, | ||
query: formatQuery({ | ||
@@ -215,0 +199,0 @@ query, |
@@ -5,3 +5,3 @@ type Fetch = typeof fetch; | ||
type Args = Omit<RequestInit, 'headers' | 'method' | 'body'> & { | ||
url: string; | ||
url: string | string[]; | ||
data?: Record<string, any> | string; | ||
@@ -8,0 +8,0 @@ headers?: Record<string, string>; |
import { QueryBase } from './createQuery'; | ||
import sendQuery from './query'; | ||
type Query = typeof sendQuery; | ||
type SendQueryArgs = Omit<Parameters<Query>[0], 'url' | 'data'>; | ||
type SendQueryArgs = Omit<Parameters<Query>[0], 'data'>; | ||
declare function queryGraph<Q extends QueryBase<any, any>>(args: SendQueryArgs & { | ||
@@ -6,0 +6,0 @@ url: string | string[]; |
{ | ||
"name": "@nftx/query", | ||
"version": "3.6.1", | ||
"version": "3.7.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/NFTX-project/nftxjs", |
138
src/query.ts
@@ -13,3 +13,3 @@ type Fetch = typeof fetch; | ||
type Args = Omit<RequestInit, 'headers' | 'method' | 'body'> & { | ||
url: string; | ||
url: string | string[]; | ||
data?: Record<string, any> | string; | ||
@@ -27,3 +27,3 @@ headers?: Record<string, string>; | ||
const { | ||
url, | ||
url: baseUrl, | ||
data: sourceData, | ||
@@ -45,80 +45,96 @@ headers = {}, | ||
} | ||
if (!url) { | ||
const urls = Array.isArray(baseUrl) ? baseUrl : [baseUrl]; | ||
if (!urls.some(Boolean)) { | ||
throw new Error('No URL provided'); | ||
} | ||
const uri = new URL(url); | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
if (!url) { | ||
continue; | ||
} | ||
const uri = new URL(url); | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
if (Array.isArray(value)) { | ||
value.forEach((v) => { | ||
if (v == null) { | ||
if (method === 'GET') { | ||
if (typeof sourceData === 'string' && sourceData) { | ||
if (sourceData.startsWith('?')) { | ||
uri.search = sourceData; | ||
} else { | ||
uri.search = '?' + sourceData; | ||
} | ||
} else if (sourceData) { | ||
Object.entries(sourceData).forEach(([key, value]) => { | ||
if (value == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
if (Array.isArray(value)) { | ||
value.forEach((v) => { | ||
if (v == null) { | ||
return; | ||
} | ||
uri.searchParams.append(key, v); | ||
}); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
} | ||
}); | ||
} else { | ||
uri.searchParams.set(key, value); | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
const body = | ||
method === 'GET' | ||
? undefined | ||
: typeof sourceData === 'string' | ||
? sourceData | ||
: stringify(sourceData); | ||
const body = | ||
method === 'GET' | ||
? undefined | ||
: typeof sourceData === 'string' | ||
? sourceData | ||
: stringify(sourceData); | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
if (method !== 'GET' && typeof sourceData === 'object') { | ||
headers['Content-Type'] = 'application/json'; | ||
} | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit, | ||
}); | ||
const response = await fetch(uri.toString(), { | ||
method, | ||
body, | ||
headers, | ||
...requestInit, | ||
}); | ||
if ( | ||
response.status >= 500 && | ||
response.status <= 599 && | ||
attempt < maxAttempts | ||
) { | ||
await new Promise((res) => setTimeout(res, 1000)); | ||
return query({ ...args, attempt: attempt + 1 }); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if ( | ||
response.status >= 500 && | ||
response.status <= 599 && | ||
attempt < maxAttempts | ||
) { | ||
await new Promise((res) => setTimeout(res, 1000)); | ||
return query({ ...args, attempt: attempt + 1 }); | ||
} | ||
const contentType = response.headers.get('content-type'); | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
if (!response.ok) { | ||
if (contentType?.includes('application/json')) { | ||
const json = await response.json(); | ||
throw new QueryError(response, json, `Error fetching ${url}`); | ||
} else { | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
} | ||
} | ||
const text = await response.text(); | ||
throw new QueryError(response, {}, text); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text as T; | ||
} | ||
} catch (e) { | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
const text = await response.text(); | ||
if (contentType?.includes('application/json')) { | ||
return parse(text); | ||
} else { | ||
return text as T; | ||
} | ||
throw new Error(); | ||
}; | ||
export default query; |
@@ -8,3 +8,3 @@ import { QueryBase } from './createQuery'; | ||
type SendQueryArgs = Omit<Parameters<Query>[0], 'url' | 'data'>; | ||
type SendQueryArgs = Omit<Parameters<Query>[0], 'data'>; | ||
@@ -55,3 +55,3 @@ const interpolateQuery = (query: string, variables: Record<string, any>) => { | ||
...rest | ||
}: SendQueryArgs & { url: string; query: string; sendQuery: Query }) => { | ||
}: SendQueryArgs & { query: string; sendQuery: Query }) => { | ||
const { data, errors } = await sendQuery<{ | ||
@@ -74,40 +74,2 @@ errors: { message: string }[] & { message: string }; | ||
const queryUrls = async ({ | ||
baseUrl, | ||
query, | ||
...rest | ||
}: Omit<SendQueryArgs, 'url'> & { | ||
baseUrl: string | string[]; | ||
query: string; | ||
sendQuery: Query; | ||
}) => { | ||
// We can be passed a single url or an array of urls | ||
// If we have an array, we'll try them in order until we get a successful response | ||
const urls = [baseUrl].flat(); | ||
while (urls.length) { | ||
try { | ||
const url = urls.shift(); | ||
// Ignore empty urls (baseUrl could be undefined, or an array could've been built with missing content) | ||
if (url == null) { | ||
continue; | ||
} | ||
const data = await sendGraphQuery({ | ||
query, | ||
url, | ||
...rest, | ||
}); | ||
return data; | ||
} catch (e) { | ||
// If there's been an error, we'll try the next url | ||
// if we've exhausted all urls, throw the most recent error | ||
if (!urls.length) { | ||
throw e; | ||
} | ||
} | ||
} | ||
}; | ||
async function queryGraph<Q extends QueryBase<any, any>>( | ||
@@ -146,4 +108,4 @@ args: SendQueryArgs & { | ||
return queryUrls({ | ||
baseUrl: url, | ||
return sendGraphQuery({ | ||
url, | ||
query: formatQuery({ query, variables }), | ||
@@ -150,0 +112,0 @@ fetch, |
71548
2386