UNPKG

@cuba-platform/front-generator

Version:
145 lines 7.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createQuery = exports.generateQueries = void 0; const method_params_type_1 = require("./method-params-type"); const ts = require("typescript"); const import_utils_1 = require("../import-utils"); const services_generation_1 = require("./services-generation"); const constants_1 = require("../../../common/constants"); const ts_helpers_1 = require("../../../common/ts-helpers"); const ts_shorthands_1 = require("../../../common/ts-shorthands"); const model_utils_1 = require("../model/model-utils"); const QUERIES_VAR_NAME = 'restQueries'; function generateQueries(restQueries, ctx) { // import declaration // import { CubaApp, FetchOptions, SerializedEntity, EntitiesWithCount } from "@cuba-platform/rest"; const importDec = (0, import_utils_1.importDeclaration)([constants_1.CUBA_APP_TYPE, constants_1.FETCH_OPTIONS_TYPE, constants_1.SERIALIZED_ENTITY_TYPE, constants_1.ENTITIES_WITH_COUNT_TYPE], constants_1.CUBA_APP_MODULE_SPEC); // compose import infos of entities, entities are used as function type parameters, i.e. 'Car' entity is used as // cubaApp.query<Car>("scr$Car", "allCars", {}, fetchOpts); const entityImportInfos = restQueries .map(restQuery => restQuery.entity) .reduce((importInfos, entityName) => { const entityInfo = (0, model_utils_1.findEntityByName)(entityName, ctx); // do not add duplicates if (entityInfo && !importInfos.find(ii => ii.className === entityInfo.entity.className)) { importInfos.push((0, import_utils_1.entityImportInfo)(entityInfo, constants_1.ENTITIES_DIR)); } return importInfos; }, []); const queriesResult = createQueries(restQueries, ctx); // includes composed from import infos of entities + import infos of types, used in parameters, i.e // // export type queries_FavoriteCar_allCars_params = { // car: Car; // }; const includes = (0, import_utils_1.createIncludes)([...queriesResult.importInfos, ...entityImportInfos]); return (0, ts_helpers_1.renderTSNodes)([importDec, ...includes, ...queriesResult.methodParamTypes, queriesResult.node], '\n\n'); } exports.generateQueries = generateQueries; function createQueries(restQueries, ctx) { const assignmentList = []; const methodParamTypes = []; const importInfos = []; const queriesByEntity = new Map(); restQueries.forEach(q => { const queriesOfEntity = queriesByEntity.get(q.entity); if (queriesOfEntity) { queriesOfEntity.push(q); } else { queriesByEntity.set(q.entity, [q]); } }); [...queriesByEntity.entries()].forEach(([entityName, queries]) => { const createItemResult = createQuery(entityName, queries, ctx); assignmentList.push(createItemResult.node); createItemResult.methodParamsTypes.forEach(mpt => methodParamTypes.push(mpt)); importInfos.push(...createItemResult.imports); }); const variableDeclaration = ts.createVariableDeclaration(QUERIES_VAR_NAME, undefined, ts.createObjectLiteral(assignmentList, true)); const node = ts.createVariableStatement([(0, ts_shorthands_1.exportModifier)()], [variableDeclaration]); return { node, methodParamTypes, importInfos }; } /** * Call example: * restQueries.Car.carsByType(cubaApp, fetchOpts?)(params?) * restQueries.Car.carsByTypeCount(cubaApp, fetchOpts?)(params?) * restQueries.Car.carsByTypeWithCount(cubaApp, fetchOpts?)(params?) * * Cuba REST call: * cubaApp.query("mpg$Car", "carsByType", params, fetchOpts); * cubaApp.queryCount("mpg$Car", "carsByType", params, fetchOpts); * cubaApp.queryWithCount("mpg$Car", "carsByType", params, fetchOpts); */ function createQuery(entityName, queries, ctx) { const methodAssignments = []; const methodParamsTypes = []; const imports = []; const className = findClassName(entityName, ctx); const paramTypePrefix = 'queries_' + className; //'overload' queries - queries with both same entity and name (0, method_params_type_1.collectMethods)(queries).forEach((mwo) => { let paramTypeName = undefined; //if any of overloads has params - create special type for it if (mwo.methods.some(m => m.params.length > 0)) { const { paramTypeNode, importInfos, name } = (0, method_params_type_1.createMethodParamsType)(mwo.methods, paramTypePrefix, ctx); imports.push(...importInfos); methodParamsTypes.push(paramTypeNode); paramTypeName = name; } const typeArguments = [ts.createTypeReferenceNode(className, [])]; ['', 'Count', 'WithCount'].forEach(suffix => { const qName = mwo.methodName; let functionType = undefined; // Promise<EntitiesWithCount<ClassName>> if (suffix === 'WithCount') functionType = createEntitiesWithCountQueryFunctionType(className); // Promise<SerializedEntity<ClassName>[]> if (suffix === '') functionType = createSerializedEntityQueryFunctionType(className); // Promise<Number> if (suffix === 'Count') functionType = createCountQueryFunctionType(); const cubaCallFunc = (0, services_generation_1.cubaAppCallFunc)('query' + suffix, paramTypeName, functionType, [entityName, qName], suffix !== 'Count' ? typeArguments : []); methodAssignments.push(ts.createPropertyAssignment(qName + suffix, cubaCallFunc)); }); }); //todo do we need to resolve entities with same names, or entity.name is unique in CUBA ? const node = ts.createPropertyAssignment(className, ts.createObjectLiteral(methodAssignments, true)); return { node, methodParamsTypes, imports }; } exports.createQuery = createQuery; /** * @param className name used in function type * @return 'Promise<SerializedEntity<ClassName>[]>' */ function createSerializedEntityQueryFunctionType(className) { const entityClassTypeNode = ts.createTypeReferenceNode(className, []); const entityTypeNode = ts.createTypeReferenceNode(constants_1.SERIALIZED_ENTITY_TYPE, [entityClassTypeNode]); const entityArrayTypeNode = ts.createArrayTypeNode(entityTypeNode); return ts.createTypeReferenceNode('Promise', [entityArrayTypeNode]); } /** * @param className name used in function type * @return 'Promise<EntitiesWithCount<ClassName>>' */ function createEntitiesWithCountQueryFunctionType(className) { const entityClassTypeNode = ts.createTypeReferenceNode(className, []); const entityTypeNode = ts.createTypeReferenceNode(constants_1.ENTITIES_WITH_COUNT_TYPE, [entityClassTypeNode]); return ts.createTypeReferenceNode('Promise', [entityTypeNode]); } /** * @return 'Promise<Number>' */ function createCountQueryFunctionType() { const numberTypeNode = ts.createTypeReferenceNode('Number', []); return ts.createTypeReferenceNode('Promise', [numberTypeNode]); } function findClassName(entityName, ctx) { const entry = [...ctx.entitiesMap.entries()] .find(([, projEntityInfo]) => { return projEntityInfo.entity.name == entityName; }); return entry[1].entity.className; } //# sourceMappingURL=queries-generation.js.map