![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
abstraction
Advanced tools
A library for modeling abstract business logic or wrapping data structures.
A way of modeling your business logic or data structures in a compact and compose-able way.
Lets say you have some data from a server that you want to display to the user:
const incomingData = {
id: "1",
type: "accounts",
attributes: {
name: "Kurtis Rainbolt-Greene",
age: "27",
email: "kurtis@amazon.com",
"created-at": "2013-02-04T10:35:24-08:00",
}
}
The age is a string, the timestamp for created at is also a string, and created at isn't camel case. We can fix this:
const accountResource = abstraction({
attributes: {
id: {source: prop("id")},
type: {source: prop("type")},
attributes: {
source: prop("attributes"),
coerce: accountAttributes,
}
}
}
There's a lot happening here so lets break it down:
const accountResource = abstraction({
attributes: {
...
}
}
Every abstraction has a set of attributes. These are properties that'll be exposed on the returning abstract object.
Lets take the id
and type
attributes for a moment:
const accountResource = abstraction({
attributes: {
id: {source: prop("id")},
type: {source: prop("type")},
}
}
For these we're just defining a source
. The source
is a function that tells us how to get to our data for id
and type
. This is easy for us, so we'll just use path()
. Now it's time to get a little more complicated with attributes
.
const accountResource = abstraction({
attributes: {
id: {source: prop("id")},
type: {source: prop("type")},
attributes: {
source: prop("attributes"),
coerce: accountAttributes,
},
},
}
So here we're not only sourcing from the raw data, but also using a fun little coerce
function. This function should take the data from source and convert it to what you need. In this case we're doing something really cool in that we're actually coercing the data into another abstraction!
const accountAttributes = abstraction({
attributes: {
username: {source: pipe(prop("email"), split("@"), head)},
email: {source: prop("email")},
name: {source: prop("name")},
age: {
source: prop("age"),
coerce: (value) => parseInt(value, 10),
},
createdAt: {
source: prop("created-at"),
coerce: moment,
},
},
}
There's some interesting things going on here as well, specifically in username
's source and createdAt
's coerce
function. Notice that there is no username on the raw data and is instead really a derived value. In addition, your final property name doesn't have to be the same as your raw property.
Finally we also give a built in validations logic:
const accountResource = abstraction({
attributes: {
id: {source: prop("id")},
type: {source: prop("type")},
attributes: {
source: prop("attributes"),
coerce: accountAttributes,
}
},
validations: {
id: {
"Must have an id": propSatisfies(isPresent, "id"),
"Must be an string": propSatisfies(isType("String"), "id"),
"Must have characters": propSatisfies(isPopulated, "id"),
},
type: {
"Must have an type": propSatisfies(isPresent, "type"),
"Must be an string": propSatisfies(isType("String"), "type"),
"Must have characters": propSatisfies(isPopulated, "type"),
},
attributes: {
"Must have attributes": propSatisfies(isPresent, "attributes"),
"Must have properties": propSatisfies(isPopulated, "attributes"),
"Must be an Object": propSatisfies(isType("Object"), "attributes"),
}
}
})
Each validation is a group, so you have a group of id
validations. The keys can be messages, like above, or slugs (regular property names). You can read more about it in the [validus.js documentation][https://github.com/krainboltgreene/validus.js].
Now time to talk about what you'll get back when you run this:
const account = accountResource(incomingData)
Here's the return value:
{
id: "1",
type: "accounts",
attributes: {
name: "Kurtis Rainbolt-Greene",
age: 27,
email: "kurtis@amazon.com",
username: "kurtis",
createdAt: 2013-02-04T18:35:24.000Z,
__abstraction__: {
...
}
},
__abstraction__: {
...
}
}
Okay, wait, what's this __abstraction__
nonsense? Well, that's where we keep the validations. Lets say id
was missing, here's what you'd see from:
account._errors
It would return:
{
id: [
"Must have an id",
"Must be an string",
"Must have characters",
],
...
}
Isn't that great? You can also ask for individual validations using validus.js directly:
import {validate} from "validus"
validate(account._validations)("id")(account)
And that would return:
[
"Must have an id",
"Must be an string",
"Must have characters",
]
Again, assuming id
was missing. The initial validations are done when you pass in the data, and the validate
is for later validation.
FAQs
A library for modeling abstract business logic or wrapping data structures.
The npm package abstraction receives a total of 0 weekly downloads. As such, abstraction popularity was classified as not popular.
We found that abstraction demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.