@horizon-labs/property-model-v3
Version:
Modelo de propriedades imobiliárias v3 - Sistema de atributos dinâmicos
423 lines (418 loc) • 21.4 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
PropertyAttributesModel: () => PropertyAttributesModel,
formatListModel: () => formatListModel,
mergePropertyAttributesModel: () => mergePropertyAttributesModel,
preparaAttrValueLabel: () => preparaAttrValueLabel,
propertyV3CustomMapper: () => propertyV3CustomMapper,
sortAttributes: () => sortAttributes,
unitListModel: () => unitListModel,
verifyAttrKeyInPropertyV3Model: () => verifyAttrKeyInPropertyV3Model
});
module.exports = __toCommonJS(index_exports);
// src/models/property-attributes-model.ts
var PropertyAttributesModel = [
// Comercial
{ key: "operacao", label: "Opera\xE7\xE3o", type: "String[]", cat: "comercial", order: 1 },
{ key: "etapa_lancamento", label: "Etapa do lan\xE7amento", type: "String[]", cat: "comercial", order: 2 },
{ key: "status_comercial", label: "Status comercial", type: "String[]", cat: "comercial", order: 3 },
{ key: "destaque", label: "Im\xF3vel em destaque", type: "Boolean", cat: "comercial", order: 4 },
{ key: "exclusividade", label: "Exclusividade do im\xF3vel", type: "Boolean", cat: "comercial", order: 5 },
{ key: "financiavel", label: "Financi\xE1vel", type: "Boolean", cat: "comercial", order: 6 },
{ key: "seguro_fianca", label: "Seguro fian\xE7a", type: "Boolean", cat: "comercial", order: 7 },
{ key: "aceita_permuta", label: "Aceita permuta", type: "Boolean", cat: "comercial", order: 8 },
{ key: "aceita_parcelamento", label: "Aceita parcelamento", type: "Boolean", cat: "comercial", order: 9 },
// Valores
{ key: "valor_condominio", label: "Valor do condom\xEDnio", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 20 },
{ key: "valor_total_venda", label: "Valor total de venda", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}}", order: 21 },
{ key: "valor_total_mensal", label: "Valor total de loca\xE7\xE3o", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /m\xEAs", order: 22 },
{ key: "valor_venda", label: "Valor de venda", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}}", order: 23 },
{ key: "valor_locacao", label: "Valor de loca\xE7\xE3o mensal", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /m\xEAs", order: 24 },
{ key: "valor_diaria", label: "Valor da di\xE1ria", type: "Number", role: "currency", unit: "BRL", cat: "valores", composedLabel: "{{valueLabel}} /dia", order: 25 },
{ key: "valor_pacote_dias", label: "Valor do pacote de dias", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 26 },
{ key: "valor_iptu", label: "Valor do IPTU", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 27 },
{ key: "valor_fci", label: "Valor do Fundo de conserva\xE7\xE3o", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 28 },
{ key: "valor_seguro_incendio", label: "Valor do seguro inc\xEAndio", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 29 },
{ key: "valor_m2", label: "Valor do m\xB2", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 30 },
{ key: "valor_taxa_limpeza", label: "Valor da taxa de limpeza", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 31 },
{ key: "valor_taxa_esgoto", label: "Valor da taxa de esgoto", type: "Number", role: "currency", unit: "BRL", cat: "valores", order: 32 },
{ key: "moeda", label: "Unidade monet\xE1ria", type: "String", cat: "valores", order: 33 },
// Situações
{ key: "alugado", label: "Alugado", type: "Boolean", cat: "situacoes", order: 40 },
{ key: "vendido", label: "Vendido", type: "Boolean", cat: "situacoes", order: 41 },
{ key: "reservado", label: "Reservado", type: "Boolean", cat: "situacoes", order: 42 },
{ key: "situacao_ocupacao", label: "Situa\xE7\xE3o de ocupa\xE7\xE3o", type: "String", cat: "situacoes", order: 43 },
{ key: "financiado", label: "Financiado", type: "Boolean", cat: "situacoes", order: 44 },
// Legal / Documental
{ key: "averbado", label: "Averbado", type: "Boolean", cat: "legal", order: 60 },
{ key: "escriturado", label: "Escriturado", type: "Boolean", cat: "legal", order: 61 },
{ key: "incorporado", label: "Incorporado", type: "Boolean", cat: "legal", order: 62 },
// Normas / Permissões / Exigências
{ key: "numero_pessoas", label: "N\xFAmero de pessoas", type: "Number", role: "count", cat: "normas", order: 81 },
{ key: "aceita_pet", label: "Aceita Pet", type: "Boolean", cat: "normas", order: 82 },
// Localização
{ key: "endereco_pais", label: "Pa\xEDs", type: "String", cat: "localizacao", order: 101 },
{ key: "endereco_cep", label: "CEP", type: "String", cat: "localizacao", order: 102 },
{ key: "endereco_estado", label: "Estado", type: "String", cat: "localizacao", order: 103 },
{ key: "endereco_cidade", label: "Cidade", type: "String", cat: "localizacao", order: 104 },
{ key: "endereco_bairro", label: "Bairro", type: "String", cat: "localizacao", order: 105 },
{ key: "endereco_logradouro", label: "Logradouro", type: "String", cat: "localizacao", order: 106 },
{ key: "endereco_numero", label: "N\xFAmero do im\xF3vel", type: "String", cat: "localizacao", order: 107 },
{ key: "endereco_complemento", label: "Complemento", type: "String", cat: "localizacao", order: 108 },
{ key: "endereco_referencia", label: "Refer\xEAncia (endere\xE7o)", type: "String", cat: "localizacao", order: 109 },
{ key: "latitude", label: "Latitude", type: "Number", cat: "localizacao", order: 110 },
{ key: "longitude", label: "Longitude", type: "Number", cat: "localizacao", order: 111 },
{ key: "geoposicionamento", label: "Geoposicionamento", type: "String", cat: "localizacao", order: 112 },
{ key: "endereco_completo", label: "Endere\xE7o completo", type: "String", cat: "localizacao", order: 113 },
{ key: "endereco_bairro_cidade_uf", label: "Bairro + Cidade + UF", type: "String", cat: "localizacao", order: 114 },
// Condomínio
{ key: "condominio_nome", label: "Nome do condom\xEDnio", type: "String", cat: "condominio", order: 120 },
{ key: "condominio_tipo", label: "Tipo do condom\xEDnio", type: "String", cat: "condominio", order: 121 },
{ key: "condominio_fechado", label: "Condom\xEDnio fechado", type: "Boolean", cat: "condominio", order: 122 },
// Localidade
{ key: "distancia_mar", label: "Dist\xE2ncia do mar", type: "Number", role: "distance", unit: "m", cat: "localidade", order: 141 },
{ key: "imovel_no_litoral", label: "Im\xF3vel no litoral", type: "Boolean", cat: "localidade", order: 142 },
{ key: "frente_mar", label: "Frente para o mar", type: "Boolean", cat: "localidade", order: 144 },
{ key: "vista_mar", label: "Vista para o mar", type: "Boolean", cat: "localidade", order: 146 },
// Estrutura do imóvel
{ key: "tipo", label: "Tipo", type: "String", cat: "estrutura", order: 160 },
{ key: "subtipo", label: "Subtipo", type: "String", cat: "estrutura", order: 161 },
{ key: "area_privativa", label: "\xC1rea privativa", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} priv.", iconName: "area", order: 163 },
{ key: "area_total", label: "\xC1rea Total", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} total", iconName: "area", order: 164 },
{ key: "area_terreno", label: "\xC1rea do terreno", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", composedLabel: "{{valueLabel}} terreno", iconName: "area", order: 165 },
{ key: "padrao_imovel", label: "Padr\xE3o do im\xF3vel", type: "String", cat: "estrutura", order: 166 },
{ key: "fase_obra", label: "Fase da obra", type: "String", cat: "estrutura", order: 167 },
{ key: "em_condominio", label: "Em condom\xEDnio", type: "Boolean", cat: "estrutura", order: 168 },
{ key: "finalidade", label: "Finalidade (prop\xF3sito)", type: "String", cat: "estrutura", order: 169 },
{ key: "estado_conservacao", label: "Estado da conserva\xE7\xE3o do im\xF3vel", type: "String", cat: "estrutura", order: 170 },
{ key: "estado_imovel", label: "Status da obra + uso do im\xF3vel", type: "String", cat: "estrutura", order: 171 },
{ key: "posicao_solar", label: "Posi\xE7\xE3o solar", type: "String", cat: "estrutura", order: 172 },
{ key: "posicao_no_terreno", label: "Posi\xE7\xE3o do im\xF3vel no terreno", type: "String", cat: "estrutura", order: 173 },
{ key: "tipo_piso", label: "Tipo de piso", type: "String", cat: "estrutura", order: 174 },
{ key: "tipos_piso", label: "Tipos de piso", type: "String[]", cat: "estrutura", order: 175 },
{ key: "material_imovel", label: "Material do im\xF3vel", type: "String", cat: "estrutura", order: 176 },
{ key: "materiais_imovel", label: "Materiais do im\xF3vel", type: "String[]", cat: "estrutura", order: 177 },
{ key: "area_construida", label: "\xC1rea constru\xEDda", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", order: 178 },
{ key: "area_util", label: "\xC1rea \xFAtil", type: "Number", role: "area", unit: "m\xB2", cat: "estrutura", order: 179 },
{ key: "data_entrega_obra", label: "Data de entrega da obra", type: "String", role: "date", cat: "estrutura", order: 180 },
{ key: "ano_construcao", label: "Ano da constru\xE7\xE3o", type: "String", role: "year", cat: "estrutura", order: 181 },
{ key: "topografia_terreno", label: "Topografia do terreno", type: "String", cat: "estrutura", order: 182 },
{ key: "pintura", label: "Pintura", type: "String", cat: "estrutura", order: 183 },
{ key: "pinturas_revestimentos", label: "Pinturas e revestimentos", type: "String[]", cat: "estrutura", order: 184 },
{ key: "tipo_esquadria", label: "Tipo de esquadrias", type: "String", cat: "estrutura", order: 185 },
{ key: "tipos_esquadrias", label: "Tipos de esquadrias", type: "String[]", cat: "estrutura", order: 186 },
{ key: "tipo_forro", label: "Tipo do forro", type: "String", cat: "estrutura", order: 187 },
{ key: "tipos_forros", label: "Tipos de forros", type: "String[]", cat: "estrutura", order: 188 },
{ key: "tipos_coberturas", label: "Tipos de coberturas", type: "String[]", cat: "estrutura", order: 189 },
{ key: "terreno_comprimento", label: "Comprimento do terreno", type: "Number", role: "distance", unit: "m", cat: "estrutura", order: 190 },
{ key: "terreno_largura", label: "Largura do Terreno", type: "Number", role: "distance", unit: "m", cat: "estrutura", order: 191 },
{ key: "cores", label: "Cores do im\xF3vel", type: "String[]", cat: "estrutura", order: 192 },
{ key: "andares", label: "N\xFAmero de andares", type: "Number", role: "count", cat: "estrutura", order: 193 },
{ key: "medida_distancia", label: "Tipo de medida de dist\xE2ncia", type: "String", cat: "estrutura", order: 194 },
{ key: "medida_area", label: "Tipo de medida de \xE1rea", type: "String", cat: "estrutura", order: 195 },
// Corretor
{ key: "corretor_id", label: "Corretor \u2192 ID", type: "String", cat: "corretor", order: 210 },
{ key: "corretor_nome", label: "Corretor \u2192 Nome", type: "String", cat: "corretor", order: 211 },
// Dependências
{ key: "dormitorios", label: "Dormit\xF3rios", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} dormit\xF3rio{{p:s}}", iconName: "bedroom", order: 230 },
{ key: "banheiros", label: "Banheiros", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} banheiro{{p:s}}", iconName: "bathroom", order: 231 },
{ key: "suites", label: "Su\xEDtes", type: "Number", role: "count", cat: "dependencias", composedLabel: "Sendo {{valueLabel}} su\xEDte{{p:s}}", iconName: "suite", order: 232 },
{ key: "vagas_garagem", label: "Vagas na garagem", type: "Number", role: "count", cat: "dependencias", composedLabel: "{{valueLabel}} vaga{{p:s}}", iconName: "garage", order: 233 },
// Características em geral
{ key: "mobiliado", label: "Mobiliado", type: "Boolean", cat: "caracteristicas", order: 250 }
// { key: "caracteristicas", label: "Características (lista)", type: "String[]", cat: "caracteristicas" order: 1, },
];
// src/models/property-attributes-fields-list-model.ts
var unitListModel = {
area: [
{
key: "m\xB2",
aliases: ["m2"],
label: "m\xB2",
labelDisplay: "Metros quadrados"
},
{
key: "ha",
aliases: ["hectare", "hectares"],
label: "ha",
labelDisplay: "Hectares"
},
{
key: "km\xB2",
aliases: ["km2"],
label: "km\xB2",
labelDisplay: "Quil\xF4metros quadrados"
}
],
length: [
{
key: "m",
aliases: ["metro", "meter", "meters"],
label: "m",
labelDisplay: "Metros"
},
{
key: "km",
aliases: ["quilometro", "kilometer", "kilometers"],
label: "km",
labelDisplay: "Quil\xF4metros"
}
],
currency: [
{
key: "BRL",
aliases: [],
label: "R$",
labelDisplay: "Real Brasileiro",
locale: "pt-BR"
}
]
};
var formatListModel = {
// Em desenvolvimento futuro
// color: [
// {
// key: "rgb",
// label: "RGB",
// },
// {
// key: "cmyk",
// label: "CMYK",
// },
// ],
};
// src/utils/index.ts
function verifyAttrKeyInPropertyV3Model(key) {
return PropertyAttributesModel.find((attr) => attr.key == key);
}
function mergePropertyAttributesModel(base, overrides) {
const map = new Map(base.map((attr) => [attr.key, { ...attr }]));
for (const overrideAttr of overrides) {
const baseAttr = map.get(overrideAttr.key);
if (baseAttr) {
for (const field in overrideAttr) {
baseAttr[field] = overrideAttr[field];
}
map.set(overrideAttr.key, baseAttr);
} else {
map.set(overrideAttr.key, { ...overrideAttr });
}
}
return Array.from(map.values());
}
function sortAttributes(attributes, sortKeys = []) {
return [...attributes].sort((a, b) => {
for (const rule of sortKeys) {
const [field, direction] = rule.split(":");
const valA = a[field];
const valB = b[field];
if (valA === void 0 || valB === void 0) continue;
const isAsc = direction === "asc";
const isDesc = direction === "desc";
if (!isAsc && !isDesc) {
console.warn(`Dire\xE7\xE3o inv\xE1lida: "${direction}". Use "asc" ou "desc".`);
continue;
}
if (valA < valB) return isAsc ? -1 : 1;
if (valA > valB) return isAsc ? 1 : -1;
}
return 0;
});
}
var preparaAttrValueLabel = function(valor) {
return Array.isArray(valor) ? `${valor.slice(0, -1).join(", ")} e ${valor[valor.length - 1]}` : valor;
};
// src/custom-mapper/index.ts
var import_ramda = require("ramda");
function upsertAttribute(attributes, attr) {
const index = attributes.findIndex((item) => item.key === attr.key);
if (index !== -1) {
attributes[index] = attr;
} else {
attributes.push(attr);
}
}
function addTags(property, list) {
const current = property.tags ? property.tags.split(" ") : [];
property.tags = (0, import_ramda.union)(current, list).join(" ");
}
function removeTags(property, list) {
const current = property.tags ? property.tags.split(" ") : [];
property.tags = current.filter((tag) => !list.includes(tag)).join(" ");
}
function removeAttr(attributes, key) {
const index = attributes.findIndex((item) => item.key === key);
if (index !== -1) attributes.splice(index, 1);
}
var actionRunner = {
upsertAttr: (property, action) => {
const { key, fn, ...rest } = action;
upsertAttribute(property.attributes, {
key,
...rest
});
},
removeAttr: (property, action) => {
removeAttr(property.attributes, action.key);
},
addTags: (property, action) => {
addTags(property, action.list);
},
removeTags: (property, action) => {
removeTags(property, action.list);
}
};
function applyAttrRules(attr, rules, property) {
const actions = rules?.[attr.value];
if (!actions) return property;
actions.forEach((action) => {
const fn = actionRunner[action.fn];
if (fn) {
const resolvedAction = resolvePlaceholders(action, attr);
fn(property, resolvedAction);
}
});
return property;
}
function applyTagRules(tags, rules, property) {
const tagsArray = tags.split(" ");
tagsArray.forEach((tag) => {
const actions = rules?.[tag];
if (!actions) return;
actions.forEach((action) => {
const fn = actionRunner[action.fn];
if (fn) fn(property, action);
});
});
}
function applyReferenceRules(reference, rules, property) {
const actions = rules?.[reference];
if (!actions) return;
actions.forEach((action) => {
const fn = actionRunner[action.fn];
if (fn) fn(property, action);
});
}
function matchCondition(attrValue, condition) {
if (!condition) return true;
const attrAsArray = Array.isArray(attrValue) ? attrValue : typeof attrValue === "string" ? [attrValue] : [];
for (const operator in condition) {
const expected = condition[operator];
switch (operator) {
case "eq":
if (attrValue !== expected) return false;
break;
case "not_eq":
if (attrValue === expected) return false;
break;
case "has": {
const attrAsArray2 = Array.isArray(attrValue) ? attrValue : [attrValue];
const expectedArray = Array.isArray(expected) ? expected : [expected];
if (!expectedArray.every((val) => attrAsArray2.includes(val)))
return false;
break;
}
case "has_any": {
const attrAsArray2 = Array.isArray(attrValue) ? attrValue : [attrValue];
const expectedArray = Array.isArray(expected) ? expected : [expected];
if (!expectedArray.some((val) => attrAsArray2.includes(val)))
return false;
break;
}
case "not_has":
if (Array.isArray(expected)) {
if (expected.some((val) => attrAsArray.includes(val))) return false;
} else {
if (attrAsArray.includes(expected)) return false;
}
break;
case "gt":
if (!(attrValue > expected)) return false;
break;
case "gte":
if (!(attrValue >= expected)) return false;
break;
case "lt":
if (!(attrValue < expected)) return false;
break;
case "lte":
if (!(attrValue <= expected)) return false;
break;
default:
return false;
}
}
return true;
}
function resolvePlaceholders(action, sourceAttr) {
const resolved = { ...action };
if (resolved.value === "{{value}}") {
resolved.value = sourceAttr.value;
} else if (typeof resolved.value === "string" && resolved.value.includes("{{value}}")) {
resolved.value = resolved.value.replace(
"{{value}}",
String(sourceAttr.value)
);
}
return resolved;
}
function applyAttributesRules(attributes, rules, property) {
for (const rule of rules) {
const attr = attributes.find((a) => a.key === rule.key);
if (!attr) continue;
if (matchCondition(attr.value, rule.condition)) {
for (const action of rule.rules) {
const fn = actionRunner[action.fn];
if (fn) {
const resolvedAction = resolvePlaceholders(action, attr);
fn(property, resolvedAction);
}
}
}
}
}
function propertyV3CustomMapper(property, mapRules) {
const newProperty = (0, import_ramda.clone)(property);
const { attributes, reference, tags } = newProperty;
const { attrTipoRules, referenceRules, tagsRules, attributesRules } = mapRules;
attrTipoRules && attributes.forEach((attr) => {
if (attr.key === "tipo") {
applyAttrRules(attr, attrTipoRules, newProperty);
}
});
tagsRules && applyTagRules(tags, tagsRules, newProperty);
referenceRules && applyReferenceRules(reference, referenceRules, newProperty);
attributesRules && applyAttributesRules(attributes, attributesRules, newProperty);
return newProperty;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
PropertyAttributesModel,
formatListModel,
mergePropertyAttributesModel,
preparaAttrValueLabel,
propertyV3CustomMapper,
sortAttributes,
unitListModel,
verifyAttrKeyInPropertyV3Model
});
//# sourceMappingURL=index.js.map