@uppy/provider-views
Advanced tools
Comparing version 3.9.1 to 3.10.0
# @uppy/provider-views | ||
## 3.10.0 | ||
Released: 2024-02-28 | ||
Included in: Uppy v3.23.0 | ||
- @uppy/provider-views: migrate to TS (Merlijn Vos / #4919) | ||
## 3.9.0 | ||
@@ -4,0 +11,0 @@ |
@@ -14,3 +14,3 @@ import { h, Fragment } from 'preact'; | ||
}; | ||
export default (props => { | ||
export default function Breadcrumbs(props) { | ||
const { | ||
@@ -28,6 +28,6 @@ getFolder, | ||
key: directory.id, | ||
getFolder: () => getFolder(directory.requestPath), | ||
getFolder: () => getFolder(directory.requestPath, directory.name), | ||
title: i === 0 ? title : directory.name, | ||
isLast: i + 1 === breadcrumbs.length | ||
}))); | ||
}); | ||
} |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -5,2 +6,4 @@ import classNames from 'classnames'; | ||
import { useMemo } from 'preact/hooks'; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore untyped | ||
import VirtualList from '@uppy/utils/lib/VirtualList'; | ||
@@ -23,9 +26,6 @@ import SearchFilterInput from "./SearchFilterInput.js"; | ||
getNextFolder, | ||
columns, | ||
f | ||
} = props; | ||
if (f.isFolder) { | ||
var _isChecked; | ||
return Item({ | ||
columns, | ||
showTitles, | ||
@@ -41,4 +41,6 @@ viewType, | ||
type: 'folder', | ||
isDisabled: (_isChecked = isChecked(f)) == null ? void 0 : _isChecked.loading, | ||
// TODO: when was this supposed to be true? | ||
isDisabled: false, | ||
isCheckboxDisabled: f.id === VIRTUAL_SHARED_DIR, | ||
// getNextFolder always exists when f.isFolder is true | ||
handleFolderClick: () => getNextFolder(f) | ||
@@ -55,4 +57,4 @@ }); | ||
toggleCheckbox: event => toggleCheckbox(event, f), | ||
isCheckboxDisabled: false, | ||
recordShiftKeyPress, | ||
columns, | ||
showTitles, | ||
@@ -62,3 +64,3 @@ viewType, | ||
type: 'file', | ||
isDisabled: restrictionError && !isChecked(f), | ||
isDisabled: Boolean(restrictionError) && !isChecked(f), | ||
restrictionError | ||
@@ -94,3 +96,2 @@ }); | ||
done, | ||
columns, | ||
noResultsLabel, | ||
@@ -146,3 +147,2 @@ loadAllFiles | ||
getNextFolder: getNextFolder, | ||
columns: columns, | ||
f: f | ||
@@ -161,3 +161,3 @@ }), | ||
, | ||
tabIndex: "-1" | ||
tabIndex: -1 | ||
}, rows.map(f => h(ListItem, { | ||
@@ -174,3 +174,2 @@ currentSelection: currentSelection, | ||
getNextFolder: getNextFolder, | ||
columns: columns, | ||
f: f | ||
@@ -177,0 +176,0 @@ })))); |
import { h } from 'preact'; | ||
export default (_ref => { | ||
export default function FooterActions(_ref) { | ||
let { | ||
@@ -22,2 +22,2 @@ cancel, | ||
}, i18n('cancel'))); | ||
}); | ||
} |
@@ -1,2 +0,2 @@ | ||
export { default as ProviderViews, defaultPickerIcon } from './ProviderView/index.js'; | ||
export { default as SearchProviderViews } from './SearchProviderView/index.js'; | ||
export { default as ProviderViews, defaultPickerIcon } from "./ProviderView/index.js"; | ||
export { default as SearchProviderViews } from "./SearchProviderView/index.js"; |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -22,3 +23,3 @@ import classNames from 'classnames'; | ||
className: className, | ||
title: isDisabled ? restrictionError == null ? void 0 : restrictionError.message : null | ||
title: isDisabled ? restrictionError == null ? void 0 : restrictionError.message : undefined | ||
}, h("input", { | ||
@@ -28,3 +29,5 @@ type: "checkbox", | ||
onChange: toggleCheckbox, | ||
onKeyDown: recordShiftKeyPress, | ||
onKeyDown: recordShiftKeyPress | ||
// @ts-expect-error this is fine onMouseDown too | ||
, | ||
onMouseDown: recordShiftKeyPress, | ||
@@ -31,0 +34,0 @@ name: "listitem", |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -43,7 +44,7 @@ function FileIcon() { | ||
} | ||
export default (props => { | ||
export default function ItemIcon(props) { | ||
const { | ||
itemIconString | ||
} = props; | ||
if (itemIconString === null) return undefined; | ||
if (itemIconString === null) return null; | ||
switch (itemIconString) { | ||
@@ -63,3 +64,5 @@ case 'file': | ||
src: itemIconString, | ||
alt: alt, | ||
alt: alt | ||
// @ts-expect-error TS does not understand but attribute exists here. | ||
, | ||
referrerPolicy: "no-referrer", | ||
@@ -72,2 +75,2 @@ loading: "lazy", | ||
} | ||
}); | ||
} |
@@ -0,1 +1,3 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -10,3 +12,3 @@ | ||
function ListItem(props) { | ||
export default function ListItem(props) { | ||
const { | ||
@@ -30,3 +32,3 @@ className, | ||
className: className, | ||
title: isDisabled ? restrictionError == null ? void 0 : restrictionError.message : null | ||
title: isDisabled ? restrictionError == null ? void 0 : restrictionError.message : undefined | ||
}, !isCheckboxDisabled ? h("input", { | ||
@@ -55,5 +57,5 @@ type: "checkbox", | ||
className: "uppy-ProviderBrowserItem-iconWrap" | ||
}, itemIconEl), showTitles && title) : | ||
}, itemIconEl), showTitles && title) | ||
// button to open a folder | ||
h("button", { | ||
: h("button", { | ||
type: "button", | ||
@@ -68,3 +70,2 @@ className: "uppy-u-reset uppy-c-btn uppy-ProviderBrowserItem-inner", | ||
}, itemIconEl), showTitles && h("span", null, title))); | ||
} | ||
export default ListItem; | ||
} |
function _extends() { _extends = Object.assign ? Object.assign.bind() : 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; }; return _extends.apply(this, arguments); } | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -7,3 +8,3 @@ import classNames from 'classnames'; | ||
import ListItem from "./components/ListLi.js"; | ||
export default (props => { | ||
export default function Item(props) { | ||
const { | ||
@@ -29,5 +30,3 @@ author, | ||
case 'grid': | ||
return h(GridListItem | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
, _extends({}, props, { | ||
return h(GridListItem, _extends({}, props, { | ||
className: className, | ||
@@ -37,26 +36,20 @@ itemIconEl: itemIconEl | ||
case 'list': | ||
return ( | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
h(ListItem, _extends({}, props, { | ||
className: className, | ||
itemIconEl: itemIconEl | ||
})) | ||
); | ||
return h(ListItem, _extends({}, props, { | ||
className: className, | ||
itemIconEl: itemIconEl | ||
})); | ||
case 'unsplash': | ||
return ( | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
h(GridListItem, _extends({}, props, { | ||
className: className, | ||
itemIconEl: itemIconEl | ||
}), h("a", { | ||
href: `${author.url}?utm_source=Companion&utm_medium=referral`, | ||
target: "_blank", | ||
rel: "noopener noreferrer", | ||
className: "uppy-ProviderBrowserItem-author", | ||
tabIndex: "-1" | ||
}, author.name)) | ||
); | ||
return h(GridListItem, _extends({}, props, { | ||
className: className, | ||
itemIconEl: itemIconEl | ||
}), h("a", { | ||
href: `${author.url}?utm_source=Companion&utm_medium=referral`, | ||
target: "_blank", | ||
rel: "noopener noreferrer", | ||
className: "uppy-ProviderBrowserItem-author", | ||
tabIndex: -1 | ||
}, author.name)); | ||
default: | ||
throw new Error(`There is no such type ${viewType}`); | ||
} | ||
}); | ||
} |
import { h } from 'preact'; | ||
export default (_ref => { | ||
export default function Loader(_ref) { | ||
let { | ||
@@ -16,2 +16,2 @@ i18n, | ||
}, loading)); | ||
}); | ||
} |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h } from 'preact'; | ||
@@ -37,3 +38,3 @@ import { useCallback } from 'preact/hooks'; | ||
} | ||
const DefaultForm = _ref => { | ||
function DefaultForm(_ref) { | ||
let { | ||
@@ -64,3 +65,3 @@ pluginName, | ||
}))); | ||
}; | ||
} | ||
const defaultRenderForm = _ref2 => { | ||
@@ -78,3 +79,3 @@ let { | ||
}; | ||
function AuthView(props) { | ||
export default function AuthView(props) { | ||
const { | ||
@@ -88,5 +89,2 @@ loading, | ||
} = props; | ||
const pluginNameComponent = h("span", { | ||
className: "uppy-Provider-authTitleName" | ||
}, pluginName, h("br", null)); | ||
return h("div", { | ||
@@ -99,3 +97,3 @@ className: "uppy-Provider-auth" | ||
}, i18n('authenticateWithTitle', { | ||
pluginName: pluginNameComponent | ||
pluginName | ||
})), h("div", { | ||
@@ -109,3 +107,2 @@ className: "uppy-Provider-authForm" | ||
}))); | ||
} | ||
export default AuthView; | ||
} |
@@ -0,14 +1,12 @@ | ||
/* eslint-disable react/destructuring-assignment */ | ||
import { h, Fragment } from 'preact'; | ||
import User from "./User.js"; | ||
import Breadcrumbs from "../Breadcrumbs.js"; | ||
export default (props => { | ||
const components = []; | ||
if (props.showBreadcrumbs) { | ||
components.push(Breadcrumbs({ | ||
getFolder: props.getFolder, | ||
breadcrumbs: props.breadcrumbs, | ||
breadcrumbsIcon: props.pluginIcon && props.pluginIcon(), | ||
title: props.title | ||
})); | ||
} | ||
components.push(User({ | ||
export default function Header(props) { | ||
return h(Fragment, null, props.showBreadcrumbs && h(Breadcrumbs, { | ||
getFolder: props.getFolder, | ||
breadcrumbs: props.breadcrumbs, | ||
breadcrumbsIcon: props.pluginIcon && props.pluginIcon(), | ||
title: props.title | ||
}), h(User, { | ||
logout: props.logout, | ||
@@ -18,3 +16,2 @@ username: props.username, | ||
})); | ||
return components; | ||
}); | ||
} |
@@ -10,6 +10,9 @@ function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } | ||
import Browser from "../Browser.js"; | ||
import CloseWrapper from '../CloseWrapper.js'; | ||
import View from '../View.js'; | ||
import CloseWrapper from "../CloseWrapper.js"; | ||
import View from "../View.js"; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore We don't want TS to generate types for the package.json | ||
const packageJson = { | ||
"version": "3.9.1" | ||
"version": "3.10.0" | ||
}; | ||
@@ -34,6 +37,9 @@ function formatBreadcrumbs(breadcrumbs) { | ||
} | ||
/** | ||
* Class to easily generate generic views for Provider plugins | ||
*/ | ||
const defaultOptions = { | ||
viewType: 'list', | ||
showTitles: true, | ||
showFilter: true, | ||
showBreadcrumbs: true, | ||
loadAllFiles: false | ||
}; | ||
var _abortController = /*#__PURE__*/_classPrivateFieldLooseKey("abortController"); | ||
@@ -44,10 +50,13 @@ var _withAbort = /*#__PURE__*/_classPrivateFieldLooseKey("withAbort"); | ||
var _recursivelyListAllFiles = /*#__PURE__*/_classPrivateFieldLooseKey("recursivelyListAllFiles"); | ||
/** | ||
* Class to easily generate generic views for Provider plugins | ||
*/ | ||
export default class ProviderView extends View { | ||
/** | ||
* @param {object} plugin instance of the plugin | ||
* @param {object} opts | ||
*/ | ||
constructor(plugin, opts) { | ||
super(plugin, opts); | ||
// set default options | ||
super(plugin, { | ||
...defaultOptions, | ||
...opts | ||
}); | ||
// Logic | ||
Object.defineProperty(this, _recursivelyListAllFiles, { | ||
@@ -69,17 +78,2 @@ value: _recursivelyListAllFiles2 | ||
}); | ||
const defaultOptions = { | ||
viewType: 'list', | ||
showTitles: true, | ||
showFilter: true, | ||
showBreadcrumbs: true, | ||
loadAllFiles: false | ||
}; | ||
// merge default options with the ones set by user | ||
this.opts = { | ||
...defaultOptions, | ||
...opts | ||
}; | ||
// Logic | ||
this.filterQuery = this.filterQuery.bind(this); | ||
@@ -119,6 +113,2 @@ this.clearFilter = this.clearFilter.bind(this); | ||
* | ||
* @param {string} requestPath | ||
* the path we need to use when sending list request to companion (for some providers it's different from ID) | ||
* @param {string} name used in the UI and to build the absDirPath | ||
* @returns {Promise} Folders/files in folder | ||
*/ | ||
@@ -185,4 +175,2 @@ async getFolder(requestPath, name) { | ||
* Fetches new folder | ||
* | ||
* @param {object} folder | ||
*/ | ||
@@ -203,2 +191,3 @@ getNextFolder(folder) { | ||
}); | ||
// res.ok is from the JSON body, not to be confused with Response.ok | ||
if (res.ok) { | ||
@@ -372,3 +361,7 @@ if (!res.revoked) { | ||
this.plugin.uppy.log('Adding files from a remote provider'); | ||
this.plugin.uppy.addFiles(newFiles.map(file => this.getTagFile(file, this.requestClientId))); | ||
this.plugin.uppy.addFiles( | ||
// @ts-expect-error `addFiles` expects `body` to be `File` or `Blob`, | ||
// but as the todo comment in `View.ts` indicates, we strangly pass `CompanionFile` as `body`. | ||
// For now it's better to ignore than to have a potential breaking change. | ||
newFiles.map(file => this.getTagFile(file, this.requestClientId))); | ||
this.plugin.setPluginState({ | ||
@@ -453,3 +446,4 @@ filterInput: '' | ||
cancel: this.cancelPicking, | ||
headerComponent: Header(headerProps), | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
headerComponent: h(Header, headerProps), | ||
title: this.plugin.title, | ||
@@ -495,2 +489,5 @@ viewType: targetViewOptions.viewType, | ||
try { | ||
// @ts-expect-error this should be typed in @uppy/dashboard. | ||
// Even then I don't think we can make this work without adding dashboard | ||
// as a dependency to provider-views. | ||
this.plugin.uppy.on('dashboard:close-panel', cancelRequest); | ||
@@ -500,2 +497,5 @@ this.plugin.uppy.on('cancel-all', cancelRequest); | ||
} finally { | ||
// @ts-expect-error this should be typed in @uppy/dashboard. | ||
// Even then I don't think we can make this work without adding dashboard | ||
// as a dependency to provider-views. | ||
this.plugin.uppy.off('dashboard:close-panel', cancelRequest); | ||
@@ -502,0 +502,0 @@ this.plugin.uppy.off('cancel-all', cancelRequest); |
@@ -1,3 +0,3 @@ | ||
import { h } from 'preact'; | ||
export default (_ref => { | ||
import { h, Fragment } from 'preact'; | ||
export default function User(_ref) { | ||
let { | ||
@@ -8,3 +8,3 @@ i18n, | ||
} = _ref; | ||
return [h("span", { | ||
return h(Fragment, null, h("span", { | ||
className: "uppy-ProviderBrowser-user", | ||
@@ -17,3 +17,3 @@ key: "username" | ||
key: "logout" | ||
}, i18n('logOut'))]; | ||
}); | ||
}, i18n('logOut'))); | ||
} |
@@ -0,6 +1,5 @@ | ||
/* eslint-disable react/require-default-props */ | ||
import { h, Fragment } from 'preact'; | ||
import { useEffect, useState, useCallback } from 'preact/hooks'; | ||
import { nanoid } from 'nanoid/non-secure'; | ||
// import debounce from 'lodash.debounce' | ||
export default function SearchFilterInput(props) { | ||
@@ -61,3 +60,3 @@ const { | ||
focusable: "false", | ||
class: "uppy-c-icon uppy-ProviderBrowser-searchFilterIcon", | ||
className: "uppy-c-icon uppy-ProviderBrowser-searchFilterIcon", | ||
width: "12", | ||
@@ -64,0 +63,0 @@ height: "12", |
@@ -7,7 +7,26 @@ function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } | ||
import Browser from "../Browser.js"; | ||
import CloseWrapper from '../CloseWrapper.js'; | ||
import View from '../View.js'; | ||
import CloseWrapper from "../CloseWrapper.js"; | ||
import View from "../View.js"; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore We don't want TS to generate types for the package.json | ||
const packageJson = { | ||
"version": "3.9.1" | ||
"version": "3.10.0" | ||
}; | ||
const defaultState = { | ||
isInputMode: true, | ||
files: [], | ||
folders: [], | ||
breadcrumbs: [], | ||
filterInput: '', | ||
currentSelection: [], | ||
searchTerm: null | ||
}; | ||
const defaultOptions = { | ||
viewType: 'grid', | ||
showTitles: true, | ||
showFilter: true, | ||
showBreadcrumbs: true | ||
}; | ||
var _updateFilesAndInputMode = /*#__PURE__*/_classPrivateFieldLooseKey("updateFilesAndInputMode"); | ||
/** | ||
@@ -17,29 +36,12 @@ * SearchProviderView, used for Unsplash and future image search providers. | ||
*/ | ||
var _updateFilesAndInputMode = /*#__PURE__*/_classPrivateFieldLooseKey("updateFilesAndInputMode"); | ||
export default class SearchProviderView extends View { | ||
/** | ||
* @param {object} plugin instance of the plugin | ||
* @param {object} opts | ||
*/ | ||
constructor(plugin, opts) { | ||
super(plugin, opts); | ||
// set default options | ||
super(plugin, { | ||
...defaultOptions, | ||
...opts | ||
}); | ||
Object.defineProperty(this, _updateFilesAndInputMode, { | ||
value: _updateFilesAndInputMode2 | ||
}); | ||
const defaultOptions = { | ||
viewType: 'grid', | ||
showTitles: false, | ||
showFilter: false, | ||
showBreadcrumbs: false | ||
}; | ||
// merge default options with the ones set by user | ||
this.opts = { | ||
...defaultOptions, | ||
...opts | ||
}; | ||
// Logic | ||
this.nextPageQuery = null; | ||
this.search = this.search.bind(this); | ||
@@ -50,17 +52,4 @@ this.clearSearch = this.clearSearch.bind(this); | ||
this.donePicking = this.donePicking.bind(this); | ||
// Visual | ||
this.render = this.render.bind(this); | ||
this.defaultState = { | ||
isInputMode: true, | ||
files: [], | ||
folders: [], | ||
breadcrumbs: [], | ||
filterInput: '', | ||
currentSelection: [], | ||
searchTerm: null | ||
}; | ||
// Set default state for the plugin | ||
this.plugin.setPluginState(this.defaultState); | ||
this.plugin.setPluginState(defaultState); | ||
this.registerRequestClient(); | ||
@@ -74,3 +63,3 @@ } | ||
resetPluginState() { | ||
this.plugin.setPluginState(this.defaultState); | ||
this.plugin.setPluginState(defaultState); | ||
} | ||
@@ -201,3 +190,2 @@ async search(query) { | ||
search: this.search, | ||
clearSelection: this.clearSelection, | ||
inputLabel: i18n('enterTextToSearch'), | ||
@@ -204,0 +192,0 @@ buttonLabel: i18n('searchImages'), |
import getFileType from '@uppy/utils/lib/getFileType'; | ||
import isPreviewSupported from '@uppy/utils/lib/isPreviewSupported'; | ||
import remoteFileObjToLocal from '@uppy/utils/lib/remoteFileObjToLocal'; | ||
// Conditional type for selecting the plugin | ||
// Conditional type for selecting the provider from the selected plugin | ||
export default class View { | ||
@@ -89,2 +94,3 @@ constructor(plugin, opts) { | ||
this.provider = opts.provider; | ||
this.opts = opts; | ||
this.isHandlingScroll = false; | ||
@@ -102,4 +108,2 @@ this.preFirstRender = this.preFirstRender.bind(this); | ||
} | ||
// eslint-disable-next-line class-methods-use-this | ||
shouldHandleScroll(event) { | ||
@@ -124,2 +128,4 @@ const { | ||
if (dashboard) { | ||
// @ts-expect-error impossible to type this correctly without adding dashboard | ||
// as a dependency to this package. | ||
dashboard.hideAllPanels(); | ||
@@ -150,3 +156,3 @@ } | ||
// todo document what is a "tagFile" or get rid of this concept | ||
// TODO: document what is a "tagFile" or get rid of this concept | ||
getTagFile(file) { | ||
@@ -156,6 +162,8 @@ const tagFile = { | ||
source: this.plugin.id, | ||
data: file, | ||
name: file.name || file.id, | ||
type: file.mimeType, | ||
isRemote: true, | ||
// @ts-expect-error meta is filled conditionally below | ||
data: file, | ||
// @ts-expect-error meta is filled conditionally below | ||
meta: {}, | ||
@@ -167,2 +175,3 @@ body: { | ||
companionUrl: this.plugin.opts.companionUrl, | ||
// @ts-expect-error untyped for now | ||
url: `${this.provider.fileUrl(file.requestPath)}`, | ||
@@ -169,0 +178,0 @@ body: { |
{ | ||
"name": "@uppy/provider-views", | ||
"description": "View library for Uppy remote provider plugins.", | ||
"version": "3.9.1", | ||
"version": "3.10.0", | ||
"license": "MIT", | ||
@@ -23,3 +23,3 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"@uppy/utils": "^5.7.2", | ||
"@uppy/utils": "^5.7.4", | ||
"classnames": "^2.2.6", | ||
@@ -31,4 +31,4 @@ "nanoid": "^4.0.0", | ||
"peerDependencies": { | ||
"@uppy/core": "^3.9.1" | ||
"@uppy/core": "^3.9.3" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
301742
4400
1
Updated@uppy/utils@^5.7.4