Coder Social home page Coder Social logo

hapi-contrib's People

Contributors

adrivanhoudt avatar allbitsnbytes avatar arb avatar cjihrig avatar danielb2 avatar devinivy avatar geek avatar haikyuu avatar harrytruong avatar hueniverse avatar leesei avatar linclark avatar marsup avatar nlf 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

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

hapi-contrib's Issues

3rd party integration tests and secrets

Hi,

I am maintaining the bell module and we have built in providers which integrate with 3rd party services. Most of the services, have online versions that we can test against.

It would be very useful if the CI could actually run some live tests to ensure that PRs do not break anything with the 3rd parties or detect if 3rd parties have changed their APIs. Right now, I attempt to do it myself but it's manual work...

Practically this would mean the following:

My questions or concerns are the following:

  • Would it be possible to create "Hapi" credentials? (ie. for facebook, google, ...)
  • 3rd Party PRs would not be able to run those tests unfortunately (someone could easily leak the secrets otherwize).

Any thoughts?

Are you in?

With a governance model, a metorship program, and a pile of modules looking for new leads, it's time to open the doors and invite new contributors to take a leading role within the hapi.js community.

With the exception of the hapijs/hapi module, all other hapijs/* modules currently listed with Eran Hammer as lead maintainer are open for new leadership requests. Please take a look, and either reply to this tread, or contact Raquel, Ben, or Eran.

For more context: Wide Open

MrHorse: new contrib module

https://github.com/mark-bradshaw/mrhorse

I'd like to offer a new module to be included as a hapi contrib module. It's called MrHorse ("No sir, I don't like it") since it was originally conceived to help with authorization tasks. This was inspired by policies in the sailsjs project, but is more flexible, IMO. Policies in sails are basically for authentication and authorization only, but MrHorse can do just about any task that isn't specific to a particular route handler.

The idea of MrHorse is to allow you to take commonly repeated bits of code out of route handlers and centralize them in a "policy" to DRY up your code. Then, in accordance with hapi's configuration driven goals, you can assign that policy to any route that needs it.

The policy can run as either a pre or post handler, so you can use it to do authentication, authorization, data prefetching, etc. before your route handler gets executed, or you can do response modification, logging, etc after it is finished. It's extremely flexible.

Only one policy can live in a single file, but you can have multiple policies directories. So each plugin in your hapi app can have its own directory of policies. Or you can have a central policy directory.

Probably the best feature of using MrHorse and policies is that you can look at your routing setup and immediately tell which routes are getting bits of business logic run on them. Say you have a policy that does authorization checks to make sure a route is only accessible to admins, called "isAdmin". One glance at your route entries and you can see immediately which routes have that policy applied.

It looks like this:

server.route({
    method: 'GET',
    path: '/loggedin',
    handler: function(request, reply) {},
    config: {
        plugins: {
            policies: ['isLoggedIn']
        }
    }
});

server.route({
    method: 'GET',
    path: '/admin',
    handler: function(request, reply) {},
    config: {
        plugins: {
            policies: ['isLoggedIn', 'isAnAdmin']
        }
    }
});

In my projects I've used it for authentication, authorization, response modification, and logging. The flexibility of the system is very useful. Take a look and let me know if you want to pull it in. I'm open to renaming it.

https://github.com/mark-bradshaw/mrhorse

Code Reviews

I'm looking for other contributors who have a bit of free time here and there, and would be open to getting pulled in for code reviews. If you fit the bill, drop a line here please.

Must internals be declared if it's not used?

Currently the style guide says:

internals - must be declared as an object at the top of each module immediate following the require section

However, it seems bad practice to declare unused variables. I think the spirit of this is simply saying that only export and internals are allowed global variables, and this section simply specifies where it should be declared.

Thoughts?

Document shrinkwrap best practices

It's not too clear from the history of npm-shrinkwrap.json in hapijs/hapi what the guidelines are for maintaining it. Seems like it just snuck in unceremoniously via hapijs/hapi#2039.

I've noticed a few shrinkwrap-related issues filed in the hapi repo due to npm whatever --production, so it seems like a relevant thing to document.

Some notes I think would be cool to see:

  • tl;dr of why it's used
  • When it's okay to change it
  • Warning of what kind of bugs it could cause
  • Rationale for why it differs from the default npm shrinkwrap output

Handling tails

I am a big fan of tails and the way it allows you to quick reply.
Now I've come across a case where I don't really know how to handle it. Specifically error handling.

var dbTail = request.tail('db tail');

return Async.series({

    s1: function (callback) {

        return Async.map(request.payload, function (meeting, callback) {

            // do stuff ...
            // if error happens `return reply(error)`

            return callback(null, newValue);
        }, function (err, results) {

            if (err) {
                // I want to reply here with the error but also stop Async flow
                // if I reply with `callback(err)` it will throw and not show a decent error to client
            }

            reply(results)

            return callback(); // continue execution
        });
    },
    s2: function (callback) {

        // do something but only on success
    }
}, function (err) {

    dbTail(); // make sure tail is resolved

    if (err) {
        throw err; // not sure what else to do
    }

    return; // clarity
});

Version bumps when package.json updates

I understand that there is no need for version bump of module when there are only changes in tests.

I am not sure if I should bump version if there are changes in package.json in devdependencies - like moving to newer lab. I would think that there is no reason to bump version for that, but noticed that some people do it here. So wondering if there is consensus for this.

Thanks

Maintainer SLA

I would like us to get closer as a team to some basic SLA:

  • Issues
    • labelled within 3 days
    • assigned, closed, or labeled with help wanted or new contributor within 1 week
  • Pull requests
    • commented on within 3 days
    • merged, closed, or changes requested within 1 week

Anything else?

repository contribution expectations

Hi,

I'd like to open discussion on etiquette and roles for community contributors (lead maintainers) contributing to each others repositories.

For reference: https://github.com/hapijs/contrib/blob/master/Governance.md#lead-maintainers

It states the lead maintainer has final say over the repository that they lead, and I'm wondering what the practical implications of that should be, as we each have full read/write/admin access to the other's repos.

As an example that prompted me to bring this up at this time is that I was the recipient of a helpful direct contribution on the master branch of the 'glue' repo that I maintain. To be clear, I have no issue with this specific contribution, and I appreciate the update from cjihrig. But the event brought this topic back to my mind which I've previously considered from the opposite end - should I create a pull request and wait for the lead maintainer to merge it, or just push/merge the commits directly to the master branch of our community repositories myself?

There are the obvious cases - you don't go rewrite someone else's project. But I'd like to contribute more to various repos, but opening a pull request and discussing something that is seemingly a minor/trivial update has too much overhead at times when I'm just trying to get things done.

Can we generate some guidelines that encourages contributions, reduces surprises and helps each other out? Thoughts?

Chris

hapi-lts and peer dependencies

Today we published a new LTS version of hapi: hapijs/hapi#2765.

The reason for a separate module is that npm is painful to use for two active branches with latest tag management. However, this will prevent hapi-lts users to install plugins once we publish new versions of the LTS branch.

Options:

  • require npm v3 with the warning disabled.
  • publish lts versions of current modules (not ideal).
  • other?

If someone has a good way to managing npm parallel releases I'm open to that but my experience has been pretty bad in the past with hapi v8.

Standards on CI across projects

Hi all,

I've been refining my travis CI build configuration on joi for quite some time now, I think it's stable now.

I was wondering if it would be worth having the same setup across all our projects or if it really is up to the maintainer.

Builds seem to happen sooner and take less time than before, and auto-publishing packages from travis without the local artifacts I might have has been a great experience for me so far.

Thoughts ?

Module documentation changes

In support of outmoded/hapijs.com#227 we need to reorganize documentation in the plugins a little bit. Each module should have two markdown files in the root of their repositories with the content described below:

README.md

  • name of module
  • build status badges (travis-ci, etc)
  • name of lead maintainer
  • sponsorship information, if applicable
  • short description of the plugin
  • short example of a common use case (with code)
  • link to API.md

API.md

  • API documentation, in a format as similar to the API.md in hapijs/hapi as possible

this is another documentation change that would be a great place for new contributors to help out where possible.

Improve CI settings

As discussed in #28, here are 2 steps to improve our travis build process.
Of course don't add my config comments, that's just for clarification ;)

Cache and containerized CI

Add those lines to your .travis.yml :

sudo: false # Enables containerized CI

# The following is all to deal with cache
cache:
  directories: # Which directories to keep between builds
    - node_modules
install: npm update # Since the modules are cached, we have to update on every build

NPM release

If you also want to publish new versions to npm after a successful build on a tag, first install the travis CLI.
Then do a travis setup npm and answer the few questions (you have to fill information of someone with publish authorization on npm).
Once done, you'll have a basic npm deploy section which should be completed accordingly :

deploy:
  provider: npm
  email: <some email>
  api_key:
    secure: <encrypted api key>
  on:
    branch: master # Only deploy on master
    tags: true # Only deploy on tags
    repo: hapijs/joi # Probably auto-filled, can't remember
    node: "0.10" # Only deploy one of the version, pick one, otherwise travis will try to publish on all CI versions (and probably fail)

Form a Code of Conduct committee

The committee will be responsible for maintaining and administrating the Code of Conduct and set the rules under which it will operate. The committee will have a lead which will be elected by the committee for a set period of time (an exception to the governance rules).

Please reply if you would like to join the committee.

API.md

I would like to suggest a new common style. Every module should have an API.md file instead of keeping the API docs in the README.md. This will allow us to automatically generate pretty API docs for all the modules and plugins on the hapijs.com site. It needs to follow the exact same structure rules of the hapi/API.md file (which would be great if someone documented).

License

What's the license of these documents?

Browser support

This is coming up over and over again. See hapijs/boom#58 for some context. Basically, someone wants to use a hapi.js module in the browser but whatever they use to make that work is grabbing a pile of shit with it (like the entire http module, or other dependencies with large footprint).

Whenever that happens we get into long arguments about why we do or do not care about this use case and if the proposed changes are worth the hassle.

My position on this is simple - hapi.js is a server-side ecosystem. Period. If we can accommodate client side usage without extra effort, great. If we can't, we should at a minimum require proof that there is an equally big market for the module on the client side before even engaging in the effort. It seems to me that most of these issues could be resolved by improvements to browerify and other such solutions than constantly requesting changed to the modules.

In addition, once we agree to make such changes we are basically committing the module to browser compatibility which is a significant limitation on it's growth.

The most I have agreed in the past was to add some fields to the package.json file to help client-side tools handle the module. But I have rejected requests to make code changes to allow the same code to work on both platforms.

I think we should have a community policy on this to guide maintainers on how to respond (while allowing them to decide on the final outcome on a case-by-case basis).

Editor configuration and style guidelines

While lab provides great enforcement around the hapi style guidelines, I find myself constantly needing to reconfigure my editor as I move between hapi projects and other open source projects. The main culprit is tabs vs. spaces for indentation. On other projects I have used EditorConfig to help alleviate this issue. Adding an .editorconfig file with something like the following could make it easier and more convenient to adhere to the hapi style guidelines (if a developer uses an editor with EditorConfig support):

root = true

[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

[*.{json,yml}]
indent_size = 2

I'm open to other suggestions on how to manage this issue as well.

Thanks

As I was sitting here wiring up some Joi validations in Hapi while listening to some sappy acoustic music, I was thinking: "wow, if I had to write all of this from scratch, I'd throw myself into oncoming traffic." That said, just wanted to give a shout-out to everyone who's contributed to the Hapi ecosystem, especially @hueniverse and the original core team; you've saved me a lot of time, money and headaches and that should be recognized. If my product ends up making any money one day, it'd be good to buy everyone a beer or preferably some really good whiskey.

Looking forward to getting more involved in the community.

James

Conflict: usage of hasOwnProperty check gives coverage issues

Use for with arrays, for...in for objects (and always check hasOwnProperty())
https://github.com/hapijs/contrib/blob/master/Style.md#for-loops

Using the advised for...in syntax is practically impossible while still following 100% coverage rules together with style guideline. Causing a failing if check there is impossible when just declaring something as an object moments earlier.

In order to "follow" guidelines, we end up writing Object.keys(obj) instead and iterating over that result for the 100% coverage. However, that conflicts with the mandate to use for...in

So can this rule be revised so both 100% code coverage and style can be followed?

I suggest not requiring hasOwnProperty for locally defined objects. If a variable is declared earlier, (e.g. internals.staticObj), then it shouldn't be an issue.

"Enforcing new on constructor" style prevents inheritance?

Enforcing new on Constructor

  • Use this.constructor === to check if a constructor function was called with new
// Right
Hoek.assert(this.constructor === Server, 'Server must be instantiated using new');

// Wrong
Hoek.assert(this instanceof Server, 'Server must be instantiated using new');

https://github.com/hapijs/contrib/blob/master/Style.md#enforcing-new-on-constructor

I'm sorry if this is a dumb question, but I couldn't find documentation on why this style exists. By asserting this.constructor === Server, prototypical inheritance breaks. Was this intentional?

// helper to enforce new on constructor
function assertUseNew(ctx, constructor) {
    // breaks for example below
    if (ctx.constructor !== constructor) throw 'Use new!';

    // works for example below
    // if (!(ctx instanceof constructor)) throw 'Use new!';
}

// this inheritance helper comes from babel (6to5)
function inherits(subClass, superClass) {
    subClass.prototype = Object.create(
        superClass.prototype,
        { constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        } }
    );

    Object.setPrototypeOf(subClass, superClass);
}


// base class of "Foo"
var Foo = function (key) {
    assertUseNew(this, Foo);
    this.key = key;
}

// child class of "Bar" (style of inheritance comes from babel/6to5)
var Bar = (function (_Foo) {
    inherits(Bar, _Foo);
    function Bar(key) {
        Object.getPrototypeOf(Bar.prototype).constructor.call(this, key);
        assertUseNew(this, Bar);
    }
    return Bar;
})(Foo);


var foo = new Foo(true);
console.log('Successful foo: ' + foo.key);
try {
    var foo = Foo(true);
} catch(e) {
    console.log('Successful Foo non-new error.');
}

var bar = new Bar(true); // <========================== !!!
console.log('Successful bar: ' + bar.key);
try {
    var bar = Bar(true);
} catch(e) {
    console.log('Successful Bar non-new error.');
}

console.log('Successful inheritance: ' + (bar instanceof Foo));

When ctx.constructor !== constructor is used, the var bar = new Bar(true); line breaks. Uncomment !(ctx instanceof constructor) to confirm it works just fine.

What was the rationale for ctx.constructor !== constructor?

Town Hall Meeting/Fireside Chats

I was wondering if we wanted to take a page from the IO folks and have like public Google Hangouts every so often to discuss things of import in the hapijs universe. It would be attended by a some lead maintainers and anyone in the community could jump on to submit questions. I think it could be a fun way to interact with the community in a more personal way than text on GitHub issues.

Is this something that anyone would be interested in?

Display sponsors somewhere

We don't list the companies that sponsor hapi or the site anywhere. I think we should have a place to list these companies and recognize their efforts.

For general sponsorship (i.e. companies that have developers who contribute a large portion of time to hapi) I would propose a special section in the Community page on the site, something to set them apart and bring attention to them.

For the site, maybe a small notice in the footer or sidebar?

The bigger question becomes, how do we determine what companies get listed where? Does anyone else have any thoughts?

Mentorship program

@nvcexploder: What's the status of the program? How many people are paired? Do we know if they are working together? How many people waiting to be paired (either side)? Do we need to add more people to help facilitate the program?

Assertion library in tests

I noticed that test scripts are defined with the -a code option in the hapijs repositories:

"test": "lab -a code -t 100 -L",

However this adds no value, because Code is used directly in test files:

var Code = require('code');
var expect = Code.expect;

So I'm curious, is there a reason why -a code is used, but var expect = Lab.assertions.expect; is not?

ES6 style: heads up

I am going through all the hapijs modules hapi depends on and publishing new major versions with the new ES6 style applied. This will remove node 0.x support and will upgrade to lab 7 which comes with new linting rules. This has to be done in a specific order otherwise we will be publishing new modules forever. I will be doing it for all modules hapi depends on and will open issues on the rest once the core modules are done.

Call for new maintainers

Here are the modules looking for new maintainers:

If you would like to be the new lead maintainer, start by submitting a few pull requests with additional documentation and tests, updating the module to the latest dependencies, etc.

To ask to be the new lead maintainer add a comment in the pull request so that the request is attached to actual contribution.

First come first served.

Security CI

I was wondering if we needed some kind of security checks in our CIs, like nsp or snyk. I'm not so worried on our direct dependencies because it's often watched closely, but more on the indirect ones which we might not monitor that much. Any opinions on that matter ?

Repo style cleanup

We need to apply this to all hapijs modules:

  • Remove Makefile and switch to using npm scripts (see hapi package.json)
  • Remove root index.js (point package.json to lib/index.js)
  • Replace package.json licenses array with single license key and "BSD-3-Clause" value
  • Update code style to stop putting functions on single line (new lab will error on that lint warning)

If you are looking for ways to help, submitting pull requests to the various modules would be great.

Header graphic

Some of the hapi ecosystem packages have a distinctive graphic up top with the funky image and font. Where are those coming from?

Node 0.12

Now that node 0.12 is (finally) released, what's our plan for supporting it ?

I've enabled it on the projects I maintain, no sign of trouble in CI so far, but they don't rely on node core features that much.

Coveralls.io

I'm the lead maintainer over at hapijs/isemail.

To my knowledge, we're currently using Travis CI as our only integration point. I'd like to also use coveralls.io for automated code coverage. It basically just gives the tests an API to hit from Travis CI that will update coverage analytics and a badge. This integration requires granting coveralls organization access on GitHub, and I'd like to give any interested parties an opportunity to shoot down or approve this idea.

I'm not married to coveralls, if you have a recommendation for another code coverage service, I'm all ears. I realize that this kind of integration isn't necessarily useful for all hapijs projects, but it's more significant for an email address validator than some other projects.

Using milestones

When using milestones, please follow these guidelines:

  • There should always be one open milestone setup.
  • When closing a milestone, create a new one incrementing the patch number (x.x.patch).
  • When assigning an issue to a milestone that is not just a bug fix but a new feature or breaking change, edit the milestone to reflect the new version. This is critical as it is the only clear way to communicate between collaborators what the changes in master include.
  • Do no assign milestones to questions, discussions, any issue that does not result in a code change, documentation, examples, or pure tests changes. This keeps the changelog clear and easy to follow.
  • When publishing a new version to npm, tag master with git tag -a v1.2.3 -m 'version 1.2.3' and git push origin --tags. Then close the milestone matching the release and create a new one.

Makefile

Hello,

I'm experimenting about Windows CI through AppVeyor, my current blocker is we use makefiles, and Windows doesn't have make, and I don't really want to go through the hassle of installing make.
Since all it's doing most of the time is running lab, my proposition is to only use npm scripts.
Opinions about the downsides of such solution ?

GitHub releases

Should we use them? Does anyone care? I find tags and issues to work just fine.

Proposal for allowed ES6 features in hapi

Now that hapi 10 is out and using Node 4, we need to consider which ES6 features (and general JS features) should be allowed in hapi modules, as well as style guide issues, etc. To get the discussion going, here is a list that @arb and I came up with.

Strongly Recommend

Strict Mode

Strict mode makes JavaScript more restrictive. It prevents the use of several features that are considered bad practices. It also enables certain new language features. In the past it has been known to help V8 (unsure if this is currently true as V8 changes rapidly). It is trivial to enable. Node core has moved to strict mode everywhere.

Object.assign()

Object.assign() is the preferred way to copy/merge objects. This can be used as a replacement for foo || {} (simpler code coverage), as well as several Hoek methods.

const

const is used to define constants. const can be used to declare a surprisingly large number of variables that are not what would normally be considered "constants." For example, in Node core, it has become a convention to use const foo = require('foo');. In general, const should be favored and used in any case where a variable’s value doesn’t change.

Map and Set

Node now offers proper map and set data structures. According to six-speed the performance is better than the ES5 alternatives. Maps are preferred over using objects as key-value stores (although this can present problems when returned from public APIs, but works perfectly fine for internal APIs).

New Math and Number Methods

New methods such as Number.isInteger() make tasks like checking for an integer, much more readable. Methods like Number.isNaN() provide a stricter alternative to the global isNaN().

Nice to Have

Template Strings

Template strings are used as an alternative to string concatenation and often require a few less characters. Performance may still be slightly worse according to six-speed. This is currently used in Node core.

Classes

Classes are syntactic sugar. They currently require strict mode. One thing worth noting is that six-speed indicates super() performs poorly.

Numeric Literals

The old way of declaring octal literals is forbidden in strict mode. The new octals, as well as binary constants, are more intuitive. This is probably not very common in the hapi ecosystem, but should be allowed, if needed, for readability.

Use with Caution

Object Literal Shorthand and Computed Properties

If deemed suitable, these should be allowed. However, computed properties were broken until relatively recently. According to six-speed, there is a significant performance penalty (although a more fine grained breakdown of shorthand vs computed properties would be nice).

Arrow Functions

Arrow functions do not clobber the existing this value, making them very useful as callback functions. However, there are a number of ways to burn yourself with them:

  • Their behavior changes slightly depending on their syntax. Strongly recommend enforcing the use of both () and {}.
  • Anytime this is important. For example, when using this inside of an object literal.
  • Arrow functions throw when used as the right hand side of the instanceof operator.

let

let provides block scoping, and in the general case is comparable to var. However, there are some cases where it breaks down. See Trevor Norris's comments here.

Things to Avoid

Symbols

Symbols allow you to more effectively hide data. I haven't encountered problems with them, but also don't see a real need for them.

General

Anything that is still behind a flag. These features are generally not complete, hence the flag. If you run into trouble, you will be sent to the V8 issue tracker.

References

Community CI service

The hapi ecosystem is getting big, much bigger than anyone can keep track of. This is particularity true for hapi itself. It is becoming very hard to ensure that changes which pass all the hapi tests, are not breaking other modules, including tightly coupled ones like inert (file and directory handlers), h2o2 (proxy handlers), and vision (views engine).

It would be awesome is someone(s) will take on the project of building a community service where people can register their open source work, and every time there is an update (publish or commit, open for debate) on any of the core framework modules, it will test those out.

Some of these projects can be nothing but tests to ensure your private code will not break without exposing it.

The npm package popular is still available...

Contact Info

I think anyone who is set up to be a Lead Maintainer on a Hapijs repo should have an email associated with their GitHub account so it's possible to contact them directly. Thoughts?

pez

looks like you're going to be basing it off of multiparty. why not just continue maintaining multiparty instead (like with qs)?

Help facilitate the mentors program

We got a great start with the fantastic work @nvcexploder put in but we need more help from people to facilitate the program, support the mentors, recruit more mentors, and use the program to help increase diversity.

If you are good at organizing and would like to help the hapi.js community in a non-technical role, this is a great role (you can always help with code!). I would like to add 2-3 new people to work on the program.

If interested, please reply here or to [email protected]. Same if you have any questions.

Test

Added some examples to the test document.

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.