Skip to content

Commit

Permalink
feat: renamed block_hash to hash + support disableTotal parameter (#926)
Browse files Browse the repository at this point in the history
* feat: renamed block_hash to hash for response of getDateToBlock() method.
* feat: add disableTotal parameter to requests of paginated methods.
* updated NextPaginatedRequestResolver.
  • Loading branch information
b4rtaz committed Jan 3, 2023
1 parent 167cf32 commit 98bd66b
Show file tree
Hide file tree
Showing 54 changed files with 475 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-bugs-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@moralisweb3/common-evm-utils': patch
---

Renamed the `block_hash` field to `hash` for the response of the `getDateToBlock()` method (according to the API changes). Introduced the `EvmBlockDate` class as a response of the `getDateToBlock()` method.
6 changes: 6 additions & 0 deletions .changeset/empty-scissors-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@moralisweb3/common-evm-utils': patch
'@moralisweb3/evm-api': patch
---

Added the `disableTotal` parameter to requests of paginated methods.
5 changes: 5 additions & 0 deletions .changeset/real-poems-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@moralisweb3/common-core': patch
---

Updated the `NextPaginatedRequestResolver` class to support responses with no `total` field.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class PaginatedOperationResolver<Request extends PaginatedRequest, JSONRe
});

const pagination = PaginationReader.read(jsonResponse);
const nextRequest = NextPaginatedRequestResolver.resolve(this.operation, request, pagination);
const nextRequest = NextPaginatedRequestResolver.resolve(this.operation.firstPageIndex, request, pagination);

