✨ 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
271 lines
10 KiB
JavaScript
271 lines
10 KiB
JavaScript
"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;
|