Code Monkey home page Code Monkey logo

api-spec-converter's Introduction

API Spec Transformer Build Status Coverage Status

This package helps to convert between different API specifications. It currently supports OAS (Swagger 2), RAML 0.8, RAML 1.0, and Postman collections.

This package is used in production @ https://stoplight.io. If you are using this package in production, please let us know and we will link you.

Note

A prior version of this library was available, but not published on NPM. If you are directly referencing the git URL in your package.json files, please update them to use the api-spec-transformer package name, instead of https://github.com/stoplightio/api-spec-converter. We will be re-naming the git repository to https://github.com/stoplightio/api-spec-transformer in the near future.

Installation

NodeJS or Browser

npm install --save api-spec-transformer

Usage

Convert RAML1.0 to OAS (Swagger), from a file.

var transformer = require('api-spec-transformer');

var ramlToSwagger = new transformer.Converter(transformer.Formats.RAML10, transformer.Formats.SWAGGER);

ramlToSwagger.loadFile('/source/raml.yaml', function(err) {
  if (err) {
    console.log(err.stack);
    return;
  }

  ramlToSwagger.convert('yaml')
    .then(function(convertedData) {
      // convertedData is swagger YAML string
    })
    .catch(function(err){
      console.log(err);
    });
});

Convert OAS (Swagger) to RAML1.0, from a URL.

var transformer = require('api-spec-transformer');

// Convert swagger to raml, from a url.

var swaggerToRaml = new transformer.Converter(transformer.Formats.SWAGGER, transformer.Formats.RAML10);

swaggerToRaml.loadFile('http://petstore.swagger.io/v2/swagger.json', function(err) {
  if (err) {
    console.log(err.stack);
    return;
  }

  swaggerToRaml.convert('yaml')
    .then(function(convertedData) {
      // convertedData is a raml YAML string
    })
    .catch(function(err){
      console.log(err);
    });
});

Convert unknown input to RAML1.0:

You can tell the converter to detect the input format automatically (by passing AUTO format), it will detect the right format for the input.

var transformer = require('api-spec-transformer');

var myConverter = new transformer.Converter(transformer.Formats.AUTO, transformer.Formats.RAML10);

swaggerToRaml.loadFile('http://petstore.swagger.io/v2/swagger.json', function(err) {
  // Will identify the input as swagger - the rest is the same as above.
});

Load a string:

var transformer = require('api-spec-transformer');

var swaggerToRaml = new transformer.Converter(transformer.Formats.SWAGGER, transformer.Formats.RAML10);

var mySwaggerString = '...';

swaggerToRaml.loadData(mySwaggerString)
  .then(function() {
    // Do the converstion, as in the first two examples.
  });

Supported Conversions

  • OAS (Swagger 2) -> RAML 0.8
  • OAS (Swagger 2) -> RAML 1.0
  • RAML 1.0 -> OAS (Swagger 2)
  • RAML 0.8 -> OAS (Swagger 2)
  • Postman Collection 1.0 -> OAS (Swagger 2) * Experimental
  • Postman Collection 1.0 -> RAML 0.8 * Experimental
  • Postman Collection 1.0 -> RAML 1.0 * Experimental

Development

Install dependencies:

npm install

Run tests:

npm test

Run eslint to check linting errors:

gulp lint

Contributing

Contributions are welcome! Please check the current issues to make sure what you are trying to do has not already been discussed.

  1. Fork.
  2. Make changes.
  3. Write tests.
  4. Send a pull request.

api-spec-converter's People

Contributors

isoppp avatar lottamus avatar philsturgeon avatar pytlesk4 avatar rainum avatar ranacseruet 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

api-spec-converter's Issues

Import from Swagger : wrong RAML mapping for allOf attributes

Take the following Swagger example:

  Manager:
    allOf:
      - $ref: '#/definitions/User'
      - type: object
        properties:
          manager_attribute:
            type: string
          manager_attribute1:
            type: string

This should be mapped as the following RAML:

  Manager:
    type: User
    properties:
       manager_attribute:
         type: string
       manager_attribute1:
          type: string

Take this other Swagger example:

Manager:
    allOf:
      - $ref: '#/definitions/User'
      - $ref: '#/definitions/Category'

This should be mapped as the following RAML:

  Manager:
    type: [User,Category]

