Socket
Socket
Sign inDemoInstall

vue

Package Overview
Dependencies
Maintainers
1
Versions
526
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue - npm Package Compare versions

Comparing version 0.12.0-rc to 0.12.0-rc2

src/compiler/content.js

2

package.json
{
"name": "vue",
"version": "0.12.0-rc",
"version": "0.12.0-rc2",
"author": "Evan You <yyx990803@gmail.com>",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -67,7 +67,8 @@ var _ = require('../util')

* @param {Element|DocumentFragment} el
* @param {Vue} [host]
* @return {Function}
*/
exports.$compile = function (el) {
return compile(el, this.$options, true)(this, el)
exports.$compile = function (el, host) {
return compile(el, this.$options, true, host)(this, el)
}

@@ -29,7 +29,7 @@ var _ = require('../util')

* @param {Boolean} partial
* @param {Boolean} transcluded
* @param {Vue} [host] - host vm of transcluded content
* @return {Function}
*/
function compile (el, options, partial, transcluded) {
function compile (el, options, partial, host) {
// link function for the node itself.

@@ -57,3 +57,3 @@ var nodeLinkFn = !partial

function compositeLinkFn (vm, el) {
return function compositeLinkFn (vm, el) {
// save original directive count before linking

@@ -63,19 +63,9 @@ // so we can capture the directives created during a

var originalDirCount = vm._directives.length
var parentOriginalDirCount =
vm.$parent && vm.$parent._directives.length
// cache childNodes before linking parent, fix #657
var childNodes = _.toArray(el.childNodes)
// if this is a transcluded compile, linkers need to be
// called in source scope, and the host needs to be
// passed down.
var source = transcluded ? vm.$parent : vm
var host = transcluded ? vm : undefined
// link
if (nodeLinkFn) nodeLinkFn(source, el, host)
if (childLinkFn) childLinkFn(source, childNodes, host)
if (nodeLinkFn) nodeLinkFn(vm, el, host)
if (childLinkFn) childLinkFn(vm, childNodes, host)
var dirs = vm._directives.slice(originalDirCount)
var selfDirs = vm._directives.slice(originalDirCount)
var parentDirs = vm.$parent &&
vm.$parent._directives.slice(parentOriginalDirCount)
/**

@@ -89,40 +79,17 @@ * The linker function returns an unlink function that

return function unlink (destroying) {
teardownDirs(vm, selfDirs, destroying)
if (parentDirs) {
teardownDirs(vm.$parent, parentDirs)
var i = dirs.length
while (i--) {
dirs[i]._teardown()
if (!destroying) {
vm._directives.$remove(dirs[i])
}
}
}
}
// transcluded linkFns are terminal, because it takes
// over the entire sub-tree.
if (transcluded) {
compositeLinkFn.terminal = true
}
return compositeLinkFn
}
/**
* Teardown a subset of directives on a vm.
*
* @param {Vue} vm
* @param {Array} dirs
* @param {Boolean} destroying
*/
function teardownDirs (vm, dirs, destroying) {
var i = dirs.length
while (i--) {
dirs[i]._teardown()
if (!destroying) {
vm._directives.$remove(dirs[i])
}
}
}
/**
* Compile the root element of an instance. There are
* 3 types of things to process here:
*
*
* 1. props on parent container (child scope)

@@ -208,9 +175,2 @@ * 2. other attrs on parent container (parent scope)

var hasAttrs = el.hasAttributes()
if (hasAttrs && checkTransclusion(el)) {
// unwrap textNode
if (el.hasAttribute('__vue__wrap')) {
el = el.firstChild
}
return compile(el, options._parent.$options, true, true)
}
// check element directives

@@ -399,3 +359,4 @@ var linkFn = checkElementDirectives(el, options)

// if not the prop binding is automatically one-way.
var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]\])*$/
var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/
var literalValueRE = /^true|false|\d+$/

@@ -435,3 +396,4 @@ function compileProps (el, attrs, propNames) {

tokens[0].oneTime ||
!settablePathRE.test(prop.value)
!settablePathRE.test(prop.value) ||
literalValueRE.test(prop.value)
}

@@ -479,3 +441,3 @@ props.push(prop)

// just set once
vm.$set(path, prop.raw)
vm.$set(path, _.toNumber(prop.raw))
}

@@ -717,17 +679,2 @@ }

return a > b ? 1 : -1
}
/**
* Check whether an element is transcluded
*
* @param {Element} el
* @return {Boolean}
*/
var transcludedFlagAttr = '__vue__transcluded'
function checkTransclusion (el) {
if (el.nodeType === 1 && el.hasAttribute(transcludedFlagAttr)) {
el.removeAttribute(transcludedFlagAttr)
return true
}
}
var _ = require('../util')
var config = require('../config')
var templateParser = require('../parsers/template')
var transcludedFlagAttr = '__vue__transcluded'

@@ -27,22 +26,2 @@ /**

}
// Mark content nodes and attrs so that the compiler
// knows they should be compiled in parent scope.
if (options && options._asComponent) {
var i = el.childNodes.length
while (i--) {
var node = el.childNodes[i]
if (node.nodeType === 1) {
node.setAttribute(transcludedFlagAttr, '')
} else if (node.nodeType === 3 && node.data.trim()) {
// wrap transcluded textNodes in spans, because
// raw textNodes can't be persisted through clones
// by attaching attributes.
var wrapper = document.createElement('span')
wrapper.textContent = node.data
wrapper.setAttribute('__vue__wrap', '')
wrapper.setAttribute(transcludedFlagAttr, '')
el.replaceChild(wrapper, node)
}
}
}
// for template tags, what we want is its content as

@@ -81,3 +60,3 @@ // a documentFragment (for block instances)

} else {
var rawContent = options._content || _.extractContent(el)
options._content = _.extractContent(el)
var replacer = frag.firstChild

@@ -93,3 +72,2 @@ if (options.replace) {

) {
transcludeContent(frag, rawContent)
return frag

@@ -99,3 +77,2 @@ } else {

mergeAttrs(el, replacer)
transcludeContent(replacer, rawContent)
return replacer

@@ -105,3 +82,2 @@ }

el.appendChild(frag)
transcludeContent(el, rawContent)
return el

@@ -113,96 +89,4 @@ }

/**
* Resolve <content> insertion points mimicking the behavior
* of the Shadow DOM spec:
*
* http://w3c.github.io/webcomponents/spec/shadow/#insertion-points
*
* @param {Element|DocumentFragment} el
* @param {Element} raw
*/
function transcludeContent (el, raw) {
var outlets = getOutlets(el)
var i = outlets.length
if (!i) return
var outlet, select, selected, j, main
function isDirectChild (node) {
return node.parentNode === raw
}
// first pass, collect corresponding content
// for each outlet.
while (i--) {
outlet = outlets[i]
if (raw) {
select = outlet.getAttribute('select')
if (select) { // select content
selected = raw.querySelectorAll(select)
if (selected.length) {
// according to Shadow DOM spec, `select` can
// only select direct children of the host node.
// enforcing this also fixes #786.
selected = [].filter.call(selected, isDirectChild)
}
outlet.content = selected.length
? selected
: _.toArray(outlet.childNodes)
} else { // default content
main = outlet
}
} else { // fallback content
outlet.content = _.toArray(outlet.childNodes)
}
}
// second pass, actually insert the contents
for (i = 0, j = outlets.length; i < j; i++) {
outlet = outlets[i]
if (outlet !== main) {
insertContentAt(outlet, outlet.content)
}
}
// finally insert the main content
if (main) {
insertContentAt(main, _.toArray(raw.childNodes))
}
}
/**
* Get <content> outlets from the element/list
*
* @param {Element|Array} el
* @return {Array}
*/
var concat = [].concat
function getOutlets (el) {
return _.isArray(el)
? concat.apply([], el.map(getOutlets))
: el.querySelectorAll
? _.toArray(el.querySelectorAll('content'))
: []
}
/**
* Insert an array of nodes at outlet,
* then remove the outlet.
*
* @param {Element} outlet
* @param {Array} contents
*/
function insertContentAt (outlet, contents) {
// not using util DOM methods here because
// parentNode can be cached
var parent = outlet.parentNode
for (var i = 0, j = contents.length; i < j; i++) {
parent.insertBefore(contents[i], outlet)
}
parent.removeChild(outlet)
}
/**
* Helper to extract a component container's attribute names
* into a map. The resulting map will be used in compiler to
* determine whether an attribute is transcluded.
* into a map.
*

@@ -209,0 +93,0 @@ * @param {Element} el

@@ -5,15 +5,42 @@ var _ = require('../util')

module.exports = function (value) {
if (this.arg) {
var method = value ? addClass : removeClass
method(this.el, this.arg)
} else {
module.exports = {
update: function (value) {
if (this.arg) {
// single toggle
var method = value ? addClass : removeClass
method(this.el, this.arg)
} else {
this.cleanup()
if (value && typeof value === 'string') {
// raw CSSText
addClass(this.el, value)
this.lastVal = value
} else if (_.isPlainObject(value)) {
// object toggle
for (var key in value) {
if (value[key]) {
addClass(this.el, key)
} else {
removeClass(this.el, key)
}
}
this.prevKeys = Object.keys(value)
}
}
},
cleanup: function (value) {
if (this.lastVal) {
removeClass(this.el, this.lastVal)
}
if (value) {
addClass(this.el, value)
this.lastVal = value
if (this.prevKeys) {
var i = this.prevKeys.length
while (i--) {
if (!value || !value[this.prevKeys[i]]) {
removeClass(this.el, this.prevKeys[i])
}
}
}
}
}

@@ -93,3 +93,6 @@ var _ = require('../util')

next = cur.nextSibling
if (cur.contains(c.$el)) {
if (
cur === c.$el ||
cur.contains && cur.contains(c.$el)
) {
return true

@@ -96,0 +99,0 @@ }

@@ -68,3 +68,4 @@ var _ = require('../../util')

this.hasRead = true
} else if (filter.write) {
}
if (filter.write) {
this.hasWrite = true

@@ -71,0 +72,0 @@ }

@@ -26,5 +26,7 @@ var _ = require('../util')

this.id = '__v_repeat_' + (++uid)
// setup anchor node
this.anchor = _.createAnchor('v-repeat')
_.replace(this.el, this.anchor)
// setup anchor nodes
this.start = _.createAnchor('v-repeat-start')
this.end = _.createAnchor('v-repeat')
_.replace(this.el, this.end)
_.before(this.start, this.end)
// check if this is a block repeat

@@ -43,2 +45,6 @@ this.template = this.el.tagName === 'TEMPLATE'

this._checkParam('trackby') // 0.11.0 compat
// check for transition stagger
var stagger = +this._checkParam('stagger')
this.enterStagger = +this._checkParam('enter-stagger') || stagger
this.leaveStagger = +this._checkParam('leave-stagger') || stagger
this.cache = Object.create(null)

@@ -131,2 +137,3 @@ },

this.template = transclude(this.template, merged)
this.content = merged._content
// Important: mark the template as a root node so that

@@ -215,3 +222,5 @@ // custom element components don't get compiled twice.

if (this.refID) {
this.vm.$[this.refID] = this.vms
this.vm.$[this.refID] = this.converted
? toRefObject(this.vms)
: this.vms
}

@@ -244,7 +253,9 @@ if (this.elId) {

var converted = this.converted
var anchor = this.anchor
var start = this.start
var end = this.end
var inDoc = _.inDoc(start)
var alias = this.arg
var init = !oldVms
var vms = new Array(data.length)
var obj, raw, vm, i, l
var obj, raw, vm, i, l, primitive
// First pass, go through the new Array and fill up

@@ -257,2 +268,3 @@ // the new vms array. If a piece of data has a cached

raw = converted ? obj.$value : obj
primitive = !isObject(raw)
vm = !init && this.getVm(raw, i, converted ? obj.$key : null)

@@ -265,3 +277,3 @@ if (vm) { // reusable instance

// rather than mutated.
if (idKey || converted) {
if (idKey || converted || primitive) {
if (alias) {

@@ -277,6 +289,2 @@ vm[alias] = raw

vm = this.build(obj, i, true)
// the _new flag is used in the second pass for
// vm cache retrival, but if this is the init phase
// the flag can just be set to false directly.
vm._new = !init
vm._reused = false

@@ -287,3 +295,3 @@ }

if (init) {
vm.$before(anchor)
vm.$before(end)
}

@@ -298,2 +306,4 @@ }

// from cache)
var removalIndex = 0
var totalRemoved = oldVms.length - vms.length
for (i = 0, l = oldVms.length; i < l; i++) {

@@ -303,39 +313,29 @@ vm = oldVms[i]

this.uncacheVm(vm)
vm.$destroy(true)
vm.$destroy(false, true) // defer cleanup until removal
this.remove(vm, removalIndex++, totalRemoved, inDoc)
}
}
// final pass, move/insert new instances into the
// right place. We're going in reverse here because
// insertBefore relies on the next sibling to be
// resolved.
var targetNext, currentNext
i = vms.length
while (i--) {
// right place.
var targetPrev, prevEl, currentPrev
var insertionIndex = 0
for (i = 0, l = vms.length; i < l; i++) {
vm = vms[i]
// this is the vm that we should be in front of
targetNext = vms[i + 1]
if (!targetNext) {
// This is the last item. If it's reused then
// everything else will eventually be in the right
// place, so no need to touch it. Otherwise, insert
// it.
if (!vm._reused) {
vm.$before(anchor)
// this is the vm that we should be after
targetPrev = vms[i - 1]
prevEl = targetPrev
? targetPrev._staggerCb
? targetPrev._staggerAnchor
: targetPrev._blockEnd || targetPrev.$el
: start
if (vm._reused && !vm._staggerCb) {
currentPrev = findPrevVm(vm, start)
if (currentPrev !== targetPrev) {
this.move(vm, prevEl)
}
} else {
var nextEl = targetNext.$el
if (vm._reused) {
// this is the vm we are actually in front of
currentNext = findNextVm(vm, anchor)
// we only need to move if we are not in the right
// place already.
if (currentNext !== targetNext) {
vm.$before(nextEl, null, false)
}
} else {
// new instance, insert to existing next
vm.$before(nextEl)
}
// new instance, or still in stagger.
// insert with updated stagger index.
this.insert(vm, insertionIndex++, prevEl, inDoc)
}
vm._new = false
vm._reused = false

@@ -380,2 +380,4 @@ }

_meta: meta,
_content: this.content,
_repeat: this.inherit,
data: data,

@@ -385,5 +387,2 @@ inherit: this.inherit,

}, Ctor)
// flag this instance as a repeat instance
// so that we can skip it in vm._digest
vm._repeat = true
// cache instance

@@ -401,2 +400,12 @@ if (needCache) {

vm.$watch(alias || '$value', function (val) {
if (dir.filters) {
_.warn(
'You seem to be mutating the $value reference of ' +
'a v-repeat instance (likely through v-model) ' +
'and filtering the v-repeat at the same time. ' +
'This will not work properly with an Array of ' +
'primitive values. Please use an Array of ' +
'Objects instead.'
)
}
dir._withLock(function () {

@@ -451,4 +460,5 @@ if (dir.converted) {

var cache = this.cache
var primitive = !isObject(data)
var id
if (key || idKey) {
if (key || idKey || primitive) {
id = idKey

@@ -458,9 +468,9 @@ ? idKey === '$index'

: data[idKey]
: key
: (key || index)
if (!cache[id]) {
cache[id] = vm
} else {
} else if (!primitive && idKey !== '$index') {
_.warn('Duplicate track-by key in v-repeat: ' + id)
}
} else if (isObject(data)) {
} else {
id = this.id

@@ -479,8 +489,2 @@ if (data.hasOwnProperty(id)) {

}
} else {
if (!cache[data]) {
cache[data] = [vm]
} else {
cache[data].push(vm)
}
}

@@ -501,3 +505,4 @@ vm._raw = data

var idKey = this.idKey
if (key || idKey) {
var primitive = !isObject(data)
if (key || idKey || primitive) {
var id = idKey

@@ -507,19 +512,6 @@ ? idKey === '$index'

: data[idKey]
: key
: (key || index)
return this.cache[id]
} else if (isObject(data)) {
} else {
return data[this.id]
} else {
var cached = this.cache[data]
if (cached) {
var i = 0
var vm = cached[i]
// since duplicated vm instances might be a reused
// one OR a newly created one, we need to return the
// first instance that is neither of these.
while (vm && (vm._reused || vm._new)) {
vm = cached[++i]
}
return vm
}
}

@@ -537,15 +529,15 @@ },

var idKey = this.idKey
var convertedKey = vm.$key
if (idKey || convertedKey) {
var index = vm.$index
var key = vm.$key
var primitive = !isObject(data)
if (idKey || key || primitive) {
var id = idKey
? idKey === '$index'
? vm.$index
? index
: data[idKey]
: convertedKey
: (key || index)
this.cache[id] = null
} else if (isObject(data)) {
} else {
data[this.id] = null
vm._raw = null
} else {
this.cache[data].pop()
}

@@ -594,2 +586,104 @@ },

}
},
/**
* Insert an instance.
*
* @param {Vue} vm
* @param {Number} index
* @param {Node} prevEl
* @param {Boolean} inDoc
*/
insert: function (vm, index, prevEl, inDoc) {
if (vm._staggerCb) {
vm._staggerCb.cancel()
vm._staggerCb = null
}
var staggerAmount = this.getStagger(vm, index, null, 'enter')
if (inDoc && staggerAmount) {
// create an anchor and insert it synchronously,
// so that we can resolve the correct order without
// worrying about some elements not inserted yet
var anchor = vm._staggerAnchor
if (!anchor) {
anchor = vm._staggerAnchor = _.createAnchor('stagger-anchor')
anchor.__vue__ = vm
}
_.after(anchor, prevEl)
var op = vm._staggerCb = _.cancellable(function () {
vm._staggerCb = null
vm.$before(anchor)
_.remove(anchor)
})
setTimeout(op, staggerAmount)
} else {
vm.$after(prevEl)
}
},
/**
* Move an already inserted instance.
*
* @param {Vue} vm
* @param {Node} prevEl
*/
move: function (vm, prevEl) {
vm.$after(prevEl, null, false)
},
/**
* Remove an instance.
*
* @param {Vue} vm
* @param {Number} index
* @param {Boolean} inDoc
*/
remove: function (vm, index, total, inDoc) {
if (vm._staggerCb) {
vm._staggerCb.cancel()
vm._staggerCb = null
// it's not possible for the same vm to be removed
// twice, so if we have a pending stagger callback,
// it means this vm is queued for enter but removed
// before its transition started. Since it is already
// destroyed, we can just leave it in detached state.
return
}
var staggerAmount = this.getStagger(vm, index, total, 'leave')
if (inDoc && staggerAmount) {
var op = vm._staggerCb = _.cancellable(function () {
vm._staggerCb = null
remove()
})
setTimeout(op, staggerAmount)
} else {
remove()
}
function remove () {
vm.$remove(function () {
vm._cleanup()
})
}
},
/**
* Get the stagger amount for an insertion/removal.
*
* @param {Vue} vm
* @param {Number} index
* @param {String} type
* @param {Number} total
*/
getStagger: function (vm, index, total, type) {
type = type + 'Stagger'
var transition = vm.$el.__v_trans
var hooks = transition && transition.hooks
var hook = hooks && (hooks[type] || hooks.stagger)
return hook
? hook.call(vm, index, total)
: index * this[type]
}

@@ -600,3 +694,3 @@

/**
* Helper to find the next element that is an instance
* Helper to find the previous element that is an instance
* root node. This is necessary because a destroyed vm's

@@ -612,6 +706,6 @@ * element could still be lingering in the DOM before its

function findNextVm (vm, anchor) {
var el = (vm._blockEnd || vm.$el).nextSibling
function findPrevVm (vm, anchor) {
var el = vm.$el.previousSibling
while (!el.__vue__ && el !== anchor) {
el = el.nextSibling
el = el.previousSibling
}

@@ -635,2 +729,18 @@ return el.__vue__

return ret
}
/**
* Convert a vms array to an object ref for v-ref on an
* Object value.
*
* @param {Array} vms
* @return {Object}
*/
function toRefObject (vms) {
var ref = {}
for (var i = 0, l = vms.length; i < l; i++) {
ref[vms[i].$key] = vms[i]
}
return ref
}

@@ -66,4 +66,4 @@ var mergeOptions = require('../util').mergeOptions

// props used in v-repeat diffing
this._new = true
this._reused = false
this._staggerOp = null

@@ -70,0 +70,0 @@ // merge options.

@@ -60,2 +60,3 @@ var _ = require('../util')

} else if (factory.requested) {
// pool callbacks
factory.pendingCallbacks.push(cb)

@@ -75,2 +76,7 @@ } else {

}
}, function reject (reason) {
_.warn(
'Failed to resolve async component: ' + id + '. ' +
(reason ? '\nReason: ' + reason : '')
)
})

@@ -77,0 +83,0 @@ }

@@ -305,3 +305,5 @@ var _ = require('../util')

} else {
if (key in obj) {
if (_.isArray(obj)) {
obj.$set(key, val)
} else if (key in obj) {
obj[key] = val

@@ -308,0 +310,0 @@ } else {

@@ -9,3 +9,2 @@ var _ = require('../util')

var animDurationProp = _.animationProp + 'Duration'
var doc = typeof document === 'undefined' ? null : document

@@ -34,3 +33,3 @@ var TYPE_TRANSITION = 1

this.pendingCssCb =
this.jsCancel =
this.cancel =
this.pendingJsCb =

@@ -82,2 +81,3 @@ this.op =

this.callHookWithCb('enter')
this.cancel = this.hooks && this.hooks.enterCancelled
queue.push(this.enterNextTick)

@@ -111,3 +111,3 @@ }

p.enterDone = function () {
this.jsCancel = this.pendingJsCb = null
this.cancel = this.pendingJsCb = null
removeClass(this.el, this.enterClass)

@@ -146,2 +146,3 @@ this.callHook('afterEnter')

this.callHookWithCb('leave')
this.cancel = this.hooks && this.hooks.enterCancelled
// only need to do leaveNextTick if there's no explicit

@@ -175,2 +176,3 @@ // js callback

p.leaveDone = function () {
this.cancel = this.pendingJsCb = null
this.op()

@@ -204,5 +206,5 @@ removeClass(this.el, this.leaveClass)

}
if (this.jsCancel) {
this.jsCancel.call(null)
this.jsCancel = null
if (this.cancel) {
this.cancel.call(this.vm, this.el)
this.cancel = null
}

@@ -240,3 +242,3 @@ }

}
this.jsCancel = hook.call(this.vm, this.el, this.pendingJsCb)
hook.call(this.vm, this.el, this.pendingJsCb)
}

@@ -260,3 +262,3 @@ }

/* istanbul ignore if */
if (!transitionEndEvent || (doc && doc.hidden)) {
if (!transitionEndEvent || document.hidden) {
return

@@ -263,0 +265,0 @@ }

@@ -33,3 +33,3 @@ var config = require('../config')

exports.warn = function (msg) {
exports.warn = function (msg, e) {
if (hasConsole && (!config.silent || config.debug)) {

@@ -40,3 +40,3 @@ console.warn('[Vue warn]: ' + msg)

/* jshint debug: true */
debugger
console.warn((e || new Error('Warning Stack Trace')).stack)
}

@@ -43,0 +43,0 @@ }

@@ -15,7 +15,4 @@ var config = require('../config')

var doc =
typeof document !== 'undefined' &&
document.documentElement
exports.inDoc = function (node) {
var doc = document.documentElement
var parent = node && node.parentNode

@@ -22,0 +19,0 @@ return doc === node ||

@@ -38,7 +38,9 @@ var _ = require('./util')

Vue.options = {
directives : require('./directives'),
filters : require('./filters'),
transitions : {},
components : {},
elementDirectives: {}
directives: require('./directives'),
filters: require('./filters'),
transitions: {},
components: {},
elementDirectives: {
content: require('./compiler/content')
}
}

@@ -45,0 +47,0 @@

@@ -83,3 +83,3 @@ var _ = require('./util')

'Error when evaluating expression "' +
this.expression + '":\n ' + e
this.expression + '"', e
)

@@ -121,3 +121,3 @@ }

'Error when evaluating setter "' +
this.expression + '":\n ' + e
this.expression + '"', e
)

@@ -124,0 +124,0 @@ }

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 too big to display

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