return new PaginatedResponseAdapter<Result, JSONResult>(
pagination,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class FirebaseClientRequestHandler implements ClientRequestHandler {
const jsonResponse = response.data;

const pagination = PaginationReader.read(jsonResponse);
const nextRequest = NextPaginatedRequestResolver.resolve(operation, request, pagination);
const nextRequest = NextPaginatedRequestResolver.resolve(operation.firstPageIndex, request, pagination);

return new PaginatedResponseAdapter<Result, JSONResult>(
pagination,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { PaginatedRequest } from '../PaginatedOperation';
import { Pagination } from '../response';
import { NextPaginatedRequestResolver } from './NextPaginatedRequestResolver';

interface TestPaginatedRequest extends PaginatedRequest {
alfa: string;
}

describe('NextPaginatedRequestResolver', () => {
const request: TestPaginatedRequest = {
limit: 10,
alfa: 'ALFA',
};

describe('cursor mode', () => {
it('returns null when cursor is not defined', () => {
const pagination: Pagination = {
page: 1,
pageSize: 10,
cursor: undefined,
};

const nextRequest = NextPaginatedRequestResolver.resolve(0, request, pagination);

expect(nextRequest).toBeNull();
});

it('returns next request when cursor is present', () => {
const pagination: Pagination = {
page: 1,
pageSize: 10,
cursor: 'CURSOR1',
};

const nextRequest = NextPaginatedRequestResolver.resolve(0, request, pagination);

expect(nextRequest).toBeDefined();
expect(nextRequest?.cursor).toBe(pagination.cursor);
expect(nextRequest?.alfa).toBe(request.alfa);
});
});

describe('total mode', () => {
it('returns null when it is last page', () => {
const pagination: Pagination = {
page: 1,
pageSize: 10,
total: 10,
};

const nextRequest = NextPaginatedRequestResolver.resolve(1, request, pagination);

expect(nextRequest).toBeNull();
});

it('returns next request when it is NOT last page', () => {
const pagination: Pagination = {
page: 1,
pageSize: 10,
total: 21,
};

const nextRequest = NextPaginatedRequestResolver.resolve(0, request, pagination);

expect(nextRequest).toBeDefined();
expect(nextRequest?.offset).toBe(20);
expect(nextRequest?.alfa).toBe(request.alfa);
});
});

it('returns null when cursor and total are not defined', () => {
const pagination: Pagination = {
page: 1,
pageSize: 10,
};

const nextRequest = NextPaginatedRequestResolver.resolve(0, request, pagination);

expect(nextRequest).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { PaginatedOperation, PaginatedRequest } from '../PaginatedOperation';
import { PaginatedRequest } from '../PaginatedOperation';
import { Pagination } from '../response/Pagination';

export class NextPaginatedRequestResolver {
public static resolve<Request extends PaginatedRequest>(
operation: PaginatedOperation<Request, unknown, unknown, unknown>,
firstPageIndex: number,
request: Request,
pagination: Pagination,
): Request | null {
const currentPage = operation.firstPageIndex === 1 ? pagination.page : pagination.page + 1;
const hasNextPage = pagination.total > pagination.pageSize * currentPage;
if (!hasNextPage) {
return null;
if (pagination.cursor) {
return { ...request, cursor: pagination.cursor };
}

const nextParams = { ...request };
if (pagination.cursor) {
nextParams.cursor = pagination.cursor;
} else {
nextParams.offset = (pagination.page + 1) * (nextParams.limit || 500);
if (typeof pagination.total === 'number') {
const currentPage = firstPageIndex === 1 ? pagination.page : pagination.page + 1;
const hasNextPage = pagination.total > pagination.pageSize * currentPage;
if (hasNextPage) {
const offset = (pagination.page + 1) * (request.limit || 500);
return { ...request, offset };
}
}
return nextParams;

return null;
}
}
2 changes: 1 addition & 1 deletion packages/common/core/src/operations/response/Pagination.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface Pagination {
total: number;
total?: number;
page: number;
pageSize: number;
cursor?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class PaginationReader {
return {
page: jsonResponse.page ?? 0,
pageSize: jsonResponse.page_size ?? 0,
total: jsonResponse.total ?? 0,
total: jsonResponse.total,
cursor: jsonResponse.cursor,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { EvmBlockDateData, EvmBlockDateInput } from './types';

export type EvmBlockDateish = EvmBlockDateInput | EvmBlockDate;

export class EvmBlockDate {
/**
* Create a new instance of EvmBlockDate.
* @param data - the EvmBlockDateish type.
*/
public static create(data: EvmBlockDateish) {
if (data instanceof EvmBlockDate) {
return data;
}
return new EvmBlockDate(EvmBlockDate.parse(data));
}

private static parse(input: EvmBlockDateInput): EvmBlockDateData {
return {
block: input.block,
date: new Date(input.date),
timestamp: input.timestamp,
// TODO: the swagger currently has wrong type for `block_timestamp`, should be `string`.
blockTimestamp: String(input.block_timestamp),
hash: input.hash,
parentHash: input.parent_hash,
};
}

private constructor(private readonly data: EvmBlockDateData) {}

/**
* @description The block number.
* @example `9193266`
*/
public get block(): number {
return this.data.block;
}

/**
* @description The date of the block.
* @example `2020-01-01T00:00:00+00:00`
*/
public get date(): Date {
return this.data.date;
}

/**
* @description The timestamp of the block
* @example `1577836811`
*/
public get timestamp(): number {
return this.data.timestamp;
}

/**
* @description The timestamp of the block
* @example `2022-01-03T22:59:39.000Z`
*/
public get blockTimestamp(): string | undefined {
return this.data.blockTimestamp;
}

/**
* @deprecated Use `blockTimestamp` instead.
*/
public get block_timestamp(): string | undefined {
return this.data.blockTimestamp;
}

/**
* @description The block hash.
* @example `0x9b559aef7ea858608c2e554246fe4a24287e7aeeb976848df2b9a2531f4b9171`
*/
public get hash(): string | undefined {
return this.data.hash;
}

/**
* @deprecated Use `hash` instead.
*/
public get block_hash(): string | undefined {
return this.data.hash;
}

/**
* @description The block hash of the parent block.
* @example `0x011d1fc45839de975cc55d758943f9f1d204f80a90eb631f3bf064b80d53e045`
*/
public get parentHash(): string | undefined {
return this.data.parentHash;
}

/**
* @deprecated Use `parentHash` instead.
*/
public get parent_hash(): string | undefined {
return this.data.parentHash;
}
}
2 changes: 2 additions & 0 deletions packages/common/evmUtils/src/dataTypes/EvmBlockDate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './EvmBlockDate';
export * from './types';
12 changes: 12 additions & 0 deletions packages/common/evmUtils/src/dataTypes/EvmBlockDate/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { components } from '../../operations/openapi';

export type EvmBlockDateInput = components['schemas']['blockDate'];

export interface EvmBlockDateData {
date: Date;
block: number;
timestamp: number;
blockTimestamp?: string;
hash?: string;
parentHash?: string;
}
1 change: 1 addition & 0 deletions packages/common/evmUtils/src/dataTypes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './Erc20Transfer';
export * from './Erc20Value';
export * from './EvmAddress';
export * from './EvmBlock';
export * from './EvmBlockDate';
export * from './EvmChain';
export * from './EvmEvent';
export * from './EvmNative';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Core, Camelize, Operation, DateInput, ResponseAdapter } from '@moralisweb3/common-core';
import { EvmChain, EvmChainish } from '../../dataTypes';
import { EvmBlockDate, EvmChain, EvmChainish } from '../../dataTypes';
import { EvmChainResolver } from '../../EvmChainResolver';
import { operations } from '../openapi';

Expand Down Expand Up @@ -57,10 +57,7 @@ function getRequestUrlParams(request: GetDateToBlockRequest, core: Core) {
}

function deserializeResponse(jsonResponse: GetDateToBlockJSONResponse) {
return {
...jsonResponse,
date: new Date(jsonResponse.date),
};
return EvmBlockDate.create(jsonResponse);
}

function serializeRequest(request: GetDateToBlockRequest, core: Core) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ describe('getContractEventsOperation', () => {
limit: 100,
offset: 0,
topic: 'topic0',
disableTotal: true,
};

const serializedRequest = getContractEventsOperation.serializeRequest(request, core);
Expand All @@ -46,6 +47,7 @@ describe('getContractEventsOperation', () => {
expect(serializedRequest.fromDate).toBe(fromDate);
expect(serializedRequest.toDate).toBe(toDate);
expect(serializedRequest.abi).toBe(request.abi);
expect(serializedRequest.disableTotal).toBe(true);

const deserializedRequest = getContractEventsOperation.deserializeRequest(serializedRequest, core);

Expand All @@ -58,5 +60,6 @@ describe('getContractEventsOperation', () => {
expect(deserializedRequest.offset).toBe(request.offset);
expect(deserializedRequest.topic).toBe(request.topic);
expect(deserializedRequest.abi).toBe(request.abi);
expect(deserializedRequest.disableTotal).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,17 @@ export const getContractEventsOperation: PaginatedOperation<
groupName: 'events',
urlPathPattern: '/{address}/events',
urlPathParamNames: ['address'],
urlSearchParamNames: ['chain', 'fromBlock', 'toBlock', 'fromDate', 'toDate', 'topic', 'offset', 'limit'],
urlSearchParamNames: [
'chain',
'fromBlock',
'toBlock',
'fromDate',
'toDate',
'topic',
'offset',
'limit',
'disableTotal',
],
bodyParamNames: ['abi'],
bodyType: 'raw',
firstPageIndex: 0,
Expand All @@ -76,6 +86,7 @@ function getRequestUrlParams(request: GetContractEventsRequest, core: Core) {
offset: maybe(request.offset, String),
limit: maybe(request.limit, String),
address: EvmAddress.create(request.address, core).lowercase,
disable_total: request.disableTotal,
};
}

Expand Down Expand Up @@ -120,6 +131,7 @@ function serializeRequest(request: GetContractEventsRequest, core: Core) {
limit: request.limit,
address: EvmAddress.create(request.address, core).lowercase,
abi: request.abi,
disableTotal: request.disableTotal,
};
}

Expand All @@ -135,5 +147,6 @@ function deserializeRequest(jsonRequest: GetContractEventsJSONRequest, core: Cor
limit: jsonRequest.limit,
address: EvmAddress.create(jsonRequest.address, core),
abi: jsonRequest.abi,
disableTotal: jsonRequest.disableTotal,
};
}
Loading

0 comments on commit 98bd66b

Please sign in to comment.