Security Vulnerabilities in api-spec-trasformer

We are using api-spec transformer version 0.2.6. We have identified security vulnerabilities identified in direct and transitive dependencies. Attached vulnerability details for reference.

artifactID Vulnerability name
cryptiles-0.2.2.tgz - CVE-2018-1000620
cryptiles-2.0.5.tgz - CVE-2018-1000620
sshpk-1.13.0.tgz - WS-2018-0084
hawk-1.1.1.tgz - CVE-2016-2515
tough-cookie-0.12.1.tgz -CVE-2017-15010
marked-0.3.6.tgz - CVE-2017-16114
tough-cookie-2.3.2.tgz - CVE-2017-15010
marked-0.3.6.tgz - WS-2017-0108
base64url-1.0.6.tgz WS-2018-0096
hoek-0.9.1.tgz CVE-2018-3728
hoek-2.16.3.tgz CVE-2018-3728
lodash-4.17.4.tgz CVE-2018-3721
request-2.51.0.tgz WS-2016-0025
marked-0.3.6.tgz CVE-2017-1000427
bl-0.9.4.tgz WS-2016-0059
http-signature-0.10.1.tgz WS-2017-0266
tough-cookie-0.12.1.tgz CVE-2016-1000232
debug-2.6.8.tgz CVE-2017-16137
stringstream-0.0.4.tgz WS-2018-0103
stringstream-0.0.5.tgz WS-2018-0103
bl-0.9.4.tgz WS-2018-0074
tunnel-agent-0.4.0.tgz WS-2018-0076
concat-stream-1.4.10.tgz WS-2018-0075
node-uuid-1.4.2.tgz WS-2016-0013
lodash-4.17.4.tgz WS-2018-0210

Kindly support with assessment of the reported issues and fixes is required.

RAML 1.0 to Swagger conversion fails with multi file RAML specification

A RAML 1.0 specification composed of multiple files does not properly convert to Swagger.

Example:
spec.raml (top level spec file)
types.raml (a RAML 1.0 library used by spec.raml)

Executing the converter on spec.raml does not convert the types in types.raml to Swagger definitions.

Import from Swagger: incorrect response with allIOf conversion to Raml.

Swagger response:

