UNPKG

@nestjs/swagger

Version:

Nest - modern, fast, powerful node.js web framework (@swagger)

213 lines (212 loc) 7.58 kB
"use strict"; 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) => { try { const decoratorName = ast_utils_1.getDecoratorName(item); return names.includes(decoratorName); } catch (_a) { return false; } }); } exports.getDecoratorOrUndefinedByNames = getDecoratorOrUndefinedByNames; function getTypeReferenceAsString(type, typeChecker) { if (ast_utils_1.isArray(type)) { const arrayType = ast_utils_1.getTypeArguments(type)[0]; const elementType = getTypeReferenceAsString(arrayType, typeChecker); if (!elementType) { return undefined; } return `[${elementType}]`; } if (ast_utils_1.isBoolean(type)) { return Boolean.name; } if (ast_utils_1.isNumber(type)) { return Number.name; } if (ast_utils_1.isBigInt(type)) { return BigInt.name; } if (ast_utils_1.isString(type) || ast_utils_1.isStringLiteral(type)) { return String.name; } if (isPromiseOrObservable(ast_utils_1.getText(type, typeChecker))) { const typeArguments = ast_utils_1.getTypeArguments(type); const elementType = getTypeReferenceAsString(lodash_1.head(typeArguments), typeChecker); if (!elementType) { return undefined; } return elementType; } if (type.isClass()) { return ast_utils_1.getText(type, typeChecker); } try { const text = ast_utils_1.getText(type, typeChecker); if (text === Date.name) { return text; } if (isOptionalBoolean(text)) { return Boolean.name; } if (isAutoGeneratedTypeUnion(type) || isAutoGeneratedEnumUnion(type, typeChecker)) { const types = type.types; return getTypeReferenceAsString(types[types.length - 1], typeChecker); } if (text === 'any' || text === 'unknown' || text === 'object' || ast_utils_1.isInterface(type) || (type.isUnionOrIntersection() && !ast_utils_1.isEnum(type))) { return 'Object'; } if (ast_utils_1.isEnum(type)) { return undefined; } if (type.aliasSymbol) { return 'Object'; } return undefined; } catch (_a) { return undefined; } } 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); try { if (path_1.isAbsolute(importPath)) { throw {}; } require.resolve(importPath); return typeReference.replace('import', 'require'); } catch (_error) { 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() && !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() && !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 (ast_utils_1.isArray(type)) { type = 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, '/'); }