@nestjs/graphql
Version:
Nest - modern, fast, powerful node.js web framework (@graphql)
201 lines (200 loc) • 7.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractTypeArgumentIfArray = exports.isAutoGeneratedTypeUnion = exports.isAutoGeneratedEnumUnion = exports.isDynamicallyAdded = exports.replaceImportPath = exports.hasPropertyKey = exports.isPromiseOrObservable = exports.getTypeReferenceAsString = exports.getDecoratorOrUndefinedByNames = void 0;
const lodash_1 = require("lodash");
const path_1 = require("path");
const ts = require("typescript");
const ast_utils_1 = require("./ast-utils");
function getDecoratorOrUndefinedByNames(names, decorators) {
return (decorators || ts.createNodeArray()).find((item) => names.includes((0, ast_utils_1.getDecoratorName)(item)));
}
exports.getDecoratorOrUndefinedByNames = getDecoratorOrUndefinedByNames;
function getTypeReferenceAsString(type, typeChecker) {
if ((0, ast_utils_1.isArray)(type)) {
const arrayType = (0, ast_utils_1.getTypeArguments)(type)[0];
const elementType = getTypeReferenceAsString(arrayType, typeChecker);
if (!elementType) {
return undefined;
}
return `[${elementType}]`;
}
if ((0, ast_utils_1.isBoolean)(type)) {
return Boolean.name;
}
if ((0, ast_utils_1.isNumber)(type)) {
return Number.name;
}
if ((0, ast_utils_1.isString)(type)) {
return String.name;
}
if (isPromiseOrObservable((0, ast_utils_1.getText)(type, typeChecker))) {
const typeArguments = (0, ast_utils_1.getTypeArguments)(type);
const elementType = getTypeReferenceAsString((0, lodash_1.head)(typeArguments), typeChecker);
if (!elementType) {
return undefined;
}
return elementType;
}
if (type.isClass()) {
return (0, ast_utils_1.getText)(type, typeChecker);
}
try {
const text = (0, ast_utils_1.getText)(type, typeChecker);
if (text === Date.name) {
return text;
}
if (isOptionalBoolean(text)) {
return Boolean.name;
}
if ((0, ast_utils_1.isEnum)(type)) {
return text;
}
const isEnumMember = type.symbol && type.symbol.flags === ts.SymbolFlags.EnumMember;
if (isEnumMember) {
type = typeChecker.getDeclaredTypeOfSymbol(type.symbol.parent);
if (!type) {
return undefined;
}
return text;
}
if (isAutoGeneratedTypeUnion(type) ||
isAutoGeneratedEnumUnion(type, typeChecker)) {
const types = type.types;
return getTypeReferenceAsString(types[types.length - 1], typeChecker);
}
if (text === 'any' ||
text === 'unknown' ||
text === 'object' ||
(0, ast_utils_1.isInterface)(type) ||
(type.isUnionOrIntersection() && !(0, ast_utils_1.isEnum)(type))) {
return 'Object';
}
if (type.aliasSymbol) {
return 'Object';
}
return 'Object';
}
catch (_a) {
return 'Object';
}
}
exports.getTypeReferenceAsString = getTypeReferenceAsString;
function isPromiseOrObservable(type) {
return type.includes('Promise') || type.includes('Observable');
}
exports.isPromiseOrObservable = isPromiseOrObservable;
function hasPropertyKey(key, properties) {
return properties
.filter((item) => !isDynamicallyAdded(item))
.some((item) => item.name.getText() === key);
}
exports.hasPropertyKey = hasPropertyKey;
function replaceImportPath(typeReference, fileName) {
if (!typeReference.includes('import')) {
return typeReference;
}
let importPath = /\(\"([^)]).+(\")/.exec(typeReference)[0];
if (!importPath) {
return undefined;
}
importPath = convertPath(importPath);
importPath = importPath.slice(2, importPath.length - 1);
let relativePath = path_1.posix.relative(path_1.posix.dirname(fileName), importPath);
relativePath = relativePath[0] !== '.' ? './' + relativePath : relativePath;
const nodeModulesText = 'node_modules';
const nodeModulePos = relativePath.indexOf(nodeModulesText);
if (nodeModulePos >= 0) {
relativePath = relativePath.slice(nodeModulePos + nodeModulesText.length + 1);
const typesText = '@types';
const typesPos = relativePath.indexOf(typesText);
if (typesPos >= 0) {
relativePath = relativePath.slice(typesPos + typesText.length + 1);
}
const indexText = '/index';
const indexPos = relativePath.indexOf(indexText);
if (indexPos >= 0) {
relativePath = relativePath.slice(0, indexPos);
}
}
typeReference = typeReference.replace(importPath, relativePath);
return typeReference.replace('import', 'require');
}
exports.replaceImportPath = replaceImportPath;
function isDynamicallyAdded(identifier) {
return identifier && !identifier.parent && identifier.pos === -1;
}
exports.isDynamicallyAdded = isDynamicallyAdded;
function isAutoGeneratedEnumUnion(type, typeChecker) {
if (type.isUnionOrIntersection() && !(0, ast_utils_1.isEnum)(type)) {
if (!type.types) {
return undefined;
}
const undefinedTypeIndex = type.types.findIndex((type) => type.intrinsicName === 'undefined');
if (undefinedTypeIndex < 0) {
return undefined;
}
let parentType = undefined;
const isParentSymbolEqual = type.types.every((item, index) => {
if (index === undefinedTypeIndex) {
return true;
}
if (!item.symbol) {
return false;
}
if (!item.symbol.parent ||
item.symbol.flags !== ts.SymbolFlags.EnumMember) {
return false;
}
const symbolType = typeChecker.getDeclaredTypeOfSymbol(item.symbol.parent);
if (symbolType === parentType || !parentType) {
parentType = symbolType;
return true;
}
return false;
});
if (isParentSymbolEqual) {
return parentType;
}
}
return undefined;
}
exports.isAutoGeneratedEnumUnion = isAutoGeneratedEnumUnion;
function isAutoGeneratedTypeUnion(type) {
if (type.isUnionOrIntersection() && !(0, ast_utils_1.isEnum)(type)) {
if (!type.types) {
return false;
}
const undefinedTypeIndex = type.types.findIndex((type) => type.intrinsicName === 'undefined');
if (type.types.length === 2 && undefinedTypeIndex >= 0) {
return true;
}
}
return false;
}
exports.isAutoGeneratedTypeUnion = isAutoGeneratedTypeUnion;
function extractTypeArgumentIfArray(type) {
if ((0, ast_utils_1.isArray)(type)) {
type = (0, ast_utils_1.getTypeArguments)(type)[0];
if (!type) {
return undefined;
}
return {
type,
isArray: true,
};
}
return {
type,
isArray: false,
};
}
exports.extractTypeArgumentIfArray = extractTypeArgumentIfArray;
function isOptionalBoolean(text) {
return typeof text === 'string' && text === 'boolean | undefined';
}
function convertPath(windowsPath) {
return windowsPath
.replace(/^\\\\\?\\/, '')
.replace(/\\/g, '/')
.replace(/\/\/+/g, '/');
}