"responses": {
          "200": {
            "description": "OK",
            "schema": {
              "type": "object",
              "description": "List of all media with added `distance` property",
              "properties": {
                "data": {
                  "type": "array",
                  "items": {
                    "allOf": [
                      {
                        "$ref": "#/definitions/Media"
                      },
                      {
                        "properties": {
                          "distance": {
                            "type": "number"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }

converted to:

      responses:
        '200':
          body:
            application/json:
              type: object
              description: List of all media with added `distance` property
              properties:
                data:
                  type: array
                  items:
                    allOf:
                      - type: Media
                      - properties:
                          distance:
                            type: number

but correct conversion is:

      responses:
        '200':
          body:
            application/json:
              type: object
              description: List of all media with added `distance` property
              properties:
                data:
                  type: array
                  items:
                    type: Media
                    properties:
                      distance:
                        type: number

Export/Import 'in': 'body' param

Problem: swagger spec doesn't support more than one ('in':'body') param.

Implications as per discussion:

  • While Importing: loose the 'name' value, and set the schema directly as request body.
  • While Exporting: name the param as 'body', and set entire request body as schema.

Import from Swagger: There is not declaration for info annotation.

Annotation info is generated but its declaration is not included.
This is the declaration that it's missing.

annotationTypes:
  info:
    properties:
      termsOfService?: string
      contact?:
        properties:
          name?: string
          url?: string
          email?: string
      license?:
        properties:
          name?: string
          url?: string

Upgrade Stoplight Format As Swagger-Extension

Current stoplight format is a raw independent format, only applicable/compatible with stoplight platform itself. This feature will help maintaining stoplight format as an swagger-extension format.

This will always be compatible anywhere swagger is supported and additionally, can be imported to stoplight platform with stoplight specific fields/attributes as well.

Here are the list of fields those need to be taken care of in swagger-extension(stoplight) format in addition to what are already supported:

Environment:
    - middlewareBefore
    - middlewareAfter
    - proxy

Endpoint:
    - _id
    - middlewareBefore
    - middlewareAfter
    - mock

utilityFunctions:
   -Everything

resourcesOrder:
   -Everything

Export to RAML: Wrong uri format

Swagger defines an invalid format like:
format: uri
type: string
swagger doesn't convert nothing in this case, so export has the same values.
The problem is that format uri is not valid in RAML, so expected result is:
type: string

Interpreting 'default' response code

Check this section on swagger spec. Besides all other valid http status code, swagger also has concept of 'default' code, which represents all codes which aren't presented in the spec.

At this moment, this code is converted to '400' http code, when imported. But it has two potential problems:

  1. There could be another response definition with code '400' . So, only one of these will get imported finally.
  2. It isn't representing all codes, which aren't covered, which originally meant by swagger spec.

@marbemac , I would like to hear about your thoughts on this.

(May be not anything urgent as on import functionality)

Error converting swagger to raml to swagger

I'm trying to run test that converts from swagger to raml to swagger using this file https://github.com/mulesoft/api-spec-converter/blob/master/example/source/swagger.json that is not working. Test results in a lot of differences.
Thanks.
Gaston

` 167 passing (2s)
46 pending
1 failing

  1. Converter convert should convert reversly from swagger to raml without loss:
  AssertionError: expected { Object (swagger, schemes, ...) } to deeply equal { Object (swagger, info, ...) }
  + expected - actual

   {
  -  "basePath": "//localhost:3000"
  +  "basePath": ""
     "consumes": [
       "application/json"
     ]
     "definitions": {
           "name"
         ]
       }
     }
  -  "host": "http"
  +  "host": "http://localhost:3000"
     "info": {
       "description": "A sample API"
       "title": "Swagger petstore"
       "version": "1.0.0"
     }
     "paths": {
       "/pets": {
         "delete": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Deletes all pets, optionally filtered by one or more criteria"
           "operationId": "deletePets"
           "parameters": [
             {
  +            "description": "Filters pets by one or more tags"
  +            "in": "query"
  +            "items": {
  +              "type": "string"
  +            }
  +            "name": "tags"
  +            "type": "array"
  +          }
  +          {
               "description": "Filters pets by type (dog, cat, or bird)"
               "in": "query"
               "name": "type"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by age"
               "in": "query"
               "name": "age"
  -            "required": false
               "type": "integer"
             }
             {
               "description": "Filters pets by date of birth"
               "in": "query"
               "name": "dob"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by city"
               "in": "query"
               "name": "address.city"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by state"
               "in": "query"
               "name": "address.state"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by zip code"
               "in": "query"
               "name": "address.zipcode"
  -            "required": false
               "type": "integer"
             }
             {
               "description": "Filters pets by veterinarian name"
               "in": "query"
               "name": "vet.name"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian city"
               "in": "query"
               "name": "vet.address.city"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian state"
               "in": "query"
               "name": "vet.address.state"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian zip code"
               "in": "query"
               "name": "vet.address.zipcode"
  -            "required": false
               "type": "integer"
             }
             {
               "description": ""
               "required": false
               "type": "string"
             }
           ]
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the pets that were deleted"
               "schema": {
           }
           "summary": ""
         }
         "get": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Returns all pets, optionally filtered by one or more criteria"
           "operationId": "findPets"
           "parameters": [
             {
  +            "description": "Filters pets by one or more tags"
  +            "in": "query"
  +            "items": {
  +              "type": "string"
  +            }
  +            "name": "tags"
  +            "type": "array"
  +          }
  +          {
               "description": "Filters pets by type (dog, cat, or bird)"
               "in": "query"
               "name": "type"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by age"
               "in": "query"
               "name": "age"
  -            "required": false
               "type": "integer"
             }
             {
               "description": "Filters pets by date of birth"
               "in": "query"
               "name": "dob"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by city"
               "in": "query"
               "name": "address.city"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by state"
               "in": "query"
               "name": "address.state"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by zip code"
               "in": "query"
               "name": "address.zipcode"
  -            "required": false
               "type": "integer"
             }
             {
               "description": "Filters pets by veterinarian name"
               "in": "query"
               "name": "vet.name"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian city"
               "in": "query"
               "name": "vet.address.city"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian state"
               "in": "query"
               "name": "vet.address.state"
  -            "required": false
               "type": "string"
             }
             {
               "description": "Filters pets by veterinarian zip code"
               "in": "query"
               "name": "vet.address.zipcode"
  -            "required": false
               "type": "integer"
             }
             {
               "description": ""
               "required": false
               "type": "string"
             }
           ]
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the matching pets"
               "schema": {
             }
           }
           "security": [
             {
  -            "oauth2": true
  +            "petstore_auth": [
  +              "read:pets"
  +            ]
             }
           ]
           "summary": ""
         }
  +      "parameters": []
         "post": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Creates a new pet in the store"
           "operationId": "addPet"
           "parameters": [
             {
  +            "description": "The pet to add to the store"
               "in": "body"
  -            "name": "body"
  +            "name": "pet"
  +            "required": false
               "schema": {
                 "$ref": "#/definitions/pet"
               }
  +            "type": "string"
             }
           ]
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "201": {
               "description": "Returns the newly-added pet"
               "schema": {
         }
       }
       "/pets/{petName}": {
         "delete": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Deletes a single pet based on the name supplied"
           "operationId": "deletePet"
  +        "parameters": []
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the pet that was deleted"
               "schema": {
           }
           "summary": ""
         }
         "get": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Returns a pet by name"
           "operationId": "findPetByName"
  +        "parameters": []
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the pet data"
               "schema": {
             }
           }
           "summary": ""
         }
  -      "parameters": [
  -        {
  -          "description": "petName"
  -          "in": "path"
  -          "name": "petName"
  -          "required": true
  -          "type": "string"
  -        }
  -      ]
  +      "parameters": []
         "patch": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Updates a pet by name"
  -        "operationId": "PATCH_pets-petName"
  +        "operationId": ""
           "parameters": [
             {
  +            "description": "The updated pet info"
               "in": "body"
  -            "name": "body"
  +            "name": "pet"
  +            "required": false
               "schema": {
                 "$ref": "#/definitions/pet"
               }
  +            "type": "string"
             }
           ]
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the updated pet data"
               "schema": {
         }
       }
       "/pets/{petName}/photos": {
         "get": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Get a list of the photos for a pet"
  -        "operationId": "GET_pets-petName-photos"
  +        "operationId": ""
  +        "parameters": []
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "200": {
               "description": "Returns the list of photos"
               "schema": {
             }
           }
           "summary": ""
         }
  -      "parameters": [
  -        {
  -          "description": "petName"
  -          "in": "path"
  -          "name": "petName"
  -          "required": true
  -          "type": "string"
  -        }
  -      ]
  +      "parameters": []
         "post": {
           "consumes": [
             "multipart/form-data"
           ]
             {
               "description": "The photo ID (generated automatically)"
               "in": "formData"
               "name": "id"
  +            "required": false
               "type": "string"
             }
             {
               "description": "A label for the photo"
               "in": "formData"
               "name": "label"
  +            "required": false
               "type": "string"
             }
             {
               "description": "An optional description of the photo"
               "in": "formData"
               "name": "description"
  +            "required": false
               "type": "string"
             }
             {
               "description": "The pet photo"
               "required": true
               "type": "string"
             }
           ]
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "Returns the photo information"
               "schema": {
         }
       }
       "/pets/{petName}/photos/{id}": {
         "delete": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Deletes a pet photo"
           "operationId": "deletePetPhoto"
  +        "parameters": []
  +        "produces": [
  +          "application/json"
  +        ]
           "responses": {
             "400": {
               "description": "The photo was deleted successfully"
             }
           }
           "summary": ""
         }
         "get": {
  +        "consumes": [
  +          "application/json"
  +        ]
           "description": "Gets a pet photo"
           "operationId": "getPetPhoto"
  +        "parameters": []
           "produces": [
             "image/jpeg"
           ]
           "responses": {
           "summary": ""
         }
         "parameters": [
           {
  -          "description": "petName"
  -          "in": "path"
  -          "name": "petName"
  -          "required": true
  -          "type": "string"
  -        }
  -        {
             "description": "The ID of the photo"
             "in": "path"
             "name": "id"
             "required": true
     ]
     "schemes": [
       "http"
       "https"
  +    "ws"
     ]
     "securityDefinitions": {
  +    "api_key": {
  +      "in": "header"
  +      "name": "api_key"
  +      "type": "apiKey"
  +    }
       "basic_auth": {
         "description": "basic authentication support"
  +      "name": "basic_auth"
         "type": "basic"
       }
  -    "oauth2": {
  +    "petstore_auth": {
         "authorizationUrl": "http://swagger.io/api/oauth/dialog"
         "flow": "implicit"
  -      "scopes": {}
  +      "scopes": {
  +        "read:pets": "read your pets"
  +        "write:pets": "modify pets in your account"
  +      }
         "type": "oauth2"
       }
     }
     "swagger": "2.0"

  at Assertion.assertEqual (node_modules/chai/lib/chai/core/assertions.js:485:19)
  at Assertion.ctx.(anonymous function) [as equal] (node_modules/chai/lib/chai/utils/addMethod.js:41:25)
  at test/lib/converter.js:121:49
  at lib/converter.js:9:2241

Writing coverage object [/Users/gaston/stoplightio/api-spec-converter/coverage/coverage.json]

Writing coverage reports at [/Users/gaston/stoplightio/api-spec-converter/coverage]

=============================== Coverage summary ===============================
Statements : 87.54% ( 1743/1991 )
Branches : 73.48% ( 690/939 )
Functions : 91.38% ( 350/383 )
Lines : 87.57% ( 1740/1987 )
================================================================================`

swagger -> raml, null primitive type -> nil

According to the raml10 spec, nil is the allowed type. The JSON schema spec uses the null primitive type, so this is what swagger specs will use. Thus, we need to change null -> nil when parsing types/schemas for raml 10.

RAML10
https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md#built-in-types

I could not find the allowed primitive types for raml08, so I am not sure if null is allowed (or nil). Perhaps @sichvoge could shed some light on this? This is what I could find:
https://github.com/raml-org/raml-spec/blob/master/versions/raml-08/raml-08.md#type

To replicate, here is an example input swagger that will lead to a (invalid) null property in the raml10 export:

{
    "swagger": "2.0",
    "info": {
        "title": "Test",
    },
    "paths": {
        "/users": {
            "get": {
                "responses": {
                    "200": {
                        "description": "",
                        "schema": {
                            "type": "object",
                            "properties": {
                                "foo": {
                                    "type": "null"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
}

Import Support For Array Of References

We currently don't support importing array of references, which might look like this in a swagger yaml as follows:

parameters:
        - $ref: "#/definitions/pet"
        - $ref: "#/definitions/address"

RAML 1.0 to Swagger usage example not working

I'm trying to test the last release of this converter, but when I execute the RAML 1.0 to Swagger usage example, it is always returning 'undefined'. Any idea about what could be happening?

RAML 1.0 to Swagger conversion doesn't convert definition type correctly

Here is what my RAML 1.0 types array looks like:

 [
     {
        definitions:
           dtype: 
               title: dtype
               $ref: '#/definitions/integer'
     }
 ]

When I convert it to swagger type property is being replaced with $ref:

 definitions:
    dtype: 
    title: dtype
    $ref: '#/definitions/integer'

I found a quick fix for this. In exporters/swagger.js I included var RAML = require('./baseraml'); and modified _mapSchema function:

Swagger.prototype._mapSchema = function(schemas) {
	return schemas.reduce(function(definitions, schema) {
		var definition = {};

		if (schema.name) {
			definition.title = schema.name;
		}

		_.merge(definition, RAML.prototype.convertRefFromModel(jsonHelper.parse(schema.Definition)));
		mapExample(schema, definition);
		definitions[schema.NameSpace] = definition;

		return definitions;
	}, {});
};

So now when I convert RAML 1.0 to Swagger type property in Definition is being converted as expected:

 definitions:
    dtype: 
        title: dtype
        type: integer

Is this a good way to fix the issue?

Enable RAML 1.0 support

At api-spec-converter, update the raml parser to support RAML 1.0 (using the raml-1-parser instead of the old raml-js-parser)

"null" generated value for baseUri in RAML

Taking the following Swagger YAML:

swagger: "2.0"
info:
  version: "1.0"
  title: "Hello World API"
paths:
  /hello/{user}:
    get:
      description: Returns a greeting to the user!
      parameters:
        - name: user
          in: path
          type: string
          required: true
          description: The name of the user to greet.
      responses:
        200:
          description: Returns the greeting.
          schema:
            type: string
        400:
          description: Invalid characters in "user" were provided.

I am getting a RAML generated that contains baseUri: "null". That obviously shouldn't happen. Am I right?

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.