Socket
Socket
Sign inDemoInstall

@uppy/provider-views

Package Overview
Dependencies
Maintainers
5
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uppy/provider-views - npm Package Compare versions

Comparing version 0.27.4 to 0.28.0

3

lib/Browser.js

@@ -72,8 +72,5 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

toggleCheckbox: props.toggleCheckbox,
getItemName: props.getItemName,
getItemIcon: props.getItemIcon,
handleScroll: props.handleScroll,
title: props.title,
showTitles: props.showTitles,
getItemId: props.getItemId,
i18n: props.i18n

@@ -80,0 +77,0 @@ }),

185

lib/index.js

@@ -51,30 +51,3 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

/**
* Class to easily generate generic views for plugins
*
*
* This class expects the plugin instance using it to have the following
* accessor methods.
* Each method takes the item whose property is to be accessed
* as a param
*
* isFolder
* @return {Boolean} for if the item is a folder or not
* getItemData
* @return {Object} that is format ready for uppy upload/download
* getItemIcon
* @return {Object} html instance of the item's icon
* getItemSubList
* @return {Array} sub-items in the item. e.g a folder may contain sub-items
* getItemName
* @return {String} display friendly name of the item
* getMimeType
* @return {String} mime type of the item
* getItemId
* @return {String} unique id of the item
* getItemRequestPath
* @return {String} unique request path of the item when making calls to Companion
* getItemModifiedDate
* @return {object} or {String} date of when last the item was modified
* getItemThumbnailUrl
* @return {String}
* Class to easily generate generic views for Provider plugins
*/

@@ -136,6 +109,4 @@

ProviderView.prototype._updateFilesAndFolders = function _updateFilesAndFolders(res, files, folders) {
var _this2 = this;
this.plugin.getItemSubList(res).forEach(function (item) {
if (_this2.plugin.isFolder(item)) {
res.items.forEach(function (item) {
if (item.isFolder) {
folders.push(item);

@@ -151,11 +122,11 @@ } else {

ProviderView.prototype.checkAuth = function checkAuth() {
var _this3 = this;
var _this2 = this;
this.plugin.setPluginState({ checkAuthInProgress: true });
this.Provider.checkAuth().then(function (authenticated) {
_this3.plugin.setPluginState({ checkAuthInProgress: false });
_this3.plugin.onAuth(authenticated);
_this2.plugin.setPluginState({ checkAuthInProgress: false });
_this2.plugin.onAuth(authenticated);
}).catch(function (err) {
_this3.plugin.setPluginState({ checkAuthInProgress: false });
_this3.handleError(err);
_this2.plugin.setPluginState({ checkAuthInProgress: false });
_this2.handleError(err);
});

@@ -172,3 +143,3 @@ };

ProviderView.prototype.getFolder = function getFolder(id, name) {
var _this4 = this;
var _this3 = this;

@@ -180,3 +151,3 @@ return this._loaderWrapper(this.Provider.list(id), function (res) {

var state = _this4.plugin.getPluginState();
var state = _this3.plugin.getPluginState();
var index = findIndex(state.directories, function (dir) {

@@ -189,8 +160,9 @@ return id === dir.id;

} else {
updatedDirectories = state.directories.concat([{ id: id, title: name || _this4.plugin.getItemName(res) }]);
updatedDirectories = state.directories.concat([{ id: id, title: name }]);
}
_this4.username = _this4.username ? _this4.username : _this4.plugin.getUsername(res);
_this4._updateFilesAndFolders(res, files, folders);
_this4.plugin.setPluginState({ directories: updatedDirectories });
_this3.username = _this3.username ? _this3.username : res.username;
_this3.nextPagePath = res.nextPagePath;
_this3._updateFilesAndFolders(res, files, folders);
_this3.plugin.setPluginState({ directories: updatedDirectories });
}, this.handleError);

@@ -207,4 +179,3 @@ };

ProviderView.prototype.getNextFolder = function getNextFolder(folder) {
var id = this.plugin.getItemRequestPath(folder);
this.getFolder(id, this.plugin.getItemName(folder));
this.getFolder(folder.requestPath, folder.name);
this.lastCheckbox = undefined;

@@ -217,14 +188,14 @@ };

source: this.plugin.id,
data: this.plugin.getItemData(file),
name: this.plugin.getItemName(file) || this.plugin.getItemId(file),
type: this.plugin.getMimeType(file),
data: file,
name: file.name || file.id,
type: file.mimeType,
isRemote: true,
body: {
fileId: this.plugin.getItemId(file)
fileId: file.id
},
remote: {
serverUrl: this.plugin.opts.serverUrl,
url: '' + this.Provider.fileUrl(this.plugin.getItemRequestPath(file)),
url: '' + this.Provider.fileUrl(file.requestPath),
body: {
fileId: this.plugin.getItemId(file)
fileId: file.id
},

@@ -238,3 +209,3 @@ providerOptions: this.Provider.opts

if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = this.plugin.getItemThumbnailUrl(file);
tagFile.preview = file.thumbnail;
}

@@ -266,3 +237,3 @@ this.plugin.uppy.log('Adding remote file');

ProviderView.prototype.logout = function logout() {
var _this5 = this;
var _this4 = this;

@@ -277,3 +248,3 @@ this.Provider.logout(location.href).then(function (res) {

};
_this5.plugin.setPluginState(newState);
_this4.plugin.setPluginState(newState);
}

@@ -300,4 +271,2 @@ }).catch(this.handleError);

ProviderView.prototype.filterItems = function filterItems(items) {
var _this6 = this;
var state = this.plugin.getPluginState();

@@ -308,3 +277,3 @@ if (state.filterInput === '') {

return items.filter(function (folder) {
return _this6.plugin.getItemName(folder).toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1;
return folder.name.toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1;
});

@@ -314,4 +283,2 @@ };

ProviderView.prototype.sortByTitle = function sortByTitle() {
var _this7 = this;
var state = _extends({}, this.plugin.getPluginState());

@@ -325,5 +292,5 @@ var files = state.files,

if (sorting === 'titleDescending') {
return _this7.plugin.getItemName(fileB).localeCompare(_this7.plugin.getItemName(fileA));
return fileB.name.localeCompare(fileA.name);
}
return _this7.plugin.getItemName(fileA).localeCompare(_this7.plugin.getItemName(fileB));
return fileA.name.localeCompare(fileB.name);
});

@@ -333,5 +300,5 @@

if (sorting === 'titleDescending') {
return _this7.plugin.getItemName(folderB).localeCompare(_this7.plugin.getItemName(folderA));
return folderB.name.localeCompare(folderA.name);
}
return _this7.plugin.getItemName(folderA).localeCompare(_this7.plugin.getItemName(folderB));
return folderA.name.localeCompare(folderB.name);
});

@@ -347,4 +314,2 @@

ProviderView.prototype.sortByDate = function sortByDate() {
var _this8 = this;
var state = _extends({}, this.plugin.getPluginState());

@@ -357,4 +322,4 @@ var files = state.files,

var sortedFiles = files.sort(function (fileA, fileB) {
var a = new Date(_this8.plugin.getItemModifiedDate(fileA));
var b = new Date(_this8.plugin.getItemModifiedDate(fileB));
var a = new Date(fileA.modifiedDate);
var b = new Date(fileB.modifiedDate);

@@ -368,4 +333,4 @@ if (sorting === 'dateDescending') {

var sortedFolders = folders.sort(function (folderA, folderB) {
var a = new Date(_this8.plugin.getItemModifiedDate(folderA));
var b = new Date(_this8.plugin.getItemModifiedDate(folderB));
var a = new Date(folderA.modifiedDate);
var b = new Date(folderB.modifiedDate);

@@ -387,4 +352,2 @@ if (sorting === 'dateDescending') {

ProviderView.prototype.sortBySize = function sortBySize() {
var _this9 = this;
var state = _extends({}, this.plugin.getPluginState());

@@ -401,4 +364,4 @@ var files = state.files,

var sortedFiles = files.sort(function (fileA, fileB) {
var a = _this9.plugin.getItemData(fileA).size;
var b = _this9.plugin.getItemData(fileB).size;
var a = fileA.size;
var b = fileB.size;

@@ -439,3 +402,3 @@ if (sorting === 'sizeDescending') {

ProviderView.prototype.addFolder = function addFolder(folder) {
var _this10 = this;
var _this5 = this;

@@ -450,18 +413,18 @@ var folderId = this.providerFileToId(folder);

this.plugin.setPluginState({ selectedFolders: folders });
return this.Provider.list(this.plugin.getItemRequestPath(folder)).then(function (res) {
return this.Provider.list(folder.requestPath).then(function (res) {
var files = [];
_this10.plugin.getItemSubList(res).forEach(function (item) {
if (!_this10.plugin.isFolder(item)) {
_this10.addFile(item);
files.push(_this10.providerFileToId(item));
res.items.forEach(function (item) {
if (!item.isFolder) {
_this5.addFile(item);
files.push(_this5.providerFileToId(item));
}
});
state = _this10.plugin.getPluginState();
state = _this5.plugin.getPluginState();
state.selectedFolders[folderId] = { loading: false, files: files };
_this10.plugin.setPluginState({ selectedFolders: folders });
var dashboard = _this10.plugin.uppy.getPlugin('Dashboard');
_this5.plugin.setPluginState({ selectedFolders: folders });
var dashboard = _this5.plugin.uppy.getPlugin('Dashboard');
var message = void 0;
if (files.length) {
message = dashboard.i18n('folderAdded', {
smart_count: files.length, folder: _this10.plugin.getItemName(folder)
smart_count: files.length, folder: folder.name
});

@@ -471,8 +434,8 @@ } else {

}
_this10.plugin.uppy.info(message);
_this5.plugin.uppy.info(message);
}).catch(function (e) {
state = _this10.plugin.getPluginState();
state = _this5.plugin.getPluginState();
delete state.selectedFolders[folderId];
_this10.plugin.setPluginState({ selectedFolders: state.selectedFolders });
_this10.handleError(e);
_this5.plugin.setPluginState({ selectedFolders: state.selectedFolders });
_this5.handleError(e);
});

@@ -535,5 +498,5 @@ };

return generateFileID({
data: this.plugin.getItemData(file),
name: this.plugin.getItemName(file) || this.plugin.getItemId(file),
type: this.plugin.getMimeType(file)
data: file,
name: file.name || file.id,
type: file.mimeType
});

@@ -550,3 +513,3 @@ };

ProviderView.prototype.handleAuth = function handleAuth() {
var _this11 = this;
var _this6 = this;

@@ -558,4 +521,4 @@ var authState = btoa(JSON.stringify({ origin: location.origin }));

var handleToken = function handleToken(e) {
if (!_this11._isOriginAllowed(e.origin, _this11.plugin.opts.serverPattern) || e.source !== authWindow) {
_this11.plugin.uppy.log('rejecting event from ' + e.origin + ' vs allowed pattern ' + _this11.plugin.opts.serverPattern);
if (!_this6._isOriginAllowed(e.origin, _this6.plugin.opts.serverPattern) || e.source !== authWindow) {
_this6.plugin.uppy.log('rejecting event from ' + e.origin + ' vs allowed pattern ' + _this6.plugin.opts.serverPattern);
return;

@@ -565,4 +528,4 @@ }

window.removeEventListener('message', handleToken);
_this11.Provider.setAuthToken(e.data.token);
_this11._loaderWrapper(_this11.Provider.checkAuth(), _this11.plugin.onAuth, _this11.handleError);
_this6.Provider.setAuthToken(e.data.token);
_this6._loaderWrapper(_this6.Provider.checkAuth(), _this6.plugin.onAuth, _this6.handleError);
};

@@ -597,16 +560,16 @@ window.addEventListener('message', handleToken);

ProviderView.prototype.handleScroll = function handleScroll(e) {
var _this12 = this;
var _this7 = this;
var scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight);
var path = this.plugin.getNextPagePath ? this.plugin.getNextPagePath() : null;
var path = this.nextPagePath ? this.nextPagePath : null;
if (scrollPos < 50 && path && !this._isHandlingScroll) {
this.Provider.list(path).then(function (res) {
var _plugin$getPluginStat5 = _this12.plugin.getPluginState(),
var _plugin$getPluginStat5 = _this7.plugin.getPluginState(),
files = _plugin$getPluginStat5.files,
folders = _plugin$getPluginStat5.folders;
_this12._updateFilesAndFolders(res, files, folders);
_this7._updateFilesAndFolders(res, files, folders);
}).catch(this.handleError).then(function () {
_this12._isHandlingScroll = false;
_this7._isHandlingScroll = false;
}); // always called

@@ -619,3 +582,3 @@

ProviderView.prototype.donePicking = function donePicking() {
var _this13 = this;
var _this8 = this;

@@ -626,6 +589,6 @@ var _plugin$getPluginStat6 = this.plugin.getPluginState(),

var promises = currentSelection.map(function (file) {
if (_this13.plugin.isFolder(file)) {
return _this13.addFolder(file);
if (file.isFolder) {
return _this8.addFolder(file);
} else {
return _this13.addFile(file);
return _this8.addFile(file);
}

@@ -635,6 +598,3 @@ });

this._loaderWrapper(Promise.all(promises), function () {
_this13.clearSelection();
var dashboard = _this13.plugin.uppy.getPlugin('Dashboard');
if (dashboard) dashboard.hideAllPanels();
_this8.clearSelection();
}, function () {});

@@ -658,9 +618,9 @@ };

ProviderView.prototype._loaderWrapper = function _loaderWrapper(promise, then, catch_) {
var _this14 = this;
var _this9 = this;
promise.then(function (result) {
_this14.plugin.setPluginState({ loading: false });
_this9.plugin.setPluginState({ loading: false });
then(result);
}).catch(function (err) {
_this14.plugin.setPluginState({ loading: false });
_this9.plugin.setPluginState({ loading: false });
catch_(err);

@@ -714,5 +674,2 @@ });

toggleCheckbox: this.toggleCheckbox,
getItemId: this.plugin.getItemId,
getItemName: this.plugin.getItemName,
getItemIcon: this.plugin.getItemIcon,
handleScroll: this.handleScroll,

@@ -719,0 +676,0 @@ done: this.donePicking,

@@ -31,8 +31,8 @@ var Row = require('./Item');

return Row({
title: props.getItemName(folder),
id: props.getItemId(folder),
title: folder.name,
id: folder.id,
type: 'folder',
// active: props.activeRow(folder),
getItemIcon: function getItemIcon() {
return props.getItemIcon(folder);
return folder.icon;
},

@@ -53,8 +53,8 @@ isDisabled: isDisabled,

return Row({
title: props.getItemName(file),
id: props.getItemId(file),
title: file.name,
id: file.id,
type: 'file',
// active: props.activeRow(file),
getItemIcon: function getItemIcon() {
return props.getItemIcon(file);
return file.icon;
},

@@ -61,0 +61,0 @@ isDisabled: false,

{
"name": "@uppy/provider-views",
"description": "View library for Uppy remote provider plugins.",
"version": "0.27.4",
"version": "0.28.0",
"license": "MIT",

@@ -23,3 +23,3 @@ "main": "lib/index.js",

"dependencies": {
"@uppy/utils": "0.27.1",
"@uppy/utils": "0.28.0",
"classnames": "^2.2.6",

@@ -29,8 +29,8 @@ "preact": "^8.2.9"

"devDependencies": {
"@uppy/core": "0.27.3"
"@uppy/core": "0.28.0"
},
"peerDependencies": {
"@uppy/core": "^0.27.0"
"@uppy/core": "^0.28.0"
},
"gitHead": "113d6f09bbe248ca156af87054244cd9e6ee9d8b"
"gitHead": "47a68a6148a41c7b8a1e10e78b6cd6794a53f7e5"
}

@@ -51,8 +51,5 @@ const classNames = require('classnames')

toggleCheckbox={props.toggleCheckbox}
getItemName={props.getItemName}
getItemIcon={props.getItemIcon}
handleScroll={props.handleScroll}
title={props.title}
showTitles={props.showTitles}
getItemId={props.getItemId}
i18n={props.i18n}

@@ -59,0 +56,0 @@ />

@@ -30,30 +30,3 @@ const { h, Component } = require('preact')

/**
* Class to easily generate generic views for plugins
*
*
* This class expects the plugin instance using it to have the following
* accessor methods.
* Each method takes the item whose property is to be accessed
* as a param
*
* isFolder
* @return {Boolean} for if the item is a folder or not
* getItemData
* @return {Object} that is format ready for uppy upload/download
* getItemIcon
* @return {Object} html instance of the item's icon
* getItemSubList
* @return {Array} sub-items in the item. e.g a folder may contain sub-items
* getItemName
* @return {String} display friendly name of the item
* getMimeType
* @return {String} mime type of the item
* getItemId
* @return {String} unique id of the item
* getItemRequestPath
* @return {String} unique request path of the item when making calls to Companion
* getItemModifiedDate
* @return {object} or {String} date of when last the item was modified
* getItemThumbnailUrl
* @return {String}
* Class to easily generate generic views for Provider plugins
*/

@@ -112,4 +85,4 @@ module.exports = class ProviderView {

_updateFilesAndFolders (res, files, folders) {
this.plugin.getItemSubList(res).forEach((item) => {
if (this.plugin.isFolder(item)) {
res.items.forEach((item) => {
if (item.isFolder) {
folders.push(item)

@@ -156,6 +129,7 @@ } else {

} else {
updatedDirectories = state.directories.concat([{id, title: name || this.plugin.getItemName(res)}])
updatedDirectories = state.directories.concat([{id, title: name}])
}
this.username = this.username ? this.username : this.plugin.getUsername(res)
this.username = this.username ? this.username : res.username
this.nextPagePath = res.nextPagePath
this._updateFilesAndFolders(res, files, folders)

@@ -173,4 +147,3 @@ this.plugin.setPluginState({ directories: updatedDirectories })

getNextFolder (folder) {
let id = this.plugin.getItemRequestPath(folder)
this.getFolder(id, this.plugin.getItemName(folder))
this.getFolder(folder.requestPath, folder.name)
this.lastCheckbox = undefined

@@ -183,14 +156,14 @@ }

source: this.plugin.id,
data: this.plugin.getItemData(file),
name: this.plugin.getItemName(file) || this.plugin.getItemId(file),
type: this.plugin.getMimeType(file),
data: file,
name: file.name || file.id,
type: file.mimeType,
isRemote: true,
body: {
fileId: this.plugin.getItemId(file)
fileId: file.id
},
remote: {
serverUrl: this.plugin.opts.serverUrl,
url: `${this.Provider.fileUrl(this.plugin.getItemRequestPath(file))}`,
url: `${this.Provider.fileUrl(file.requestPath)}`,
body: {
fileId: this.plugin.getItemId(file)
fileId: file.id
},

@@ -204,3 +177,3 @@ providerOptions: this.Provider.opts

if (fileType && isPreviewSupported(fileType)) {
tagFile.preview = this.plugin.getItemThumbnailUrl(file)
tagFile.preview = file.thumbnail
}

@@ -262,3 +235,3 @@ this.plugin.uppy.log('Adding remote file')

return items.filter((folder) => {
return this.plugin.getItemName(folder).toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1
return folder.name.toLowerCase().indexOf(state.filterInput.toLowerCase()) !== -1
})

@@ -273,5 +246,5 @@ }

if (sorting === 'titleDescending') {
return this.plugin.getItemName(fileB).localeCompare(this.plugin.getItemName(fileA))
return fileB.name.localeCompare(fileA.name)
}
return this.plugin.getItemName(fileA).localeCompare(this.plugin.getItemName(fileB))
return fileA.name.localeCompare(fileB.name)
})

@@ -281,5 +254,5 @@

if (sorting === 'titleDescending') {
return this.plugin.getItemName(folderB).localeCompare(this.plugin.getItemName(folderA))
return folderB.name.localeCompare(folderA.name)
}
return this.plugin.getItemName(folderA).localeCompare(this.plugin.getItemName(folderB))
return folderA.name.localeCompare(folderB.name)
})

@@ -299,4 +272,4 @@

let sortedFiles = files.sort((fileA, fileB) => {
let a = new Date(this.plugin.getItemModifiedDate(fileA))
let b = new Date(this.plugin.getItemModifiedDate(fileB))
let a = new Date(fileA.modifiedDate)
let b = new Date(fileB.modifiedDate)

@@ -310,4 +283,4 @@ if (sorting === 'dateDescending') {

let sortedFolders = folders.sort((folderA, folderB) => {
let a = new Date(this.plugin.getItemModifiedDate(folderA))
let b = new Date(this.plugin.getItemModifiedDate(folderB))
let a = new Date(folderA.modifiedDate)
let b = new Date(folderB.modifiedDate)

@@ -338,4 +311,4 @@ if (sorting === 'dateDescending') {

let sortedFiles = files.sort((fileA, fileB) => {
let a = this.plugin.getItemData(fileA).size
let b = this.plugin.getItemData(fileB).size
let a = fileA.size
let b = fileB.size

@@ -378,6 +351,6 @@ if (sorting === 'sizeDescending') {

this.plugin.setPluginState({selectedFolders: folders})
return this.Provider.list(this.plugin.getItemRequestPath(folder)).then((res) => {
return this.Provider.list(folder.requestPath).then((res) => {
let files = []
this.plugin.getItemSubList(res).forEach((item) => {
if (!this.plugin.isFolder(item)) {
res.items.forEach((item) => {
if (!item.isFolder) {
this.addFile(item)

@@ -394,3 +367,3 @@ files.push(this.providerFileToId(item))

message = dashboard.i18n('folderAdded', {
smart_count: files.length, folder: this.plugin.getItemName(folder)
smart_count: files.length, folder: folder.name
})

@@ -452,5 +425,5 @@ } else {

return generateFileID({
data: this.plugin.getItemData(file),
name: this.plugin.getItemName(file) || this.plugin.getItemId(file),
type: this.plugin.getMimeType(file)
data: file,
name: file.name || file.id,
type: file.mimeType
})

@@ -508,3 +481,3 @@ }

const scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight)
const path = this.plugin.getNextPagePath ? this.plugin.getNextPagePath() : null
const path = this.nextPagePath ? this.nextPagePath : null

@@ -526,3 +499,3 @@ if (scrollPos < 50 && path && !this._isHandlingScroll) {

const promises = currentSelection.map((file) => {
if (this.plugin.isFolder(file)) {
if (file.isFolder) {
return this.addFolder(file)

@@ -536,5 +509,2 @@ } else {

this.clearSelection()
const dashboard = this.plugin.uppy.getPlugin('Dashboard')
if (dashboard) dashboard.hideAllPanels()
}, () => {})

@@ -607,5 +577,2 @@ }

toggleCheckbox: this.toggleCheckbox,
getItemId: this.plugin.getItemId,
getItemName: this.plugin.getItemName,
getItemIcon: this.plugin.getItemIcon,
handleScroll: this.handleScroll,

@@ -612,0 +579,0 @@ done: this.donePicking,

@@ -22,7 +22,7 @@ const Row = require('./Item')

return Row({
title: props.getItemName(folder),
id: props.getItemId(folder),
title: folder.name,
id: folder.id,
type: 'folder',
// active: props.activeRow(folder),
getItemIcon: () => props.getItemIcon(folder),
getItemIcon: () => folder.icon,
isDisabled: isDisabled,

@@ -38,7 +38,7 @@ isChecked: isChecked,

return Row({
title: props.getItemName(file),
id: props.getItemId(file),
title: file.name,
id: file.id,
type: 'file',
// active: props.activeRow(file),
getItemIcon: () => props.getItemIcon(file),
getItemIcon: () => file.icon,
isDisabled: false,

@@ -45,0 +45,0 @@ isChecked: props.isChecked(file),

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
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc