Git Product home page Git Product logo

omise-node's Introduction

omise-node

Please contact [email protected] if you have any question regarding this library and the functionality it provides.

Omise Node.js bindings.

Installation

From NPM

$ npm install omise

The library has been tested with Node version 4.4.6.

Code Status

Node.js CI Code Climate

Usage

Flow

  1. User enters the credit card information on your website or application using a form.
  2. The card information is sent via HTTPS directly from the client to Opn Payment Servers using Omise.js, Card.js or Omise-iOS SDK.
  3. If the card passes the authorization, then your frontend will send the token to omise-node backend to finally capture the charge with Omise-node.

The code

After you have implemented Omise.js on your frontend. You can charge the card by passing the token ( if card.security_code_check is true ) to omise-node backend.

To implement omise-node as your backend code. You have to configure the library by passing the secret key from https://dashboard.omise.co/ to omise export, for example:

var omise = require('omise')({
  'secretKey': 'skey_test_...',
  'omiseVersion': '2019-05-29'
});
omise.charges.create({
  'description': 'Charge for order ID: 888',
  'amount': '100000', // 1,000 Baht
  'currency': 'thb',
  'capture': false,
  'card': tokenId
}, function(err, resp) {
  if (resp.paid) {
    //Success
  } else {
    //Handle failure
    throw resp.failure_code;
  }
});

Please see Opn Payments Documentation for more information on how to use the library.

Important Note:

Full Credit Card data should never touch or go through your servers. That means, do not send credit card data to Opn Payments from your servers directly unless you are PCI-DSS compliant.

The token creation method in the library should only be used either with fake data in test mode (e.g.: quickly creating some fake data, testing our API from a terminal, etc.), or if you are PCI-DSS compliant, send card data from your server. You must achieve and maintain PCI compliance at all times following Security Best Practices

So, we recommended that you create a token using the omise.js library that runs on the browser. It uses Javascript to send the credit card data on the client side to Opn Payments. You can then populate the form with a unique one-time use token, which can be used later on with omise-node or Omise.js. By using this library, you can build a credit card payment form window and create a card token, which you can use to create a charge with omise-node.

For both methods, the client will directly send the card information to the Opn Payments gateway; your servers don't have to deal with card information at all. The library reduces the risk of supporting card payments.

Please read Collecting card information for an explanation on collecting card information.

Examples

Create a customer with card associated to it

Creating a customer can be done by using omise.customers.create that accepts an optional card argument. When you pass in a tokenId retrieved from omise.js, the card associated to that token will be associated to the customer.

omise.customers.create({
  'email': '[email protected]',
  'description': 'John Doe (id: 30)',
  'card': 'tokn_test_4xs9408a642a1htto8z' //tokenId
}, function(err, customer) {
  var customerId = customer.id;
  console.log(customerId);
});

List all customers

After customers are created, you can list them with customer.customers.list by passing a callback to it. The object returned from the list API will be a list object. You can then access the raw data using the data attribute:

omise.customers.list(function(err, list) {
  console.log(list.data);
});

Retrieve a customer

You can retrieve the created customer by using omise.customers.retrieve and passing a customer ID to it, e.g.

omise.customers.retrieve(customerId, function(err, resp) {
  console.log(resp.description);
});

Updating a Customer

To update customer information, use omise.customers.update and pass a customer ID and an object containing changes:

omise.customers.update(customerId, {
  description: 'Customer for [email protected]'
}, function(err, resp) {
  console.log(resp.description);
});

Promise support

The library also supports the Promise/A+ interface that shares the same API method as the callback one, for example:

omise.tokens.retrieve('tokn_test_4xs9408a642a1htto8z', function(error, token) {
  return omise.customers.create({
    email: '[email protected]',
    description: 'John Doe (id: 30)',
    card: token.id
  });
}).then(function(customer) {
  // And we make a charge to actually charge the customer for something.
  console.log(customer.id);
  return omise.charges.create({
    amount: 10000,
    currency: 'thb',
    customer: customer.id
  });

}).then(function(charge) {

  // This function will be called after a charge is created.

}).catch(function(err) {

  // Put error handling code here.

}).finally();

