UNPKG

@cosmology/ast

Version:
168 lines (167 loc) 6.79 kB
"use strict"; 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.buildRpcStores = exports.createMobxQueryStores = void 0; const t = __importStar(require("@babel/types")); const utils_1 = require("../../utils"); const utils_2 = require("@cosmology/utils"); const utils_3 = require("@cosmology/utils"); const case_1 = require("case"); const makeQueryStoreName = (name) => { return `Query${(0, case_1.pascal)(name)}Store`; }; /** * Entry for building stores. * @param {Object=} context - context of generating the file * @param {Object=} service - method details */ const createMobxQueryStores = (context, service) => { const isIncluded = context.pluginValue('mobx.enabled') && (0, utils_2.isRefIncluded)(context.ref, context.pluginValue('mobx.include')); if (isIncluded) { // before this, make sure: // 1. refactor adding getQueryService part into helpers. // 2. add new query store class to helpers. // build whole ast, don't forget to add utils. return (0, exports.buildRpcStores)(context, service); } return null; }; exports.createMobxQueryStores = createMobxQueryStores; /** * Create an AST to generate creating store functions. * eg: * export const createRpcQueryMobxStores = (rpc: ProtobufRpcClient | undefined) => { * const queryService = getQueryService(rpc); * * class QueryCertificatesStore { * ... * } * * return { * QueryCertificatesStore * }; * }; * @param {Object=} context - context of generating the file * @param {Object=} service - method details * @returns {ParseResult} created AST */ const buildRpcStores = (context, service) => { // add imports context.addUtil('ProtobufRpcClient'); //TODO: add util for getQueryService const isCamelRpcMethods = context.pluginValue('rpcClients.camelCase'); const storeNames = []; const stores = Object.keys(service.methods ?? {}).map((key) => { const method = service.methods[key]; const name = isCamelRpcMethods ? (0, utils_3.camel)(key) : key; storeNames.push({ name, comment: method.comment }); return buildStore(context, name, method); }); return t.exportNamedDeclaration(t.variableDeclaration('const', [ t.variableDeclarator(t.identifier('createRpcQueryMobxStores'), t.arrowFunctionExpression([ (0, utils_1.identifier)('rpc', t.tsTypeAnnotation(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('getQueryService'), [ t.identifier('rpc') ])) ]), ...stores, // return the methods... t.returnStatement(t.objectExpression(storeNames.map(({ name, comment }) => { const id = t.identifier(makeQueryStoreName(name)); return (0, utils_1.objectProperty)(id, id, false, true, null, (0, utils_1.makeCommentLineWithBlocks)(comment)); }))) ]) // end body )) ])); }; exports.buildRpcStores = buildRpcStores; /** * Create an AST of inherited store. * eg: * class QueryCertificatesStore { * store = new QueryStore<QueryCertificatesRequest, QueryCertificatesResponse>(queryService?.certificates); * certificates(request: QueryCertificatesRequest) { * return this.store.getData(request); * } * } * @param {Object=} context - context of generating the file * @param {string} name - name of the store * @param {Object=} serviceMethod - method details * @returns {ParseResult} created AST */ const buildStore = (context, name, serviceMethod) => { //add util for QueryStore context.addUtil('QueryStore'); //add util for MobxResponse context.addUtil('MobxResponse'); //add util for makeObservable context.addUtil('makeObservable'); //add util for override context.addUtil('override'); const requestType = serviceMethod.requestType; const responseType = serviceMethod.responseType; const fieldNames = Object.keys(serviceMethod.fields ?? {}); const hasParams = fieldNames.length > 0; let isOptional = false; // // if no params, then let's default to empty object for cleaner API if (!hasParams) { isOptional = true; } else if (hasParams && fieldNames.length === 1 && fieldNames.includes('pagination')) { // if only argument "required" is pagination // also default to empty isOptional = true; } const storeClassName = makeQueryStoreName(name); const storeQueryClass = t.classDeclaration(t.identifier(storeClassName), null, t.classBody([ t.classProperty(t.identifier('store'), (0, utils_1.newExpression)(t.identifier('QueryStore'), [ t.optionalMemberExpression(t.identifier('queryService'), t.identifier(name), false, true) ], t.tsTypeParameterInstantiation([ t.tsTypeReference(t.identifier(requestType)), t.tsTypeReference(t.identifier(responseType)) ]))), t.classMethod('method', t.identifier(name), [ (0, utils_1.identifier)('request', t.tsTypeAnnotation(t.tsTypeReference(t.identifier(requestType)))) ], t.blockStatement([ t.returnStatement(t.callExpression(t.memberExpression(t.memberExpression(t.thisExpression(), t.identifier('store')), t.identifier('getData')), [t.identifier('request')])) ], [])) ])); return storeQueryClass; };