@cosmology/ast
Version:
Cosmos TypeScript AST generation
207 lines (206 loc) • 10.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRpcVueQueryHookClientMap = exports.createRpcVueQueryHookInterfaces = exports.createRpcVueQueryHooks = void 0;
const t = __importStar(require("@babel/types"));
const utils_1 = require("../../utils");
const utils_2 = require("@cosmology/utils");
const weak_map_1 = require("./weak-map");
const rpcHookMethod = (context, name, svc) => {
const requestType = svc.requestType;
const responseType = svc.responseType;
const fieldNames = Object.keys(svc.fields ?? {});
const hasParams = fieldNames.length > 0;
let optional = false;
// if no params, then let's default to empty object for cleaner API
if (!hasParams) {
optional = true;
}
else if (hasParams && fieldNames.length === 1 && fieldNames.includes('pagination')) {
// if only argument "required" is pagination
// also default to empty
optional = true;
}
// add import
context.addUtil('useVueQuery');
return t.variableDeclaration('const', [
t.variableDeclarator(t.identifier((0, utils_2.makeUseHookName)(name)), (0, utils_1.arrowFunctionExpression)([
(0, utils_1.objectPattern)([
t.objectProperty(t.identifier('request'), t.identifier('request'), false, true),
t.objectProperty(t.identifier('options'), t.identifier('options'), false, true)
], t.tsTypeAnnotation(t.tsTypeReference(t.identifier((0, utils_2.makeUseHookTypeName)(name)), t.tsTypeParameterInstantiation([
t.tsTypeReference(t.identifier('TData'))
]))))
], t.blockStatement([
t.variableDeclaration('const', [
t.variableDeclarator(t.identifier('queryKey'), t.arrayExpression([
t.stringLiteral((0, utils_2.makeHookKeyName)(name)),
t.identifier('queryService')
]))
]),
t.ifStatement(t.identifier('request'), t.blockStatement([
t.expressionStatement(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('values')), [t.identifier('request')]), t.identifier('forEach')), [
t.arrowFunctionExpression([(0, utils_1.identifier)('val', t.tsTypeAnnotation(t.tsAnyKeyword()))], t.blockStatement([
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('queryKey'), t.identifier('push')), [t.identifier('val')]))
]))
]))
])),
t.returnStatement((0, utils_1.callExpression)(t.identifier('useQuery'), [
t.objectExpression([
t.objectProperty(t.identifier('queryKey'), t.identifier('queryKey'), false, true),
t.objectProperty(t.identifier('queryFn'), t.arrowFunctionExpression([], t.blockStatement([
t.ifStatement(t.unaryExpression('!', t.memberExpression(t.identifier('queryService'), t.identifier('value')), true), t.throwStatement(t.newExpression(t.identifier('Error'), [t.stringLiteral('Query Service not initialized')]))),
t.variableDeclaration('let', [
t.variableDeclarator(t.identifier('params'), t.tsAsExpression(t.objectExpression([]), t.tsAnyKeyword()))
]),
t.ifStatement(t.identifier('request'), t.blockStatement([
t.expressionStatement(t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('entries')), [t.identifier('request')]), t.identifier('forEach')), [
t.arrowFunctionExpression([
t.arrayPattern([
(0, utils_1.identifier)('key', t.tsTypeAnnotation(t.tsStringKeyword())),
(0, utils_1.identifier)('val', t.tsTypeAnnotation(t.tsAnyKeyword())),
])
], t.blockStatement([
t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('params'), t.identifier('key'), true), t.memberExpression(t.identifier('val'), t.identifier('value'))))
]))
]))
])),
t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('queryService'), t.identifier('value')), t.identifier(name)), [t.identifier('params')]))
]))),
t.spreadElement(t.identifier('options'))
]),
], t.tsTypeParameterInstantiation([
t.tsTypeReference(t.identifier(responseType)),
t.tsTypeReference(t.identifier('Error')),
t.tsTypeReference(t.identifier('TData'))
])))
]), undefined, false, (0, utils_1.tsTypeParameterDeclaration)([
t.tsTypeParameter(null, t.tsTypeReference(t.identifier(responseType)), 'TData')
])))
]);
};
const createRpcVueQueryHooks = (context, service) => {
// add imports
context.addUtil('QueryClient');
context.addUtil('createProtobufRpcClient');
context.addUtil('ProtobufRpcClient');
context.addUtil('ComputedRef');
context.addUtil('computed');
context.addUtil('Ref');
const camelRpcMethods = context.pluginValue('rpcClients.camelCase');
const methods = Object.keys(service.methods ?? {})
.map(key => {
const method = service.methods[key];
const name = camelRpcMethods ? (0, utils_2.camel)(key) : key;
return rpcHookMethod(context, name, method);
});
const methodNames = Object.keys(service.methods ?? {})
.map(key => {
const name = camelRpcMethods ? (0, utils_2.camel)(key) : key;
return {
name,
comment: service.methods[key].comment ?? ""
};
});
return t.exportNamedDeclaration(t.variableDeclaration('const', [
t.variableDeclarator(t.identifier('createRpcQueryHooks'), t.arrowFunctionExpression([
(0, utils_1.identifier)('rpc', t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Ref'), t.tsTypeParameterInstantiation([
t.tsUnionType([
t.tsTypeReference(t.identifier('ProtobufRpcClient')),
t.tsUndefinedKeyword()
])
]))))
],
// body
t.blockStatement([
// query service
t.variableDeclaration('const', [
t.variableDeclarator(t.identifier('queryService'), t.callExpression(t.identifier('useQueryService'), [
t.identifier('rpc')
]))
]),
...methods,
// return the methods...
t.returnStatement(t.objectExpression(methodNames.map(({ name, comment }) => (0, utils_1.objectProperty)(t.identifier((0, utils_2.makeUseHookName)(name)), t.identifier((0, utils_2.makeUseHookName)(name)), false, true, null, (0, utils_1.makeCommentLineWithBlocks)(comment)))))
])
// end body
))
]));
};
exports.createRpcVueQueryHooks = createRpcVueQueryHooks;
const rpcVueHookMethodInterface = (context, name, svc) => {
const requestType = svc.requestType;
const responseType = svc.responseType;
const fieldNames = Object.keys(svc.fields ?? {});
const hasParams = fieldNames.length > 0;
let optional = false;
// if no params, then let's default to empty object for cleaner API
if (!hasParams) {
optional = true;
}
else if (hasParams && fieldNames.length === 1 && fieldNames.includes('pagination')) {
// if only argument "required" is pagination
// also default to empty
optional = true;
}
// import VueQueryParams in the generated file.
context.addUtil('VueQueryParams');
return t.exportNamedDeclaration(t.tsInterfaceDeclaration(t.identifier((0, utils_2.makeUseHookTypeName)(name)), t.tsTypeParameterDeclaration([
t.tsTypeParameter(null, null, 'TData')
]), [
t.tsExpressionWithTypeArguments(t.identifier('VueQueryParams'), t.tsTypeParameterInstantiation([
t.tsTypeReference(t.identifier(responseType)),
t.tsTypeReference(t.identifier('TData'))
]))
], t.tsInterfaceBody([
(0, utils_1.tsPropertySignature)(t.identifier('request'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`Reactive${requestType}`))), optional)
])));
};
/**
* Create ASTs for all the methods of a proto service.
* @param {Object=} context - context of generating the file
* @param {Object=} service - service details
* @returns {ParseResult} created AST
*/
const createRpcVueQueryHookInterfaces = (context, service) => {
const camelRpcMethods = context.pluginValue('rpcClients.camelCase');
const methods = Object.keys(service.methods ?? {})
.map(key => {
const name = camelRpcMethods ? (0, utils_2.camel)(key) : key;
const method = service.methods[key];
return {
name,
method
};
});
return methods.map(method => rpcVueHookMethodInterface(context, method.name, method.method));
};
exports.createRpcVueQueryHookInterfaces = createRpcVueQueryHookInterfaces;
const createRpcVueQueryHookClientMap = (context, service) => {
const name = service.name + 'ClientImpl';
// get ast based on a template.
return (0, weak_map_1.createClientMap)(name);
};
exports.createRpcVueQueryHookClientMap = createRpcVueQueryHookClientMap;