Error Handling

To handle an invalid request, it is required to check any error using an Error object that includes code and message attributes as stated in Errors. However, for any valid request, checking failure_code and failure_message is required, for example: If you'd like to create a Charge or a Transfer with a valid request, a sucessful charge or tranfer happens only when there are no failutes - that means both failure_code and failure_message must be null.

Resource methods

The following API methods are available. Please read Opn Payments documentation for details.

  • account
    • retrieve()
    • update(data)
  • balance
    • retrieve()
  • charges
    • create(data)
    • list([data])
    • retrieve(chargeId)
    • capture(chargeId)
    • createRefund(chargeId[, data])
    • update(chargeId[, data])
    • reverse(chargeId)
    • expire(chargeId)
    • schedules([data])
  • customers
    • create(data)
    • list([data])
    • update(customerId[, data])
    • destroy(customerId)
    • retrieve(customerId)
    • listCards(customerId[, data])
    • retrieveCard(customerId, cardId)
    • updateCard(customerId, cardId[, data])
    • destroyCard(customerId, cardId)
  • tokens
    • create(data)
    • retrieve(tokenId)
  • transfers
    • create(data)
    • list([data])
    • retrieve(transferId)
    • update(transferId[, data])
    • schedules([data])
  • transactions
    • list([data])
    • retrieve(transactionId)
  • disputes
    • list([data])
    • listClosed()
    • listOpen()
    • listPending()
    • retrieve(disputeId)
    • update(disputeId[, data])
  • recipients
    • create(data)
    • list([data])
    • update(recipientId[, data])
    • destroy(recipientId)
    • retrieve(recipientId)
  • events
    • list([data])
    • retrieve(eventId)
  • links
    • create(data)
    • list([data])
    • retrieve(linkId)
  • sources
    • create(data)
  • schedules
    • create(data)
    • destroy(scheduleId)
    • retrieve([scheduleId])
  • search
    • list(data)

Testing

There are two modes of testing.

To test without connecting to the remote API server:

$ npm test

To test by connecting to the actual API server, you must first obtain public and secret keys and export them:

$ export OMISE_PUBLIC_KEY=<test public key>
$ export OMISE_SECRET_KEY=<test secret key>
$ NOCK_OFF=true npm test

Contributions

Before submitting a pull request, please run jscs to verify coding styles and ensure that all tests pass:

$ npm run jscs
$ npm test

You could use also use a Git pre-commit hook to do this automatically by aliasing pre-commit.sh to the Git pre-commit hook:

ln -s ./pre-commit.sh .git/hooks/pre-commit

Adding new resources

Resources are handled via apiResource. To add a new resource, create a new resource file named lib/resourceName.js with the following content:

var resource = require('../apiResources');
var resourceName = function(config) {
  return resource.resourceActions(
    'resourceName',
    ['create', 'list', 'retrieve', 'destroy', 'update'],
    {'key': config['secretKey']}
  );
}

module.exports = resourceName;

Then register the newly created resource to lib/apiResources.js as e.g. resourceName('resourceName'). Pre-built actions are: create, list, retrieve, destroy and update.

Requests mocking

Request mocks are stored as test/mocks/<resource>_<action>.js.

omise-node's People

Contributors

aashishgurung avatar ajzkk avatar anasnaouchi avatar bigomise avatar chalker avatar cpv123 avatar danfowler avatar dependabot[bot] avatar die-tech avatar fred avatar fujiharuka avatar gitter-badger avatar glim-palo avatar jacstn avatar jun-omise avatar keeratita avatar kraikov avatar mazon avatar muthuswamyopn avatar panj avatar phureewat29 avatar probir03 avatar rezigned avatar sirn avatar snyk-bot avatar tonmanna avatar turboza avatar varshard avatar wingyplus avatar zdk 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

