@cosmology/ast
Version:
Cosmos TypeScript AST generation
123 lines (109 loc) • 3.47 kB
text/typescript
import * as t from '@babel/types';
import { ProtoService, ProtoServiceMethod } from '@cosmology/types';
import { GenericParseContext } from '../../encoding';
import { camel } from '@cosmology/utils';
const firstLower = (s: string) => s = s.charAt(0).toLowerCase() + s.slice(1);
const firstUpper = (s: string) => s = s.charAt(0).toUpperCase() + s.slice(1);
interface Method {
name: string,
method: any,
}
function buildState(methods: Method[]) {
const fields = methods.map(x => t.objectProperty(
t.identifier(x.name),
t.tsAsExpression(
t.identifier("{}"),
t.tsUnionType([
t.tsTypeReference(t.identifier(`${x.method.responseType}SDKType`)),
]),
)))
return t.arrowFunctionExpression([], t.blockStatement([
t.returnStatement(t.objectExpression(fields))
]))
}
function buildAction(methods: Method[]) {
const fields = methods.map(x => t.objectMethod(
'method',
t.identifier(`fetch${firstUpper(x.name)}`),
[t.identifier(`param : ${x.method.requestType}SDKType`)],
t.blockStatement([
t.expressionStatement(
t.assignmentExpression(
'=',
t.memberExpression(t.thisExpression(), t.identifier(x.name)),
t.awaitExpression(
t.callExpression(
t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('lcdClient')), t.identifier(x.name)),
[t.identifier('param')]
)
)
)
),
t.returnStatement(t.memberExpression(t.thisExpression(), t.identifier(x.name)))
]),
false, false, true
))
return t.objectExpression(fields)
}
function buildGetter(method: Method[]) {
return t.objectExpression([t.objectMethod(
'method',
t.identifier('lcdClient'),
[],
t.blockStatement([
t.variableDeclaration(
'const',
[
t.variableDeclarator(
t.identifier('requestClient'),
t.memberExpression(
t.callExpression(t.identifier('useEndpoint'), []),
t.identifier('restClient')
)
),
]
),
t.returnStatement(t.newExpression(t.identifier('LCDQueryClient'),
[
t.identifier('{ requestClient }')
]))
])
)])
}
function getStoreName(key: string): string {
const names = key.split('/')
return `use${firstUpper(names[0])}${firstUpper(names[1])}`
}
export const createPiniaStore = (
context: GenericParseContext,
service: ProtoService
) => {
context.addUtil('LCDClient');
context.addUtil('useEndpoint');
const key = context.ref.filename
const storeName = 'usePiniaStore'
// const storeName = getStoreName(key)
const methods: Method[] = Object.keys(service.methods ?? {})
.map(key => {
const method = service.methods[key];
// console.log('method:', method)
const name = camel(key)
return { name, method }
});
return t.exportNamedDeclaration(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(storeName),
t.callExpression(
t.identifier('defineStore'),
[
t.identifier(`'${key}'`),
t.objectExpression([
t.objectProperty(t.identifier('state'), buildState(methods)),
t.objectProperty(t.identifier('getters'), buildGetter(methods)),
t.objectProperty(t.identifier('actions'), buildAction(methods)),
]),
]))
])
)
};