GithubHelp home page GithubHelp logo

typestack / class-validator Goto Github PK

View Code? Open in Web Editor NEW
10.5K 62.0 762.0 6.37 MB

Decorator-based property validation for classes.

License: MIT License

TypeScript 99.81% JavaScript 0.19%
validation validator decorators typescript

class-validator's People

Contributors

0xflotus avatar adnan-kamili avatar braaar avatar christophercr avatar clashsoft avatar cyri-l avatar dependabot[bot] avatar dystopianprogrammer avatar edcarroll avatar felipesabino avatar greenkeeper[bot] avatar henrikra avatar honoluluhenk avatar iliyazelenko avatar jerradpatch avatar jucrouzet avatar kiancross avatar kiliandeca avatar mheironimus avatar michallytek avatar neilime avatar nonameprovided avatar pleerock avatar rmuchall avatar rubiin avatar salimlou avatar snyk-bot avatar vincent-chapron avatar vlapo avatar ytetsuro 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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

class-validator's Issues

Error "Validation.js Error: This library (validator.js) validates strings only" on number field

Hello,

I'm getting this error on a number field on my class:

Some model class...

@IsIn([
      Difficulties.EASY,
      Difficulties.MEDIUM,
      Difficulties.DIFFICULT
    ])
    public difficulty:number;
export class Difficulties {
  static EASY:number=0;
  static MEDIUM:number=1;
  static DIFFICULT:number=2;
};

According to this post looks like the validator.js library doesn't work anymore with fields that are not STRING: validatorjs/validator.js#505

Thanks, F.

add complete es5/es6 support

Right now its possible to use validator with es5/es6, but we can provide more features to make this experience smoother. List of todos:

  • add support of registering validation schema for target class
  • add support of registering custom validations without using decorators
  • make schema validation better
  • cover schema validation with tests
  • add samples with javascript, or javascript + babel + decorators?
  • add docs how to use class-validator with javascript
  • add docs how to use class-validator with system-js

IsEmpty and IsNotEmpty decorater mixed up?

Hello, I just tried to validate my class with the @isempty and @isnotempty , however I noticed, that these two decoraters do what the other should do. But when validating them manually, they show the correct result.

export function validObject(obj, groups, res): any {
    options.groups = groups;
    let valObj = validate(obj, options);
    valObj.then(errors => {
        if(errors.length > 0) {
            res.status(400).json(errors);
        }
    })
}

yields following result

[
  {
    "value": "test",
    "property": "_name",
    "children": [],
    "constraints": {
      "isEmpty": ""
    }
  },
  {
    "value": "",
    "property": "_accessCode",
    "children": [],
    "constraints": {
      "isNotEmpty": ""
    }
  }
]

With the same request I validated the class inside the constructor manually with new Validator() and printed the result.

         let val = new Validator();
        console.log(`Var name: '${this._name}'`);
        if(val.isEmpty(this._name)) { console.log("isEmpty")    }
        else                        { console.log("isNotEmpty") }

        console.log(`Var access: '${this._accessCode}'`);
        if(val.isNotEmpty(this._accessCode)) { console.log("isNotEmpty") }
        else                                 { console.log("isEmpty")    }

printed result:

Var name: 'test'
isNotEmpty
Var access: ''
isEmpty

skipMissing:true and error.target:false

Tried this but it doesnt seem to work, ie, the errors thrown by validation failure still have the "target" field.

validate(modelTradeByPartnerCountry,
                    {
                        skipMissingProperties: true,
                        error: { target: false }
                    })

http://localhost:4200/validator 404 (Not Found)

I have the following

import {
  IsNotEmpty,
  Matches,
  MinLength
} from "class-validator";

export class Language {
  @IsNotEmpty({
    message: 'Cannot be empty'
  })
  @MinLength(2, {
    message: "Minimum characters arg[0]"
  })
  first: string = ''

  second: string = ''
}

Running my angular-cli application always throws the console error

zone.js:101 GET http://localhost:4200/validator 404 (Not Found)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM5846:3fetchTextFromURL @ system.src.js:1154(anonymous function) @ system.src.js:1735ZoneAwarePromise @ zone.js:584(anonymous function) @ system.src.js:1734(anonymous function) @ system.src.js:2759(anonymous function) @ system.src.js:3333(anonymous function) @ system.src.js:3600(anonymous function) @ system.src.js:3985(anonymous function) @ system.src.js:4448(anonymous function) @ system.src.js:4700(anonymous function) @ system.src.js:406ZoneDelegate.invoke @ zone.js:323Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426
zone.js:461 Unhandled Promise rejection: Error: XHR error (404 Not Found) loading http://localhost:4200/validator
at XMLHttpRequest.wrapFn as _onreadystatechange
at ZoneDelegate.invokeTask (http://localhost:4200/vendor/zone.js/dist/zone.js:356:38)
at Zone.runTask (http://localhost:4200/vendor/zone.js/dist/zone.js:256:48)
at XMLHttpRequest.ZoneTask.invoke (http://localhost:4200/vendor/zone.js/dist/zone.js:423:34)
Error loading http://localhost:4200/validator as "validator" from http://localhost:4200/vendor/class-validator/validation/Validator.js ; Zone: ; Task: Promise.then ; Value: Error: Error: XHR error (404 Not Found) loading http://localhost:4200/validator(…)consoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
zone.js:463 Error: Uncaught (in promise): Error: Error: XHR error (404 Not Found) loading http://localhost:4200/validator(…)consoleError @ zone.js:463_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
zone.js:101 GET http://localhost:4200/validator 404 (Not Found)scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM5846:3fetchTextFromURL @ system.src.js:1154(anonymous function) @ system.src.js:1735ZoneAwarePromise @ zone.js:584(anonymous function) @ system.src.js:1734(anonymous function) @ system.src.js:2759(anonymous function) @ system.src.js:3333(anonymous function) @ system.src.js:3600(anonymous function) @ system.src.js:3985(anonymous function) @ system.src.js:4448(anonymous function) @ system.src.js:4700(anonymous function) @ system.src.js:406ZoneDelegate.invoke @ zone.js:323Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426

This is the only place in my small app that I am importing 'class-validator'.
Removing the import the cosole error goes away and the application is displayed.

When I comment the annotations as shown below - the console errors disappear:

import {
  IsNotEmpty,
  Matches,
  MinLength
} from "class-validator";

export class Language {
  // @IsNotEmpty({
  //   message: 'Cannot be empty'
  // })
  // @MinLength(2, {
  //     message: "Minimum characters arg[0]"
  //   })
  // @Matches(nounRegex, {
  //   message: 'Only letters, space, - and \' allowed'
  // })
  first: string = ''

  // @Matches(nounRegexOptional, {
  //   message: 'Only letters, space, - and \' allowed'
  // })
  second: string = ''
}

So it appears that the annotations are causing this issue.

Hope you can help.

IsInt validator syntax

The syntax has changed but i did not figure out how i could assign this without getting an error like this:
error TS2346: Supplied parameters do not match any signature of call target.

@IsInt({ min: 0, max: 20 }, { each: true })
public q4h: Number[];

I get also errors with

@IsInt({ min: 0, max: 20 }

Synchronous validation

Is it possible with v0.4 to reproduce the validateOrThrow functionality that was present in v0.3?

We have been using this lib to validate options passed into the constructors of modules/classes where we need to be synchronous. Unfortunately we can't target ES6 yet to get async/await support due to being pinned to node v4 and it'd be a non-trivial amount of work to rewrite the all of our bootstrapping to be asynchronous.

@length(), default message wording

with a length decorator of '@Length(0, 4)', with an field value of '12334', I get a error of 'XXXX must be shorter than 4 characters'. What the error means to me is XXXX < 4, but its actually XXXX<= 4 ?

Travis CI installation error: `typings: not found`

I got error during Travis CI building.

> [email protected] postinstall /home/travis/build/sanex3339/javascript-obfuscator/node_modules/class-validator
> typings install
sh: 1: typings: not found

This error comes after i removed typings package from package.json of my package.

Looks like "typings": "^1.3.1" must be in dependencies instead of devDependencies.

@Length minimum validation off by 1

Sorry, to give keep lodging issues, I am just using this validation lib a lot recently.

so I have this,

  @Length(2, 40)
  @IsString()
  BRIEF_DESCRIPTION : string =null;

when I enter '1' I get no validation error. When I have this

  @Length(2, 40)
  @IsString()
  BRIEF_DESCRIPTION : string =null;

and enter '1' I get an error 'BRIEF_DESCRIPTION must be longer than or equal to 2 characters'.

In addition, it seems @minlength(min: number), has the same issue? Where a validation error isn't returned unless @minlength(2) or greater?

using version 0.6.0

Building into single .js

I'm having trouble building the build/package *.js files into a single .js file. I have cloned the repo, ran npm install, tsd install, gulp compile and gulp packageFiles in it's root and it compiled perfectly.

What's the best entry point for the package, is it decorators/Validator.js? I'm still trying to get my head around compiling, concatenating and minifying typescript projects and their dependancies so apologies for the novice question. How do you use this in production? I have the following in a model file:

import {Validator} from "validator.ts/Validator";
import {NotEmpty, IsInt} from "validator.ts/decorator/Validation";

And great work on the project by the way, thanks very much for sharing it. I'm really looking forward to putting it to use.

question: groups confusion

@isdefined({groups: ["createCollections","updateCollections"]})
@isin(AllCollections.allLanguages)
subtitleLanguage: string=null;

if I call validation on group 'createCollections' it doesnt call 'IsIn'. So I have to add it to the group. But now its not called if I pass no group to the validator. Is this desired functionality? B/c I would be nice if it called the no group validation even when a group is specified. Like, in all groups I need IsIn to be called, however I sometimes need it to be defined.

Async validators & model passing

Currently the signature for validator interface is

export interface ValidatorInterface {
    validate(value: any): boolean;
}

This is fine for trivial validation, but more complex validation needs to be able to access the whole object, and also return promised booleans for async.

Proposed signature

export interface ValidatorInterface {
    validate(value: any, meta:ValidationMetadata): boolean | Promise<boolean>;
}

This will allow for

  • context-aware validators like @IsLongerThan('propertyName'), @RequiredIf('propertyName', 'value')
  • async validators like @UsernameAvailable

Notes:

  • If skipMissingProperties == true then a context aware validator will fail. The passed ValidationMetadata should pass the skipMissingProperties value through so that the validator can act appropriately.
  • Allowing promised validation will require a significant refactor to the Validator.validate method
    • It's probably best to refactor everything to be promise based - wrapping all calls with Promise.resolve() will allow both promised and basic validators to run
    • validateOrThrow would need a timeout(() => throw new ValidationError()) in the promise chain so the thrown errors escape. (for backwards compatibility).
    • validate would need a call signature of validate(object: any, validatorOptions?: ValidatorOptions): Promise<ValidationErrorInterface[]>. This would have to be a breaking change.

I downloaded it and it doesn't work

Hello, I'm new to Node, I need to use this validator in a project so I tried first to make it work in an example but it just doesn't.

I downloaded every thing, I place the cmd where I downloaded the stuff and I did 'npm install', then I put an html file inside class-validator-master\sample\sample1-simple-validation that contains the following:

<html>
<head>
	<title>Clases en TS</title>
</head>
<body>
<h1>Ejemplo JS</h1>
<section id="container"></section>
<script type="text/javascript" src="app.js"></script>
</body>
</html>

Then I go to the browser and I get the following error in the console:

VM147 app.js:2
Uncaught ReferenceError: require is not defined(…)(anonymous function) @ VM147 app.js:2

Thank you for your time.

0.4.0

Im going to release next 0.4.0 version. There are a lot of changes and improvements, and breaking changes too. Last breaking change I made today - I've changed ValidationError signature. Before releasing I wanted to ask you guys @zakhenry @DominicBoettger if there is something you think is wrong in this release, or something should be added/changed before this release.

Thank you

How to do an OR

Case:

if number = 9999.99 or is less than 1

how to do this, with two predefined annotations?

Property 'matches' does not exist on type 'typeof Validator'.

I have the following snippets

import {Validator} from 'class-validator/Validator'

console.log(Validator.matches('Tom', '[a-z]+', 'i'))

However, I keep getting the following error:

Property 'matches' does not exist on type 'typeof Validator'.

I am uncertain what is causing this. It seems simple enough.

Thanks

Nested validation skipmissing

I get the error:
[Error: Only objects and arrays are supported to nested validation]

I think it happens when nesting more than one hyrachie (and having no data in some objects).

What i tried to skip this error:

class subOptions implements ValidatorOptions {
public skipMissingProperties: boolean;
public groups: string[];
constructor() {
this.skipMissingProperties = true;
}
}
@ValidateNested(new subOptions())
public beforeRent: myclass;

Any ideas?

Thanks
Dominic

@IsUrl options not works

It seems what @IsURL options not works at all.

   /**
     * @type {string}
     */
    @IsString()
    @ValidateIf((options: IOptions) => Boolean(options.sourceMapBaseUrl))
    @IsUrl({
        require_protocol: true,
        require_valid_protocol: true
    })
    public readonly sourceMapBaseUrl: string;

Input string google.ru -> validator does not trows any errors.

Validate Promise API

I like this library but the API could be better. I'm talking about this:

validate(post).then(errors => { // errors is an array of validation errors
    if (errors.length > 0) {
        console.log("validation failed. errors: ", errors);
    } else {
        console.log("validation succeed");
    }
});

It would be better if the validate() reject promise on errors. To do that, this line should be replaced with:

const errors = executor.stripEmptyErrors(validationErrors);
return errors.length ? Promise.reject(errors) : Promise.resolve();

Then we simply work with validate() in async&await:

try {
    await validate(post);
    console.log("validation succeed");
} catch (errors) {
    console.log("validation failed. errors: ", errors);
}

And if you don't want to handle the errors (like in routing-controllers), you can just simply do that and it will throw error on errors:

await validate(post);
await postRepository.persist(post);
...

What do you think about this? It might be a breaking change, so you should publish this as a major version (to prevent auto update on npm install for older users) or we have to create a new name for the validate function with promise rejection behavior.

Rename package name

Looks like for some users (@amcdnl) its confusing to have a .ts postfix in the package name. What are suggestions for a new package name?

  • validator.ts (old name)
  • validator-ts
  • constraint-validator
  • .... ?

Use custom validations with json-schema file

Hi,

Currently, it is not possible to use custom validations with json-schemas in a JSON file.

Eventhough you can specify this in your schema file:

{
"name": "mySchema",
  "properties": {
      "myProperty": [
       { "type": "customValidation", "constraintCls": "myConstraintClass" }
      ],
  }
}

The custom constraint class is not picked up so the custom validation is not performed.

This does work when you use an schema object rather than a json file. so it seems that the mechanism that picks up the metadatas, expects an actual class in the "constraintCls" field of the schema, but for obvious reasons you can't provide such class instance in a JSON file.

IsInstance validator

Is exists like isInstanse validator for run time checking?

class Post {
  @IsInstance(User);
  user: User;
}

Thanks a lot!

More information needed on Manual Validation parameters

I come from a php background, where the validation libraries I’m used to, just return true or false (which is awesome), then I do whatever I want from there. So, I opted to use the “Manual validation” here (isEmail precisely), and it worked as expected. (I’m using in a Nativescript application BTW)
Problem is with the second parameter, “options”, whose properties are not mentioned at all in the documentation.
I just ended up setting allow_display_name, allow_utf8_local_part and require_tld to true without even knowing what they mean.
I’d appreciate if these properties (and others like allow_negative_sign_placeholder, host_whitelist and host_blacklist) are explained.

EDIT::
I tried to use the decorators way as shown in the first example, and it worked. BUT console.log("validation failed. errors: ", errors) just outputs 'validation failed. errors: [object Object]' in the terminal. So, I really want to stick with the “Manual validation"

Throwing an error if a field is null or undefined

the example using validation decorators,

e.g.

    @Field()
    @MinLength(125)
    @MaxLength(2000)
    mission: string;
TypeError: This library (validator.js) validates strings only
    at assertString (/var/www/demo-app/node_modules/validator/lib/util/assertString.js:9:11)
    at Object.isLength (/var/www/demo-app/node_modules/validator/lib/isLength.js:19:30)
    at Validator.isLength (/var/www/demo-app/node_modules/validator.ts/Validator.js:345:30)
    at Validator.performValidation (/var/www/demo-app/node_modules/validator.ts/Validator.js:586:29)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:47:37
    at Array.map (native)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:40:45
    at Array.map (native)
    at Validator.validate (/var/www/demo-app/node_modules/validator.ts/Validator.js:35:26)
    at /var/www/demo-app/node_modules/validator.ts/Validator.js:90:32

Inheritance support

Hello,

I'm in front of a problem when using the validate method.

I have an abstract class User with fields annotated with class-validator.

`export abstract class User {
id: string;

@MaxLength(200)
@Matches(Regex.REGEX_MAIL)
@IsNotEmpty()
@IsDefined()
email: string;

@MaxLength(50)
lastName: string;

@MaxLength(50)
firstName: string;

lastModifiedHeader: string;

}`

And an other class Artisan which extends User.

export class Artisan extends User { enterprise: string; }

When, in a component, I'm trying to validate an Artisan like this

artisan: Artisan = new Artisan(); validate(this.artisan, {skipMissingProperties: true}).then(...)

I have no errors.

But if I move the annotated fields from User to Artisan then no problem.

So is there a way for the validate method to considerate the inheritance ?

Best regard and thank you in advance.

Cannot find module 'validator.ts/Validator'

Hi,
I'm trying to use your library but I'm getting a strange compilation error.

Basically the compilation output message is Cannot find module 'validator.ts/Validator' for all files that have import * as Validator from "validator.ts/Validator";

All packages look in the right place and VSCode offers me the intellisense for your package, but the compilation doesn't work.

Any hint?
Thx

ts-node register?

In your gulp file you are doing some interesting evaluating to transform your typescript file on the fly, there is a project that is similar to babel/register for typescript called ts-node

In your gulpfile.js you would just do:

require('ts-node/register');
require('gulpfile')

Comparing password fields

I am using class-validator to validate my incoming requests in an express application and I am very happy with it.

Currently I am implementing a registration service, my request has two password fields, password and password2. I would like to compare them to each other but it seems that this functionality is lacking in class-validator.

Is class-validator able to handle this scenario already or is this a feature request?

ValidationErrorInterface and ValidationError cannot be typehinted

With the following snippet

import { validateAsync, ValidationOptions, ValidationError} from 'class-validator';
[...]

public validate(model:T, validationOptions?:ValidationOptions):Promise<T> {

    try {
      return validateAsync(model, validationOptions);
    } catch (e){
      if (e instanceof ValidationError){
        throw new ValidationException(null, e.errors);
      }
      throw e;
    }
  }

I get

src/common/stores/store.ts(37,24): error TS2304: Cannot find name 'ValidationError'.

Same issue elsewhere for the ValidationErrorInterface

Proposal: @IsArray validator

It would be nice if you add @IsArray validator.

For example i have following code:

@IsString({
    each: true
})
public readonly reservedNames: string[];

with this rule validator will not throw an error with string value assigned to the reservedNames property.

@IsArray validator should check only for array type, no matter - empty array or not.

Integration with Routing-Controllers

Hi,

Do you have some examples on how to integrate your two great frameworks? What would be the best strategy? Perhaps using Middlewares to keep everything using decorators?

Thanks for the great work!

ValidatidationError .toString()

It would be nice to define .toString() method for ValidationError which will return ValidationError.constraints messages as string.

if (errors.length) {
    for (let error of errors) {
         console.log(error.toString());
    }
}

Format for message something like (formatted string with new lines):

PROPERTY_NAME errors
    length: "PROPERTY_NAME must be shorter than 10 characters"
    contains: "PROPERTY_NAME must contain a hello string"

or

PROPERTY_NAME errors
    - PROPERTY_NAME must be shorter than 10 characters
    - PROPERTY_NAME must contain a hello string

"options" in ValidationDecoratorOptions interface should be optional

Hi,

I'm using this awesome library in my project and now I enabled the strictNullChecks option from TS to have more explicit types. Then I noticed that the "options" property in the ValidationDecoratorOptions interface is required. However, digging a bit in the source code I noticed that it is used ValidationMetadata class but only if is defined. This class implements the corresponding ValidationMetadataArgs interface where indeed the "options" (alias "validationOptions") are optional.

Therefore I think that the "options" property should be marked as optional in the ValidationDecoratorOptions.

It's an easy and quick fix...

$value not resolving in message templates

Hi,

  @MinLength(
      2, {
        message: (args: ValidationArguments) => {
          if (args.value.length < 2) {
            return "$value is too short, minimum length is $constraint1 characters $property";
          }
        }
      })
  first: string = ''

The $value interpolation is not being resolved in the returned messages. $constraint1 and $property are resolved.

Cheers

Joi?

Joi support would be cool :)

Improvement: isRequired

It would be helpful to have a isRequired decorator for some stuff.

In the meantime i will solve this with a custom validator

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.