omise-node's Issues

Webpack fails to bundle library because of dependency expressions

Recently I tried using this library with Next.js API Routes, but was unable to do so because the Webpack bundling (which Next.js uses for both frontend and backend by default) did not work properly.

The issue occurs because this library uses 'dependency expressions' - file names are generated and required using a function meaning Webpack cannot resolve them statically.

Specifically, this happens at https://github.com/omise/omise-node/blob/master/lib/apiResources.js#L6

function resourceName(name) {
  return require(['./resources/', name].join(''))(omiseConfig);
}

The fix is to require the files using their full names hardcoded e.g.

require('./resources/Source`)

Slightly more code, but should enable the use of this library with Webpack and therefore Next.js.

I have raised a PR to fix this: #141 #166

Got an "Unexpected end of JSON input" error

Hi,

We got this Unexpected end of JSON input error in about 1% of the transaction. I have tried to investigate the library itself but could not find anything. I will try again with DEBUG_OMISE=true and wait for the issue to occur. I'm still not sure if the problem is the library itself or the response from the server is invalid JSON format.

Here's error message.

error:  SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at IncomingMessage.<anonymous> (/app/node_modules/omise/lib/api.js:20:23)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:188:7)
    at endReadableNT (_stream_readable.js:975:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickCallback (internal/process/next_tick.js:104:9)

Missing IRequest

Getting the error when running tsc command - "node_modules/omise/types/index.d.ts(39,26): error TS2304: Cannot find name 'IRequest'."

index.d.ts - updateAccount(req: IRequest, callback?: ResponseCallback<IAccount>): Bluebird<IAccount>;

Cannot call create from omise.schedules

I followed the documentation but got this error

omise.schedules.create({
    'every': 2,
    'period': 'day',
    'start_date': '2017-05-01',
    'end_date': '2018-05-01',
    'charge': {
        'customer': 'cust_test_57m2wcnfx96k634rkqq',
        'card': 'card_test_57m2w8iemdovs4f92m2',
        'amount': 100000,
        'description': 'Membership fee'
    }
}, function(error, schedule) {
    /* Response. */
});
TypeError: Cannot read property 'retrieve' of undefined

omise.charges.list do not take in account the pagination parameters

I think I spot out a mistake in the nodejs lib.

At the moment it s not possible to use the paging parameter ( from https://www.omise.co/api-pagination )
because the https://github.com/omise/omise-node/blob/master/lib/apiResources.js
at line 56 :

list: function(callback) {
return api.get(_makeOptions(options, path()), callback);
},
is missing data, it should be

list: function(data,callback) {

To been able to use the pagination parameters as :

omisePromise = omise.charges.list({"limit": 5});

I know that I should have provided a PR, but I am a bit lazy to do it.

Beside, I believe that the unit testing should also integrate the paging parameters, and it sounds like a bit of work ;-)

Anyway, I have fixed it on my side, but I would really appreciate if you could add fix it in the official package :-)

authorize_uri does not work.

Dear Support,

I attempted to integrate Omise Internet Banking as a payment option, but I encountered an issue with the authorize_uri upon creating a charge. The error message displayed is as follows:

"Failed to launch 'krungsri-kma://map.payment?tokenId=7de8c5b6d2f44a36a196443d225c80f7' because the scheme does not have a registered handler."

To troubleshoot the problem, I performed the following validations:

[x] Verified the usage of Omise JS (2017 version).
[x] Confirmed successful creation of the charge request (see attached image:
image
).
[x] Ensured that the backend was able to retrieve the Omise object response code, which displayed the following information:
{status: 'pending', status_code: 'redirect', authorize_uri: 'krungsri-kma://map.payment?tokenId=7de8c5b6d2f44a36a196443d225c80f7'}

Despite these validations, I encountered the aforementioned error when attempting to redirect the URL. I have tried both in a browser and a Flutter app's webview.
image

I kindly request your assistance and guidance in resolving this matter.

Migrate from JSCS to eslint

JSCS has been merged with eslint and isn't updated for over a year. I think we should also migrate to eslint too.

Eslint also go beyond code style checking by checking for potential bug such as detecting for unused variables too.

Fix remote test

Unit test with mock data or npm test works fine.
But remote test or NOCK_OFF=true failed miserably due to expecting mock data.

capture flag ignored

Hi, when submitting the following request

omise.charges.create({
    amount:5067,
    capture:false,
    card:"tokn_test_***",
    currency:"thb"
})
.then(function(result){
// ...
})

the result object says

{
// ...  
    capture:true,
    captured:true,
// ...
}

however the http body passed here seems correct, thus I suspect the error comes from the backend.

How can I make sure my transaction has been authorized only ? (ie not captured)

Note: I am working with livemode=false and with test credit card 4111111111111111

regards,

Laurent.R

Property "on" in ICreateSchedule interface it can not be optional property

i try to call create schedule api from SDK with out "on" property. like a charge every 2 day example. i will get only this { object: 'error', location: 'https://www.omise.co/api-errors#bad-request', code: 'bad_request', message: 'on must be an object and on must contain one of these keys: days_of_month, weekday_of_month' } error.

Test fails in actual API server

While I am trying to create test to cover #50, I found that the current test is failing on 2 cases. Here is the information:

  35 passing (12s)
  2 failing

  1) Omise #Charges should be able to reverse a charge:
     Uncaught TypeError: Cannot read property 'object' of undefined
      at test/test_omise_charges.js:111:20
      at tryCatcher (node_modules/bluebird/js/main/util.js:26:23)
      at Promise.errorAdapter (node_modules/bluebird/js/main/nodeify.js:36:34)
      at Promise._settlePromiseAt (node_modules/bluebird/js/main/promise.js:582:21)
      at Promise._settlePromises (node_modules/bluebird/js/main/promise.js:700:14)
      at Async._drainQueue (node_modules/bluebird/js/main/async.js:123:16)
      at Async._drainQueues (node_modules/bluebird/js/main/async.js:133:10)
      at Immediate.Async.drainQueues [as _onImmediate] (node_modules/bluebird/js/main/async.js:15:14)

  2) Omise #Events should be able to retrieve an event:
     Uncaught TypeError: Cannot read property 'object' of undefined
      at test/test_omise_events.js:25:20
      at tryCatcher (node_modules/bluebird/js/main/util.js:26:23)
      at Promise.errorAdapter (node_modules/bluebird/js/main/nodeify.js:36:34)
      at Promise._settlePromiseAt (node_modules/bluebird/js/main/promise.js:582:21)
      at Promise._settlePromises (node_modules/bluebird/js/main/promise.js:700:14)
      at Async._drainQueue (node_modules/bluebird/js/main/async.js:123:16)
      at Async._drainQueues (node_modules/bluebird/js/main/async.js:133:10)
      at Immediate.Async.drainQueues [as _onImmediate] (node_modules/bluebird/js/main/async.js:15:14)

Maybe there's something about API versioning.

Using the library for React Native

Working with a React Native app now, and previous suggestions have been to make use of this node library to create the token.

Running into 2 issues

  1. React Native can't do dynamic import but line 7 of apiResources.js has a require that is dynamic
  2. api.js requires bluebird and https which the React Native library can't handle too

Wanted to check if there are possible solutions for integrating Omise into a React Native app other than writing our own native modules, or using a webview with Omise.js

Refund missing argument

Version 0.8.1
https://www.omise.co/refunds-api -> Create a refund
omise.charges.createRefund(
'chrg_test_4ype2jynk2len88i4er',
{'amount': 10000},
function(error, refund) {
/* Response. */
}
);

From the example, it provides 3 arguments required; however, when calling this function, getting the error as following.
Expected 1-2 arguments, but got 3.ts(2554)

Creating Charge with Source in a single request

I've to create a source and then create a charge after that. I think the library should support create a charge with source. And source seems not up to date because it can't create installment.

Fix dns uncaught exception

Fix case receive uncaught exception error when cannot call dns server which is the cause of node server down.

ex:

Error: getaddrinfo ENOTFOUND api.omise.co api.omise.co:443
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:57:26)

fix by handle event error in function _responseHandler

omise-node/lib/api.js

Lines 13 to 36 in bce1acb

