<h1>Full data</h1>
<pre id="data-full"></pre>
<h1>Redacted data</h1>
<pre id="data-redacted"></pre>
* {
box-sizing: border-box;
}
body {
padding: 2rem;
min-width: 360px;
}
h1 {
margin-top: 0;
}
pre {
display: block;
background-color: #eee;
margin-bottom: 2rem;
padding: 1rem;
width: 100%;
white-space: normal;
overflow: auto;
max-width: 100%;
}
/* SAMPLE DATA */
const USER = {
firstName: "John",
middleName: "",
lastName: "Doe",
email: "john.doe@email.com",
balance: 2649.53,
currency: "USD",
locale: "en-US"
};
/* UTILS */
const getFullName = (firstName, lastName, middleName) =>
[firstName, middleName, lastName].filter((n) => !!n).join(" ");
const getFormattedBalance = (locale, currency, value) => {
return new Intl.NumberFormat(locale, {
style: "currency",
currency
}).format(value);
};
const getRedactedEmail = (email) => {
const [name, ...rest] = email.split("@");
const [service, domain] = rest.join("").split(".");
const redactedName = `${name[0]}*****${name[name.length - 1]}`;
const redactedDomain = `${service[0]}***${
service[service.length - 1]
}.${domain}`;
return `${redactedName}@${redactedDomain}`;
};
const getRedactedName = (name) => (Boolean(name.length) ? `${name[0]}.` : "");
/* PROXY */
const handleFullGet = (obj, prop) => {
if (prop === "fullName") {
return getFullName(
Reflect.get(obj, "firstName"),
Reflect.get(obj, "lastName"),
Reflect.get(obj, "middleName")
);
}
if (prop === "balance") {
return getFormattedBalance(
Reflect.get(obj, "locale"),
Reflect.get(obj, "currency"),
Reflect.get(obj, "balance")
);
}
if (!(prop in obj)) {
console.error(`${prop.toString()} doesn't exist in object`, obj);
return;
}
return Reflect.get(obj, prop);
};
const createUserDataProxy = (user) => {
const proxy = new Proxy(user, {
get: handleFullGet
});
return proxy;
};
const handleRedactedGet = (obj, prop) => {
if (prop === "fullName") {
return getFullName(
Reflect.get(obj, "firstName"),
getRedactedName(Reflect.get(obj, "lastName")),
getRedactedName(Reflect.get(obj, "middleName") || "")
);
}
if (prop === "middleName") {
return getRedactedName(Reflect.get(obj, "middleName"));
}
if (prop === "lastName") {
return getRedactedName(Reflect.get(obj, "lastName"));
}
if (prop === "email") {
return getRedactedEmail(Reflect.get(obj, "email"));
}
if (!(prop in obj)) {
console.error(`${prop} doesn't exist in object`, obj);
return;
}
return "Data not available";
};
const createRedactedDataProxy = (user) => {
const proxy = new Proxy(user, {
get: handleRedactedGet
});
return proxy;
};
/* APPLY PROXY */
const userFull = createUserDataProxy(USER);
const userRedacted = createRedactedDataProxy(USER);
/* OUTPUT */
const containerFull = document.getElementById("data-full");
const containerRedacted = document.getElementById("data-redacted");
containerFull.append(userFull.fullName);
containerFull.append(document.createElement("br"));
containerFull.append(userFull.email);
containerFull.append(document.createElement("br"));
containerFull.append(userFull.balance);
containerRedacted.append(userRedacted.fullName);
containerRedacted.append(document.createElement("br"));
containerRedacted.append(userRedacted.email);
containerRedacted.append(document.createElement("br"));
containerRedacted.append(userRedacted.balance);
containerRedacted.append(document.createElement("br"));
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.