GithubHelp home page GithubHelp logo

archetype's Introduction

archetype

Archetype is a library for casting and validating objects. It has exceptional support for deeply nested objects, type composition, custom types, and geoJSON.

CircleCI

const { ObjectId } = require('mongodb');
const moment = require('moment');

// `Person` is now a constructor
const Person = new Archetype({
  name: 'string',
  bandId: {
    $type: ObjectId,
    $required: true
  },
  createdAt: {
    $type: moment,
    $default: () => moment()
  }
}).compile('Person');

const test = new Person({
  name: 'test',
  bandId: '507f191e810c19729de860ea'
});

test.bandId; // Now a mongodb ObjectId
test.createdAt; // moment representing now

If casting fails, archetype throws a nice clean exception:

try {
  new Person({
    name: 'test',
    bandId: 'ImNotAValidObjectId'
  });
} catch(error) {
  error.errors['bandId'].message; // Mongodb ObjectId error
}

Archetypes are composable, inspectable, and extendable via extends.

Connect

Follow archetype on Twitter for updates, including our gists of the week. Here's some older gists of the week:

archetype's People

Contributors

bahmutov avatar damirsehic avatar mrister avatar vkarpov15 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

archetype's Issues

Numbers cast as strings

using [email protected]

const Archetype = require('archetype-js')
const Person = new Archetype({
  name: { $type: 'string', $required: true }
}).compile('Person')
const p = new Person({name: 42})
console.log('person is', p)

outputs

person is Person { name: '42' }

$transform with array cast

const NameType = new Archetype({
  first: { $type: 'string' },
  last: { $type: 'string' }
}).compile('NameType');

const Params = new Archetype({
  names: { 
    $type: [{ $type: NameType, $transform: JSON.parse }],
    $default: []
  }
}).compile('Params');

app.get('/', function(req, res) {
  const { names } = new Params(req.query);
  res.json(names.map(n => `${n.first} ${n.last}`).join(','));
});

run().catch(error => console.error(error));

async function run() {
  await app.listen(3000);

  const root = 'http://localhost:3000';
  const names = [
    { first: 'James', last: 'Kirk' },
    { first: 'Leonard', last: 'McCoy' }
  ];
  console.log(await superagent.get(`${root}`).then(res => res.text));
  console.log(await superagent.get(`${root}?names=${JSON.stringify(names[0])}`).then(res => res.text));
  let url = `${root}?names=${JSON.stringify(names[0])}&names=${JSON.stringify(names[1])}`;
  console.log(await superagent.get(url).then(res => res.text));
}

Get rid of compile()?

In hindsight, there doesn't seem to be any real need for compile(). The original intent was the ability to modify the type before actually compiling it. But because types already have pick(), omit(), transform(), etc. it isn't really necessary. The extra need to call compile() just adds an extra concept and makes it easier to shoot yourself in the foot.

Add ability to decorate an inherited class with `path()`, `omit()`, etc.

const Archetype = require('archetype-js')

const ABase = new Archetype({ x: { $type: 'string' } }).compile('ABase')

class A extends ABase {
  constructor(obj) {
    console.log('Called!')
    super(obj)
  }
}

const B = A.path({ y: { $type: 'string' } }).compile('B')

new B({ x: '1', y: '2' })

Currently errors out

Throw on extra

Hi. Currently, after defining a schema, if a user enters more fields than what is defined in the schema, the extra fields are dropped silently. Ex:

const Person = new Archetype({
  name: 'string',
  bandId: {
    $type: ObjectId,
    $required: true
  },
  createdAt: {
    $type: moment,
    $default: () => moment()
  }
}).compile('Person');

// first client on the website sends this
let userObject = {
  name: 'wagner',
  bandId: '000000000000000000000001',
  isHacker: true
}

let user = new Person(userObject);

// user.isHacker === undefined

I wonder if there are any plans to adding the feature of throwing on extra fields like what we currently have with mongoose strict mode.
Thanks.

