Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization/make template tags #610

Merged
merged 4 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class LCDQueryClient {
if (typeof params?.queryHeight !== "undefined") {
options.params.query_height = params.queryHeight;
}
const endpoint = `ibc/apps/fee/v1/channels/${params.packetId.channel_id}/ports/${params.packetId.port_id}/sequences/${params.packetId.sequence}/incentivized_packet`;
const endpoint = `ibc/apps/fee/v1/channels/${params.packet_id.channel_id}/ports/${params.packet_id.port_id}/sequences/${params.packet_id.sequence}/incentivized_packet`;
return QueryIncentivizedPacketResponse.fromSDKJSON(await this.req.get<QueryIncentivizedPacketResponseSDKType>(endpoint, options));
}
/* Gets all incentivized packets for a specific channel */
Expand All @@ -65,17 +65,17 @@ export class LCDQueryClient {
}
/* TotalRecvFees returns the total receive fees for a packet given its identifier */
async totalRecvFees(_params: QueryTotalRecvFeesRequest = {}): Promise<QueryTotalRecvFeesResponseSDKType> {
const endpoint = `ibc/apps/fee/v1/channels/${params.packetId.channel_id}/ports/${params.packetId.port_id}/sequences/${params.packetId.sequence}/total_recv_fees`;
const endpoint = `ibc/apps/fee/v1/channels/${params.packet_id.channel_id}/ports/${params.packet_id.port_id}/sequences/${params.packet_id.sequence}/total_recv_fees`;
return QueryTotalRecvFeesResponse.fromSDKJSON(await this.req.get<QueryTotalRecvFeesResponseSDKType>(endpoint));
}
/* TotalAckFees returns the total acknowledgement fees for a packet given its identifier */
async totalAckFees(_params: QueryTotalAckFeesRequest = {}): Promise<QueryTotalAckFeesResponseSDKType> {
const endpoint = `ibc/apps/fee/v1/channels/${params.packetId.channel_id}/ports/${params.packetId.port_id}/sequences/${params.packetId.sequence}/total_ack_fees`;
const endpoint = `ibc/apps/fee/v1/channels/${params.packet_id.channel_id}/ports/${params.packet_id.port_id}/sequences/${params.packet_id.sequence}/total_ack_fees`;
return QueryTotalAckFeesResponse.fromSDKJSON(await this.req.get<QueryTotalAckFeesResponseSDKType>(endpoint));
}
/* TotalTimeoutFees returns the total timeout fees for a packet given its identifier */
async totalTimeoutFees(_params: QueryTotalTimeoutFeesRequest = {}): Promise<QueryTotalTimeoutFeesResponseSDKType> {
const endpoint = `ibc/apps/fee/v1/channels/${params.packetId.channel_id}/ports/${params.packetId.port_id}/sequences/${params.packetId.sequence}/total_timeout_fees`;
const endpoint = `ibc/apps/fee/v1/channels/${params.packet_id.channel_id}/ports/${params.packet_id.port_id}/sequences/${params.packet_id.sequence}/total_timeout_fees`;
return QueryTotalTimeoutFeesResponse.fromSDKJSON(await this.req.get<QueryTotalTimeoutFeesResponseSDKType>(endpoint));
}
/* Payee returns the registered payee address for a specific channel given the relayer address */
Expand Down
8 changes: 4 additions & 4 deletions packages/ast/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,19 @@
"url": "https://github.com/cosmology-tech/telescope/issues"
},
"devDependencies": {
"@babel/parser": "^7.23.6",
"@cosmology/proto-parser": "^1.5.3",
"@types/jest": "^29.5.0",
"ast-stringify": "0.1.0",
"cross-env": "^7.0.2",
"deepmerge": "4.3.1",
"eslint": "8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint": "8.38.0",
"esprima": "4.0.1",
"glob": "8.0.3",
"jest": "^29.5.0",
"jest-in-case": "^1.0.2",
"jest": "^29.5.0",
"mkdirp": "3.0.0",
"prettier": "^2.8.7",
"regenerator-runtime": "^0.13.11",
Expand All @@ -82,11 +83,10 @@
"typescript": "5.0.4"
},
"dependencies": {
"@babel/parser": "^7.23.6",
"@babel/types": "7.23.6",
"@cosmology/types": "^1.5.3",
"@cosmology/utils": "^1.5.3",
"case": "1.6.3",
"dotty": "0.1.2"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -758,5 +758,3 @@ exports[`service info template 5`] = `
],
}
`;

exports[`template tags 1`] = `"\`/\${params.cosmos}/feegrant/v1beta1/\${params.allowance}/\${params.granter}/\${params.grantee}\`"`;
7 changes: 2 additions & 5 deletions packages/ast/src/clients/lcd/class/lcd.keepCase.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import {
getUrlTemplateString,
createAggregatedLCDClient,
createLCDClient,
makeTemplateTagLegacy
createLCDClient
} from './lcd';
import { traverse } from '@cosmology/proto-parser'
import { getNestedProto } from '@cosmology/utils'
import { defaultTelescopeOptions, ProtoService } from '@cosmology/types';
import generate from '@babel/generator';
import { GenericParseContext } from '../../../encoding';
import { getTestProtoStore, expectCode, printCode } from '../../../../test-utils';
const store = getTestProtoStore();
// @ts-ignore
store.options.prototypes.parser.keepCase = true;
store.traverseAll();

Expand Down
21 changes: 2 additions & 19 deletions packages/ast/src/clients/lcd/class/lcd.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import {
getUrlTemplateString,
createAggregatedLCDClient,
createLCDClient,
makeTemplateTagLegacy
createLCDClient
} from './lcd';
import { traverse } from '@cosmology/proto-parser'
import { getNestedProto } from '@cosmology/utils'
import { defaultTelescopeOptions, ProtoService } from '@cosmology/types';
import generate from '@babel/generator';
import { GenericParseContext } from '../../../encoding';
import { getTestProtoStore, expectCode, printCode } from '../../../../test-utils';
import { getTestProtoStore, expectCode } from '../../../../test-utils';
const store = getTestProtoStore();
store.traverseAll();

Expand All @@ -21,20 +18,6 @@ it('service info template', () => {
expect(getUrlTemplateString('/cosmos/feegrant/v1beta1/allowance/{granter}/{grantee}')).toMatchSnapshot();
});

it('template tags', () => {
const info = {
url: '/{cosmos}/feegrant/v1beta1/{allowance}/{granter}/{grantee}',
pathParams: [
'cosmos',
'allowance',
'granter',
'grantee'
]
};
// @ts-ignore
expectCode(makeTemplateTagLegacy(info));
})

it('osmosis LCDClient', () => {
const ref = store.findProto('osmosis/gamm/v1beta1/query.proto');
const res = traverse(store, ref);
Expand Down
137 changes: 33 additions & 104 deletions packages/ast/src/clients/lcd/class/lcd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,6 @@ import { ProtoService, ProtoServiceMethod, ProtoServiceMethodInfo } from '@cosmo
import { GenericParseContext } from '../../../encoding';
import { arrowFunctionExpression, callExpression, classMethod, classProperty, identifier, objectPattern } from '../../../utils';

// this is the ONLY time ast uses babel/parser
import { parse } from '@babel/parser';

const getAstFromString = (str: string) => {
const plugins = [
'objectRestSpread',
'classProperties',
'optionalCatchBinding',
'asyncGenerators',
'decorators-legacy',
'typescript',
'dynamicImport'
];
const ast = parse(str, {
sourceType: 'module',
// @ts-ignore
plugins
});
return ast;
};


const getResponseTypeName = (
context: GenericParseContext,
name: string
Expand Down Expand Up @@ -254,101 +232,52 @@ export const getUrlTemplateString = (url: string) => {
};

const routeRegexForReplace = /[^\{\}\\-\_\\.$/a-zA-Z0-9]+/g;
export const makeTemplateTag = (info: ProtoServiceMethodInfo) => {
export function makeTemplateTag(info: ProtoServiceMethodInfo, noLeadingSlash: boolean = true): t.TemplateLiteral {
const route = info.url
.split('/')
.filter(a => a !== '')
.map(a => {
if (a.startsWith('{')) {
// clean weird routes like this one:
// /ibc/apps/transfer/v1/denom_traces/{hash=**}
return `$${a}`
.replace(routeRegexForReplace, '')
.replace('{', `{params.`)
return a.replace(routeRegexForReplace, '')
} else {
return a;
}
})
.join('/');

// clean route here

const parsed = getAstFromString(`\`${route}\``);
// @ts-ignore
const ast: t.TemplateLiteral = parsed.program.body[0].expression;

ast.expressions = ast.expressions.map((expr: t.MemberExpression) => {
let name;
switch (expr.object.type) {
case 'MemberExpression': {
// e.g. params.thing.another
const memberExpr: t.MemberExpression = expr.object;
// @ts-ignore
name = memberExpr.property.name;
name = info.casing?.[name] ? info.casing[name] : name;
// @ts-ignore
expr.object.property.name = name;
break;
}
case 'Identifier': {
// e.g. params.thing
// @ts-ignore
const identifier: t.Identifier = expr.property;
name = identifier.name;
name = info.casing?.[name] ? info.casing[name] : name;
// @ts-ignore
expr.property.name = name;
break;
}
case 'Identifier':
break;
default:
throw new Error('unknown expression type in route parsing');
const segments = route.split('/');
const expressions: (t.Identifier | t.MemberExpression)[] = [];
const quasis = [];
let accumulatedPath = '';
let isFirst = true;

segments.forEach((segment, _index) => {
if (noLeadingSlash && segment === '') return;

if (segment.startsWith('{') && segment.endsWith('}')) {
// Dynamic segment
const paramName = segment.slice(1, -1);
// Push the accumulated static text as a quasi before adding the expression
quasis.push(t.templateElement({ raw: accumulatedPath + '/', cooked: accumulatedPath }, false));
accumulatedPath = ''; // Reset accumulated path after adding to quasis

// expressions.push(t.identifier(`params.${paramName}`));
expressions.push(t.memberExpression(t.identifier('params'), t.identifier(info.casing?.[paramName] ? info.casing[paramName] : paramName)));
// Prepare the next quasi to start with a slash if this is not the last segment
isFirst = false;
} else {
// Accumulate static text, ensuring to prepend a slash if it's not the first segment
accumulatedPath += (isFirst ? '' : '/') + segment;
isFirst = false;
}
return expr;
}).filter(Boolean);
return ast;
};

// do we need to set end prop in ast?
// we may want to t.templateElement!!!
export const makeTemplateTagLegacy = (info: ProtoServiceMethodInfo) => {
if (!info.url) throw new Error('no URL on service method');

const parts = getUrlTemplateString(info.url);
const templateElts = parts.strs.map(raw => t.templateElement({ raw }))

// Number of TemplateLiteral quasis should be exactly one more than the number of expressions

const pathParams = info.pathParams.map(param => {
const name = info.casing?.[param] ? info.casing[param] : param;
return t.memberExpression(
t.identifier('params'),
t.identifier(name)
);
});

if (parts.atEnd) {
templateElts.push(t.templateElement({ raw: '' }));
}

// THIS MEANS WE PROBABLY HAVE A BUG
if (templateElts.length !== pathParams.length + 1) {
templateElts.push(t.templateElement({ raw: '' }));
}

templateElts.forEach((el, n) => {
if (n === templateElts.length - 1) {
// remove trailing slash...
el.value.raw = el.value.raw.replace(/\/$/, '');
}
});
// Add the final accumulated static text as the last quasi
quasis.push(t.templateElement({ raw: accumulatedPath, cooked: accumulatedPath }, true)); // Mark the last quasi as tail

return t.templateLiteral(
templateElts,
pathParams
);
};
return t.templateLiteral(quasis, expressions);
}

const makeComment = (comment: string) => {
return [{ type: 'CommentBlock', value: ` ${comment} ` }]
Expand Down Expand Up @@ -416,10 +345,10 @@ const buildRequestMethod = (
t.objectProperty(
t.identifier('pagination'),
paginationDefaultFromPartial ? t.callExpression(
t.memberExpression(t.identifier("PageRequest"), t.identifier("fromPartial")),
[t.objectExpression([])]
t.memberExpression(t.identifier("PageRequest"), t.identifier("fromPartial")),
[t.objectExpression([])]
) :
t.identifier('undefined'),
t.identifier('undefined'),
false,
false
)
Expand Down
3 changes: 1 addition & 2 deletions packages/ast/types/clients/lcd/class/lcd.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export declare const getUrlTemplateString: (url: string) => {
strs: any[];
atEnd: boolean;
};
export declare const makeTemplateTag: (info: ProtoServiceMethodInfo) => t.TemplateLiteral;
export declare const makeTemplateTagLegacy: (info: ProtoServiceMethodInfo) => t.TemplateLiteral;
export declare function makeTemplateTag(info: ProtoServiceMethodInfo, noLeadingSlash?: boolean): t.TemplateLiteral;
export declare const createLCDClient: (context: GenericParseContext, service: ProtoService) => t.ExportNamedDeclaration;
export declare const createAggregatedLCDClient: (context: GenericParseContext, services: ProtoService[], clientName: string) => t.ExportNamedDeclaration;
Loading