@rxap/schematics-ts-morph
Version:
This package provides utilities for manipulating TypeScript code using ts-morph, particularly for Angular and NestJS projects. It offers functions to add, coerce, and modify code elements like classes, methods, decorators, and imports. The package also in
342 lines • 15 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GetPageOperationColumnToCodeText = GetPageOperationColumnToCodeText;
exports.CoerceToRowDtoMethod = CoerceToRowDtoMethod;
exports.CoerceToPageDtoMethod = CoerceToPageDtoMethod;
exports.CoerceGetPageDataMethod = CoerceGetPageDataMethod;
exports.GetResponseTypeFromUpstream = GetResponseTypeFromUpstream;
exports.GetRawRowDataType = GetRawRowDataType;
exports.BuildGetPageGetDataImplementation = BuildGetPageGetDataImplementation;
exports.CoerceGetPageOperationDtoClass = CoerceGetPageOperationDtoClass;
exports.BuiltGetPageDtoDataMapperImplementation = BuiltGetPageDtoDataMapperImplementation;
exports.CoerceGetPageOperation = CoerceGetPageOperation;
const schematics_utilities_1 = require("@rxap/schematics-utilities");
const ts_morph_1 = require("@rxap/ts-morph");
const utilities_1 = require("@rxap/utilities");
const ts_morph_2 = require("ts-morph");
const coerce_type_alias_1 = require("../ts-morph/coerce-type-alias");
const write_type_1 = require("../ts-morph/write-type");
const ts_morph_3 = require("@rxap/ts-morph");
const coerce_operation_1 = require("./coerce-operation");
const coerce_page_dto_class_1 = require("./coerce-page-dto-class");
const coerce_row_dto_class_1 = require("./coerce-row-dto-class");
const table_query_list_1 = require("./table-query-list");
function GetPageOperationColumnToCodeText(property) {
var _a;
let propertyName = (0, schematics_utilities_1.camelize)(property.name);
const prefixMatch = property.name.match(/^(_+)/);
if (prefixMatch) {
propertyName = (0, schematics_utilities_1.camelize)(property.name.replace(/^_+/, ''));
propertyName = prefixMatch[0] + propertyName;
}
return `${propertyName}: item.${(_a = property.source) !== null && _a !== void 0 ? _a : (0, schematics_utilities_1.camelize)(property.name)}`;
}
function CoerceToRowDtoMethod(sourceFile, classDeclaration, rowClassName, options) {
var _a, _b, _c;
const { rowId } = options;
let rowIdSource;
if (rowId === null || rowId === void 0 ? void 0 : rowId.name) {
rowIdSource = `item.${rowId.name}`;
}
else {
rowIdSource = `(pageIndex * pageSize + index)${((_a = rowId === null || rowId === void 0 ? void 0 : rowId.type) !== null && _a !== void 0 ? _a : 'number' === 'number') ? '' : '.toFixed(0)'}`;
}
(0, ts_morph_1.CoerceClassMethod)(classDeclaration, 'toRowDto', {
scope: ts_morph_2.Scope.Private,
returnType: rowClassName,
parameters: [
{
name: 'item',
type: (0, write_type_1.WriteType)({
isArray: false,
type: GetRawRowDataType(options),
}, sourceFile),
},
{
name: 'index',
type: 'number',
},
{
name: 'pageIndex',
type: 'number',
},
{
name: 'pageSize',
type: 'number',
},
{
name: 'list',
type: (0, write_type_1.WriteType)({
isArray: true,
type: GetRawRowDataType(options),
}, sourceFile),
},
],
statements: [
'return {',
` __rowId: ${rowIdSource},\n `,
(_c = (_b = options.propertyList) === null || _b === void 0 ? void 0 : _b.filter(p => p.name !== '__rowId').map(GetPageOperationColumnToCodeText).join(',\n ')) !== null && _c !== void 0 ? _c : '',
'};',
],
});
}
function CoerceToPageDtoMethod(sourceFile, classDeclaration, pageClassName, rowClassName, options) {
(0, ts_morph_1.CoerceClassMethod)(classDeclaration, 'toPageDto', {
scope: ts_morph_2.Scope.Private,
returnType: pageClassName,
parameters: [
{
name: 'list',
type: (0, write_type_1.WriteType)({
isArray: true,
type: GetRawRowDataType(options),
}, sourceFile),
},
{
name: 'total',
type: 'number',
},
{
name: 'pageIndex',
type: 'number',
},
{
name: 'pageSize',
type: 'number',
},
{
name: 'sortBy',
type: 'string',
},
{
name: 'sortDirection',
type: 'string',
},
{
name: 'filter',
type: 'FilterQuery[]',
},
],
statements: [
'return {',
' total, pageIndex, pageSize, sortBy, sortDirection, filter,',
` rows: list.map((item, index) => this.toRowDto(item, index, pageIndex, pageSize, list))`,
'};',
],
});
}
function CoerceGetPageDataMethod(sourceFile, classDeclaration, moduleSourceFile, options) {
var _a, _b, _c, _d, _e, _f, _g;
const { upstream } = options;
const statements = [];
if (upstream && (0, ts_morph_1.IsNormalizedOpenApiUpstreamOptions)(upstream)) {
const { memberName, className: commandClassName } = (0, ts_morph_3.CoerceUpstreamBasicOperationImplementation)(classDeclaration, moduleSourceFile, upstream);
(0, ts_morph_1.CoercePropertyDeclaration)(classDeclaration, memberName, {
type: commandClassName,
scope: ts_morph_2.Scope.Private,
hasExclamationToken: true,
decorators: [
{
name: 'Inject',
arguments: [commandClassName],
},
],
});
(0, ts_morph_1.CoerceImports)(sourceFile, [
{
namedImports: [commandClassName],
moduleSpecifier: (0, ts_morph_1.OperationIdToCommandClassImportPath)(upstream.operationId, upstream.scope, upstream.isService),
}, {
namedImports: ['Inject'],
moduleSpecifier: '@nestjs/common',
},
]);
let pageIndex = 'pageIndex';
let pageSize = 'pageSize';
let sortBy = 'sortBy';
let sortDirection = 'sortDirection';
let filter = null;
let list = 'list';
let total = 'total';
const { mapper } = upstream;
if (mapper && (0, ts_morph_1.IsNormalizedPagedRequestMapper)(mapper)) {
pageIndex = (_a = mapper.pageIndex) !== null && _a !== void 0 ? _a : pageIndex;
pageSize = (_b = mapper.pageSize) !== null && _b !== void 0 ? _b : pageSize;
sortBy = (_c = mapper.sortBy) !== null && _c !== void 0 ? _c : sortBy;
sortDirection = (_d = mapper.sortDirection) !== null && _d !== void 0 ? _d : sortDirection;
filter = (_e = mapper.filter) !== null && _e !== void 0 ? _e : filter;
list = (_f = mapper.list) !== null && _f !== void 0 ? _f : list;
total = (_g = mapper.total) !== null && _g !== void 0 ? _g : total;
}
statements.push(`const response = await this.${memberName}.execute({
parameters: {
${pageIndex}: pageIndex,
${pageSize}: pageSize,
${sortBy}: sortBy,
${sortDirection}: sortDirection,
filter: ${filter ?
`filter.map((item) => \`\${ item.column }${filter.eq}\${ item.filter }\`).join('${filter.join}')` :
'filter'},
},
});`, 'return {', ` list: response.${list} ?? [],`, ` total: response.${total} ?? 0,`, '};');
}
else {
statements.push('return {', ' list: [],', ' total: 0,', '};');
}
(0, ts_morph_1.CoerceClassMethod)(classDeclaration, 'getPageData', {
scope: ts_morph_2.Scope.Public,
returnType: w => {
w.write('Promise<');
ts_morph_2.Writers.object({
list: (0, write_type_1.WriteType)({
isArray: true,
type: GetRawRowDataType(options),
}, sourceFile),
total: 'number',
})(w);
w.write('>');
},
isAsync: true,
parameters: [
{
name: 'sortBy',
type: 'string',
},
{
name: 'sortDirection',
type: 'string',
},
{
name: 'pageSize',
type: 'number',
},
{
name: 'pageIndex',
type: 'number',
},
{
name: 'filter',
type: 'FilterQuery[]',
},
],
statements: statements,
});
}
function GetResponseTypeFromUpstream(upstream) {
var _a;
if ((0, ts_morph_1.IsNormalizedOpenApiUpstreamOptions)(upstream)) {
const { mapper } = upstream;
let list = 'list';
if (mapper && (0, ts_morph_1.IsNormalizedPagedRequestMapper)(mapper)) {
list = (_a = mapper.list) !== null && _a !== void 0 ? _a : list;
}
const className = (0, ts_morph_1.OperationIdToResponseClassName)(upstream.operationId);
return {
name: `${className}['${list}'][number]`,
namedImport: className,
moduleSpecifier: (0, ts_morph_1.OperationIdToResponseClassImportPath)(upstream.operationId, upstream.scope),
};
}
throw new Error(`Upstream kind '${upstream.kind}' not supported`);
}
function GetRawRowDataType(options) {
const { upstream } = options;
if (upstream && (0, ts_morph_1.IsNormalizedOpenApiUpstreamOptions)(upstream)) {
return GetResponseTypeFromUpstream(upstream);
}
return {
name: 'RawRowData',
};
}
function BuildGetPageGetDataImplementation(classDeclaration, moduleSourceFile, dto, options) {
return (operationOptions) => {
var _a;
(_a = operationOptions.statements) !== null && _a !== void 0 ? _a : (operationOptions.statements = []);
operationOptions.statements = (0, utilities_1.coerceArray)(operationOptions.statements);
operationOptions.statements.push('const data = await this.getPageData(sortBy, sortDirection, pageSize, pageIndex, filter);');
};
}
function CoerceGetPageOperationDtoClass(classDeclaration, controllerName, moduleSourceFile, options) {
const sourceFile = classDeclaration.getSourceFile();
const project = sourceFile.getProject();
const { propertyList, coerceToRowDtoMethod = CoerceToRowDtoMethod, coerceToPageDtoMethod = CoerceToPageDtoMethod, coerceGetPageDataMethod = CoerceGetPageDataMethod, buildOperationDtoClassName = ts_morph_3.BuildOperationDtoClassName, dtoClassName = buildOperationDtoClassName(controllerName, options), rowId, } = options;
const { className: rowClassName, filePath: rowFilePath, } = (0, coerce_row_dto_class_1.CoerceRowDtoClass)({
project,
name: dtoClassName,
propertyList,
rowIdType: rowId === null || rowId === void 0 ? void 0 : rowId.type,
});
(0, ts_morph_1.CoerceImports)(sourceFile, {
namedImports: [rowClassName],
moduleSpecifier: rowFilePath,
});
const dto = (0, coerce_page_dto_class_1.CoercePageDtoClass)({
project,
name: dtoClassName,
rowClassName,
rowFilePath,
});
const { className: pageClassName } = dto;
coerceGetPageDataMethod(sourceFile, classDeclaration, moduleSourceFile, options);
coerceToRowDtoMethod(sourceFile, classDeclaration, rowClassName, options);
coerceToPageDtoMethod(sourceFile, classDeclaration, pageClassName, rowClassName, options);
return dto;
}
function BuiltGetPageDtoDataMapperImplementation(classDeclaration, moduleSourceFile, dto, options) {
return () => {
return 'this.toPageDto(data.list, data.total, pageIndex, pageSize, sortBy, sortDirection, filter)';
};
}
function CoerceGetPageOperation(options) {
var _a;
const { operationName = 'get-page', tsMorphTransform = utilities_1.noop, upstream, builtDtoDataMapperImplementation = BuiltGetPageDtoDataMapperImplementation, coerceOperationDtoClass = CoerceGetPageOperationDtoClass, buildGetDataImplementation = BuildGetPageGetDataImplementation, idProperty, nestModule, controllerName, propertyList = [], paramList: paramList = [], } = options;
if (idProperty) {
/**
* If the module is not specified. This controller has an own module. Else the
* module is originated by another controller.
*
* **Example**
* true:
* The controller ReportDetailsController should be extended with getById Operation.
* And the controller is used in the module ReportDetailsModule
*
* name = "report-details"
* module = undefined
*
* false:
* The controller ReportDetailsNotificationController should be extend with getById Operation.
* And the controller ise used in the module ReportDetailsModule
*
* name = "notification"
* module = "report-details"
*/
const isFirstBornSibling = !nestModule || nestModule === controllerName;
// if (isFirstBornSibling) {
// CoerceArrayItems(propertyList, [{
// name: idProperty.name,
// type: idProperty.type ?? 'string',
// isArray: idProperty.isArray,
// }], (a, b) => a.name === b.name, true);
// }
(0, utilities_1.CoerceArrayItems)(paramList, [{
name: idProperty.name,
type: idProperty.type,
fromParent: (_a = idProperty.fromParent) !== null && _a !== void 0 ? _a : !isFirstBornSibling,
}], (a, b) => a.name === b.name, true);
}
return (0, coerce_operation_1.CoerceOperation)(Object.assign(Object.assign({}, options), { propertyList,
paramList,
operationName,
builtDtoDataMapperImplementation,
coerceOperationDtoClass,
buildGetDataImplementation, tsMorphTransform: (project, sourceFile, classDeclaration, controllerName, moduleSourceFile) => {
if (!upstream || !(0, ts_morph_1.IsNormalizedOpenApiUpstreamOptions)(upstream)) {
(0, coerce_type_alias_1.CoerceTypeAlias)(sourceFile, 'RawRowData', {
isExported: false,
type: 'any',
});
}
return Object.assign({ queryList: table_query_list_1.TABLE_QUERY_LIST }, tsMorphTransform(project, sourceFile, classDeclaration, controllerName, moduleSourceFile, (0, coerce_page_dto_class_1.BuildPageDtoClassName)((0, ts_morph_3.BuildOperationDtoClassName)(controllerName, options)), (0, coerce_row_dto_class_1.BuildRowDtoClassName)((0, ts_morph_3.BuildOperationDtoClassName)(controllerName, options))));
} }));
}
//# sourceMappingURL=coerce-get-page-operation.js.map