datalize-multi-language

1.1.1 • Public • Published

Datalize

此包修改自flowstudio/datalize,添加了多语言功能。

Parameter, query, form data validation and filtering for Koa and Express.

See also this post about it on the Toptal Engineering Blog.

npm npm license vulnerabilities dependencies

Installation

npm install --save datalize

Usage

Koa

const Koa = require("koa");
const Router = require("koa-router");
const datalize = require("datalize");
const field = datalize.field;
 
const app = new Koa();
 
// add any body parser
app.use(require("koa-body")());
 
const router = new Router();
 
router.post(
  "/",
  datalize([
    field("email", "E-mail")
      .required()
      .email(),
    field("firstname", "Firstname").required(),
    field("lastname", "Lastname")
      .required()
      .trim(),
    field("isTerms").bool(true)
  ]),
  (ctx, next) => {
    ctx.body = {
      status: "success",
      data: ctx.form
    };
  }
);
 
app.use(router.routes()).use(router.allowedMethods());

Express

const express = require("express");
const datalize = require("datalize");
const field = datalize.field;
 
const app = express();
 
// add any body parser
app.use(require("body-parser").json());
 
app.post(
  "/",
  datalize([
    field("email", "E-mail")
      .required()
      .email(),
    field("firstname", "Firstname").required(),
    field("lastname", "Lastname")
      .required()
      .trim(),
    field("isTerms").bool(true)
  ]),
  (req, res) => {
    res.send({
      status: "success",
      data: req.form
    });
  }
);

Methods

datalize(fields, options)

Creates Data object and returns validation middleware, which uses body as source. Result is set to context/request.form object.

datalize.params(fields, options)

Same as datalize(), but uses params as source. Result is set to context/request.data object.

datalize.query(fields, options)

Same as datalize(), but uses query as source. Result is set to context/request.data object.

datalize.field(name, label)

Returns: Field

Creates Field object.

datalize.set(name, value)

Sets global option for datalize.

datalize.set("autoValidate", true);

Options

type

Type: String, Default: 'form'

breakOnRequired

Type: Boolean, Default: true

If required error is returned, no other errors will be collected.

autoValidate

Type: Boolean, Default: false

Auto validates form and throws Data.Error if there is any error.

autoConvertToArray

Type: Boolean, Default: false

Auto converts field.array() fields to array.

error

Type: Error, Default: DataError

Error object thrown on autoValidate.

Filters

All filters and chainable.

field("rooms")
  .required()
  .int()
  .range(1, 20);
  • condition: can throw error
  • filter: updates value

field.required()

  • condition

field.requiredIf(nameOrFn, requiredValue)

  • condition
  • nameOrFn: String|function
  • requiredValue: any (optional) used only if nameOrFn is string

field.optional()

  • filter
  • The field is removed if value is undefined.

field.optionalIf(nameOrFn, requiredValue)

  • filter
  • nameOrFn: String|function
  • requiredValue: any (optional) used only if nameOrFn is string
  • The field is removed if value is undefined and conditions are passed.

field.patch()

  • filter
  • The same as optional but only if request's method is PATCH.

field.array()

  • filter
  • Returned value will be an Array.

field.container(children)

  • filter
  • children: Array
  • Creates container will children fields, can be combined with field.array().

field.split(separator = ',')

  • filter
  • Converts value to array via splitting by separator.

field.custom(fn)

  • condition, filter

field.bool(requiredValue)

  • condition, filter
  • requiredValue: Boolean (optional)
  • Converts to boolean and if requiredValue is provided, the field's value must be equal to it.

field.toggle(requiredValue)

  • condition, filter
  • requiredValue: Number (optional)
  • Converts to number (0, 1) and if requiredValue is provided, the field's value must be equal to it.

field.equal(compare)

  • condition
  • compare: any

field.default(defaultValue)

  • filter
  • defaultValue: any

field.nullable()

  • filter
  • Converts to null if is empty.

field.email()

  • condition

field.number()

  • condition, filter

field.uppercase()

  • filter

field.lowercase()

  • filter

field.trim()

  • filter

field.truncate(length)

  • filter
  • length: Number

field.range(min, max)

  • condition, filter
  • min: Number|String|Function (can be a number or name of a field or function that returns number)
  • max: Number|String|Function (can be a number or name of a field or function that returns number)

field.min(min)

  • condition, filter
  • min: Number|String|Function (can be a number or name of a field or function that returns number)

field.max(max)

  • condition, filter
  • max: Number|String|Function (can be a number or name of a field or function that returns number)

field.length(min, max)

  • condition
  • min: Number
  • max: Number

field.minLength(min)

  • condition
  • min: Number

field.maxLength(max)

  • condition
  • max: Number

field.int()

  • condition, filter

field.float()

  • condition, filter

field.id()

  • condition, filter

field.select(options)

  • condition
  • options: Array

File filters

field.file()

  • filter
  • Gets file from req.files object.

field.mime(types)

  • condition
  • types: Array

field.size(limit)

  • condition
  • limit: Number in Bytes

Custom filter

field.custom(function(value, result, ctx) {
  if (["optionA", "optionB"].indexOf(value) === -1) {
    throw new Error("{0} has invalid value.");
  }
});
 
field.custom(function(value, result, ctx) {
  return moment(value).format("YYYY/MM/DD");
});
 
field.custom(async (value, result, ctx) => {
  const typeValue = await result.getValue("type");
 
  if (type === "business") {
    return null;
  }
});

Using custom filter globally

const datalize = require("datalize");
const field = datalize.field;
 
datalize.Field.prototype.isSlug = function(chars = "a-z-") {
  const regexp = new RegExp(`^([${chars}]+)$`);
 
  // make sure to return this.add() or this object to allow chaining
  return this.add(function(value, result, ctx) {
    if (!regexp.test(String(value))) {
      throw new Error("{0} contains invalid characters.");
    }
  });
};
 
// then the filter can be used anywhere
datalize([
  field("slug")
    .required()
    .isSlug()
]);

Error handling

router.post(
  "/",
  datalize([
    field("email", "E-mail")
      .required()
      .email()
  ]),
  (ctx, next) => {
    if (!ctx.form.isValid) {
      ctx.status = 400;
      ctx.body = {
        status: "error",
        errors: ctx.form.errors
      };
 
      return;
    }
 
    ctx.body = {
      status: "success",
      data: ctx.form
    };
  }
);

Global error handling

Koa

datalize.set("autoValidate", true);
 
// add to very beginning of koa middlewares
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    if (err instanceof datalize.Error) {
      ctx.status = 400;
      ctx.body = Object.assign(
        {
          status: "error"
        },
        err.toJSON()
      );
    }
  }
});

Express

datalize.set("autoValidate", true);
 
// add to very end of express middlewares
app.use(function(err, req, res, next) {
  if (err instanceof datalize.Error) {
    res.status(400).send(
      Object.assign(
        {
          status: "error"
        },
        err.toJSON()
      )
    );
  }
});

License

MIT

Copyright (c) 2018 Andrej Adamcik

Package Sidebar

Install

npm i datalize-multi-language

Weekly Downloads

2

Version

1.1.1

License

none

Unpacked Size

31.5 kB

Total Files

9

Last publish

Collaborators

  • cocacms