Socket
Socket
Sign inDemoInstall

carousel-js

Package Overview
Dependencies
6
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.5.0 to 2.0.0

10

bower.json
{
"name": "carousel-js",
"version": "1.5.0",
"version": "2.0.0",
"homepage": "https://github.com/mkay581/carousel-js",

@@ -31,9 +31,7 @@ "authors": [

"dependencies": {
"element-kit": "^1.0.5",
"jquery": "^2.2.1",
"module.js": "^2.2.4",
"promise": "^7.1.1",
"resource-manager-js": "^1.2.1",
"underscore": "^1.8.3"
"lodash": "^4.6.1",
"module-js": "^3.0.1",
"promise": "^7.1.1"
}
}

15

package.json
{
"name": "carousel-js",
"version": "1.5.0",
"version": "2.0.0",
"description": "A carousel class",

@@ -26,11 +26,9 @@ "repository": {

"dependencies": {
"element-kit": "^1.0.5",
"jquery": "^2.2.1",
"module.js": "^2.2.4",
"promise": "^7.1.1",
"resource-manager-js": "^1.2.1",
"underscore": "^1.8.3"
"lodash": "^4.6.1",
"module-js": "^3.0.1",
"promise": "^7.1.1"
},
"devDependencies": {
"build-tools": "^2.4.0",
"build-tools": "^2.6.0",
"grunt": "^0.4.5",

@@ -41,4 +39,5 @@ "grunt-cli": "^0.1.13",

"scripts": {
"test": "grunt bt:test"
"test": "grunt bt:test",
"start": "grunt bt:server:local"
}
}
'use strict';
var _ = require('underscore');
var ElementKit = require('element-kit');
var Module = require('module.js');
var Promise = require('promise');
import _ from 'lodash';
import Module from 'module-js';

@@ -21,3 +19,3 @@ /**

*/
var CarouselArrows = Module.extend({
class CarouselArrows extends Module {

@@ -34,5 +32,5 @@ /**

*/
initialize: function (options) {
constructor (options) {
this.options = _.extend({
options = _.extend({
leftArrow: null,

@@ -47,13 +45,16 @@ rightArrow: null,

this._checkForInitErrors();
if (!options.leftArrow && !options.rightArrow) {
console.error('Carousel Arrows Error: no left and right arrows were passed into constructor');
}
Module.prototype.initialize.call(this, this.options);
super(options);
this.options = options;
this.arrows = [];
// setup listeners
if (options.leftArrow) {
this.arrows.push(options.leftArrow);
options.leftArrow.kit.addEventListener('click', 'onLeftArrowClick', this);
this._leftArrowEventListener = e => this.onLeftArrowClick(e);
options.leftArrow.addEventListener('click', this._leftArrowEventListener);
}

@@ -63,23 +64,12 @@

this.arrows.push(options.rightArrow);
options.rightArrow.kit.addEventListener('click', 'onRightArrowClick', this);
this._rightArrowEventListener = e => this.onRightArrowClick(e);
options.rightArrow.addEventListener('click', this._rightArrowEventListener);
}
},
}
/**
* Checks for errors upon initialize.
* @memberOf CarouselArrows
* @private
*/
_checkForInitErrors: function () {
var options = this.options;
if (!options.leftArrow && !options.rightArrow) {
console.error('Carousel Arrows Error: no left and right arrows were passed into constructor');
}
},
/**
* Updates the arrow based on the supplied panel index.
* @param {Number} panelIndex - The new panel index
*/
update: function (panelIndex) {
update (panelIndex) {
var currentItemNum = panelIndex + 1,

@@ -105,3 +95,3 @@ maxItems = this.options.panels.length,

},
}

@@ -111,6 +101,6 @@ /**

*/
disable: function () {
disable () {
this.disableLeftArrow();
this.disableRightArrow();
},
}

@@ -120,7 +110,7 @@ /**

*/
disableLeftArrow: function () {
disableLeftArrow () {
if (this.options.leftArrow) {
this.options.leftArrow.classList.add(this.options.arrowDisabledClass);
}
},
}

@@ -130,7 +120,7 @@ /**

*/
disableRightArrow: function () {
disableRightArrow () {
if (this.options.rightArrow) {
this.options.rightArrow.classList.add(this.options.arrowDisabledClass);
}
},
}

@@ -140,6 +130,6 @@ /**

*/
enable: function () {
enable () {
this.enableLeftArrow();
this.enableRightArrow();
},
}

@@ -149,7 +139,7 @@ /**

*/
enableLeftArrow: function () {
enableLeftArrow () {
if (this.options.leftArrow) {
this.options.leftArrow.classList.remove(this.options.arrowDisabledClass);
}
},
}

@@ -159,7 +149,7 @@ /**

*/
enableRightArrow: function () {
enableRightArrow () {
if (this.options.rightArrow) {
this.options.rightArrow.classList.remove(this.options.arrowDisabledClass);
}
},
}

@@ -170,3 +160,3 @@ /**

*/
onLeftArrowClick: function (e) {
onLeftArrowClick (e) {
var isDisabled = this.options.leftArrow.classList.contains(this.options.arrowDisabledClass);

@@ -176,3 +166,3 @@ if (this.options.onLeftArrowClick && !isDisabled) {

}
},
}

@@ -183,3 +173,3 @@ /**

*/
onRightArrowClick: function (e) {
onRightArrowClick (e) {
var isDisabled = this.options.rightArrow.classList.contains(this.options.arrowDisabledClass);

@@ -189,3 +179,3 @@ if (this.options.onRightArrowClick && !isDisabled) {

}
},
}

@@ -196,14 +186,14 @@ /**

*/
destroy: function () {
destroy () {
if (this.options.leftArrow) {
this.options.leftArrow.kit.removeEventListener('click', 'onLeftArrowClick', this);
this.options.leftArrow.removeEventListener('click', this._leftArrowEventListener);
}
if (this.options.rightArrow) {
this.options.rightArrow.kit.removeEventListener('click', 'onRightArrowClick', this);
this.options.rightArrow.removeEventListener('click', this._rightArrowEventListener);
}
Module.prototype.destroy.call(this);
super.destroy();
}
});
}
module.exports = CarouselArrows;
module.exports = CarouselArrows;
'use strict';
var _ = require('underscore');
var ElementKit = require('element-kit');
var Module = require('module.js');
var Promise = require('promise');
import _ from 'lodash';
import Module from 'module-js';
import Promise from 'promise';

@@ -19,3 +18,3 @@ /**

*/
var CarouselPanels = Module.extend({
class CarouselPanels extends Module {

@@ -32,5 +31,5 @@ /**

*/
initialize: function (options) {
constructor (options) {
this.options = _.extend({
options = _.extend({
panels: [],

@@ -44,19 +43,11 @@ assetLoadingClass: 'carousel-asset-loading',

this._checkForInitErrors();
Module.prototype.initialize.call(this, this.options);
},
super(options);
/**
* Checks for errors upon initialize.
* @memberOf CarouselPanels
* @private
*/
_checkForInitErrors: function () {
var options = this.options,
panelCount = options.panels.length;
if (!panelCount) {
if (!options.panels.length) {
console.error('carousel error: no panels were passed in constructor');
}
},
this.options = options;
}
/**

@@ -68,3 +59,3 @@ * Transitions to a panel of an index.

*/
goTo: function (index) {
goTo (index) {
var maxIndex = this.options.panels.length - 1,

@@ -94,3 +85,3 @@ minIndex = 0,

return promise;
},
}

@@ -103,10 +94,10 @@ /**

*/
_updatePanels: function (index) {
_updatePanels (index) {
var panels = this.options.panels,
prevIndex = this.getCurrentIndex();
if (prevIndex !== undefined) {
panels[prevIndex].kit.classList.remove(this.options.panelActiveClass);
panels[prevIndex].classList.remove(this.options.panelActiveClass);
}
panels[index].kit.classList.add(this.options.panelActiveClass);
},
panels[index].classList.add(this.options.panelActiveClass);
}

@@ -118,5 +109,5 @@ /**

*/
getCurrentIndex: function () {
getCurrentIndex () {
return this._currentIndex;
},
}

@@ -129,3 +120,3 @@ /**

*/
loadPanelAssets: function (index) {
loadPanelAssets (index) {
var options = this.options,

@@ -151,22 +142,32 @@ panel = options.panels[index],

return Promise.all(loadPromises);
},
}
/**
* Manually lazy loads a resource using an element's data attribute.
* @param {HTMLImageElement} el - The image element to load
* @param {HTMLImageElement} img - The image element to load
* @memberOf CarouselPanels
*/
loadPanelImageAsset: function (el) {
var img = el,
src = el.getAttribute(this.options.lazyLoadAttr),
loadPanelImageAsset (img) {
var src = img.getAttribute(this.options.lazyLoadAttr),
loadingClass = this.options.assetLoadingClass;
img.kit.classList.add(loadingClass);
return img.kit.load(src)
.then(function() {
img.kit.classList.remove(loadingClass);
img.classList.add(loadingClass);
return new Promise(function (resolve) {
img.onload = function () {
resolve(img);
};
img.onerror = function () {
// IE 9-11 have an issue where it automatically triggers an error on some images,
// and then will immediately trigger onload() causing intermittent errors to appear
// until this is fixed or we have a workaround, we will be resolving
// even if there is an error
resolve(img);
};
img.src = src;
}).then(function() {
img.classList.remove(loadingClass);
})
.catch(function () {
img.kit.classList.remove(loadingClass);
img.classList.remove(loadingClass);
});
},
}

@@ -177,3 +178,3 @@ /**

*/
destroy: function () {
destroy () {
var options = this.options,

@@ -183,9 +184,9 @@ currentIndex = this.getCurrentIndex();

if (currentIndex) {
options.panels[currentIndex].kit.classList.remove(options.panelActiveClass);
options.panels[currentIndex].classList.remove(options.panelActiveClass);
}
this._currentIndex = null;
Module.prototype.destroy.call(this);
super.destroy();
}
});
}
module.exports = CarouselPanels;
module.exports = CarouselPanels;
'use strict';
var ElementKit = require('element-kit');
var utils = ElementKit.utils;
var Module = require('module.js');
import Module from 'module-js';
import _ from 'lodash';

@@ -18,3 +17,3 @@ /**

*/
var CarouselThumbs = Module.extend({
class CarouselThumbs extends Module {

@@ -29,5 +28,4 @@ /**

*/
initialize: function (options) {
this.options = utils.extend({
constructor (options) {
options = _.extend({
thumbnails: [],

@@ -39,7 +37,8 @@ thumbnailActiveTriggerEvent: 'click',

Module.prototype.initialize.call(this, this.options);
super(options);
this.options = options;
this._thumbnailEventListener = this.onThumbnailEvent.bind(this);
this.setup();
},
}

@@ -50,14 +49,10 @@ /**

*/
setup: function () {
setup () {
var thumbs = this.options.thumbnails;
if (thumbs.length) {
utils.triggerHtmlCollectionMethod(thumbs, 'addEventListener', [
this.options.thumbnailActiveTriggerEvent,
'onThumbnailEvent',
this
]);
this.triggerThumbsEventListener('addEventListener');
} else {
console.error('carousel thumb error: no thumbnails were passed to constructor');
}
},
}

@@ -69,3 +64,3 @@ /**

*/
onThumbnailEvent: function (e) {
onThumbnailEvent (e) {
if (!this._thumbnailArr) {

@@ -76,2 +71,4 @@ // convert thumbnail HTMLCollection to real array so we can perform necessary array methods

var index = this._thumbnailArr.indexOf(e.currentTarget);
// we are checking that the selected thumbnail is still in the HTMLCollection
// because it is live introducing the possibility that the element is no longer in the DOM
if (index !== -1 && index !== this.getCurrentIndex()) {

@@ -83,3 +80,3 @@ this.goTo(index);

}
},
}

@@ -91,3 +88,3 @@ /**

*/
_checkForInitErrors: function () {
_checkForInitErrors () {
var options = this.options,

@@ -98,3 +95,3 @@ thumbnailCount = options.thumbnails.length;

}
},
}

@@ -106,3 +103,3 @@ /**

*/
goTo: function (index) {
goTo (index) {
var thumbs = this.options.thumbnails,

@@ -118,9 +115,9 @@ prevIndex = this.getCurrentIndex() || 0,

thumbs[index].kit.classList.add(activeClass);
thumbs[index].classList.add(activeClass);
if (prevIndex !== index) {
thumbs[prevIndex].kit.classList.remove(activeClass);
thumbs[prevIndex].classList.remove(activeClass);
}
this._currentIndex = index;
},
}

@@ -132,27 +129,34 @@ /**

*/
getCurrentIndex: function () {
getCurrentIndex () {
return this._currentIndex;
},
}
/**
* Triggers an event listener method on all thumbnail elements.
* @param {string} method - The event listener method to call on each of the elements
*/
triggerThumbsEventListener (method) {
var count = this.options.thumbnails.length,
i, el;
for (i = 0; i < count; i++) {
el = this.options.thumbnails[i];
el[method](this.options.thumbnailActiveTriggerEvent, this._thumbnailEventListener);
}
}
/**
* Destroys the instance.
* @memberOf CarouselThumbs
*/
destroy: function () {
var options = this.options,
thumbs = options.thumbnails;
destroy () {
let thumbs = this.options.thumbnails;
this._currentIndex = null;
if (thumbs.length) {
this.triggerThumbsEventListener('removeEventListener');
if (thumbs.length) {
utils.triggerHtmlCollectionMethod(thumbs, 'removeEventListener', [
options.thumbnailActiveTriggerEvent,
'onThumbnailEvent',
this
]);
}
Module.prototype.destroy.call(this);
super.destroy();
}
});
}
module.exports = CarouselThumbs;
module.exports = CarouselThumbs;
'use strict';
var CarouselPanels = require('./carousel-panels');
var CarouselThumbs = require('./carousel-thumbs');
var CarouselArrows = require('./carousel-arrows');
var ElementKit = require('element-kit');
var utils = ElementKit.utils;
var Module = require('module.js');
var _ = require('underscore');
import CarouselThumbs from './carousel-thumbs';
import CarouselPanels from './carousel-panels';
import CarouselArrows from './carousel-arrows';
import _ from 'lodash';
import Module from 'module-js';
/**

@@ -30,3 +28,3 @@ * A callback function that fires after a new active panel is set

var Carousel = Module.extend({
class Carousel extends Module {

@@ -37,3 +35,3 @@ /**

*/
initialize: function (options) {
constructor (options) {

@@ -51,3 +49,3 @@ options = options || {};

this.options = utils.extend({
options = _.extend({
panels: [],

@@ -71,8 +69,8 @@ assetLoadingClass: 'carousel-asset-loading',

super(options);
this.options = options;
this._checkForInitErrors();
Module.prototype.initialize.call(this, this.options);
this.setup();
},
}

@@ -83,3 +81,6 @@ /**

*/
setup: function () {
setup () {
this.subModules = this.subModules || {};
if (!this.subModules.panels) {

@@ -100,3 +101,3 @@ this.subModules.panels = this.setupPanels(this.options);

}
},
}

@@ -108,7 +109,7 @@ /**

*/
setupThumbs: function (options) {
return new CarouselThumbs(utils.extend({}, options, {
setupThumbs (options) {
return new CarouselThumbs(_.extend({}, options, {
onChange: this.onThumbnailChange.bind(this)
}));
},
}

@@ -120,7 +121,9 @@ /**

*/
setupPanels: function (options) {
return new CarouselPanels(utils.extend({}, options, {
onChange: this.onPanelChange.bind(this)
}));
},
setupPanels (options) {
if (options.panels.length) {
return new CarouselPanels(_.extend({}, options, {
onChange: this.onPanelChange.bind(this)
}));
}
}

@@ -132,3 +135,3 @@ /**

*/
setupArrows: function (options) {
setupArrows (options) {
var internalOptions;

@@ -141,3 +144,3 @@ // make clone of original options

return new CarouselArrows(internalOptions);
},
}

@@ -149,3 +152,3 @@ /**

*/
_checkForInitErrors: function () {
_checkForInitErrors () {
var options = this.options,

@@ -159,3 +162,3 @@ panelCount = options.panels.length,

}
},
}

@@ -167,3 +170,3 @@ /**

*/
onPanelChange: function (index) {
onPanelChange (index) {
if (this.subModules.thumbnails) {

@@ -180,3 +183,3 @@ this.subModules.thumbnails.goTo(index);

}
},
}

@@ -188,5 +191,5 @@ /**

*/
onThumbnailChange: function (index) {
onThumbnailChange (index) {
this.goTo(index);
},
}

@@ -197,3 +200,3 @@ /**

*/
onRightArrowClick: function (e) {
onRightArrowClick (e) {
this.goTo(this.subModules.panels.getCurrentIndex() + 1);

@@ -203,3 +206,3 @@ if (this.options.onRightArrowClick) {

}
},
}

@@ -210,3 +213,3 @@ /**

*/
onLeftArrowClick: function (e) {
onLeftArrowClick (e) {
this.goTo(this.subModules.panels.getCurrentIndex() - 1);

@@ -216,3 +219,3 @@ if (this.options.onLeftArrowClick) {

}
},
}

@@ -224,3 +227,3 @@ /**

*/
goTo: function (index) {
goTo (index) {
var options = this.options,

@@ -244,5 +247,8 @@ maxIndex = options.panels.length - 1,

}
return this.subModules.panels.goTo(index);
},
if (this.subModules.panels) {
return this.subModules.panels.goTo(index);
}
}
/**

@@ -253,5 +259,5 @@ * Gets the current index that is showing.

*/
getCurrentIndex: function () {
getCurrentIndex () {
return this.subModules.panels.getCurrentIndex();
},
}

@@ -261,5 +267,5 @@ /**

*/
next: function () {
next () {
this.goTo(this.getCurrentIndex() + 1);
},
}

@@ -269,7 +275,7 @@ /**

*/
prev: function () {
prev () {
this.goTo(this.getCurrentIndex() - 1);
}
});
}
module.exports = Carousel;
module.exports = Carousel;

@@ -107,2 +107,3 @@ var sinon = require('sinon');

});
assert.equal(rightArrowClickSpy.callCount, 0);
rightArrow.dispatchEvent(TestUtils.createEvent('click'));

@@ -113,2 +114,15 @@ assert.equal(rightArrowClickSpy.callCount, 1);

it('should NOT trigger onRightArrowClick callback when right arrow is clicked after destruction', function () {
var fixture = document.getElementById('qunit-fixture');
var rightArrow = document.createElement('div');
var rightArrowClickSpy = sinon.spy();
var arrowsView = new CarouselArrows({
rightArrow: rightArrow,
onRightArrowClick: rightArrowClickSpy
});
arrowsView.destroy();
rightArrow.dispatchEvent(TestUtils.createEvent('click'));
assert.equal(rightArrowClickSpy.callCount, 0);
});
it('should NOT call onRightArrowClick callback when a disabled right arrow is clicked', function () {

@@ -128,3 +142,3 @@ var fixture = document.getElementById('qunit-fixture');

it('should call onLeftArrowClick callback when right arrow is clicked', function () {
it('should call onLeftArrowClick callback when left arrow is clicked', function () {
var fixture = document.getElementById('qunit-fixture');

@@ -137,2 +151,3 @@ var leftArrow = document.createElement('div');

});
assert.equal(leftArrowClickSpy.callCount, 0);
leftArrow.dispatchEvent(TestUtils.createEvent('click'));

@@ -143,2 +158,15 @@ assert.equal(leftArrowClickSpy.callCount, 1);

it('should NOT trigger onLeftArrowClick callback when left arrow is clicked after destruction', function () {
var fixture = document.getElementById('qunit-fixture');
var leftArrow = document.createElement('div');
var leftArrowClickSpy = sinon.spy();
var arrowsView = new CarouselArrows({
leftArrow: leftArrow,
onLeftArrowClick: leftArrowClickSpy
});
arrowsView.destroy();
leftArrow.dispatchEvent(TestUtils.createEvent('click'));
assert.equal(leftArrowClickSpy.callCount, 0);
});
it('should add disabled css class on left arrow when update() is called on first panel index', function () {

@@ -300,2 +328,2 @@ var fixture = document.getElementById('qunit-fixture');

});
});
var sinon = require('sinon');
var CarouselPanels = require('../src/carousel-panels');
var assert = require('assert');
var Promise = require('promise');
var _ = require('lodash');

@@ -12,6 +12,6 @@ describe('Carousel Panels', function () {

image.setAttribute('data-test-src', testSrc);
image.kit.load = sinon.stub().returns(Promise.resolve());
var panelsView = new CarouselPanels({panels: [image], lazyLoadAttr: 'data-test-src'});
panelsView.loadPanelImageAsset(image);
assert.ok(image.kit.load.args[0][0], testSrc, 'element kits image load is passed correct arguments');
image.onload(); // trigger onload immediately
assert.ok(image.src, testSrc, 'correct src is set');
panelsView.destroy();

@@ -22,3 +22,2 @@ });

var image = document.createElement('img');
image.kit.load = sinon.stub().returns(Promise.resolve()); // prevent attempt to get actual image
var imageLoadingClass = 'loading';

@@ -28,13 +27,19 @@ var panelsView = new CarouselPanels({panels: [image], assetLoadingClass: imageLoadingClass});

assert.ok(image.classList.contains(imageLoadingClass), 'loading class is added initially');
panelsView.destroy();
});
it('loadPanelImageAsset() should remove loading class when image is done loading', function () {
it('loadPanelImageAsset() should remove loading class when image is done loading', function (done) {
var image = document.createElement('img');
image.kit.load = sinon.stub().returns(Promise.resolve()); // prevent attempt to get actual image
var imageLoadingClass = 'loading';
var panelsView = new CarouselPanels({panels: [image], assetLoadingClass: imageLoadingClass});
return panelsView.loadPanelImageAsset(image).then(function () {
panelsView.loadPanelImageAsset(image).then(function () {
assert.ok(!image.classList.contains(imageLoadingClass), 'once image is loaded, the loading class is removed');
panelsView.destroy();
done();
});
// delay following code until the loadPanelImageAssets()
// call stack has completed since it is wrapped in a Promise
_.defer(function () {
image.onload();
});
});

@@ -88,2 +93,2 @@

});
});

@@ -333,2 +333,2 @@ var sinon = require('sinon');

});
});

@@ -54,3 +54,55 @@ var sinon = require('sinon');

it('should NOT add active classes when clicking on thumbnails after destruction', function () {
var fixture = document.getElementById('qunit-fixture');
var thumbsEl = document.createElement('div');
thumbsEl.innerHTML =
'<button>Thumb 1</button>' +
'<button>Thumb 2</button>' +
'<button>Thumb 3</button>';
var thumbActiveClass = 'thumb-active';
var thumbEls = thumbsEl.getElementsByTagName('button');
var thumbsView = new CarouselThumbs({
thumbnails: thumbEls,
thumbnailActiveClass: thumbActiveClass
});
// destroy immediately
thumbsView.destroy();
// click second thumbnail
thumbEls[1].dispatchEvent(TestUtils.createEvent('click'));
assert.ok(!thumbEls[1].classList.contains(thumbActiveClass), 'second thumbnail does not have active class when clicked');
// click first thumbnail
thumbEls[0].dispatchEvent(TestUtils.createEvent('click'));
assert.ok(!thumbEls[0].classList.contains(thumbActiveClass), 'first thumbnail does not have active class when clicked');
// click third thumbnail
thumbEls[2].dispatchEvent(TestUtils.createEvent('click'));
assert.ok(!thumbEls[2].classList.contains(thumbActiveClass), 'third thumbnail does not have active class when clicked');
});
});
it('should NOT call goTo method when clicking on thumbnails after destruction', function () {
var fixture = document.getElementById('qunit-fixture');
var thumbsEl = document.createElement('div');
thumbsEl.innerHTML =
'<button>Thumb 1</button>' +
'<button>Thumb 2</button>' +
'<button>Thumb 3</button>';
var goToSpy = sinon.spy(CarouselThumbs.prototype, 'goTo');
var thumbActiveClass = 'thumb-active';
var thumbEls = thumbsEl.getElementsByTagName('button');
var thumbsView = new CarouselThumbs({
thumbnails: thumbEls,
thumbnailActiveClass: thumbActiveClass
});
// destroy immediately
thumbsView.destroy();
// click second thumbnail
thumbEls[1].dispatchEvent(TestUtils.createEvent('click'));
// click first thumbnail
thumbEls[0].dispatchEvent(TestUtils.createEvent('click'));
// click third thumbnail
thumbEls[2].dispatchEvent(TestUtils.createEvent('click'));
assert.equal(goToSpy.callCount, 0);
goToSpy.restore();
});
});

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc