🎯 MapView v2.0 - Global Deployment Ready

 MAJOR FEATURES:
• Auto-zoom intelligence với smart bounds fitting
• Enhanced 3D GPS markers với pulsing effects
• Professional route display với 6-layer rendering
• Status-based parking icons với availability indicators
• Production-ready build optimizations

🗺️ AUTO-ZOOM FEATURES:
• Smart bounds fitting cho GPS + selected parking
• Adaptive padding (50px) cho visual balance
• Max zoom control (level 16) để tránh quá gần
• Dynamic centering khi không có selection

🎨 ENHANCED VISUALS:
• 3D GPS marker với multi-layer pulse effects
• Advanced parking icons với status colors
• Selection highlighting với animation
• Dimming system cho non-selected items

🛣️ ROUTE SYSTEM:
• OpenRouteService API integration
• Multi-layer route rendering (glow, shadow, main, animated)
• Real-time distance & duration calculation
• Visual route info trong popup

📱 PRODUCTION READY:
• SSR safe với dynamic imports
• Build errors resolved
• Global deployment via Vercel
• Optimized performance

🌍 DEPLOYMENT:
• Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app
• Bundle size: 22.8 kB optimized
• Global CDN distribution
• HTTPS enabled

💾 VERSION CONTROL:
• MapView-v2.0.tsx backup created
• MAPVIEW_VERSIONS.md documentation
• Full version history tracking
This commit is contained in:
2025-07-20 19:52:16 +07:00
parent 3203463a6a
commit c65cc97a33
64624 changed files with 7199453 additions and 6462 deletions

View File

@@ -0,0 +1,30 @@
import * as ts from 'typescript';
import { Decorator, Node, ObjectFlags, SourceFile, Type, TypeChecker, TypeFlags, TypeFormatFlags, UnionTypeNode } from 'typescript';
import { DocNode, DocComment } from '@microsoft/tsdoc';
export declare function renderDocNode(docNode: DocNode): string;
export declare function isArray(type: Type): boolean;
export declare function getTypeArguments(type: Type): any;
export declare function isBoolean(type: Type): boolean;
export declare function isString(type: Type): boolean;
export declare function isStringLiteral(type: Type): boolean;
export declare function isStringMapping(type: Type): boolean;
export declare function isNumber(type: Type): boolean;
export declare function isBigInt(type: Type): boolean;
export declare function isInterface(type: Type): boolean;
export declare function isEnum(type: Type): boolean;
export declare function isEnumLiteral(type: Type): boolean;
export declare function hasFlag(type: Type, flag: TypeFlags): boolean;
export declare function hasObjectFlag(type: Type, flag: ObjectFlags): boolean;
export declare function getText(type: Type, typeChecker: TypeChecker, enclosingNode?: Node, typeFormatFlags?: TypeFormatFlags): string;
export declare function getDefaultTypeFormatFlags(enclosingNode: Node): number;
export declare function getDocComment(node: Node): DocComment;
export declare function getMainCommentOfNode(node: Node, sourceFile: SourceFile): string;
export declare function parseCommentDocValue(docValue: string, type: ts.Type): string;
export declare function getTsDocTagsOfNode(node: Node, typeChecker: TypeChecker): any;
export declare function getTsDocErrorsOfNode(node: Node): any[];
export declare function getDecoratorArguments(decorator: Decorator): any[] | ts.NodeArray<ts.Expression>;
export declare function getDecoratorName(decorator: Decorator): string;
export declare function findNullableTypeFromUnion(typeNode: UnionTypeNode, typeChecker: TypeChecker): ts.TypeNode;
export declare function createBooleanLiteral(factory: ts.NodeFactory, flag: boolean): ts.BooleanLiteral;
export declare function createPrimitiveLiteral(factory: ts.NodeFactory, item: unknown, typeOfItem?: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"): ts.StringLiteral | ts.NumericLiteral | ts.PrefixUnaryExpression | ts.BooleanLiteral;
export declare function createLiteralFromAnyValue(factory: ts.NodeFactory, item: unknown): any;

View File

@@ -0,0 +1,270 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLiteralFromAnyValue = exports.createPrimitiveLiteral = exports.createBooleanLiteral = exports.findNullableTypeFromUnion = exports.getDecoratorName = exports.getDecoratorArguments = exports.getTsDocErrorsOfNode = exports.getTsDocTagsOfNode = exports.parseCommentDocValue = exports.getMainCommentOfNode = exports.getDocComment = exports.getDefaultTypeFormatFlags = exports.getText = exports.hasObjectFlag = exports.hasFlag = exports.isEnumLiteral = exports.isEnum = exports.isInterface = exports.isBigInt = exports.isNumber = exports.isStringMapping = exports.isStringLiteral = exports.isString = exports.isBoolean = exports.getTypeArguments = exports.isArray = exports.renderDocNode = void 0;
const typescript_1 = require("typescript");
const plugin_utils_1 = require("./plugin-utils");
const tsdoc_1 = require("@microsoft/tsdoc");
function renderDocNode(docNode) {
let result = '';
if (docNode) {
if (docNode instanceof tsdoc_1.DocExcerpt) {
result += docNode.content.toString();
}
for (const childNode of docNode.getChildNodes()) {
result += renderDocNode(childNode);
}
}
return result;
}
exports.renderDocNode = renderDocNode;
function isArray(type) {
const symbol = type.getSymbol();
if (!symbol) {
return false;
}
return symbol.getName() === 'Array' && getTypeArguments(type).length === 1;
}
exports.isArray = isArray;
function getTypeArguments(type) {
return type.typeArguments || [];
}
exports.getTypeArguments = getTypeArguments;
function isBoolean(type) {
return hasFlag(type, typescript_1.TypeFlags.Boolean);
}
exports.isBoolean = isBoolean;
function isString(type) {
return hasFlag(type, typescript_1.TypeFlags.String);
}
exports.isString = isString;
function isStringLiteral(type) {
return hasFlag(type, typescript_1.TypeFlags.StringLiteral) && !type.isUnion();
}
exports.isStringLiteral = isStringLiteral;
function isStringMapping(type) {
return hasFlag(type, typescript_1.TypeFlags.StringMapping);
}
exports.isStringMapping = isStringMapping;
function isNumber(type) {
return hasFlag(type, typescript_1.TypeFlags.Number);
}
exports.isNumber = isNumber;
function isBigInt(type) {
return hasFlag(type, typescript_1.TypeFlags.BigInt);
}
exports.isBigInt = isBigInt;
function isInterface(type) {
return hasObjectFlag(type, typescript_1.ObjectFlags.Interface);
}
exports.isInterface = isInterface;
function isEnum(type) {
const hasEnumFlag = hasFlag(type, typescript_1.TypeFlags.Enum);
if (hasEnumFlag) {
return true;
}
if (isEnumLiteral(type)) {
return false;
}
const symbol = type.getSymbol();
if (!symbol) {
return false;
}
const valueDeclaration = symbol.valueDeclaration;
if (!valueDeclaration) {
return false;
}
return valueDeclaration.kind === typescript_1.SyntaxKind.EnumDeclaration;
}
exports.isEnum = isEnum;
function isEnumLiteral(type) {
return hasFlag(type, typescript_1.TypeFlags.EnumLiteral) && !type.isUnion();
}
exports.isEnumLiteral = isEnumLiteral;
function hasFlag(type, flag) {
return (type.flags & flag) === flag;
}
exports.hasFlag = hasFlag;
function hasObjectFlag(type, flag) {
return (type.objectFlags & flag) === flag;
}
exports.hasObjectFlag = hasObjectFlag;
function getText(type, typeChecker, enclosingNode, typeFormatFlags) {
if (!typeFormatFlags) {
typeFormatFlags = getDefaultTypeFormatFlags(enclosingNode);
}
const compilerNode = !enclosingNode ? undefined : enclosingNode;
return typeChecker.typeToString(type, compilerNode, typeFormatFlags);
}
exports.getText = getText;
function getDefaultTypeFormatFlags(enclosingNode) {
let formatFlags = typescript_1.TypeFormatFlags.UseTypeOfFunction |
typescript_1.TypeFormatFlags.NoTruncation |
typescript_1.TypeFormatFlags.UseFullyQualifiedType |
typescript_1.TypeFormatFlags.WriteTypeArgumentsOfSignature;
if (enclosingNode && enclosingNode.kind === typescript_1.SyntaxKind.TypeAliasDeclaration)
formatFlags |= typescript_1.TypeFormatFlags.InTypeAlias;
return formatFlags;
}
exports.getDefaultTypeFormatFlags = getDefaultTypeFormatFlags;
function getDocComment(node) {
const tsdocParser = new tsdoc_1.TSDocParser();
const parserContext = tsdocParser.parseString(node.getFullText());
return parserContext.docComment;
}
exports.getDocComment = getDocComment;
function getMainCommentOfNode(node, sourceFile) {
const docComment = getDocComment(node);
return renderDocNode(docComment.summarySection).trim();
}
exports.getMainCommentOfNode = getMainCommentOfNode;
function parseCommentDocValue(docValue, type) {
let value = docValue.replace(/'/g, '"').trim();
if (!type || !isString(type)) {
try {
value = JSON.parse(value);
}
catch (_a) { }
}
else if (isString(type)) {
if (value.split(' ').length !== 1 && !value.startsWith('"')) {
value = null;
}
else {
value = value.replace(/"/g, '');
}
}
return value;
}
exports.parseCommentDocValue = parseCommentDocValue;
function getTsDocTagsOfNode(node, typeChecker) {
const docComment = getDocComment(node);
const tagDefinitions = {
example: {
hasProperties: true,
repeatable: true
}
};
const tagResults = {};
const introspectTsDocTags = (docComment) => {
for (const tag in tagDefinitions) {
const { hasProperties, repeatable } = tagDefinitions[tag];
const blocks = docComment.customBlocks.filter((block) => block.blockTag.tagName === `@${tag}`);
if (blocks.length === 0)
continue;
if (repeatable && !tagResults[tag])
tagResults[tag] = [];
const type = typeChecker.getTypeAtLocation(node);
if (hasProperties) {
blocks.forEach((block) => {
const docValue = renderDocNode(block.content).split('\n')[0];
const value = parseCommentDocValue(docValue, type);
if (value !== null) {
if (repeatable) {
tagResults[tag].push(value);
}
else {
tagResults[tag] = value;
}
}
});
}
else {
tagResults[tag] = true;
}
}
if (docComment.remarksBlock) {
tagResults['remarks'] = renderDocNode(docComment.remarksBlock.content).trim();
}
if (docComment.deprecatedBlock) {
tagResults['deprecated'] = true;
}
};
introspectTsDocTags(docComment);
return tagResults;
}
exports.getTsDocTagsOfNode = getTsDocTagsOfNode;
function getTsDocErrorsOfNode(node) {
const tsdocParser = new tsdoc_1.TSDocParser();
const parserContext = tsdocParser.parseString(node.getFullText());
const docComment = parserContext.docComment;
const tagResults = [];
const errorParsingRegex = /{(\d+)} (.*)/;
const introspectTsDocTags = (docComment) => {
const blocks = docComment.customBlocks.filter((block) => block.blockTag.tagName === '@throws');
blocks.forEach((block) => {
try {
const docValue = renderDocNode(block.content).split('\n')[0].trim();
const match = docValue.match(errorParsingRegex);
tagResults.push({
status: match[1],
description: `"${match[2]}"`
});
}
catch (err) { }
});
};
introspectTsDocTags(docComment);
return tagResults;
}
exports.getTsDocErrorsOfNode = getTsDocErrorsOfNode;
function getDecoratorArguments(decorator) {
const callExpression = decorator.expression;
return (callExpression && callExpression.arguments) || [];
}
exports.getDecoratorArguments = getDecoratorArguments;
function getDecoratorName(decorator) {
const isDecoratorFactory = decorator.expression.kind === typescript_1.SyntaxKind.CallExpression;
if (isDecoratorFactory) {
const callExpression = decorator.expression;
const identifier = callExpression
.expression;
if ((0, plugin_utils_1.isDynamicallyAdded)(identifier)) {
return undefined;
}
return getIdentifierFromName(callExpression.expression).getText();
}
return getIdentifierFromName(decorator.expression).getText();
}
exports.getDecoratorName = getDecoratorName;
function getIdentifierFromName(expression) {
const identifier = getNameFromExpression(expression);
if (expression && expression.kind !== typescript_1.SyntaxKind.Identifier) {
throw new Error();
}
return identifier;
}
function getNameFromExpression(expression) {
if (expression && expression.kind === typescript_1.SyntaxKind.PropertyAccessExpression) {
return expression.name;
}
return expression;
}
function findNullableTypeFromUnion(typeNode, typeChecker) {
return typeNode.types.find((tNode) => hasFlag(typeChecker.getTypeAtLocation(tNode), typescript_1.TypeFlags.Null));
}
exports.findNullableTypeFromUnion = findNullableTypeFromUnion;
function createBooleanLiteral(factory, flag) {
return flag ? factory.createTrue() : factory.createFalse();
}
exports.createBooleanLiteral = createBooleanLiteral;
function createPrimitiveLiteral(factory, item, typeOfItem = typeof item) {
switch (typeOfItem) {
case 'boolean':
return createBooleanLiteral(factory, item);
case 'number': {
if (item < 0) {
return factory.createPrefixUnaryExpression(typescript_1.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(item)));
}
return factory.createNumericLiteral(item);
}
case 'string':
return factory.createStringLiteral(item);
}
}
exports.createPrimitiveLiteral = createPrimitiveLiteral;
function createLiteralFromAnyValue(factory, item) {
return Array.isArray(item)
? factory.createArrayLiteralExpression(item.map((item) => createLiteralFromAnyValue(factory, item)))
: createPrimitiveLiteral(factory, item);
}
exports.createLiteralFromAnyValue = createLiteralFromAnyValue;

View File

@@ -0,0 +1 @@
export declare const isFilenameMatched: (patterns: string[], filename: string) => boolean;

View File

@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isFilenameMatched = void 0;
const isFilenameMatched = (patterns, filename) => patterns.some((path) => filename.includes(path));
exports.isFilenameMatched = isFilenameMatched;

View File

@@ -0,0 +1,29 @@
import * as ts from 'typescript';
import { PluginOptions } from '../merge-options';
export declare function getDecoratorOrUndefinedByNames(names: string[], decorators: readonly ts.Decorator[], factory: ts.NodeFactory): ts.Decorator | undefined;
export declare function getTypeReferenceAsString(type: ts.Type, typeChecker: ts.TypeChecker, arrayDepth?: number): {
typeName: string;
isArray?: boolean;
arrayDepth?: number;
};
export declare function isPromiseOrObservable(type: string): boolean;
export declare function hasPropertyKey(key: string, properties: ts.NodeArray<ts.PropertyAssignment>): boolean;
export declare function replaceImportPath(typeReference: string, fileName: string, options: PluginOptions): {
typeReference: string;
typeName: string;
importPath: string;
} | {
typeReference: string;
importPath: string;
typeName?: undefined;
};
export declare function insertAt(string: string, index: number, substring: string): string;
export declare function isDynamicallyAdded(identifier: ts.Node): boolean;
export declare function isAutoGeneratedEnumUnion(type: ts.Type, typeChecker: ts.TypeChecker): ts.Type;
export declare function isAutoGeneratedTypeUnion(type: ts.Type): boolean;
export declare function extractTypeArgumentIfArray(type: ts.Type): {
type: ts.Type;
isArray: boolean;
};
export declare function convertPath(windowsPath: string): string;
export declare function canReferenceNode(node: ts.Node, options: PluginOptions): boolean;

View File

@@ -0,0 +1,279 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.canReferenceNode = exports.convertPath = exports.extractTypeArgumentIfArray = exports.isAutoGeneratedTypeUnion = exports.isAutoGeneratedEnumUnion = exports.isDynamicallyAdded = exports.insertAt = 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, factory) {
return (decorators || factory.createNodeArray()).find((item) => {
try {
const decoratorName = (0, ast_utils_1.getDecoratorName)(item);
return names.includes(decoratorName);
}
catch (_a) {
return false;
}
});
}
exports.getDecoratorOrUndefinedByNames = getDecoratorOrUndefinedByNames;
function getTypeReferenceAsString(type, typeChecker, arrayDepth = 0) {
if ((0, ast_utils_1.isArray)(type)) {
const arrayType = (0, ast_utils_1.getTypeArguments)(type)[0];
const { typeName, arrayDepth: depth } = getTypeReferenceAsString(arrayType, typeChecker, arrayDepth + 1);
if (!typeName) {
return { typeName: undefined };
}
return {
typeName: `${typeName}`,
isArray: true,
arrayDepth: depth
};
}
if ((0, ast_utils_1.isBoolean)(type)) {
return { typeName: Boolean.name, arrayDepth };
}
if ((0, ast_utils_1.isNumber)(type)) {
return { typeName: Number.name, arrayDepth };
}
if ((0, ast_utils_1.isBigInt)(type)) {
return { typeName: BigInt.name, arrayDepth };
}
if ((0, ast_utils_1.isString)(type) || (0, ast_utils_1.isStringLiteral)(type) || (0, ast_utils_1.isStringMapping)(type)) {
return { typeName: String.name, arrayDepth };
}
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, arrayDepth);
return elementType;
}
if (type.isClass()) {
return { typeName: (0, ast_utils_1.getText)(type, typeChecker), arrayDepth };
}
try {
const text = (0, ast_utils_1.getText)(type, typeChecker);
if (text === Date.name) {
return { typeName: text, arrayDepth };
}
if (isOptionalBoolean(text)) {
return { typeName: Boolean.name, arrayDepth };
}
if (isAutoGeneratedTypeUnion(type) ||
isAutoGeneratedEnumUnion(type, typeChecker)) {
const types = type.types;
return getTypeReferenceAsString(types[types.length - 1], typeChecker, arrayDepth);
}
if (text === 'any' ||
text === 'unknown' ||
text === 'object' ||
(0, ast_utils_1.isInterface)(type) ||
(type.isUnionOrIntersection() && !(0, ast_utils_1.isEnum)(type))) {
return { typeName: 'Object', arrayDepth };
}
if ((0, ast_utils_1.isEnum)(type)) {
return { typeName: undefined, arrayDepth };
}
if (type.aliasSymbol) {
return { typeName: 'Object', arrayDepth };
}
if (typeChecker.getApparentType(type).getSymbol().getEscapedName() === 'String') {
return { typeName: String.name, arrayDepth };
}
return { typeName: undefined };
}
catch (_a) {
return { typeName: 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, options) {
if (!typeReference.includes('import')) {
return { typeReference, importPath: null };
}
let importPath = /\(\"([^)]).+(\")/.exec(typeReference)[0];
if (!importPath) {
return { typeReference: undefined, importPath: null };
}
importPath = convertPath(importPath);
importPath = importPath.slice(2, importPath.length - 1);
try {
if ((0, path_1.isAbsolute)(importPath)) {
throw {};
}
require.resolve(importPath);
typeReference = typeReference.replace('import', 'require');
return {
typeReference,
importPath: null
};
}
catch (_error) {
const from = (options === null || options === void 0 ? void 0 : options.readonly)
? convertPath(options.pathToSource)
: path_1.posix.dirname(convertPath(fileName));
let relativePath = path_1.posix.relative(from, 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);
if (options.readonly) {
const { typeName, typeImportStatement } = convertToAsyncImport(typeReference);
return {
typeReference: typeImportStatement,
typeName,
importPath: relativePath
};
}
return {
typeReference: typeReference.replace('import', 'require'),
importPath: relativePath
};
}
}
exports.replaceImportPath = replaceImportPath;
function convertToAsyncImport(typeReference) {
const regexp = /import\(.+\).([^\]]+)(\])?/;
const match = regexp.exec(typeReference);
if ((match === null || match === void 0 ? void 0 : match.length) >= 2) {
const importPos = typeReference.indexOf(match[0]);
typeReference = typeReference.replace(`.${match[1]}`, '');
return {
typeImportStatement: insertAt(typeReference, importPos, 'await '),
typeName: match[1]
};
}
return { typeImportStatement: typeReference };
}
function insertAt(string, index, substring) {
return string.slice(0, index) + substring + string.slice(index);
}
exports.insertAt = insertAt;
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' || type.intrinsicName === 'null');
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, '/');
}
exports.convertPath = convertPath;
function canReferenceNode(node, options) {
var _a;
if (!options.readonly) {
return true;
}
if (ts.isCallExpression(node) || ts.isIdentifier(node)) {
return false;
}
if (ts.isNewExpression(node)) {
if (((_a = node.expression) === null || _a === void 0 ? void 0 : _a.escapedText) === 'Date') {
return true;
}
return false;
}
if (node.kind === ts.SyntaxKind.FalseKeyword ||
node.kind === ts.SyntaxKind.TrueKeyword ||
node.kind === ts.SyntaxKind.NullKeyword) {
return true;
}
if (ts.isNumericLiteral(node) ||
ts.isPrefixUnaryExpression(node) ||
ts.isStringLiteral(node)) {
return true;
}
return false;
}
exports.canReferenceNode = canReferenceNode;

