├── .travis.yml ├── .babelrc ├── .gitignore ├── .npmignore ├── index.js ├── .eslintrc ├── src ├── utils │ ├── TermSuggestion.js │ ├── Category.js │ ├── Image.js │ ├── User.js │ ├── Media.js │ ├── Images.js │ └── responseFormatter.js ├── handlers │ ├── ResponseHandler.js │ └── RequestHandler.js └── GphApiClient.js ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── PULL_REQUEST_TEMPLATE.md ├── tests ├── termSuggestion.spec.js ├── gifsByCategories.spec.js ├── categories.spec.js ├── translate.spec.js ├── gifsByIds.spec.js ├── gifById.spec.js ├── random.spec.js ├── subcategories.spec.js ├── misc.spec.js ├── trending.spec.js └── search.spec.js ├── gulpfile.js ├── CHANGELOG.md ├── package.json ├── webpack.config.js ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── README.md └── LICENSE /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "7" -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["babel-plugin-add-module-exports"] 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .DS_Store 3 | npm-debug.log 4 | tester.js 5 | lib 6 | /out 7 | /build_for_browser -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src/ 2 | .babelrc 3 | .eslintrc 4 | .npmignore 5 | gulpfile.js 6 | test.js 7 | tests/ 8 | build_for_browser/ 9 | .travis.yml 10 | webpack.config.js 11 | tester.js 12 | out/ 13 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 'use strict'; 10 | 11 | module.exports = require('./lib/GphApiClient'); -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es6": true 6 | }, 7 | "parser": "babel-eslint", 8 | "extends": "eslint:recommended", 9 | "rules": { 10 | "no-irregular-whitespace ": 0, 11 | "no-mixed-spaces-and-tabs": 1, 12 | "eqeqeq": 1, 13 | "no-console": 0, 14 | "camelcase": 0, 15 | "comma-dangle": 2, 16 | "quotes": 0 17 | } 18 | } -------------------------------------------------------------------------------- /src/utils/TermSuggestion.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var TermSuggestion = function(data) { 11 | return ({ 12 | "term": data.name ? data.name : null 13 | }) 14 | } 15 | 16 | 17 | module.exports = TermSuggestion -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. 2 | 3 | If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged. 4 | 5 | Test Plan: 6 | Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Bonus points for screenshots and videos! 7 | 8 | Changelog: 9 | Help reviewers and the release process by writing your own changelog entry describing your changes. Please take a look at our changelog for an example. 10 | -------------------------------------------------------------------------------- /src/utils/Category.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | var Media = require('./Media'); 10 | var _ = require('lodash'); 11 | 12 | var Category = function(data) { 13 | return ({ 14 | name: data.name ? data.name : null, 15 | name_encoded: data.name_encoded ? data.name_encoded : null, 16 | gif: data.gif ? Media(data.gif) : null, 17 | subcategories: data.subcategories ? _.map(data.subcategories, (subcat) => Category(subcat)) : null 18 | }) 19 | } 20 | 21 | module.exports = Category -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Reproducible Demo** 24 | Let us know how to reproduce the issue. Include a code sample or share a project that reproduces the issue. Please follow the guidelines for providing a MCVE: https://stackoverflow.com/help/mcve 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /src/utils/Image.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | /** 11 | * Custom Image object. 12 | * 13 | * @param {object} data 14 | * @param {string} id 15 | * @param {string} rendition_type 16 | * 17 | * @returns {object} Object containing API Image object, id from GIF 18 | * object and rendition type. 19 | */ 20 | var Image = function(data, id, rendition_type) { 21 | return ({ 22 | media_id: id ? id : null, 23 | rendition_type: rendition_type ? rendition_type : null, 24 | url: data.url ? data.url : null, 25 | width: data.width ? data.width : null, 26 | height: data.height ? data.height : null, 27 | size: data.size ? data.size : null, 28 | frames: data.frames ? data.frames : null, 29 | mp4: data.mp4 ? data.mp4 : null, 30 | mp4_size: data.mp4_size ? data.mp4_size : null, 31 | webp: data.webp ? data.webp : null, 32 | webp_size: data.webp_size ? data.webp_size : null 33 | }) 34 | } 35 | 36 | 37 | module.exports = Image -------------------------------------------------------------------------------- /tests/termSuggestion.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('TERM SUGGESTIONS', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | it('PROMISE - returns an array of terms', function(done) { 19 | this.timeout(5000); 20 | client.termSuggestions("fake").then((response) => { 21 | expect(Array.isArray(response.data)).to.equal(true); 22 | expect(response.data.length).to.be.above(0); 23 | done(); 24 | }).catch((err) => { 25 | done(err); 26 | }) 27 | }); 28 | 29 | it('CALLBACK - returns an array of terms', function(done) { 30 | this.timeout(5000); 31 | client.termSuggestions("fake", function(response, err) { 32 | if (err) done(err); 33 | expect(Array.isArray(response.data)).to.equal(true); 34 | expect(response.data.length).to.be.above(0); 35 | done(); 36 | }); 37 | }); 38 | }); 39 | /// -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | 11 | var gulp = require("gulp"); 12 | var eslint = require("gulp-eslint"); 13 | var prettify = require('gulp-jsbeautifier'); 14 | 15 | 16 | gulp.task('prettify', function() { 17 | gulp.src(['./src/**/*.js']) 18 | .pipe(prettify({ 19 | "indent_size": 4, 20 | "indent_char": ' ', 21 | // other options 22 | "js": { 23 | // other options 24 | "indent_size": 2 25 | } 26 | })) 27 | .pipe(gulp.dest('./src')); 28 | }); 29 | 30 | gulp.task('clean_tests', function() { 31 | gulp.src(['./tests/**.js']) 32 | .pipe(prettify({ 33 | "indent_size": 4, 34 | "indent_char": ' ', 35 | // other options 36 | "js": { 37 | // other options 38 | "indent_size": 2 39 | } 40 | })) 41 | .pipe(gulp.dest('./tests')); 42 | }); 43 | 44 | gulp.task("lint", function(){ 45 | gulp.src("./src/**/*.js") 46 | .pipe(eslint()) 47 | .pipe(eslint.format()) 48 | .pipe(eslint.failAfterError()) 49 | }) 50 | 51 | //build this for npm 52 | 53 | gulp.task("default", ["lint", "prettify"]); 54 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 6 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 7 | 8 | **Types of changes** 9 | 10 | - `Added` - new features. 11 | - `Changed` - changes in existing functionality. 12 | - `Deprecated` - soon-to-be removed features. 13 | - `Removed` - now removed features. 14 | - `Fixed` - bug fixes. 15 | - `Security` - vulnerabilities. 16 | 17 | ## [1.0.6] 18 | 19 | ### Added 20 | - Code of conduct [#32](https://github.com/Giphy/giphy-js-sdk-core/pull/32). 21 | - PR template [#38](https://github.com/Giphy/giphy-js-sdk-core/pull/38). 22 | - Contribution guidelines [#33](https://github.com/Giphy/giphy-js-sdk-core/pull/33). 23 | 24 | ### Changed 25 | - Update `Image` object to match [GIPHY API](https://developers.giphy.com/docs/#images-object) [#29](https://github.com/Giphy/giphy-js-sdk-core/pull/29). 26 | - Updated README [#47](https://github.com/Giphy/giphy-js-sdk-core/pull/47). 27 | 28 | ### Fixed 29 | - Fix downloads/month count in badge [#42](https://github.com/Giphy/giphy-js-sdk-core/pull/42). 30 | 31 | ## [Unreleased] 32 | 33 | [Unreleased]: https://github.com/Giphy/giphy-js-sdk-core/compare/v1.0.5...HEAD 34 | [1.0.6]: https://github.com/Giphy/giphy-js-sdk-core/compare/v1.0.5...v1.0.6 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "giphy-js-sdk-core", 3 | "version": "1.0.06", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "babel -d lib/ src/ && mocha --compilers js:babel-core/register --recursive \"./tests/**/*.spec.js\"", 8 | "lint": "gulp default", 9 | "publish_npm": "npm run test patch && npm publish", 10 | "build_for_npm": "gulp; babel -d lib/ src/", 11 | "build_for_browser": "WEBPACK_ENV=build webpack" 12 | }, 13 | "author": "Cosmo Cochrane", 14 | "license": "ISC", 15 | "dependencies": { 16 | "es6-promise": "^4.1.0", 17 | "isomorphic-fetch": "^2.2.1", 18 | "lodash": "^4.17.4", 19 | "promise": "^7.1.1" 20 | }, 21 | "devDependencies": { 22 | "babel-cli": "^6.24.1", 23 | "babel-core": "^6.24.1", 24 | "babel-eslint": "^7.2.3", 25 | "babel-loader": "^7.0.0", 26 | "babel-plugin-add-module-exports": "^0.2.1", 27 | "babel-plugin-transform-class-properties": "^6.24.1", 28 | "babel-preset-es2015": "^6.24.1", 29 | "babel-preset-react": "^6.24.1", 30 | "chai": "^3.5.0", 31 | "eslint-loader": "^1.7.1", 32 | "gulp": "^3.9.1", 33 | "gulp-eslint": "^3.0.1", 34 | "gulp-jsbeautifier": "^2.1.0", 35 | "mocha": "^3.3.0", 36 | "webpack": "^2.5.1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/gifsByCategories.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | 15 | describe('GIFS BY CATEGORIES', function() { 16 | var apiKey = "4OMJYpPoYwVpe"; 17 | var client = GphApiClient(apiKey); 18 | 19 | it('PROMISE - returns an array of gifs', function(done) { 20 | this.timeout(5000); 21 | client.gifsByCategories("tv", "'the office'", {}).then((response) => { 22 | expect(Array.isArray(response.data)).to.equal(true); 23 | expect(response.data.length).to.be.above(0); 24 | 25 | response.data.forEach(function(category) { 26 | expect(category.type).to.equal('gif') 27 | }); 28 | done(); 29 | }).catch((err) => { 30 | done(err); 31 | }) 32 | }); 33 | 34 | it('CALLBACK - returns an array of gifs', function(done) { 35 | this.timeout(5000); 36 | client.gifsByCategories("tv", "'the office'", {}, function(response, err) { 37 | if (err) done(err); 38 | expect(Array.isArray(response.data)).to.equal(true); 39 | expect(response.data.length).to.be.above(0); 40 | done(); 41 | }); 42 | }); 43 | }); -------------------------------------------------------------------------------- /tests/categories.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('CATEGORIES', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | it('PROMISE - returns an array of categories', function(done) { 19 | this.timeout(5000); 20 | client.categoriesForGifs({}).then((response) => { 21 | expect(Array.isArray(response.data)).to.equal(true); 22 | response.data.forEach(function(category) { 23 | expect(category).to.have.keys('name', 'name_encoded', 'subcategories', 'gif') 24 | }); 25 | done(); 26 | }).catch((err) => { 27 | done(err); 28 | }) 29 | }); 30 | 31 | it('CALLBACK - returnss an array of categories', function(done) { 32 | this.timeout(5000); 33 | client.categoriesForGifs({}, function(response, err) { 34 | if (err) done(err); 35 | expect(Array.isArray(response.data)).to.equal(true); 36 | response.data.forEach(function(category) { 37 | expect(category).to.have.keys('name', 'name_encoded', 'subcategories', 'gif') 38 | }); 39 | done(); 40 | }); 41 | }); 42 | }); -------------------------------------------------------------------------------- /tests/translate.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | 15 | describe('TRANSLATE - gifs', function() { 16 | var apiKey = "4OMJYpPoYwVpe"; 17 | var client = GphApiClient(apiKey); 18 | 19 | it('PROMISE - returns a single object that is a gif', function(done) { 20 | this.timeout(5000); 21 | client.translate("gifs", { 22 | "s": "cool" 23 | }).then((response) => { 24 | expect(Array.isArray(response.data)).to.equal(false); 25 | expect(response.data.type).to.equal('gif'); 26 | done(); 27 | 28 | }).catch((err) => { 29 | done(err) 30 | }) 31 | }); 32 | }); 33 | 34 | describe('TRANSLATE - stickers', function(done) { 35 | var apiKey = "4OMJYpPoYwVpe"; 36 | var client = GphApiClient(apiKey); 37 | 38 | it('PROMISE - returns one sticker from the sticker shop', function(done) { 39 | this.timeout(5000); 40 | client.translate("stickers", { 41 | "s": "cool" 42 | }, (response, err) => { 43 | if (err) done(err); 44 | 45 | expect(Array.isArray(response.data)).to.equal(false); 46 | expect(response.data.type).to.equal('gif'); 47 | 48 | done(); 49 | }); 50 | }); 51 | 52 | }); -------------------------------------------------------------------------------- /src/utils/User.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var User = function(data) { 11 | return ({ 12 | id: data.id ? data.is_sticker : null, 13 | avatar_url: data.avatar_url ? data.avatar_url : null, 14 | banner_url: data.banner_url ? data.banner_url : null, 15 | profile_url: data.profile_url ? data.profile_url : null, 16 | username: data.username ? data.username : null, 17 | display_name: data.display_name ? data.display_name : null, 18 | twitter: data.twitter ? data.twitter : null, 19 | is_public: data.is_public ? data.is_public : null, 20 | attribution_display_name: data.attribution_display_name ? data.attribution_display_name : null, 21 | name: data.name ? data.name : null, 22 | description: data.description ? data.description : null, 23 | facebook_url: data.facebook_url ? data.facebook_url : null, 24 | twitter_url: data.twitter_url ? data.twitter_url : null, 25 | instagram_url: data.instagram_url ? data.instagram_url : null, 26 | tumblr_url: data.tumblr_url ? data.tumblr_url : null, 27 | suppress_chrome: data.suppress_chrome ? data.suppress_chrome : null, 28 | website_url: data.website_url ? data.website_url : null, 29 | website_display_url: data.website_display_url ? data.website_display_url : null 30 | }) 31 | } 32 | 33 | module.exports = User -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var webpack = require('webpack'); 11 | var path = require('path'); 12 | var libraryName = 'library'; 13 | var outputFile = libraryName + '.js'; 14 | 15 | var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin; 16 | var env = process.env.WEBPACK_ENV; 17 | 18 | var libraryName = 'GphApiClient'; 19 | var plugins = []; 20 | var outputFile; 21 | 22 | if (env === 'build') { 23 | plugins.push(new UglifyJsPlugin({ minimize: true })); 24 | outputFile = libraryName + '.min.js'; 25 | } else { 26 | outputFile = libraryName + '.js'; 27 | } 28 | 29 | module.exports = { 30 | entry: __dirname + '/src/GphApiClient.js', 31 | devtool: 'source-map', 32 | output: { 33 | path: __dirname + '/build_for_browser', 34 | filename: outputFile, 35 | library: libraryName, 36 | libraryTarget: 'umd', 37 | umdNamedDefine: true 38 | }, 39 | module: { 40 | loaders: [ 41 | { 42 | test: /(\.jsx|\.js)$/, 43 | loader: 'babel-loader', 44 | exclude: /(node_modules|bower_components)/ 45 | }, 46 | { 47 | test: /(\.jsx|\.js)$/, 48 | loader: "eslint-loader", 49 | exclude: /node_modules/ 50 | } 51 | ] 52 | }, 53 | plugins: plugins, 54 | resolve: { 55 | modules: [ 56 | path.join(__dirname, "src"), 57 | "node_modules" 58 | ] 59 | } 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /tests/gifsByIds.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('GIFS BY IDS', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | 19 | it('PROMISE - returns gifs based on the ids sent', function(done) { 20 | this.timeout(5000); 21 | client.gifsByIDs({ 22 | "ids": ["3og0IvOsj15uYsxYZi", "l41lS0IgRIFkAuA5G", "3o6oziEt5VUgsuunxS"] 23 | }).then((response) => { 24 | expect(Array.isArray(response.data)).to.equal(true); 25 | expect(response.data.length).to.equal(3); 26 | 27 | response.data.forEach(function(gif) { 28 | expect(gif.type).to.equal('gif'); 29 | }); 30 | 31 | done(); 32 | }).catch((err) => { 33 | done(err); 34 | }) 35 | }); 36 | 37 | it('CALLBACK - returns gifs based on the ids sent', function(done) { 38 | this.timeout(5000); 39 | client.gifsByIDs({ 40 | "ids": ["3og0IvOsj15uYsxYZi", "l41lS0IgRIFkAuA5G", "3o6oziEt5VUgsuunxS"] 41 | }, function(response, err) { 42 | if (err) done(err); 43 | 44 | expect(Array.isArray(response.data)).to.equal(true); 45 | expect(response.data.length).to.equal(3); 46 | 47 | response.data.forEach(function(gif) { 48 | expect(gif.type).to.equal('gif'); 49 | }); 50 | 51 | done(); 52 | }); 53 | }); 54 | }); -------------------------------------------------------------------------------- /src/handlers/ResponseHandler.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var responseFormatter = require('../utils/responseFormatter'); 11 | 12 | //handle status code and resolve/reject promise 13 | function ResponseHandler(res, data, resolve, reject, endpoint) { 14 | //handle error status code 15 | if (res.status >= 400 && res.status <= 502) { 16 | reject({ 17 | status: res && res.status ? res.status : "unknown api error", 18 | error: res && data && data.meta && data.meta.msg ? data.meta.msg : null, 19 | statusText: res && res.statusText ? res.statusText : null 20 | }) 21 | } 22 | //deal with successful status code 23 | if (res && res.status >= 200 && res.status < 300) { 24 | //pass the api response into a formatter to ensure it is to spec 25 | var constructorModifiedData = formatApiReturn(data, endpoint); 26 | resolve(constructorModifiedData); 27 | } else { 28 | //reject promise with unexpected error 29 | reject({ 30 | status: res && res.status ? res.status : 'unknown api error', 31 | error: res && res.status ? res.status : 'unknown api error', 32 | statusText: res && res.statusText ? res.statusText : null 33 | }); 34 | } 35 | } 36 | 37 | //creates the response object 38 | function formatApiReturn(body, endpoint) { 39 | var responseObject = {}; 40 | //modify the data field to match spec 41 | responseObject.data = responseFormatter(body.data, endpoint); 42 | responseObject.meta = body.meta; 43 | if (body.pagination) { 44 | responseObject.pagination = body.pagination; 45 | if (!responseObject.pagination.offset) { 46 | responseObject.pagination.offset = null 47 | } 48 | } 49 | return responseObject 50 | 51 | } 52 | 53 | module.exports = ResponseHandler -------------------------------------------------------------------------------- /tests/gifById.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('GIF BY ID', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | it('PROMISE - returns a single gif given an ID', function(done) { 19 | this.timeout(5000); 20 | client.gifByID("3og0IvOsj15uYsxYZi").then((response) => { 21 | expect(Array.isArray(response.data)).to.equal(false); 22 | expect(response.data.type).to.equal('gif'); 23 | 24 | done() 25 | }).catch((err) => { 26 | done(err) 27 | }) 28 | }); 29 | 30 | it('CALLBACK - returns a single gif given an ID', function(done) { 31 | this.timeout(5000); 32 | client.gifByID("3og0IvOsj15uYsxYZi", function(response, err) { 33 | if (err) done(err); 34 | 35 | expect(Array.isArray(response.data)).to.equal(false); 36 | expect(response.data.type).to.equal('gif'); 37 | done() 38 | }) 39 | }); 40 | 41 | 42 | it('PROMISE - errors out when an invalid gif ID was passed in', function(done) { 43 | this.timeout(5000); 44 | client.gifByID("3og0IvOsj15uYadsjandkjanssxYZi").then((response) => { 45 | 46 | throw 'should have never made it to the success block' 47 | }).catch((err) => { 48 | done() 49 | }) 50 | }); 51 | 52 | it('CALLBACK - errors out when an invalid gif ID was passed in', function(done) { 53 | this.timeout(5000); 54 | client.gifByID("3og0IvOsj15uadasdasdasdYsxYZi", function(response, err) { 55 | if (err) done(); 56 | throw 'should have never made it to the success block' 57 | }) 58 | }); 59 | 60 | }); 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /tests/random.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | 15 | describe('RANDOM - gifs', function() { 16 | var apiKey = "4OMJYpPoYwVpe"; 17 | var client = GphApiClient(apiKey); 18 | 19 | it('PROMISE - returns a random single gif', function(done) { 20 | this.timeout(5000); 21 | client.random("gifs", {}).then((response) => { 22 | expect(Array.isArray(response.data)).to.equal(false); 23 | expect(response.data.type).to.equal('gif'); 24 | done(); 25 | 26 | }).catch((err) => { 27 | done(err) 28 | }) 29 | }); 30 | 31 | it('CALLBACK - returns a random single gif', function(done) { 32 | this.timeout(5000); 33 | client.random("gifs", {}, (response, err) => { 34 | expect(Array.isArray(response.data)).to.equal(false); 35 | expect(response.data.type).to.equal('gif'); 36 | done(); 37 | }); 38 | }); 39 | 40 | }); 41 | 42 | describe('RANDOM - stickers', function() { 43 | var apiKey = "4OMJYpPoYwVpe"; 44 | var client = GphApiClient(apiKey); 45 | 46 | 47 | 48 | it('PROMISE - returns a random single gif', function(done) { 49 | this.timeout(5000); 50 | client.random("stickers", {}).then((response) => { 51 | expect(Array.isArray(response.data)).to.equal(false); 52 | expect(response.data.type).to.equal('gif'); 53 | done(); 54 | 55 | }).catch((err) => { 56 | done(err) 57 | }) 58 | }); 59 | 60 | 61 | it('CALLBACK - returns a random single gif', function(done) { 62 | this.timeout(5000); 63 | client.random("stickers", {}, (response, err) => { 64 | expect(Array.isArray(response.data)).to.equal(false); 65 | expect(response.data.type).to.equal('gif'); 66 | done(); 67 | }); 68 | }); 69 | 70 | }); -------------------------------------------------------------------------------- /src/utils/Media.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var Images = require('./Images'); 11 | var User = require('./User'); 12 | 13 | var Media = function(data) { 14 | return ({ 15 | type: data.type ? data.type : null, 16 | id: data.id ? data.id : null, 17 | slug: data.slug ? data.slug : null, 18 | url: data.url ? data.url : null, 19 | bitly_gif_url: data.bitly_gif_url ? data.bitly_gif_url : null, 20 | bitly_url: data.bitly_url ? data.bitly_url : null, 21 | embed_url: data.embed_url ? data.embed_url : null, 22 | source: data.source ? data.source : null, 23 | rating: data.rating ? data.rating : null, 24 | content_url: data.content_url ? data.content_url : null, 25 | tags: data.tags ? data.tags : null, 26 | featured_tags: data.features_tags ? data.features_tags : null, 27 | user: data.user ? User(data.user) : null, 28 | images: data.images ? Images(data.images, data.id) : null, 29 | source_tld: data.source_tld ? data.source_tld : null, 30 | source_post_url: data.source_post_url ? new Date(data.source_post_url) : null, 31 | update_datetime: data.update_datetime ? new Date(data.update_datetime) : null, 32 | create_datetime: data.create_datetime ? new Date(data.create_datetime) : null, 33 | import_datetime: data.import_datetime ? new Date(data.import_datetime) : null, 34 | trending_datetime: data.trending_datetime ? new Date(data.trending_datetime) : null, 35 | title: data.title ? data.title : null, 36 | is_hidden: data.is_hidden ? true : false, 37 | is_removed: data.is_removed ? true : false, 38 | is_community: data.is_community ? true : false, 39 | is_anonymous: data.is_anonymous ? true : false, 40 | is_featured: data.is_featured ? true : false, 41 | is_realtime: data.is_realtime ? true : false, 42 | is_indexable: data.is_indexable ? true : false, 43 | is_sticker: data.is_sticker ? true : false 44 | }) 45 | } 46 | 47 | module.exports = Media -------------------------------------------------------------------------------- /tests/subcategories.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('SUBCATEGORIES', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | 19 | it('PROMISE - returns an array of categories', function(done) { 20 | this.timeout(5000); 21 | client.subCategoriesForGifs("tv", {}).then((response) => { 22 | expect(Array.isArray(response.data)).to.equal(true); 23 | response.data.forEach(function(category) { 24 | expect(category).to.have.keys('name_encoded', 'subcategories', 'name', 'gif') 25 | }); 26 | done(); 27 | }).catch((err) => { 28 | done(err); 29 | }) 30 | }); 31 | 32 | it('CALLBACK - returns an array of categories', function(done) { 33 | this.timeout(5000); 34 | client.subCategoriesForGifs("tv", {}, function(response, err) { 35 | if (err) done(err); 36 | expect(Array.isArray(response.data)).to.equal(true); 37 | response.data.forEach(function(category) { 38 | expect(category).to.have.keys('name_encoded', 'subcategories', 'name', 'gif') 39 | }); 40 | done(); 41 | }); 42 | }); 43 | 44 | it('passing limit and offset to categories endpoint returns with pagination', function(done) { 45 | this.timeout(5000); 46 | client.subCategoriesForGifs("tv", { 47 | "offset": 1, 48 | "limit": 10 49 | }).then((response) => { 50 | expect(response.data.length).to.equal(10); 51 | 52 | done(); 53 | }).catch((err) => { 54 | done(err); 55 | }) 56 | }); 57 | 58 | it('PROMISE correctly responds with an error', function(done) { 59 | this.timeout(5000); 60 | client.subCategoriesForGifs({ 61 | "offset": 1, 62 | "limit": 10 63 | }).then((response) => { 64 | throw "did not catch the error" 65 | }).catch((err) => { 66 | done(); 67 | }) 68 | }); 69 | }); -------------------------------------------------------------------------------- /src/handlers/RequestHandler.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var ResponseHandler = require('./ResponseHandler'); 11 | require('es6-promise').polyfill(); 12 | if (typeof fetch === 'undefined') { 13 | require('isomorphic-fetch'); 14 | } 15 | 16 | function RequestHandler(vals, endpoint, cb) { 17 | 18 | function req(args, cb) { 19 | var canceled = false; 20 | var query_params_string = "?"; 21 | 22 | Object.keys(args.params).forEach((key) => { 23 | query_params_string = query_params_string.concat(key + "=" + args.params[key] + "&"); 24 | }); 25 | 26 | var constructedRequest = new Promise((resolve, reject) => { 27 | if (vals.type && vals.type !== 'gifs' && vals.type !== 'stickers') { 28 | reject("The type argument was passed in incorrectly. It should be either 'gifs' or 'stickers'") 29 | } 30 | 31 | fetch(args.url + query_params_string, { 32 | method: args.method 33 | }).then((response) => { //calling the end function will send the actual request 34 | if (canceled === true) { 35 | return 36 | } else { 37 | response.json().then((data) => { 38 | ResponseHandler(response, data, 39 | (res) => { 40 | resolve(res); 41 | if (cb !== undefined) { 42 | cb(res, null); 43 | } 44 | }, 45 | (err) => { 46 | reject(err); 47 | if (cb !== undefined) { 48 | cb(null, err); 49 | } 50 | }, endpoint) //pass in args.url so you can determine before resolving the promise what request was just made 51 | // we pass the response to our helper method imported from ./helpers/ 52 | }) 53 | } 54 | }).catch((err) => { 55 | reject(err) 56 | }) 57 | }) 58 | //allows users to cancel outgoing requests 59 | constructedRequest.cancel = function() { 60 | canceled = true; 61 | } 62 | 63 | return constructedRequest 64 | } 65 | 66 | return req(vals, cb); 67 | //return the promise 68 | } 69 | 70 | module.exports = RequestHandler -------------------------------------------------------------------------------- /src/utils/Images.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var Image = require('./Image'); 11 | 12 | var Images = function(data, id) { 13 | return ({ 14 | media_id: id, 15 | fixed_height: data.fixed_height ? Image(data.fixed_height, id, 'fixed_height') : null, 16 | fixed_height_still: data.fixed_height_still ? Image(data.fixed_height_still, id, 'fixed_height_still') : null, 17 | fixed_height_downsampled: data.fixed_height_downsampled ? Image(data.fixed_height_downsampled, id, 'fixed_height_downsampled') : null, 18 | fixed_width: data.fixed_width ? Image(data.fixed_width, id, 'fixed_width') : null, 19 | fixed_width_still: data.fixed_width_still ? Image(data.fixed_width_still, id, 'fixed_width_still') : null, 20 | fixed_width_downsampled: data.fixed_width_downsampled ? Image(data.fixed_width_downsampled, id, 'fixed_width_downsampled') : null, 21 | fixed_height_small: data.fixed_height_small ? Image(data.fixed_height_small, id, 'fixed_height_small') : null, 22 | fixed_height_small_still: data.fixed_height_small_still ? Image(data.fixed_height_small_still, id, 'fixed_height_small_still') : null, 23 | fixed_width_small: data.fixed_width_small ? Image(data.fixed_width_small, id, 'fixed_width_small') : Image({}, id, 'fixed_width_small'), 24 | fixed_width_small_still: data.fixed_width_small_still ? Image(data.fixed_width_small_still, id, 'fixed_width_small_still') : null, 25 | downsized: data.downsized ? Image(data.downsized, id, 'downsized') : null, 26 | downsized_still: data.downsized_still ? Image(data.downsized_still, id, 'downsized_still') : null, 27 | downsized_large: data.downsized_large ? Image(data.downsized_large, id, 'downsized_large') : null, 28 | downsized_medium: data.downsized_medium ? Image(data.downsized_medium, id, 'downsized_medium') : null, 29 | original: data.original ? Image(data.original, id, 'original') : null, 30 | original_still: data.original_still ? Image(data.original_still, id, 'original_still') : null, 31 | looping: data.looping ? Image(data.looping, id, 'looping') : null, 32 | preview: data.preview ? Image(data.preview, id, 'preview') : null, 33 | preview_gif: data.preview_gif ? Image(data.preview_gif, id, 'preview_gif') : null, 34 | downsized_small: data.downsized_small ? Image(data.downsized_small, id, 'downsized_small') : null 35 | }) 36 | } 37 | 38 | module.exports = Images -------------------------------------------------------------------------------- /src/utils/responseFormatter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var _ = require('lodash'); 11 | var Media = require('./Media'); 12 | var Category = require('./Category'); 13 | var TermSuggestion = require('./TermSuggestion'); 14 | 15 | function responseFormatter(data, endpoint) { 16 | switch (endpoint) { 17 | case "translate": 18 | case "gifByID": 19 | return Media(data); 20 | 21 | case "search": 22 | case "trending": 23 | case "gifsByIDs": 24 | case "gifsByCategories": 25 | return _.map(data, (gifObject) => { 26 | return Media(gifObject); 27 | }); 28 | 29 | case "categoriesForGifs": 30 | return _.map(data, (singleCategory) => { 31 | return Category(singleCategory) 32 | }) 33 | 34 | case "subCategoriesForGifs": 35 | return _.map(data, (singleSubCategory) => { 36 | return Category(singleSubCategory) 37 | }) 38 | 39 | case "termSuggestions": 40 | return _.map(data, (singleTerm) => { 41 | return TermSuggestion(singleTerm) 42 | }) 43 | case ("random"): 44 | return { 45 | images: { 46 | fixed_height_downsampled: { 47 | gif_url: data.fixed_height_downsampled_url, 48 | height: data.fixed_height_downsampled_height, 49 | width: data.fixed_height_downsampled_width 50 | }, 51 | fixed_height_small: { 52 | gif_url: data.fixed_height_small_url, 53 | height: data.fixed_height_small_height, 54 | width: data.fixed_height_small_width 55 | }, 56 | fixed_width_downsampled: { 57 | gif_url: data.fixed_height_small_url, 58 | height: data.fixed_height_small_height, 59 | width: data.fixed_height_small_width 60 | }, 61 | fixed_width_small: { 62 | gif_url: data.fixed_width_small_url, 63 | height: data.fixed_width_small_height, 64 | width: data.fixed_width_small_width 65 | }, 66 | fixed_width_small_still: { 67 | gif_url: data.fixed_width_small_url, 68 | height: data.fixed_width_small_height, 69 | width: data.fixed_width_small_width 70 | }, 71 | original: { 72 | frames: data.image_frames, 73 | gif_url: data.image_original_url, 74 | height: data.image_height, 75 | mp4: data.image_mp4_url, 76 | width: data.image_width 77 | }, 78 | id: data.id 79 | }, 80 | user: { 81 | username: data.username 82 | }, 83 | url: data.url, 84 | type: data.type 85 | }; 86 | 87 | default: 88 | throw "Unimplemented endpoint " + endpoint 89 | } 90 | } 91 | 92 | 93 | module.exports = responseFormatter -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at editor@giphy.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]. 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /tests/misc.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | 11 | var expect = require('chai').expect; 12 | var GphApiClient = require('../lib/GphApiClient') 13 | var _ = require('lodash'); 14 | 15 | describe('EMPTY RESPONSES', function() { 16 | var apiKey = "4OMJYpPoYwVpe"; 17 | var client = GphApiClient(apiKey); 18 | 19 | it('Search term with no responses returns empty array', function(done) { 20 | // Increase the default timeout for this test 21 | // If the test takes longer than this, it will fail 22 | this.timeout(5000); 23 | 24 | client.search("gifs", { 25 | "q": "funfunfunfunnofun" 26 | }).then((response) => { 27 | expect(Array.isArray(response.data)).to.equal(true); 28 | expect(response.data.length).to.equal(0); 29 | 30 | done(); 31 | }).catch((err) => { 32 | done(err); 33 | }) 34 | }); 35 | }); 36 | 37 | describe('ERROR RESPONSES', function() { 38 | var apiKey = "4OMJYpPoYwVpe"; 39 | var client = GphApiClient(apiKey); 40 | 41 | it('SEARCH Missing type variable throws appropriate error (gif instead of gifs)', function(done) { 42 | // Increase the default timeout for this test 43 | // If the test takes longer than this, it will fail 44 | this.timeout(5000); 45 | 46 | client.search("gif", { 47 | "q": "funfunfunfunnofun" 48 | }).then((response) => { 49 | }).catch((err) => { 50 | expect(err).to.be.a('string', "The type argument was passed in incorrectly. It should be either 'gifs' or 'stickers'"); 51 | done() 52 | }) 53 | }); 54 | 55 | it('GifById - pass in a wrong ID', function(done) { 56 | // Increase the default timeout for this test 57 | // If the test takes longer than this, it will fail 58 | this.timeout(5000); 59 | 60 | client.gifByID("8SDNJAJS2WRONG").then((response) => { 61 | 62 | }).catch((err) => { 63 | expect(err).to.have.keys('status', 'error', 'statusText'); 64 | done(); 65 | }) 66 | }); 67 | }); 68 | 69 | 70 | describe('INVALID API KEY ATTEMPTS', function() { 71 | var apiKey = "4OMJYpPoYwVpe888888"; 72 | var client = GphApiClient(apiKey); 73 | 74 | it('INVALID API KEY', function(done) { 75 | // Increase the default timeout for this test 76 | // If the test takes longer than this, it will fail 77 | var apiKeyTemp = "4OMsssssJYpPoYwVpe"; 78 | var clientTemp = GphApiClient(apiKey); 79 | 80 | this.timeout(5000); 81 | 82 | client.gifByID("8SDNJAJS2WRONG").then((response) => { 83 | 84 | }).catch((err) => { 85 | expect(err).to.have.keys('status', 'error', 'statusText'); 86 | done(); 87 | }) 88 | }); 89 | }); 90 | 91 | describe('Cancel requests properly', function() { 92 | 93 | it('Cancel requests properly', function(done) { 94 | // Increase the default timeout for this test 95 | // If the test takes longer than this, it will fail 96 | var apiKey = "4OMJYpPoYwVpe"; 97 | var client = GphApiClient(apiKey); 98 | 99 | this.timeout(5000); 100 | 101 | var didItGetHere = false 102 | setTimeout(function() { 103 | done() 104 | }, 2000); 105 | 106 | var cancelRequest = client.gifByID("8SDNJAJS2WRONG") 107 | cancelRequest.cancel(); 108 | cancelRequest.then((response) => { 109 | throw "did not cancel" 110 | }) 111 | cancelRequest.catch((err) => { 112 | throw err 113 | }) 114 | 115 | }); 116 | }); -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to GIPHY Core SDK for JS 2 | 3 | If you're interested in contributing to GIPHY Core SDK for JS, hopefully this document makes the process for contributing clear. 4 | 5 | ## [Code of Conduct][CODE_OF_CONDUCT] 6 | 7 | GIPHY has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text][CODE_OF_CONDUCT] so that you can understand what actions will and will not be tolerated. 8 | 9 | ## Get involved 10 | 11 | There are many ways to contribute to GIPHY, and many of them do not involve writing any code. Here's a few ideas to get started: 12 | 13 | * Look through the [open issues](https://github.com/Giphy/giphy-js-sdk-core/issues). Provide workarounds, ask for clarification, or suggest labels. 14 | * If you find an issue you would like to fix, [open a pull request](https://github.com/Giphy/giphy-js-sdk-core/pulls). 15 | 16 | For non-doc fixes: 17 | 18 | * Provide changelog entry in the [unreleased section of the CHANGELOG.md](https://github.com/Giphy/giphy-js-sdk-core/blob/master/CHANGELOG.md#unreleased). 19 | * Ensure CI passes and that you added a test that passes with the fix and fails without the fix. 20 | * Squash all commits down to one with a nice commit message *ONLY* once final review is given. Make sure this single commit is rebased on top of master. 21 | * Please address all code review comments. 22 | * Ensure that docs are updated accordingly if a feature is added. 23 | 24 | ### Commit Messages 25 | 26 | From [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) 27 | 28 | #### The seven rules of a great git commit message 29 | > Keep in mind: This has all been said before. 30 | 31 | 1. Separate subject from body with a blank line 32 | 1. Limit the subject line to 50 characters 33 | 1. Capitalize the subject line 34 | 1. Do not end the subject line with a period 35 | 1. Use the imperative mood in the subject line 36 | 1. Wrap the body at 72 characters 37 | 1. Use the body to explain what and why vs. how 38 | 39 | ## Reporting Issues 40 | 41 | ### Look For an Existing Issue 42 | 43 | Before you create a new issue, please do a search in [open issues](https://github.com/Giphy/giphy-js-sdk-core/issues) to see if the issue or feature request has already been filed. 44 | 45 | If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment: 46 | 47 | * 👍 - upvote 48 | * 👎 - downvote 49 | 50 | 51 | If you cannot find an existing issue that describes your bug or feature, create a new issue using the guidelines below. 52 | 53 | ### Writing Good Bug Reports and Feature Requests 54 | 55 | File a single issue per problem and feature request. Do not enumerate multiple bugs or feature requests in the same issue. 56 | 57 | Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes. 58 | 59 | The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix. 60 | 61 | ## Pull requests 62 | 63 | ### Your first pull request 64 | 65 | So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at. 66 | 67 | Working on your first Pull Request? You can learn how from this free video series: 68 | 69 | [**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) 70 | 71 | ## Attributions 72 | 73 | This document is based on Facebook's [React Native](https://github.com/facebook/react-native/blob/e9e20e6c8335f27af8469cd23cb7ba079b0422f9/CONTRIBUTING.md), Microsoft's [VS Code](https://github.com/Microsoft/vscode/blob/8261bddefa224dc4a9bd3ca1b40cac578f1b6f09/CONTRIBUTING.md) and Shakacode's [React on Rails](https://github.com/shakacode/react_on_rails/blob/94366056a63b0ef340dccd810734a8791806257b/CONTRIBUTING.md) Contribution Guidelines. 74 | 75 | [CODE_OF_CONDUCT]: https://github.com/Giphy/giphy-js-sdk-core/CODE_OF_CONDUCT.md 76 | -------------------------------------------------------------------------------- /tests/trending.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var expect = require('chai').expect; 11 | var GphApiClient = require('../lib/GphApiClient') 12 | var _ = require('lodash'); 13 | 14 | describe('TRENDING - gifs', function() { 15 | var apiKey = "4OMJYpPoYwVpe"; 16 | var client = GphApiClient(apiKey); 17 | 18 | 19 | 20 | it('PROMISE - trending results', function(done) { 21 | // Increase the default timeout for this test 22 | // If the test takes longer than this, it will fail 23 | this.timeout(5000); 24 | 25 | client.trending("gifs", {}).then((response) => { 26 | expect(Array.isArray(response.data)).to.equal(true); 27 | expect(response.data.length).to.be.above(0); 28 | 29 | done(); 30 | }).catch((err) => { 31 | done(err); 32 | }) 33 | }); 34 | 35 | 36 | it('passed in arguments returns search results (OFFSET) validated', function(done) { 37 | // Increase the default timeout for this test 38 | // If the test takes longer than this, it will fail 39 | this.timeout(5000); 40 | 41 | client.trending("gifs", { 42 | "limit": 10, 43 | "offset": 25 44 | }).then((response) => { 45 | expect(response.data.length).to.equal(10); 46 | expect(response.pagination.offset).to.equal(25); 47 | done(); 48 | }).catch((err) => { 49 | done(err); 50 | }) 51 | }); 52 | 53 | it('CALLBACK - returns trending results', function(done) { 54 | // Increase the default timeout for this test 55 | // If the test takes longer than this, it will fail 56 | this.timeout(5000); 57 | 58 | client.trending("gifs", {}, function(response, err) { 59 | if (err) { 60 | done(err) 61 | } 62 | expect(Array.isArray(response.data)).to.equal(true); 63 | expect(response.data.length).to.be.above(0); 64 | done(); 65 | }); 66 | }); 67 | 68 | it('PROMISE - returns an array of objects (gifs)', function(done) { 69 | // Increase the default timeout for this test 70 | // If the test takes longer than this, it will fail 71 | this.timeout(5000); 72 | client.trending("gifs", {}).then((response) => { 73 | 74 | response.data.forEach(function(gif) { 75 | expect(gif.type).to.equal('gif'); 76 | }); 77 | done(); 78 | }).catch((err) => { 79 | throw done(err) 80 | }) 81 | }) 82 | 83 | it('CALLBACK - returns an array of objects (gifs)', function(done) { 84 | // Increase the default timeout for this test 85 | // If the test takes longer than this, it will fail 86 | this.timeout(5000); 87 | client.trending("gifs", {}, function(response, err) { 88 | if (err) done(err); 89 | 90 | response.data.forEach(function(gif) { 91 | expect(gif.type).to.equal('gif'); 92 | }); 93 | done(); 94 | }); 95 | }); 96 | 97 | }); 98 | 99 | describe('TRENDING - stickers', function() { 100 | var apiKey = "4OMJYpPoYwVpe"; 101 | var client = GphApiClient(apiKey); 102 | 103 | 104 | it('PROMISE - trending results', function(done) { 105 | // Increase the default timeout for this test 106 | // If the test takes longer than this, it will fail 107 | this.timeout(5000); 108 | 109 | client.trending("stickers", {}).then((response) => { 110 | expect(Array.isArray(response.data)).to.equal(true); 111 | expect(response.data.length).to.be.above(0); 112 | 113 | done(); 114 | }).catch((err) => { 115 | done(err); 116 | }) 117 | }); 118 | 119 | it('CALLBACK - returns trending results', function(done) { 120 | // Increase the default timeout for this test 121 | // If the test takes longer than this, it will fail 122 | this.timeout(5000); 123 | 124 | client.trending("stickers", {}, function(response, err) { 125 | if (err) { 126 | done(err) 127 | } 128 | expect(Array.isArray(response.data)).to.equal(true); 129 | expect(response.data.length).to.be.above(0); 130 | done(); 131 | }); 132 | }); 133 | 134 | it('passed in arguments returns search results (OFFSET) validated', function(done) { 135 | // Increase the default timeout for this test 136 | // If the test takes longer than this, it will fail 137 | this.timeout(5000); 138 | 139 | client.trending("stickers", { 140 | "limit": 10, 141 | "offset": 25 142 | }).then((response) => { 143 | expect(response.data.length).to.equal(10); 144 | expect(response.pagination.offset).to.equal(25); 145 | done(); 146 | }).catch((err) => { 147 | done(err); 148 | }) 149 | }); 150 | 151 | it('PROMISE - returns an array of objects (gifs)', function(done) { 152 | // Increase the default timeout for this test 153 | // If the test takes longer than this, it will fail 154 | this.timeout(5000); 155 | client.trending("stickers", {}).then((response) => { 156 | 157 | response.data.forEach(function(gif) { 158 | expect(gif.type).to.equal('gif'); 159 | 160 | }); 161 | done(); 162 | }).catch((err) => { 163 | throw done(err) 164 | }) 165 | }) 166 | 167 | it('CALLBACK - returns an array of objects (gifs)', function(done) { 168 | // Increase the default timeout for this test 169 | // If the test takes longer than this, it will fail 170 | this.timeout(5000); 171 | client.trending("stickers", {}, function(response, err) { 172 | if (err) done(err); 173 | 174 | response.data.forEach(function(gif) { 175 | expect(gif.type).to.equal('gif'); 176 | }); 177 | done(); 178 | }); 179 | }); 180 | 181 | }); -------------------------------------------------------------------------------- /tests/search.spec.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | 11 | var expect = require('chai').expect; 12 | var GphApiClient = require('../lib/GphApiClient') 13 | var _ = require('lodash'); 14 | 15 | describe('SEARCH - gifs', function() { 16 | var apiKey = "4OMJYpPoYwVpe"; 17 | var client = GphApiClient(apiKey); 18 | 19 | it('PROMISE - returns search results', function(done) { 20 | // Increase the default timeout for this test 21 | // If the test takes longer than this, it will fail 22 | this.timeout(5000); 23 | 24 | client.search("gifs", { 25 | "q": "fun" 26 | }).then((response) => { 27 | expect(Array.isArray(response.data)).to.equal(true); 28 | expect(response.data.length).to.be.above(0); 29 | 30 | done(); 31 | }).catch((err) => { 32 | done(err); 33 | }) 34 | }); 35 | 36 | it('passed in arguments returns search results (OFFSET) validated', function(done) { 37 | // Increase the default timeout for this test 38 | // If the test takes longer than this, it will fail 39 | this.timeout(5000); 40 | 41 | client.search("gifs", { 42 | "q": "fun", 43 | "limit": 12, 44 | "offset": 25 45 | }).then((response) => { 46 | expect(Array.isArray(response.data)).to.equal(true); 47 | expect(response.data.length).to.equal(12); 48 | expect(response.pagination.offset).to.equal(25) 49 | done(); 50 | }).catch((err) => { 51 | done(err); 52 | }) 53 | }); 54 | 55 | it('CALLBACK - returns search results', function(done) { 56 | // Increase the default timeout for this test 57 | // If the test takes longer than this, it will fail 58 | this.timeout(5000); 59 | 60 | client.search("gifs", { 61 | "q": "fun" 62 | }, function(response, err) { 63 | if (err) { 64 | done(err) 65 | } 66 | expect(Array.isArray(response.data)).to.equal(true); 67 | expect(response.data.length).to.be.above(0); 68 | done(); 69 | }); 70 | }); 71 | 72 | it('PROMISE - returns an array of objects (gifs)', function(done) { 73 | // Increase the default timeout for this test 74 | // If the test takes longer than this, it will fail 75 | this.timeout(5000); 76 | client.search("gifs", { 77 | "q": "fun" 78 | }).then((response) => { 79 | 80 | response.data.forEach(function(gif) { 81 | expect(gif.type).to.equal('gif'); 82 | }); 83 | done(); 84 | }).catch((err) => { 85 | throw done(err) 86 | }) 87 | }) 88 | 89 | it('CALLBACK - returns an array of objects (gifs)', function(done) { 90 | // Increase the default timeout for this test 91 | // If the test takes longer than this, it will fail 92 | this.timeout(5000); 93 | client.search("gifs", { 94 | "q": "fun" 95 | }, function(response, err) { 96 | if (err) done(err); 97 | 98 | response.data.forEach(function(gif) { 99 | expect(gif.type).to.equal('gif'); 100 | }); 101 | done(); 102 | }); 103 | }); 104 | 105 | }); 106 | 107 | 108 | describe('SEARCH - stickers', function() { 109 | var apiKey = "4OMJYpPoYwVpe"; 110 | var client = GphApiClient(apiKey); 111 | 112 | it('PROMISE - returns search results', function(done) { 113 | // Increase the default timeout for this test 114 | // If the test takes longer than this, it will fail 115 | this.timeout(5000); 116 | 117 | client.search("stickers", { 118 | "q": "fun" 119 | }).then((response) => { 120 | expect(Array.isArray(response.data)).to.equal(true); 121 | expect(response.data.length).to.be.above(0); 122 | 123 | done(); 124 | }).catch((err) => { 125 | done(err); 126 | }) 127 | }); 128 | 129 | 130 | it('passed in arguments returns search results (OFFSET) validated', function(done) { 131 | // Increase the default timeout for this test 132 | // If the test takes longer than this, it will fail 133 | this.timeout(5000); 134 | 135 | client.search("stickers", { 136 | "q": "fun", 137 | "limit": 10, 138 | "offset": 25 139 | }).then((response) => { 140 | expect(Array.isArray(response.data)).to.equal(true); 141 | expect(response.data.length).to.equal(10); 142 | expect(response.pagination.offset).to.equal(25); 143 | done(); 144 | }).catch((err) => { 145 | done(err); 146 | }) 147 | }); 148 | 149 | 150 | it('CALLBACK - returns search results', function(done) { 151 | // Increase the default timeout for this test 152 | // If the test takes longer than this, it will fail 153 | this.timeout(5000); 154 | 155 | client.search("stickers", { 156 | "q": "fun" 157 | }, function(response, err) { 158 | if (err) { 159 | done(err) 160 | } 161 | expect(Array.isArray(response.data)).to.equal(true); 162 | expect(response.data.length).to.be.above(0); 163 | done(); 164 | }); 165 | }); 166 | 167 | it('PROMISE - returns an array of objects (gifs)', function(done) { 168 | // Increase the default timeout for this test 169 | // If the test takes longer than this, it will fail 170 | this.timeout(5000); 171 | client.search("stickers", { 172 | "q": "fun" 173 | }).then((response) => { 174 | 175 | response.data.forEach(function(gif) { 176 | expect(gif.type).to.equal('gif'); 177 | 178 | }); 179 | done(); 180 | }).catch((err) => { 181 | throw done(err) 182 | }) 183 | }) 184 | 185 | it('CALLBACK - returns an array of objects (gifs)', function(done) { 186 | // Increase the default timeout for this test 187 | // If the test takes longer than this, it will fail 188 | this.timeout(5000); 189 | client.search("stickers", { 190 | "q": "fun" 191 | }, function(response, err) { 192 | if (err) done(err); 193 | 194 | response.data.forEach(function(gif) { 195 | expect(gif.type).to.equal('gif'); 196 | 197 | }); 198 | done(); 199 | }); 200 | }); 201 | }); -------------------------------------------------------------------------------- /src/GphApiClient.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Cosmo Cochrane on 4/20/17. 3 | * Copyright (c) 2017 Giphy Inc. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this 7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 | */ 9 | 10 | var _ = require('lodash'); 11 | var RequestHandler = require('./handlers/RequestHandler'); 12 | 13 | 14 | var serverUrl = "https://api.giphy.com"; 15 | 16 | /** 17 | * Class representing the networking client. 18 | */ 19 | 20 | 21 | class GphApiClient { 22 | 23 | constructor(apiKey) { 24 | this.apiKey = apiKey; 25 | } 26 | 27 | /** 28 | * Initialize the SDK by passing in the apiKey. 29 | */ 30 | setCredentials(apiKey) { 31 | this.apiKey = apiKey; 32 | } 33 | 34 | /** 35 | * @return a list of gifs that match the inputted search query 36 | * @param {String} type - specify whether it is a gif or a sticker 37 | * @param {Object} params an object containing parameters 38 | * @param {String} params.q search query term or phrase 39 | * @param {Integer} params.limit (optional) number of results to return, maximum 100. Default 25. 40 | * @param {Integer} params.offset(optional) results offset, defaults to 0. 41 | * @param {String} params.rating (optional) limit results to those rated (y,g, pg, pg-13 or r). 42 | * @param {String} params.lang (optional) specify default country for regional content; format is 2-letter ISO 639-1 country code. See list of supported languages here 43 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 44 | */ 45 | search(type, params, cb) { 46 | 47 | const data = { 48 | //grabs the correct endpoint from an object 49 | url: `${serverUrl}/v1/${type}/search`, 50 | method: 'get', 51 | type: type, 52 | params: _.extend({ 53 | api_key: this.apiKey 54 | }, params) 55 | } 56 | 57 | return RequestHandler(data, 'search', cb); 58 | } 59 | 60 | /** 61 | * @return a list of currently trending gifs 62 | * @param {Object} params an object containing parameters 63 | * @param {String} type specify whether it is a gif or a sticker 64 | * @param {Integer} params.limit (optional) number of results to return, maximum 100. Default 25. 65 | * @param {Integer} params.offset(optional) results offset, defaults to 0. 66 | * @param {String} params.rating (optional) limit results to those rated (y,g, pg, pg-13 or r). 67 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 68 | */ 69 | trending(type, params, cb) { 70 | 71 | const data = { 72 | //grabs the correct endpoint from an object 73 | url: `${serverUrl}/v1/${type}/trending`, 74 | method: 'get', 75 | type: type, 76 | params: _.extend({ 77 | api_key: this.apiKey 78 | }, params) 79 | } 80 | 81 | return RequestHandler(data, 'trending', cb); 82 | } 83 | 84 | /** 85 | * @return a single gif 86 | * @param {String} type specify whether it is a gif or a sticker 87 | * @param {Object} params an object containing parameters 88 | * @param {String} params.s (optional) the term you would like to have translated 89 | * @param {String} params.rating (optional) @type string limit results to those rated (y,g, pg, pg-13 or r). 90 | * @param {String} params.lang (optional) specify default country for regional content; format is 2-letter ISO 639-1 country code 91 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 92 | */ 93 | translate(type, params, cb) { 94 | 95 | const data = { 96 | //grabs the correct endpoint from an object 97 | url: `${serverUrl}/v1/${type}/translate`, 98 | method: 'get', 99 | type: type, 100 | params: _.extend({ 101 | api_key: this.apiKey 102 | }, params) 103 | } 104 | 105 | return RequestHandler(data, 'translate', cb); 106 | } 107 | 108 | /** 109 | * @return a random gif 110 | * @param {String} type specify whether it is a gif or a sticker 111 | * @param {Object} params an object containing parameters 112 | * @param {String} params.tag (optional) the GIF tag to limit randomness by 113 | * @param {String} params.rating (optional) limit results to those rated (y,g, pg, pg-13 or r). 114 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 115 | */ 116 | random(type, params, cb) { 117 | 118 | const data = { 119 | //grabs the correct endpoint from an object 120 | url: `${serverUrl}/v1/${type}/random`, 121 | method: 'get', 122 | type: type, 123 | params: _.extend({ 124 | api_key: this.apiKey 125 | }, params) 126 | } 127 | 128 | return RequestHandler(data, 'random', cb); 129 | } 130 | 131 | /** 132 | * @return single gif based on the provided ID 133 | * @param {String} id ID associated with a specific gif 134 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 135 | */ 136 | gifByID(id, cb) { 137 | 138 | const data = { 139 | //grabs the correct endpoint from an object 140 | url: `${serverUrl}/v1/gifs/${id}`, 141 | method: 'get', 142 | params: { 143 | api_key: this.apiKey 144 | } 145 | } 146 | 147 | return RequestHandler(data, 'gifByID', cb); 148 | } 149 | 150 | /** 151 | * @return a list of gifs per ID 152 | * @param {Object} params an object containing parameters 153 | * @param {Array} params.ids (optional) return results in html or json format (useful for viewing responses as GIFs to debug/test) 154 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 155 | */ 156 | gifsByIDs(params, cb) { 157 | 158 | //separate teh array into a string of separated values as superagent needs special formatting for array params 159 | params.ids = params.ids.join(','); 160 | 161 | const data = { 162 | //grabs the correct endpoint from an object 163 | url: `${serverUrl}/v1/gifs`, 164 | method: 'get', 165 | params: _.extend({ 166 | api_key: this.apiKey 167 | }, params) 168 | } 169 | 170 | return RequestHandler(data, 'gifsByIDs', cb); 171 | } 172 | 173 | /** 174 | * @return a list of categories 175 | * @param {String} type gif or a sticker 176 | * @param {Object} params an object containing parameters 177 | * @param {String} params.sort (optional) 178 | * @param {Integer} params.limit (optional) number of results to return, maximum 100. Default 25. 179 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 180 | */ 181 | categoriesForGifs(params, cb) { 182 | 183 | const data = { 184 | //grabs the correct endpoint from an object 185 | url: `${serverUrl}/v1/gifs/categories`, 186 | method: 'get', 187 | params: _.extend({ 188 | api_key: this.apiKey 189 | }, params) 190 | } 191 | 192 | return RequestHandler(data, 'categoriesForGifs', cb); 193 | } 194 | 195 | /** 196 | * @return a list of subcategories for a category 197 | * @param {String} subcategory subcategory name 198 | * @param {Object} params an object containing parameters 199 | * @param {Integer} params.limit (optional) number of results to return, maximum 100. Default 25. 200 | * @param {Integer} params.offset (optional) results offset, defaults to 0. 201 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 202 | */ 203 | subCategoriesForGifs(subcategory, params, cb) { 204 | 205 | const data = { 206 | //grabs the correct endpoint from an object 207 | url: `${serverUrl}/v1/gifs/categories/${subcategory}`, 208 | method: 'get', 209 | params: _.extend({ 210 | api_key: this.apiKey 211 | }, params) 212 | } 213 | 214 | return RequestHandler(data, 'subCategoriesForGifs', cb); 215 | } 216 | 217 | /** 218 | * @return a list of gifs 219 | * @param {Object} params an object containing parameters 220 | * @param {String} category category name 221 | * @param {String} subcategory subcategory name 222 | * @param {Integer} params.limit (optional) number of results to return, maximum 100. Default 25. 223 | * @param {Integer} params.offset offset (optional) results offset, defaults to 0. 224 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 225 | */ 226 | gifsByCategories(category, subcategory, params, cb) { 227 | 228 | const data = { 229 | //grabs the correct endpoint from an object 230 | url: `${serverUrl}/v1/gifs/categories/${category}/${subcategory}`, 231 | method: 'get', 232 | params: _.extend({ 233 | api_key: this.apiKey 234 | }, params) 235 | } 236 | 237 | return RequestHandler(data, 'gifsByCategories', cb); 238 | } 239 | 240 | /** 241 | * @return a list of term suggestions 242 | * @param {String} term a term to receive back similar terms 243 | * @param {Function} callback (optional) callback will default to a promise if nothing is passed in 244 | */ 245 | termSuggestions(term, cb) { 246 | 247 | const data = { 248 | //grabs the correct endpoint from an object 249 | url: `${serverUrl}/v1/queries/suggest/${term}`, 250 | method: 'get', 251 | params: _.extend({ 252 | api_key: this.apiKey 253 | }) 254 | } 255 | 256 | return RequestHandler(data, 'termSuggestions', cb); 257 | } 258 | } 259 | 260 | module.exports = function(apiKey) { 261 | return new GphApiClient(apiKey); 262 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Giphy Core SDK for JS (deprecated) 2 | 3 | > This package is deprecated, please use our [fetch api package](https://github.com/Giphy/giphy-js/blob/master/packages/fetch-api/README.md) as a wrapper around [Giphy API](https://github.com/Giphy/GiphyAPI). It contains typescript definitions and should be a better experience, if we're missing a feature, please feel free to file an issue on the [monorepo](https://github.com/Giphy/giphy-js). 4 | 5 | > Also check out the new UI packages for [React](https://github.com/Giphy/giphy-js/blob/master/packages/react-components/README.md) and [vanilla JS](https://github.com/Giphy/giphy-js/blob/master/packages/components/README.md), they can greatly facitilate your GIPHY integration. 6 | 7 | The **Giphy Core SDK** is a wrapper around [Giphy API](https://github.com/Giphy/GiphyAPI). 8 | 9 | [license-url]: LICENSE.md 10 | [downloads-image]: https://img.shields.io/npm/dm/giphy-js-sdk-core.svg?style=flat-square 11 | [downloads-url]: http://npm-stat.com/charts.html?package=giphy-js-sdk-core 12 | [version-svg]: https://img.shields.io/npm/v/giphy-js-sdk-core.svg?style=flat-square 13 | [package-url]: https://npmjs.org/package/giphy-js-sdk-core 14 | 15 | [Giphy](https://www.giphy.com) is the best way to search, share, and discover GIFs on the Internet. Similar to the way other search engines work, the majority of our content comes from indexing based on the best and most popular GIFs and search terms across the web. We organize all those GIFs so you can find the good content easier and share it out through your social channels. We also feature some of our favorite GIF artists and work with brands to create and promote their original GIF content. 16 | 17 | [![](https://media.giphy.com/media/5xaOcLOqNmWHaLeB14I/giphy.gif)]() 18 | 19 | # Getting Started 20 | 21 | ### Supported End-points 22 | 23 | * [Search GIFs/Stickers](#search-endpoint) 24 | * [Trending GIFs/Stickers](#trending-endpoint) 25 | * [Translate GIFs/Stickers](#translate-endpoint) 26 | * [Random GIFs/Stickers](#random-endpoint) 27 | * [GIF by ID](#get-gif-by-id-endpoint) 28 | * [GIFs by IDs](#get-gifs-by-ids-endpoint) 29 | * [Categories for GIFs](#categories-endpoint) 30 | * [Subcategories for GIFs](#subcategories-endpoint) 31 | * [GIFs for a Subcategory](#subcategory-content-endpoint) 32 | * [Term Suggestions](#term-suggestions-endpoint) 33 | 34 | 35 | # Setup 36 | 37 | ### Require Module 38 | 39 | 40 | npm 41 | ```shell 42 | npm install --save giphy-js-sdk-core 43 | ``` 44 | 45 | ### Initialize Giphy SDK 46 | 47 | ```javascript 48 | var GphApiClient = require('giphy-js-sdk-core') 49 | client = GphApiClient("YOUR_API_KEY") 50 | ``` 51 | 52 | ### Search Endpoint 53 | Search all Giphy GIFs for a word or phrase. Punctuation will be stripped and ignored. 54 |
55 |
56 | 57 | *Required Params* 58 | * "q" - string - search query term or phrase 59 | 60 | *Optional Params* 61 | * "limit" - integer - number of results to return, maximum 100. Default 25. 62 | * "offset" - integer - results offset, defaults to 0. 63 | * "rating" - string - limit results to those rated (y,g, pg, pg-13 or r). 64 | * "lang" - string - specify default country for regional content; format is 2-letter ISO 639-1 country code. See list of supported languages [here](https://github.com/Giphy/GiphyAPI/blob/master/README.md#language-support) 65 | * "fmt" - string - return results in html or json format (useful for viewing responses as GIFs to debug/test) 66 | * "sort" - string - the sort order of the results returned (recent | relevant) 67 | 68 | ```javascript 69 | /// Gif Search 70 | client.search('gifs', {"q": "cats"}) 71 | .then((response) => { 72 | response.data.forEach((gifObject) => { 73 | console.log(gifObject) 74 | }) 75 | }) 76 | .catch((err) => { 77 | 78 | }) 79 | 80 | /// Sticker Search 81 | client.search('stickers', {"q": "cats"}) 82 | .then((response) => { 83 | 84 | }) 85 | .catch((err) => { 86 | 87 | }) 88 | ``` 89 | ### Trending Endpoint 90 | Fetch GIFs currently trending online. Hand curated by the Giphy editorial team. The data returned mirrors the GIFs showcased on the [Giphy](https://www.giphy.com) homepage. 91 |
92 |
93 | *Required Params* 94 | * none 95 | 96 | *Optional Params* 97 | * "limit" - integer - number of results to return, maximum 100. Default 25. 98 | * "offset" - integer - results offset, defaults to 0 99 | * "rating" - string - limit results to those rated (y,g, pg, pg-13 or r). 100 | * "fmt" - string - return results in html or json format (useful for viewing responses as GIFs to debug/test) 101 | 102 | 103 | ```javascript 104 | /// Trending Gifs 105 | client.trending("gifs", {}) 106 | .then((response) => { 107 | 108 | }) 109 | .catch((err) => { 110 | 111 | }) 112 | 113 | /// Trending Stickers 114 | client.trending("stickers", {}) 115 | .then((response) => { 116 | 117 | }) 118 | .catch((err) => { 119 | 120 | }) 121 | ``` 122 | 123 | ### Translate Endpoint 124 | The translate API draws on search, but uses the Giphy "special sauce" to handle translating from one vocabulary to another. In this case, words and phrases to GIFs. Example implementations of translate can be found in the Giphy Slack, Hipchat, Wire, or Dasher integrations. Use a plus or url encode for phrases. 125 |
126 |
127 | *Required Params* 128 | * "s" - string - term or phrase to translate into a GIF 129 | 130 | *Optional Params* 131 | * "rating" - (optional) limit results to those rated (y,g, pg, pg-13 or r). 132 | * "lang" - (optional) specify default country for regional content; format is 2-letter ISO 639-1 country code. See list of supported langauges [here](https://github.com/Giphy/GiphyAPI/blob/master/README.md#language-support) 133 | * "fmt" - (optional) return results in html or json format (useful for viewing responses as GIFs to debug/test) 134 | 135 | ```javascript 136 | /// Translate to a Gif 137 | client.translate('gifs', {"s": 'cool'}) 138 | .then((response) => { 139 | 140 | }) 141 | .catch((err) => { 142 | 143 | }) 144 | 145 | /// Translate to a Sticker 146 | client.translate('stickers', {"s": 'cool'}) 147 | .then((response) => { 148 | 149 | }) 150 | .catch((err) => { 151 | 152 | }) 153 | ``` 154 | 155 | ### Random Endpoint 156 | Returns a random GIF, limited by tag. Excluding the tag parameter will return a random GIF from the Giphy catalog. 157 |
158 |
159 | *Required Params* 160 | * none 161 | 162 | *Optional Params* 163 | * "tag" - string - the GIF tag to limit randomness by 164 | * "rating" - string - limit results to those rated (y,g, pg, pg-13 or r). 165 | * "fmt" - (optional) return results in html or json format (useful for viewing responses as GIFs to debug/test) 166 | 167 | ```javascript 168 | /// Random Gif 169 | client.random('gifs', {}) 170 | .then((response) => { 171 | 172 | }) 173 | .catch((err) => { 174 | 175 | }) 176 | 177 | /// Random Sticker 178 | client.random('stickers', {}) 179 | .then((response) => { 180 | 181 | }) 182 | .catch((err) => { 183 | 184 | }) 185 | ``` 186 | 187 | ### Get GIF by ID Endpoint 188 | Returns meta data about a GIF, by GIF id. In the below example, the GIF ID is "feqkVgjJpYtjy" 189 |
190 |
191 | *Required Params* 192 | * none 193 | 194 | *Optional Params* 195 | * none 196 | 197 | ```javascript 198 | /// Gif by Id 199 | client.gifByID("feqkVgjJpYtjy") 200 | .then((response) => { 201 | 202 | }) 203 | .catch((err) => { 204 | 205 | }) 206 | ``` 207 | 208 | ### Get GIFs by IDs Endpoint 209 | A multiget version of the get GIF by ID endpoint. In this case the IDs are feqkVgjJpYtjy and 7rzbxdu0ZEXLy. 210 | *Required Params* 211 | * "ids" - a comma separated list of IDs to fetch GIF size data. 212 | 213 | *Optional Params* 214 | * none 215 | ```javascript 216 | /// Gifs by Ids 217 | 218 | client.gifsByIDs({"ids": ["feqkVgjJpYtjy", "7rzbxdu0ZEXLy"]}) 219 | .then((response) => { 220 | 221 | }) 222 | .catch((err) => { 223 | 224 | }) 225 | ``` 226 | 227 | ### Categories Endpoint 228 | Fetch Giphy categories 229 |
230 |
231 | *Required Params* 232 | * none 233 | 234 | *Optional Params* 235 | * "limit" - integer - number of results to return, maximum 100. Default 25. 236 | * "offset" - integer - results offset, defaults to 0. 237 | 238 | 239 | ```javascript 240 | /// Gifs by Ids 241 | 242 | client.categoriesForGifs({}) 243 | .then((response) => { 244 | 245 | }) 246 | .catch((err) => { 247 | 248 | }) 249 | ``` 250 | 251 | ### Subcategories Endpoint 252 | Get Subcategories for GIFs given a category. You will need this subcategory object to pull GIFs for this category. 253 |
254 |
255 | *Required Params* 256 | * none 257 | 258 | *Optional Params* 259 | * "limit" - integer - number of results to return, maximum 100. Default 25. 260 | * "offset" - integer - results offset, defaults to 0. 261 | 262 | 263 | ```javascript 264 | /// Gifs by Ids 265 | 266 | client.subCategoriesForGifs("tv", {}) 267 | .then((response) => { 268 | 269 | }) 270 | .catch((err) => { 271 | 272 | }) 273 | ``` 274 | 275 | ### Subcategory Content Endpoint 276 | Get GIFs for a given Sub-Category. 277 |
278 |
279 | *Required Params* 280 | * none 281 | 282 | *Optional Params* 283 | * "limit" - integer - number of results to return, maximum 100. Default 25. 284 | * "offset" - integer - results offset, defaults to 0. 285 | 286 | ```javascript 287 | /// Gifs by Ids 288 | 289 | client.gifsByCategories("tv", "'the office'", {}) 290 | .then((response) => { 291 | 292 | }) 293 | .catch((err) => { 294 | 295 | }) 296 | ``` 297 | 298 | ### Term Suggestions Endpoint 299 | Get term suggestions given a search term, or a substring. 300 |
301 |
302 | *Required Params* 303 | * none 304 | 305 | *Optional Params* 306 | * none 307 | 308 | 309 | ```javascript 310 | /// Gifs by Ids 311 | 312 | client.termSuggestions("cool") 313 | .then((response) => { 314 | 315 | }) 316 | .catch((err) => { 317 | 318 | }) 319 | ``` 320 | 321 | 322 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | --------------------------------------------------------------------------------