function _responseHandler(req) {
return new Promise(function(resolve, reject) {
req.on('response', function(res) {
var resp = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
resp += chunk;
});
res.on('end', function() {
try {
logger.log('info', resp);
resp = JSON.parse(resp);
if (resp.object === 'error') {
reject(resp);
} else {
resolve(resp);
}
} catch (err) {
reject(err);
}
});
});
});
}

function _responseHandler(req) {
  return new Promise(function(resolve, reject) {
    req
      .on('response', function(res) {
        var resp = '';
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
          resp += chunk;
        });
        res.on('end', function() {
          try {
            logger.log('info', resp);
            resp = JSON.parse(resp);
            if (resp.object === 'error') {
              reject(resp);
            } else {
              resolve(resp);
            }
          } catch (err) {
            reject(err);
          }
        });
      })
      .on('error', function(err) {  // add this line
        reject(err);
      });
  });
}

Issue with WebPack

I'm trying to use the omise-node library with webpack to tokenize a card, this is what i'm getting

screen shot 2560-01-18 at 9 14 19 pm

cannot create/retrieve token

I'm testing omise services and while I can retrieve customers/cards fine, I cannot create/retrieve token. The error is

{ object: 'error',
  location: 'https://www.omise.co/api-errors#authentication-failure',
  code: 'authentication_failure',
  message: 'authentication failed' }

and i was using the same secret key when I test customer (actually run in one-go)

Is there a different key to use with token API?

Error: card was not found, hard to reproduce

Hi again,

I am having weird bug right now, which is hard to reproduce. The detail as follows

  • The error message is card tokn_test_55tsnhljnyn2d8ye0br was not found when trying to charge a card
  • The bug occurs unpredictably from time to time
  • If the issue occurs, it will persist until the running app is restarted
  • After restart, it will work normally as expected

Happened to me 2 times this week. I am running the library on nodejs v5 the code looks like this

const omise = require('omise')({
  secretKey: 'xxx',
  omiseVersion: '2015-11-17'
});
...
app.get('charge', (req, res) => {
    Promise.resolve({
      amount: req.query.amount,
      card: req.query.token,
      currency: 'THB',
    })
    .then(omise.charges.create)
    .then((response) => {
      // check for error
    })
    .then((data) => res.send(data))
    .catch((err) => res.error(err));
})

And I am suspecting that omise object is persisted for too long and somehow is mutated, then the bug occurs. I will try to move omise inside the (req, res) => { ... } and see if the bug still occur.

Please let me know if you have any idea about this issue.

Thanks!
PanJ

Add missing recipients.create type

Expected behavior

According to this documentation, bank_account.number existed and is a required value for recipients creation. This is the expected code (with no errors).

const recp = await omise.recipients.create({
    name: "Somchai Prasert",
    email: "[email protected]",
    type: "individual",
    bank_account: {
      brand: "bbl",
      number: "1234567890",
      name: "SOMCHAI PRASERT",
    },
  });

  console.log(recp);

Actual behavior

Upon completing the omise.recipients.create 's parameter, the following type error occurs...

Object literal may only specify known properties, and 'number' does not exist in type 'IBankAccount'.ts(2353)
index.d.ts(621, 7): The expected type comes from property 'bank_account' which is declared here on type 'IRequest'

The IBankAccount object type is missing its number property.

Update: It seems like the Omise.Recipients object type is missing several attributes written in the documentation.

