Git Product home page Git Product logo

astrohelm / metaforge Goto Github PK

View Code? Open in Web Editor NEW
3.0 1.0 1.0 342 KB

Library ๐Ÿ“ that allow you to describe data structures by subset of JavaScript syntax and validate them at runtime

Home Page: https://astrohelm.ru

License: MIT License

Makefile 4.20% JavaScript 95.80%
astrohelm javascript metadata metalanguage nodejs runtime-verification schema types zero-dependencies checker

metaforge's Introduction

MetaForge v1.0.0 ๐Ÿ•ต๏ธ

Describe your data structures by subset of JavaScript and:

  • ๐Ÿ“ Generate data relational structures (types, jsdoc, diagrams, migrations, etc.)
  • ๐Ÿ”Ž Validate it in runtime with strict & partial validations
  • ๐Ÿ‘€ Send it to other server to validate data consistency
  • ๐Ÿ› ๏ธ Handle it with custom modules
  • ๐Ÿ’‰ Calculate fields

Installation

npm i metaforge --save

Usage example

const userSchema = new Schema({
  $id: 'userSchema',
  $meta: { '@name': 'User', '@description': 'Schema for user testing' }, //? JSDOC
  phone: { $type: 'union', types: ['number', 'string'] }, //? number or string
  name: { $type: 'set', items: ['string', '?string'] }, //? set tuple
  phrase: (sample, parent, root) => 'Hello ' + [...parent.name].join(' ') + ' !', // Calculated fields
  mask: { $type: 'array', items: 'string' }, //? array of strings
  ip: {
    $meta: { '@description': 'User ip adress' },
    $type: 'array',
    $required: false,
    $rules: [ip => ip[0] === '192'], //? custom rules
    items: {
      $type: 'union',
      types: ['string', 'number', 'null'], // Array<string | null | number>
      condition: 'oneof',
      $required: true,
    },
  },
  type: ['elite', 'member', 'guest'], //? enum
  '/[a-Z]+Id/': { $type: '?number', isPattern: true }, // pattern fields
  address: 'string',
  secondAddress: '?string', // optional fields
  options: { notifications: 'boolean', lvls: ['number', 'string'] },
});

const systemSchema = new Schema({ $type: 'array', items: userSchema });

const sample = [
  {
    myId: 1,
    phone: '7(***)...',
    ip: ['192', 168, '1', null],
    type: 'elite',
    mask: ['255', '255', '255', '0'],
    name: new Set(['Alexander', undefined]),
    options: { notifications: true, lvls: [2, '["admin", "user"]'] },
    address: 'Pushkin street',
  },
  //...
];

systemSchema.warnings; // Inspect warnings after build
systemSchema.calculate(sample); // Will assign calculated fields
systemSchema.test(sample); // Schema validation
systemSchema.dts('SystemInterface'); // Typescript generation
systemSchema.pull('userSchema').test(sample[0]); // Subschema validation
systemSchema.pull('userSchema').test({ phone: 123 }, 'root', true); // Partial validation
systemSchema.pull('userSchema'); // Metadata: {..., name: 'user', description: 'schema for users testing'}

Docs

Copyright & contributors

Copyright ยฉ 2023 Astrohelm contributors. This library is MIT licensed.
And it is part of Astrohelm ecosystem.

metaforge's People

Contributors

sashapop10 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

sashapop10

metaforge's Issues

Custom checks

Describe the problem

const rule1 = sample => (sample > 5 && sample < 100);
const rule2 = sample => sample.toString().includes('.');
const schema = { type: 'number', rules: { items: [rule1, rule2], condition: 'allof' } };
schema.test(12.34) // true
schema.test(12) // false 
schema.test(3.4) // false

Fronted build

Describe the problem

We need to create metaforge browser build for frontend Apps.

  1. npm run build for build generation
  2. export from package.json for browsers

Schema namespaces

Describe the problem

const entities = new Map();
entities.set('User', {
    type: 'object',
    properties: {
        job: 'string',
        name: 'string',
        tasks: { type: 'reference', many: 'Task' }, 
        currentTask: { type: 'reference', one: 'Task' }
    }
});

entities.set('Task', { type: 'object', properties: { ends: 'date',  name: 'string' } });

const date = () => ({
    kind: 'scalar',
    test: sample => new Date(sample) ? true : false, 
    // ... Other custom type logic 
});

const namespace = new Namespace({ date }, entities);
const plan = { type: 'object', properties: { users: { type: 'array', items: ['User'] } }  } // May be just 'User'
new Schema(plan, { namespace }); 

JSDOC for type annotations module

Describe the problem

Paste metadata as JSDOC to type annotations

Input

({
 $id: 'User',
 $meta: { name: 'user', description: 'About user' },
 name: 'string',
 age: '?number'
});

// Output

/**
 * @name user
 * @description About user
 */
interface User {
  name: string;
  age?: number;
}

SQL Model

Describe the problem

const model = new Model(new Schema(plan));
model.migrate() // Will return sql migrations for model and submodels

Meta information & Builded tree export

Describe the problem

const plan  = { type: 'number', meta: { key: 'My favorite number' } }; 
new Schema(plan);
( {
    key: 'My favorite number',
    kind: 'scalar',
    type: 'number',
    //...
);

Custom types

Describe the problem

Allow users to pass their custom types

const types = new Map();

types.add('date', { 
   kind: 'scalar',
   build: sample => ...
   // Default structure
});

const plan = {
    type: 'object',
    properties: {
        job: 'string',
        name: 'string',
        // lastEntry: { type: 'date', format: 'd.m.y' }
        lastEntry: 'date' // Custom type
    }
};
new Schema(plan, { types });

FS Utilities

Describe the problem

Schema.require('/path/to/plans', options); // Map<Schema>
Schema.require('/path/to/plan.js', options); // Schema
schema.saveDTS('/path/to/plan.d.ts'); // Promise<void>
schema.savePlan('/path/to/plan.js'); // Promise<void>

Module for fields calculations

Describe the problem

Calculated schemas another words - Functional fields

const schema = new Schema({
  name: 'string',
  phrase: (parent, root) => 'Hello ' + parent.name + ' !',
})
const mode = true; // true - copy, false - assign; 
const sample = { name: 'Alexander' };
schema.calc(sample,true); // { result: { name: 'Alexander', phrase: 'Hello Alexander !' } };
sample; // { name: 'Alexander' }
schema.calc(sample); 
// If sample not an object in this mode - throw error
sample; // { name: 'Alexander', phrase: 'Hello Alexander !' }

Customizable errors output

Describe the problem

Give some options

{
    throw , // possible 'first' | 'all',  
    warnings, // 'as-errors' | 'warnings' | 'ignore' 
}

Generate Schema / Plan from sample

Describe the problem

Schema.fromSample({
   a: 1,
   b: 'test',
   c: [1, 2, 3]
});
// Output
({
   type: 'object',
   properties: {
       a: number,
       b: 'string',
       c: {
           type: 'array',
           items: ['number'],
           condition: 'anyof'
       }
   }
})

Modular schema

Describe the problem

Separate schema to different modules: test, types, other

Schema.modules // default modules
const module = (schema, options, plan) => {}; // Extend schema
new Schema(plan, { modules }); // provide custom
new Schema(plan); // Will generate schema with default modules 

Benefits

  • lightweight schemas
  • perfomance
  • custom behavior

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.