Add `$transform`

To work around cases where we have to use inheritance to do things like trim strings before validating

lodash cloneDeep and cyclic data leads to "call stack size exceeded"

[email protected], using [email protected], results in "call stack size exceeded", presumably due to cyclic data in:

  • archetype/src/type.js - Type constructor method
  • archetype/src/index.js - Archetype constructor and visitObject methods

So, first questions: which uses of archetype are circular (and how detected), and can the circularities be avoided or addressed?

As for possible workarounds/solutions, which of the many deepClone alternatives would be appropriate?

One possible solution - rfdc - addresses circular structures, but at a %25 performance:

const clone = require('rfdc')(circles: true)
...
b = clone(a)

The key question its whether circularities can be eliminated, whether an across-the-board %25 performance reduction can be tolerated, or whether circularity can be detected, to determine which flavor of deep cloning should be applied.

Some (problematic) workarounds:

  1. replace lodash.cloneDeep with clone, in each file:

    • replace const cloneDeep = require('lodash.clonedeep'); with const clone = require('clone');
    • replace references to _.cloneDeep(...) with clone(...)
  2. replace cloneDeep with fclone, as discussed here.

The problem with each is that circular values are replaced with a string: '[Circular]', presumably problematic when dealing with types.

Ultimately, this needs to be fixed in archetype, as that's where reliance on lodash.deepClone breaks down.

Nested defaults don't act as you'd expect

var c = new Archetype({
  name: {
    first: {
      $type: 'string',
      $default: ()=>'jarryd'
    }
  }
}).compile('c')
> new c({})
c {}

> new c({name: {}})
c { name: {} }

> new c({name: {first: undefined}})
c { name: { first: undefined } }

> new c({name: {first: null}})
c { name: { first: undefined } }

new Object does not gets validated

I'm using Archetype for schema validation on a side project.
I'm using the compile option, but when I call the new constructor the object does not respect the $required rule.

Wha'ts I'm attempt to do is validate objetcts like mongoose, since archetype does not is a ODM, I can only validate the fields, plus, I'm attempted to do a password hash on a validation and gets the same message I received before.

import Archetype from 'archetype'
import { passwordHash } from '../crypto.js'

const authSchema  = new Archetype({
  name: { $type: 'string', $required: true },
  last_name: { $type: 'string', $required: true },
  password: { $type: 'string', $required: true },
  email: { $type: 'string', $required: (user) => passwordHash(user.password) },
  account_type: { type: 'number', $default: () => 0, required: true },
  date_created: { type: 'date', $default: () => Date.now() }
}).compile('users')

export const authModel = authSchema

Also, the default options doesn't set automatically. What could I'm doing wrong? Is this way that the things occur on the archetype wordl?

Thanks in advance.

support `$enum` validation natively

You should be able to specify an $enum:Array property on a field and have archetype automatically validate the field again that array without having to manually write the $validate function. I think this is a common enough use-case to be built in natively.

AGPL Licensed standard-error library

My organization and others such as Google will not allow use of libraries that have a transient dependencies on libraries licensed via the AGPL.

Google's Policy on AGPL
https://opensource.google/docs/using/agpl-policy/#:~:text=WARNING%3A%20Code%20licensed%20under%20the,NOT%20be%20used%20at%20Google.&text=Using%20AGPL%20software%20requires%20that,be%20licensed%20under%20the%20AGPL.

The standard-error library falls into this category.
https://github.com/moll/js-standard-error/blob/master/LICENSE

Which means we cannot use any libraries that use archetype.

Also filed an issue in the standard-error project
moll/js-standard-error#4

mpath <0.8.4 vulnerability

Github's Dependabot has started issuing warnings for any projects that have a dependency on mpath versions <0.8.4, due to CVE-2021-23438, so it's probably worthwhile to update archetype to use 0.8.4 so that projects further up the tree can incorporate the newer version of mpath.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.