interface IRequest {
      name: string;
      email?: string;
      description?: string;
      type: string;
      tax_id?: string;
      bank_account: IBankAccount;
      metadata?: { [key: string]: any };
    }

  interface IBankAccount {
    object: string;
    brand: string;
    last_digits: string;
    name: string;
    created: string;
  }

Steps to reproduce the issue

Using "omise": "^0.12.1" installed using bun

Logs

This is only a type error, filling complate type ensures good developer experiences.

Screenshots

No response

Name and version information

bun --version: 1.1.3
node --version: v20.10.0

Using Macbook Air M1
❯ sw_vers
ProductName: macOS
ProductVersion: 14.0
BuildVersion: 23A344

❯ uname
Darwin

Charge with card

I am unable to charge the added card for the customer.
My scenario :

  1. I create a customer and then add the card to the customer.
  2. get the card list.
  3. Do the payment after selecting one card from the list.

1 and 2 points are working but I am unable to do the payment with a card.
Can you please provide me the code for that?
I have a card id, customer id what parameter I sent to the charge API?

Thanks,

TypeScript support

I use TypeScript as primary node project. It can be good if omise-node support TypeScript by default.

My idea is writing the declaration file to make TypeScript can check the type when compile.

If you agree with this feature. I can make a pull request to finish it.

Implementing omise-node in Ionic 2

I'm creating a hybrid mobile app with payment feature using Ionic 2 framework. I tried omise.js via CDN which worked perfectly when serving in desktop browser (using ionic serve command). However, when I run the app on actual device (in this case, iPhone) the Omise.createToken() gave request timeout error.

After some searching I found a hint in an omise.js issue that omise-node should work with hybrid mobile apps and can be installed via NPM. So I tried importing the module like following:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import  Omise  from 'omise';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  constructor(public navCtrl: NavController) {
    var omise = new Omise({
      'publicKey': MY_PUBLIC_KEY
    });
  }
}

This results in the following error:

ERROR Error: Uncaught (in promise): Error: Cannot find module "."
Error: Cannot find module "."
    at d (polyfills.js:3)
    at webpackMissingModule (main.js:136768)
    at resourceName (main.js:136768)
    at Object.module.exports.omiseResources (main.js:136799)
    at new module.exports (main.js:136649)
    at new HomePage (main.js:58694)
    at createClass (main.js:11066)
    at createDirectiveInstance (main.js:10905)
    at createViewNodes (main.js:12255)
    at createRootView (main.js:12160)
    at callWithDebugContext (main.js:13291)
    at Object.debugCreateRootView [as createRootView] (main.js:12752)
    at ComponentFactory_.create (main.js:10096)
...

Since Omise is not undefined, I think the problem is omise-node's index.js couldn't get reference from another file by require() function. I know it is not exactly this repo's issue but I hope someone who had done this successfully might be able to point out what did I do wrong here.

When trying to create resource omise.sources.create(source) giving me authentication failure error

Hi,
When i try to create internet banking resource omise.sources.create(source) then it is giving me authentication error rest of the API is working fine for example omise.charges.create() etc it is giving me authentication failure only when i use omise.sources.create(source)

omise: ^0.5.4
node: v8.11.3

my code is

const omise = require('omise')({
  'secretKey': 'my_secret_key',
  'omiseVersion': '2017-11-02'
});

let service = {};

service.createSource = function(type, amount, orderID) {
  const promise = new Promise((resolve, reject) => {
    const source = {
      type, 
      amount,
      currency: 'thb'
    };
    omise.sources.create(source, function(err, resSource) {
      if (err) {  
        return reject(err);
      }
      omise.charges.create({
        'description': `Charge for Order ID: ${orderID}`,
        'amount': amount, 
        'currency': 'thb',
        'source': resSource.id,
        'return_uri': 'http://www.example.com/orders/3947/complete'
      }, function(err, resp) {
        if (err) {
          return reject(err);
        }
        return resolve(resp);
      });
    });
  });
  return promise;
};

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.