Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

ar-gql

Package Overview
Dependencies
Maintainers
2
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ar-gql - npm Package Compare versions

Comparing version
1.0.2
to
1.2.0
+2
-2
dist/index.d.ts
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;

@@ -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;
{
"name": "ar-gql",
"version": "1.0.2",
"version": "1.2.0",
"main": "dist/index",

@@ -5,0 +5,0 @@ "types": "dist/index",

@@ -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 @@ //...

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;
};
}
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)
})
})