View File

@@ -0,0 +1,7 @@
import * as ts from 'typescript';
import { PluginOptions } from '../merge-options';
export declare function typeReferenceToIdentifier(typeReferenceDescriptor: {
typeName: string;
isArray?: boolean;
arrayDepth?: number;
}, hostFilename: string, options: PluginOptions, factory: ts.NodeFactory, type: ts.Type, typeImports: Record<string, string>): ts.Identifier;

View File

@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.typeReferenceToIdentifier = void 0;
const plugin_debug_logger_1 = require("../plugin-debug-logger");
const plugin_utils_1 = require("./plugin-utils");
function typeReferenceToIdentifier(typeReferenceDescriptor, hostFilename, options, factory, type, typeImports) {
if (options.readonly) {
assertReferenceableType(type, typeReferenceDescriptor.typeName, hostFilename, options);
}
const { typeReference, importPath, typeName } = (0, plugin_utils_1.replaceImportPath)(typeReferenceDescriptor.typeName, hostFilename, options);
let identifier;
if (options.readonly && (typeReference === null || typeReference === void 0 ? void 0 : typeReference.includes('import'))) {
if (!typeImports[importPath]) {
typeImports[importPath] = typeReference;
}
let ref = `t["${importPath}"].${typeName}`;
if (typeReferenceDescriptor.isArray) {
ref = wrapTypeInArray(ref, typeReferenceDescriptor.arrayDepth);
}
identifier = factory.createIdentifier(ref);
}
else {
let ref = typeReference;
if (typeReferenceDescriptor.isArray) {
ref = wrapTypeInArray(ref, typeReferenceDescriptor.arrayDepth);
}
identifier = factory.createIdentifier(ref);
}
return identifier;
}
exports.typeReferenceToIdentifier = typeReferenceToIdentifier;
function wrapTypeInArray(typeRef, arrayDepth) {
for (let i = 0; i < arrayDepth; i++) {
typeRef = `[${typeRef}]`;
}
return typeRef;
}
function assertReferenceableType(type, parsedTypeName, hostFilename, options) {
if (!type.symbol) {
return true;
}
if (!type.symbol.isReferenced) {
return true;
}
if (parsedTypeName.includes('import')) {
return true;
}
const errorMessage = `Type "${parsedTypeName}" is not referenceable ("${hostFilename}"). To fix this, make sure to export this type.`;
if (options.debug) {
plugin_debug_logger_1.pluginDebugLogger.debug(errorMessage);
}
throw new Error(errorMessage);
}