Socket
Socket
Sign inDemoInstall

@commodo/fields

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@commodo/fields - npm Package Compare versions

Comparing version 1.0.2 to 1.0.3-canary.4

4

fields/boolean.js

@@ -20,3 +20,3 @@ "use strict";

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -28,3 +28,3 @@ const boolean = (_ref = {}) => {

rest = (0, _objectWithoutProperties2.default)(_ref, ["list"]);
const field = (0, _createField.default)(_objectSpread({}, rest, {
const field = (0, _createField.default)(_objectSpread(_objectSpread({}, rest), {}, {
list,

@@ -31,0 +31,0 @@ type: "boolean"

@@ -94,3 +94,3 @@ "use strict";

if (typeof this.validation === "function") {
await this.validation((await this.getValue()));
await this.validation(await this.getValue());
}

@@ -97,0 +97,0 @@ };

@@ -26,3 +26,3 @@ "use strict";

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -63,3 +63,3 @@ const prepareValue = ({

const field = (0, _createField.default)(_objectSpread({}, rest, {
const field = (0, _createField.default)(_objectSpread(_objectSpread({}, rest), {}, {
list,

@@ -66,0 +66,0 @@ type: "fields"

@@ -20,3 +20,3 @@ "use strict";

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -28,3 +28,3 @@ const number = (_ref = {}) => {

rest = (0, _objectWithoutProperties2.default)(_ref, ["list"]);
const field = (0, _createField.default)(_objectSpread({}, rest, {
const field = (0, _createField.default)(_objectSpread(_objectSpread({}, rest), {}, {
list,

@@ -31,0 +31,0 @@ type: "number"

@@ -20,3 +20,3 @@ "use strict";

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

@@ -28,3 +28,3 @@ const string = (_ref = {}) => {

rest = (0, _objectWithoutProperties2.default)(_ref, ["list"]);
let field = (0, _createField.default)(_objectSpread({}, rest, {
let field = (0, _createField.default)(_objectSpread(_objectSpread({}, rest), {}, {
list,

@@ -31,0 +31,0 @@ type: "string"

@@ -10,2 +10,6 @@ "use strict";

function isPromise(value) {
return Boolean(value && typeof value.then === "function");
}
const onSet = callback => {

@@ -18,3 +22,9 @@ return (0, _repropose.withProps)(props => {

setValue(value) {
return setValue.call(this, callback(value));
const newValue = callback(value);
if (isPromise(newValue)) {
throw new Error(`A promise was returned from the "onSet" callback (applied on the "${props.name}" field). Provided callbacks cannot perform async operations.`);
}
return setValue.call(this, newValue);
}

@@ -21,0 +31,0 @@

{
"name": "@commodo/fields",
"version": "1.0.2",
"version": "1.0.3-canary.4",
"main": "index.js",

@@ -13,5 +13,2 @@ "repository": {

"license": "MIT",
"devDependencies": {
"jest": "^23.6.0"
},
"dependencies": {

@@ -32,3 +29,3 @@ "repropose": "^1.0.2"

},
"gitHead": "c1b358ed44519f5c06ae22c72d6a25f9b363bfa4"
"gitHead": "650e9cd2f388653f6bdca662499c76cd6aca02e5"
}

@@ -1,4 +0,5 @@

# @commodo/fields
Creates a new function, whose instances are decorated with defined fields and a couple of useful methods (more information in the following sections).
# @commodo/fields [![](https://img.shields.io/npm/v/@commodo/fields.svg)](https://www.npmjs.com/package/@commodo/fields)
Enables defining rich data models by decorating function instances with specified model fields. Additionally, it adds `populate` and `validate` methods, for populating model instances with data, and then validating it, respectively.
## Usage

@@ -9,6 +10,20 @@ ```js

// User function (data model).
const User = compose(
withFields({
// A field which accepts string values.
email: string(),
previousEmails: string({ list: true }),
// Set "list" to true in order to store a list of string values.
previousEmails: string({ list: true }),
// A field which accepts boolean values.
verified: boolean(),
// A field that consists of nested fields. It can accept an instance of Company data model,
// or a plain object, from which a new Company instance will be created upon value assignment.
company: fields({ instanceOf: Company }),
// A field which accepts number values. Additionally, with the passed "validation" callback,
// we are ensuring that the assigned value is greater than or equal to 30.
age: number({

@@ -20,8 +35,7 @@ validation: value => {

}
}),
verified: boolean(),
company: fields({ instanceOf: Company })
})
})
)(function() {});
)();
// Company function (data model).
const Company = compose(

@@ -31,4 +45,5 @@ withFields({

})
)(function() {});
)();
// Let's create an instance of the User data model, and populate it with some data.
const user = new User();

@@ -45,16 +60,24 @@ user.populate({

// Throws an error with message "User too young".
// Using the "validate" method, we can check if the assigned values are valid.
// This will throws an error with the "User too young" message.
async user.validate();
```
## Fields
## Available fields
There are four types of fields you can define:
1. `string` - accepts `null` and string values
2. `number` - accepts `null` and number values
3. `boolean` - accepts `null` and boolean values
4. `fields` - accepts `null`, a plain object or an instance of another `withFields` function
Out of the box, there are four types of fields you can utilize:
1. `string` - accepts string values
2. `number` - accepts number values
3. `boolean` - accepts boolean values
4. `fields` - accepts a plain object or an instance of another `withFields` function
In the following examples, all types of fields are utilized:
```
```js
// Company function (data model).
const Company = compose(
withFields({
name: string()
})
)();
const User = compose(

@@ -67,19 +90,70 @@ withFields({

})
)(function() {});
)();
```
Note that if the data type of a value is different than field type, an error will immediately be thrown:
## Data validation
### Data-type validation
When a value is assigned to a field of a model instance, it is immediately validated on a data-type level, meaning you cannot pass a string value to a field that doesn't accept strings.
Consider the following example:
```js
import { withFields, string, number } from "@commodo/fields";
const User = withFields({
name: string(),
age: number(),
})();
const user = new User();
// Will throw data type error, because we cannot populate the "age" field with a string
// value. Since the field accepts only numbers, the age must be an integer or a float.
user.age = "7";
// The same will happen here.
user.populate({ name: "Rex", age: "7", drools: false });
```
const User = compose(
withFields({
email: string()
})
)(function() {});
Data-type validation is always executed upon value assignment, synchronously.
### Custom validation
Additionally, you can also add your own custom, business logic related, validation. Unlike the data-type validation, which happens immediately upon assigning the value to a field, the custom validation is triggered by calling the `validate` method. Note that this method validates the whole model instance.
The following snippet shows how we can add your own custom validation and trigger it:
```js
import { withFields, string, number } from "@commodo/fields";
const User = withFields({
name: string({
validate: value => {
if (!value) {
throw new Error("Name is required.");
}
}
}),
age: number({
validate: value => {
if (value && value < 2) {
throw new Error("Your dog is to young.");
}
}
})
})();
const user = new User();
// Throws a WithFieldsError (code: "FIELD_DATA_TYPE_ERROR"):
user.email = true;
// Will throw an error, since the dog is too young.
user.populate({ name: "Rex", age: 1 });
await user.validate();
// The age is now correct, but now the name is missing.
user.populate({ age: 2 });
await user.validate();
```
Unlike the data-type validation, custom validation can perform asynchronous operations.
## Field options
Each field can accept a few options:

@@ -94,2 +168,3 @@ #### `list: boolean`

## Additional higher order functions
Except options, fields can also be enhanced with a couple of provided higher order functions:

@@ -105,5 +180,2 @@

#### `readOnly: Function => Function`
When enabled, field will no longer accept any value. Can be paired with `onGet` higher order function, to achieve "dynamic" fields (more on this in the next section).
## Reference

@@ -110,0 +182,0 @@

@@ -16,10 +16,7 @@ "use strict";

return {
valueSet: false,
setValue(value) {
if (this.valueSet) {
if (this.state.set) {
return;
}
this.valueSet = true;
return setValue.call(this, value);

@@ -26,0 +23,0 @@ }

@@ -12,4 +12,2 @@ "use strict";

var _ramda = require("ramda");
const withFields = fields => {

@@ -16,0 +14,0 @@ return baseFn => {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc