+2
-2
| import GQLResultInterface, { GQLEdgeInterface, GQLNodeInterface } from "./faces"; | ||
| export interface ArGql { | ||
| export interface ArGqlInterface { | ||
| run: (query: string, variables?: Record<string, unknown>) => Promise<GQLResultInterface>; | ||
@@ -11,2 +11,2 @@ all: (query: string, variables?: Record<string, unknown>) => Promise<GQLEdgeInterface[]>; | ||
| } | ||
| export default function arGql(endpointUrl?: string): ArGql; | ||
| export declare function arGql(endpointUrl?: string): ArGqlInterface; |
+2
-1
@@ -50,2 +50,3 @@ "use strict"; | ||
| exports.__esModule = true; | ||
| exports.arGql = void 0; | ||
| var tx_1 = require("./queries/tx"); | ||
@@ -152,2 +153,2 @@ function arGql(endpointUrl) { | ||
| } | ||
| exports["default"] = arGql; | ||
| exports.arGql = arGql; |
+1
-1
| { | ||
| "name": "ar-gql", | ||
| "version": "1.0.2", | ||
| "version": "1.2.0", | ||
| "main": "dist/index", | ||
@@ -5,0 +5,0 @@ "types": "dist/index", |
+10
-1
@@ -16,6 +16,15 @@ # `ar-gql` version 1 | ||
| > ## Migrating from version v0.x.x to v1.x.x | ||
| > - Functions are no longer directly imported. You need to import an `ArGqlInterface` object and create instanced from it. See [Code Set Up](#code-set-up) section below | ||
| > - As axios is no longer used internally `e.response` will always be undefined. You can catch regular `Error` objects with: | ||
| > ```ts | ||
| > e.message // status text | ||
| > e.cause // http status number | ||
| > ``` | ||
| > in all other Fetch error cases there will be a standard Fetch `TypeError` with a relevent message. | ||
| ## Code Set Up | ||
| ```ts | ||
| import arGql from 'ar-gql' | ||
| import { arGql } from 'ar-gql' | ||
@@ -22,0 +31,0 @@ //... |
-63
| export interface GQLPageInfoInterface { | ||
| hasNextPage: boolean; | ||
| } | ||
| export interface GQLOwnerInterface { | ||
| address: string; | ||
| key: string; | ||
| } | ||
| export interface GQLAmountInterface { | ||
| winston: string; | ||
| ar: string; | ||
| } | ||
| export interface GQLMetaDataInterface { | ||
| size: number; | ||
| type: string; | ||
| } | ||
| export interface GQLTagInterface { | ||
| name: string; | ||
| value: string; | ||
| } | ||
| export interface GQLBlockInterface { | ||
| id: string; | ||
| timestamp: number; | ||
| height: number; | ||
| previous: string; | ||
| } | ||
| export interface GQLNodeInterface { | ||
| id: string; | ||
| anchor: string; | ||
| signature: string; | ||
| recipient: string; | ||
| owner: GQLOwnerInterface; | ||
| fee: GQLAmountInterface; | ||
| quantity: GQLAmountInterface; | ||
| data: GQLMetaDataInterface; | ||
| tags: GQLTagInterface[]; | ||
| block: GQLBlockInterface; | ||
| parent: { | ||
| id: string; | ||
| }; | ||
| } | ||
| export interface GQLEdgeInterface { | ||
| cursor: string; | ||
| node: GQLNodeInterface; | ||
| } | ||
| export interface GQLTransactionsResultInterface { | ||
| pageInfo: GQLPageInfoInterface; | ||
| edges: GQLEdgeInterface[]; | ||
| } | ||
| export default interface GQLResultInterface { | ||
| data: { | ||
| transaction: GQLNodeInterface; | ||
| transactions: GQLTransactionsResultInterface; | ||
| }; | ||
| } |
-112
| import GQLResultInterface, { | ||
| GQLEdgeInterface, | ||
| GQLNodeInterface, | ||
| } from "./faces"; | ||
| import txQuery from "./queries/tx"; | ||
| export interface ArGql { | ||
| run: (query: string, variables?: Record<string, unknown>) => Promise<GQLResultInterface> | ||
| all: (query: string, variables?: Record<string, unknown>) => Promise<GQLEdgeInterface[]> | ||
| tx: (id: string) => Promise<GQLNodeInterface> | ||
| fetchTxTag: (id: string, name: string) => Promise<string | undefined> | ||
| getConfig: () => { endpointUrl: string } | ||
| } | ||
| export default function arGql(endpointUrl?: string): ArGql { | ||
| //sanity check | ||
| if(endpointUrl && !endpointUrl.match(/^https?:\/\/.*\/graphql$/)){ | ||
| throw new Error(`string doesn't appear to be a URL of the form <http(s)://some-domain/graphql>'. You entered "${endpointUrl}"`) | ||
| } | ||
| const _endpointUrl = endpointUrl || 'https://arweave.net/graphql' //default to arweave.net/graphql | ||
| const run = async ( | ||
| query: string, | ||
| variables?: Record<string, unknown>, | ||
| ): Promise<GQLResultInterface> => { | ||
| const graphql = JSON.stringify({ | ||
| query, | ||
| variables, | ||
| }); | ||
| const res = await fetch(_endpointUrl, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Accept': 'application/json', | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: graphql, | ||
| }); | ||
| if(!res.ok){ | ||
| throw new Error(res.statusText, { cause: res.status }) | ||
| } | ||
| return await res.json(); | ||
| }; | ||
| const all = async ( | ||
| query: string, | ||
| variables?: Record<string, unknown>, | ||
| ): Promise<GQLEdgeInterface[]> => { | ||
| let hasNextPage = true; | ||
| let edges: GQLEdgeInterface[] = []; | ||
| let cursor: string = ""; | ||
| while (hasNextPage) { | ||
| const res = ( | ||
| await run( | ||
| query, | ||
| { ...variables, cursor }, | ||
| ) | ||
| ).data.transactions; | ||
| if (res.edges && res.edges.length) { | ||
| edges = edges.concat(res.edges); | ||
| cursor = res.edges[res.edges.length - 1].cursor; | ||
| } | ||
| hasNextPage = res.pageInfo.hasNextPage; | ||
| } | ||
| return edges; | ||
| }; | ||
| const tx = async (id: string): Promise<GQLNodeInterface> => { | ||
| const isBrowser: boolean = typeof window !== "undefined"; | ||
| // if (isBrowser) { | ||
| // const cache = JSON.parse(localStorage.getItem("gqlCache") || "{}"); | ||
| // if (id in cache) return JSON.parse(cache[id]); | ||
| // } | ||
| const res = await run(txQuery, { id }); | ||
| // if (isBrowser && res.data.transaction.block) { | ||
| // const cache = JSON.parse(localStorage.getItem("gqlCache") || "{}"); | ||
| // cache[id] = res.data.transaction; | ||
| // localStorage.setItem("gqlCache", JSON.stringify(cache)); | ||
| // } | ||
| return res.data.transaction; | ||
| }; | ||
| const fetchTxTag = async ( | ||
| id: string, | ||
| name: string, | ||
| ): Promise<string | undefined> => { | ||
| const res = await tx(id); | ||
| const tag = res.tags.find((tag) => tag.name === name); | ||
| if (tag) return tag.value; | ||
| }; | ||
| return { | ||
| run, | ||
| all, | ||
| tx, | ||
| fetchTxTag, | ||
| getConfig: ()=> ({ | ||
| endpointUrl: _endpointUrl, | ||
| }) | ||
| } | ||
| } |
| export default ` | ||
| query($id: ID!) { | ||
| transaction(id: $id) { | ||
| id | ||
| anchor | ||
| signature | ||
| recipient | ||
| owner { | ||
| address | ||
| key | ||
| } | ||
| fee { | ||
| winston | ||
| ar | ||
| } | ||
| quantity { | ||
| winston | ||
| ar | ||
| } | ||
| data { | ||
| size | ||
| type | ||
| } | ||
| tags { | ||
| name | ||
| value | ||
| } | ||
| block { | ||
| id | ||
| timestamp | ||
| height | ||
| previous | ||
| } | ||
| parent { | ||
| id | ||
| } | ||
| } | ||
| } | ||
| `; |
| import { expect } from 'chai' | ||
| import { } from 'mocha' | ||
| import arGql from '../src/index' | ||
| const testQuery = `query($cursor: String) { | ||
| transactions( | ||
| # your query parameters | ||
| tags: [ | ||
| { name: "App-Name", values: ["CommunityXYZ"] } | ||
| ] | ||
| # standard template below | ||
| after: $cursor | ||
| first: 100 | ||
| ) { | ||
| pageInfo { | ||
| hasNextPage | ||
| } | ||
| edges { | ||
| cursor | ||
| node { | ||
| # what tx data you want to query for: | ||
| id | ||
| } | ||
| } | ||
| } | ||
| }` | ||
| describe('ar-gql tests', function(){ | ||
| it('should initialise default and other instances of arGql', async()=> { | ||
| const argql = arGql() | ||
| expect(argql.getConfig().endpointUrl, 'defaults did not load').equal('https://arweave.net/graphql') | ||
| const testUrl = 'https://test.com/graphql' | ||
| const testGql = arGql(testUrl) | ||
| expect(testGql.getConfig().endpointUrl, 'testUrl did not load').equal(testUrl) | ||
| const badUrl = 'arweave.net' | ||
| try{ | ||
| const badGql = arGql(badUrl) | ||
| expect(true, 'no error was thrown with badUrl').false //should not get here | ||
| }catch(e:any){ | ||
| expect(e.message).eq(`string doesn't appear to be a URL of the form <http(s)://some-domain/graphql>'. You entered "${badUrl}"`) | ||
| } | ||
| }) | ||
| it('should execute `run` successfully', async function() { | ||
| this.timeout(5_000) | ||
| const argql = arGql() | ||
| const res = await argql.run(testQuery) | ||
| expect(res.data.transactions.edges.length).to.be.greaterThan(0) | ||
| }) | ||
| it('should throw error in `run` with status details', async()=> { | ||
| const argql = arGql() | ||
| const badQuery = `query($cursor: String) { transactions( tags: [ { name:` | ||
| try{ | ||
| const res = await argql.run(badQuery) | ||
| expect(false).true //should not get here | ||
| }catch(e:any){ | ||
| expect(e.cause).eq(400) //this is the status numer | ||
| expect(e.message).eq('Bad Request') | ||
| } | ||
| }) | ||
| it('should execute `all` and retrieve several pages successfully', async function() { | ||
| this.timeout(10_000) | ||
| const argql = arGql() | ||
| const edges = await argql.all(testQuery) | ||
| expect(edges.length).to.be.greaterThan(0) | ||
| }) | ||
| it('should execute `tx` successfully', async()=> { | ||
| const argql = arGql() | ||
| const txid = 'DeYQPjoEQLLds7usOMZFJFCe7VyTpodYl6Mok6UP6Z4' | ||
| const txMeta = await argql.tx(txid) | ||
| expect(txMeta.id).eq(txid) | ||
| }) | ||
| it('should execute `fetchTxTag` successfully', async()=> { | ||
| const argql = arGql() | ||
| const txid = 'DeYQPjoEQLLds7usOMZFJFCe7VyTpodYl6Mok6UP6Z4' | ||
| const tag = { name: 'Content-Type', value: 'text/plain'} | ||
| const txMeta = await argql.fetchTxTag(txid, tag.name) | ||
| expect(txMeta).eq(tag.value) | ||
| }) | ||
| }) |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
97
10.23%1
-50%14092
-31.66%10
-28.57%235
-52.62%