✨ 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
358 lines
17 KiB
JavaScript
358 lines
17 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.SchemaObjectFactory = void 0;
|
|
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
|
const lodash_1 = require("lodash");
|
|
const constants_1 = require("../constants");
|
|
const helpers_1 = require("../decorators/helpers");
|
|
const api_extra_models_explorer_1 = require("../explorers/api-extra-models.explorer");
|
|
const utils_1 = require("../utils");
|
|
const enum_utils_1 = require("../utils/enum.utils");
|
|
const is_body_parameter_util_1 = require("../utils/is-body-parameter.util");
|
|
const is_built_in_type_util_1 = require("../utils/is-built-in-type.util");
|
|
const is_date_ctor_util_1 = require("../utils/is-date-ctor.util");
|
|
class SchemaObjectFactory {
|
|
constructor(modelPropertiesAccessor, swaggerTypesMapper) {
|
|
this.modelPropertiesAccessor = modelPropertiesAccessor;
|
|
this.swaggerTypesMapper = swaggerTypesMapper;
|
|
}
|
|
createFromModel(parameters, schemas) {
|
|
const parameterObjects = parameters.map((param) => {
|
|
if (this.isLazyTypeFunc(param.type)) {
|
|
[param.type, param.isArray] = (0, helpers_1.getTypeIsArrayTuple)(param.type(), undefined);
|
|
}
|
|
if (!(0, is_body_parameter_util_1.isBodyParameter)(param) && param.enumName) {
|
|
return this.createEnumParam(param, schemas);
|
|
}
|
|
if (this.isPrimitiveType(param.type)) {
|
|
return param;
|
|
}
|
|
if (this.isArrayCtor(param.type)) {
|
|
return this.mapArrayCtorParam(param);
|
|
}
|
|
if (!(0, is_body_parameter_util_1.isBodyParameter)(param)) {
|
|
return this.createQueryOrParamSchema(param, schemas);
|
|
}
|
|
const modelName = this.exploreModelSchema(param.type, schemas);
|
|
const name = param.name || modelName;
|
|
const schema = Object.assign(Object.assign({}, (param.schema || {})), { $ref: (0, utils_1.getSchemaPath)(modelName) });
|
|
const isArray = param.isArray;
|
|
param = (0, lodash_1.omit)(param, 'isArray');
|
|
if (isArray) {
|
|
return Object.assign(Object.assign({}, param), { name, schema: {
|
|
type: 'array',
|
|
items: schema
|
|
} });
|
|
}
|
|
return Object.assign(Object.assign({}, param), { name,
|
|
schema });
|
|
});
|
|
return (0, lodash_1.flatten)(parameterObjects);
|
|
}
|
|
createQueryOrParamSchema(param, schemas) {
|
|
if ((0, is_date_ctor_util_1.isDateCtor)(param.type)) {
|
|
return Object.assign(Object.assign({ format: 'date-time' }, param), { type: 'string' });
|
|
}
|
|
if (this.isBigInt(param.type)) {
|
|
return Object.assign(Object.assign({ format: 'int64' }, param), { type: 'integer' });
|
|
}
|
|
if ((0, lodash_1.isFunction)(param.type)) {
|
|
const propertiesWithType = this.extractPropertiesFromType(param.type, schemas);
|
|
if (!propertiesWithType) {
|
|
return param;
|
|
}
|
|
return propertiesWithType.map((property) => {
|
|
var _a, _b;
|
|
const parameterObject = Object.assign(Object.assign({}, (0, lodash_1.omit)(property, 'enumName')), { in: (_a = param.in) !== null && _a !== void 0 ? _a : 'query', required: (_b = property.required) !== null && _b !== void 0 ? _b : true });
|
|
return parameterObject;
|
|
});
|
|
}
|
|
return param;
|
|
}
|
|
extractPropertiesFromType(type, schemas, pendingSchemasRefs = []) {
|
|
const { prototype } = type;
|
|
if (!prototype) {
|
|
return;
|
|
}
|
|
const extraModels = (0, api_extra_models_explorer_1.exploreGlobalApiExtraModelsMetadata)(type);
|
|
extraModels.forEach((item) => this.exploreModelSchema(item, schemas, pendingSchemasRefs));
|
|
this.modelPropertiesAccessor.applyMetadataFactory(prototype);
|
|
const modelProperties = this.modelPropertiesAccessor.getModelProperties(prototype);
|
|
const propertiesWithType = modelProperties.map((key) => {
|
|
const property = this.mergePropertyWithMetadata(key, prototype, schemas, pendingSchemasRefs);
|
|
const schemaCombinators = ['oneOf', 'anyOf', 'allOf'];
|
|
let keyOfCombinators = '';
|
|
if (schemaCombinators.some((_key) => {
|
|
keyOfCombinators = _key;
|
|
return _key in property;
|
|
})) {
|
|
if (((property === null || property === void 0 ? void 0 : property.type) === 'array' ||
|
|
property.isArray) &&
|
|
keyOfCombinators) {
|
|
property.items = {};
|
|
property.items[keyOfCombinators] =
|
|
property[keyOfCombinators];
|
|
delete property[keyOfCombinators];
|
|
}
|
|
else {
|
|
delete property.type;
|
|
}
|
|
}
|
|
return property;
|
|
});
|
|
return propertiesWithType;
|
|
}
|
|
exploreModelSchema(type, schemas, pendingSchemasRefs = []) {
|
|
if (this.isLazyTypeFunc(type)) {
|
|
type = type();
|
|
}
|
|
const propertiesWithType = this.extractPropertiesFromType(type, schemas, pendingSchemasRefs);
|
|
if (!propertiesWithType) {
|
|
return '';
|
|
}
|
|
const extensionProperties = Reflect.getMetadata(constants_1.DECORATORS.API_EXTENSION, type) || {};
|
|
const typeDefinition = Object.assign({ type: 'object', properties: (0, lodash_1.mapValues)((0, lodash_1.keyBy)(propertiesWithType, 'name'), (property) => (0, lodash_1.omit)(property, ['name', 'isArray', 'required', 'enumName'])) }, extensionProperties);
|
|
const typeDefinitionRequiredFields = propertiesWithType
|
|
.filter((property) => property.required != false)
|
|
.map((property) => property.name);
|
|
if (typeDefinitionRequiredFields.length > 0) {
|
|
typeDefinition['required'] = typeDefinitionRequiredFields;
|
|
}
|
|
schemas[type.name] = typeDefinition;
|
|
return type.name;
|
|
}
|
|
mergePropertyWithMetadata(key, prototype, schemas, pendingSchemaRefs, metadata) {
|
|
if (!metadata) {
|
|
metadata =
|
|
Reflect.getMetadata(constants_1.DECORATORS.API_MODEL_PROPERTIES, prototype, key) ||
|
|
{};
|
|
}
|
|
if (this.isLazyTypeFunc(metadata.type)) {
|
|
metadata.type = metadata.type();
|
|
[metadata.type, metadata.isArray] = (0, helpers_1.getTypeIsArrayTuple)(metadata.type, metadata.isArray);
|
|
}
|
|
if (Array.isArray(metadata.type)) {
|
|
return this.createFromNestedArray(key, metadata, schemas, pendingSchemaRefs);
|
|
}
|
|
return this.createSchemaMetadata(key, metadata, schemas, pendingSchemaRefs);
|
|
}
|
|
createEnumParam(param, schemas) {
|
|
var _a, _b, _c, _d, _e;
|
|
const enumName = param.enumName;
|
|
const $ref = (0, utils_1.getSchemaPath)(enumName);
|
|
if (!(enumName in schemas)) {
|
|
const _enum = param.enum
|
|
? param.enum
|
|
: param.schema
|
|
? param.schema['items']
|
|
? param.schema['items']['enum']
|
|
: param.schema['enum']
|
|
: param.isArray && param.items
|
|
? param.items.enum
|
|
: undefined;
|
|
schemas[enumName] = Object.assign({ type: (_d = (param.isArray
|
|
? (_b = (_a = param.schema) === null || _a === void 0 ? void 0 : _a['items']) === null || _b === void 0 ? void 0 : _b['type']
|
|
: (_c = param.schema) === null || _c === void 0 ? void 0 : _c['type'])) !== null && _d !== void 0 ? _d : 'string', enum: _enum }, (param['x-enumNames'] ? { 'x-enumNames': param['x-enumNames'] } : {}));
|
|
}
|
|
param.schema =
|
|
param.isArray || ((_e = param.schema) === null || _e === void 0 ? void 0 : _e['items'])
|
|
? { type: 'array', items: { $ref } }
|
|
: { $ref };
|
|
return (0, lodash_1.omit)(param, ['isArray', 'items', 'enumName', 'enum', 'x-enumNames']);
|
|
}
|
|
createEnumSchemaType(key, metadata, schemas) {
|
|
var _a;
|
|
if (!metadata.enumName) {
|
|
return Object.assign(Object.assign({}, metadata), { name: metadata.name || key });
|
|
}
|
|
const enumName = metadata.enumName;
|
|
const $ref = (0, utils_1.getSchemaPath)(enumName);
|
|
const additionalParams = ['description', 'deprecated', 'default'];
|
|
const additionalFields = additionalParams.reduce((acc, param) => (Object.assign(Object.assign({}, acc), (metadata[param] && { [param]: metadata[param] }))), {});
|
|
const enumType = (_a = (metadata.isArray ? metadata.items['type'] : metadata.type)) !== null && _a !== void 0 ? _a : 'string';
|
|
schemas[enumName] = Object.assign(Object.assign({ type: enumType }, additionalFields), { enum: metadata.isArray && metadata.items
|
|
? metadata.items['enum']
|
|
: metadata.enum });
|
|
const _schemaObject = Object.assign(Object.assign({}, metadata), { name: metadata.name || key, type: metadata.isArray ? 'array' : 'string' });
|
|
const refHost = metadata.isArray ? { items: { $ref } } : { $ref };
|
|
const paramObject = Object.assign(Object.assign({}, _schemaObject), refHost);
|
|
const pathsToOmit = ['enum', 'enumName', ...additionalParams];
|
|
if (!metadata.isArray) {
|
|
pathsToOmit.push('type');
|
|
}
|
|
return (0, lodash_1.omit)(paramObject, pathsToOmit);
|
|
}
|
|
createNotBuiltInTypeReference(key, metadata, trueMetadataType, schemas, pendingSchemaRefs) {
|
|
if ((0, shared_utils_1.isUndefined)(trueMetadataType)) {
|
|
throw new Error(`A circular dependency has been detected (property key: "${key}"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").`);
|
|
}
|
|
let schemaObjectName = trueMetadataType.name;
|
|
if (!(schemaObjectName in schemas) &&
|
|
!pendingSchemaRefs.includes(schemaObjectName)) {
|
|
schemaObjectName = this.exploreModelSchema(trueMetadataType, schemas, [...pendingSchemaRefs, schemaObjectName]);
|
|
}
|
|
const $ref = (0, utils_1.getSchemaPath)(schemaObjectName);
|
|
if (metadata.isArray) {
|
|
return this.transformToArraySchemaProperty(metadata, key, { $ref });
|
|
}
|
|
const keysToRemove = ['type', 'isArray', 'required', 'name'];
|
|
const validMetadataObject = (0, lodash_1.omit)(metadata, keysToRemove);
|
|
const extraMetadataKeys = Object.keys(validMetadataObject);
|
|
if (extraMetadataKeys.length > 0) {
|
|
return Object.assign(Object.assign({ name: metadata.name || key, required: metadata.required }, validMetadataObject), { allOf: [{ $ref }] });
|
|
}
|
|
return {
|
|
name: metadata.name || key,
|
|
required: metadata.required,
|
|
$ref
|
|
};
|
|
}
|
|
transformToArraySchemaProperty(metadata, key, type) {
|
|
const keysToRemove = ['type', 'enum'];
|
|
const [movedProperties, keysToMove] = this.extractPropertyModifiers(metadata);
|
|
const schemaHost = Object.assign(Object.assign({}, (0, lodash_1.omit)(metadata, [...keysToRemove, ...keysToMove])), { name: metadata.name || key, type: 'array', items: (0, lodash_1.isString)(type)
|
|
? Object.assign({ type }, movedProperties) : Object.assign(Object.assign({}, type), movedProperties) });
|
|
schemaHost.items = (0, lodash_1.omitBy)(schemaHost.items, shared_utils_1.isUndefined);
|
|
return schemaHost;
|
|
}
|
|
mapArrayCtorParam(param) {
|
|
return Object.assign(Object.assign({}, (0, lodash_1.omit)(param, 'type')), { schema: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string'
|
|
}
|
|
} });
|
|
}
|
|
createFromObjectLiteral(key, literalObj, schemas) {
|
|
const objLiteralKeys = Object.keys(literalObj);
|
|
const properties = {};
|
|
objLiteralKeys.forEach((key) => {
|
|
const propertyCompilerMetadata = literalObj[key];
|
|
if ((0, enum_utils_1.isEnumArray)(propertyCompilerMetadata)) {
|
|
propertyCompilerMetadata.type = 'array';
|
|
const enumValues = (0, enum_utils_1.getEnumValues)(propertyCompilerMetadata.enum);
|
|
propertyCompilerMetadata.items = {
|
|
type: (0, enum_utils_1.getEnumType)(enumValues),
|
|
enum: enumValues
|
|
};
|
|
delete propertyCompilerMetadata.enum;
|
|
}
|
|
else if (propertyCompilerMetadata.enum) {
|
|
const enumValues = (0, enum_utils_1.getEnumValues)(propertyCompilerMetadata.enum);
|
|
propertyCompilerMetadata.enum = enumValues;
|
|
propertyCompilerMetadata.type = (0, enum_utils_1.getEnumType)(enumValues);
|
|
}
|
|
const propertyMetadata = this.mergePropertyWithMetadata(key, Object, schemas, [], propertyCompilerMetadata);
|
|
const keysToRemove = ['isArray', 'name'];
|
|
const validMetadataObject = (0, lodash_1.omit)(propertyMetadata, keysToRemove);
|
|
properties[key] = validMetadataObject;
|
|
});
|
|
return {
|
|
name: key,
|
|
type: 'object',
|
|
properties
|
|
};
|
|
}
|
|
createFromNestedArray(key, metadata, schemas, pendingSchemaRefs) {
|
|
const recurse = (type) => {
|
|
if (!Array.isArray(type)) {
|
|
const schemaMetadata = this.createSchemaMetadata(key, metadata, schemas, pendingSchemaRefs, type);
|
|
return (0, lodash_1.omit)(schemaMetadata, ['isArray', 'name']);
|
|
}
|
|
return {
|
|
name: key,
|
|
type: 'array',
|
|
items: recurse(type[0])
|
|
};
|
|
};
|
|
return recurse(metadata.type);
|
|
}
|
|
createSchemaMetadata(key, metadata, schemas, pendingSchemaRefs, nestedArrayType) {
|
|
const typeRef = nestedArrayType || metadata.type;
|
|
if (this.isObjectLiteral(typeRef)) {
|
|
return this.createFromObjectLiteral(key, typeRef, schemas);
|
|
}
|
|
if ((0, lodash_1.isString)(typeRef)) {
|
|
if ((0, enum_utils_1.isEnumMetadata)(metadata)) {
|
|
return this.createEnumSchemaType(key, metadata, schemas);
|
|
}
|
|
if (metadata.isArray) {
|
|
return this.transformToArraySchemaProperty(metadata, key, typeRef);
|
|
}
|
|
return Object.assign(Object.assign({}, metadata), { name: metadata.name || key });
|
|
}
|
|
if ((0, is_date_ctor_util_1.isDateCtor)(typeRef)) {
|
|
if (metadata.isArray) {
|
|
return this.transformToArraySchemaProperty(metadata, key, {
|
|
format: metadata.format || 'date-time',
|
|
type: 'string'
|
|
});
|
|
}
|
|
return Object.assign(Object.assign({ format: 'date-time' }, metadata), { type: 'string', name: metadata.name || key });
|
|
}
|
|
if (this.isBigInt(typeRef)) {
|
|
return Object.assign(Object.assign({ format: 'int64' }, metadata), { type: 'integer', name: metadata.name || key });
|
|
}
|
|
if (!(0, is_built_in_type_util_1.isBuiltInType)(typeRef)) {
|
|
return this.createNotBuiltInTypeReference(key, metadata, typeRef, schemas, pendingSchemaRefs);
|
|
}
|
|
const typeName = this.getTypeName(typeRef);
|
|
const itemType = this.swaggerTypesMapper.mapTypeToOpenAPIType(typeName);
|
|
if (metadata.isArray) {
|
|
return this.transformToArraySchemaProperty(metadata, key, {
|
|
type: itemType
|
|
});
|
|
}
|
|
else if (itemType === 'array') {
|
|
const defaultOnArray = 'string';
|
|
return this.transformToArraySchemaProperty(metadata, key, {
|
|
type: defaultOnArray
|
|
});
|
|
}
|
|
return Object.assign(Object.assign({}, metadata), { name: metadata.name || key, type: itemType });
|
|
}
|
|
isArrayCtor(type) {
|
|
return type === Array;
|
|
}
|
|
isPrimitiveType(type) {
|
|
return ((0, lodash_1.isFunction)(type) &&
|
|
[String, Boolean, Number].some((item) => item === type));
|
|
}
|
|
isLazyTypeFunc(type) {
|
|
return (0, lodash_1.isFunction)(type) && type.name == 'type';
|
|
}
|
|
getTypeName(type) {
|
|
return type && (0, lodash_1.isFunction)(type) ? type.name : type;
|
|
}
|
|
isObjectLiteral(obj) {
|
|
if (typeof obj !== 'object' || !obj) {
|
|
return false;
|
|
}
|
|
const hasOwnProp = Object.prototype.hasOwnProperty;
|
|
let objPrototype = obj;
|
|
while (Object.getPrototypeOf((objPrototype = Object.getPrototypeOf(objPrototype))) !== null)
|
|
;
|
|
for (const prop in obj) {
|
|
if (!hasOwnProp.call(obj, prop) && !hasOwnProp.call(objPrototype, prop)) {
|
|
return false;
|
|
}
|
|
}
|
|
return Object.getPrototypeOf(obj) === objPrototype;
|
|
}
|
|
isBigInt(type) {
|
|
return type === BigInt;
|
|
}
|
|
extractPropertyModifiers(metadata) {
|
|
const modifierKeys = [
|
|
'format',
|
|
'maximum',
|
|
'maxLength',
|
|
'minimum',
|
|
'minLength',
|
|
'pattern'
|
|
];
|
|
return [(0, lodash_1.pick)(metadata, modifierKeys), modifierKeys];
|
|
}
|
|
}
|
|
exports.SchemaObjectFactory = SchemaObjectFactory;
|