You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					178 lines
				
				4.3 KiB
			
		
		
			
		
	
	
					178 lines
				
				4.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function SemVerStore () {
							 | 
						||
| 
								 | 
							
								  if (!(this instanceof SemVerStore)) {
							 | 
						||
| 
								 | 
							
								    return new SemVerStore()
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  this.tree = new Node()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SemVerStore.prototype.set = function (version, store) {
							 | 
						||
| 
								 | 
							
								  if (typeof version !== 'string') {
							 | 
						||
| 
								 | 
							
								    throw new TypeError('Version should be a string')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  var currentNode = this.tree
							 | 
						||
| 
								 | 
							
								  version = version.split('.')
							 | 
						||
| 
								 | 
							
								  while (version.length) {
							 | 
						||
| 
								 | 
							
								    currentNode = currentNode.addChild(
							 | 
						||
| 
								 | 
							
								      new Node(version.shift())
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  currentNode.setStore(store)
							 | 
						||
| 
								 | 
							
								  return this
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SemVerStore.prototype.get = function (version) {
							 | 
						||
| 
								 | 
							
								  if (typeof version !== 'string') return null
							 | 
						||
| 
								 | 
							
								  if (version === '*') version = 'x.x.x'
							 | 
						||
| 
								 | 
							
								  var node = this.tree
							 | 
						||
| 
								 | 
							
								  var firstDot = version.indexOf('.')
							 | 
						||
| 
								 | 
							
								  var secondDot = version.indexOf('.', firstDot + 1)
							 | 
						||
| 
								 | 
							
								  var major = version.slice(0, firstDot)
							 | 
						||
| 
								 | 
							
								  var minor = secondDot === -1
							 | 
						||
| 
								 | 
							
								    ? version.slice(firstDot + 1)
							 | 
						||
| 
								 | 
							
								    : version.slice(firstDot + 1, secondDot)
							 | 
						||
| 
								 | 
							
								  var patch = secondDot === -1
							 | 
						||
| 
								 | 
							
								    ? 'x'
							 | 
						||
| 
								 | 
							
								    : version.slice(secondDot + 1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  node = node.getChild(major)
							 | 
						||
| 
								 | 
							
								  if (node === null) return null
							 | 
						||
| 
								 | 
							
								  node = node.getChild(minor)
							 | 
						||
| 
								 | 
							
								  if (node === null) return null
							 | 
						||
| 
								 | 
							
								  node = node.getChild(patch)
							 | 
						||
| 
								 | 
							
								  if (node === null) return null
							 | 
						||
| 
								 | 
							
								  return node.store
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SemVerStore.prototype.del = function (version) {
							 | 
						||
| 
								 | 
							
								  if (typeof version !== 'string') {
							 | 
						||
| 
								 | 
							
								    throw new TypeError('Version should be a string')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  var firstDot = version.indexOf('.')
							 | 
						||
| 
								 | 
							
								  var secondDot = version.indexOf('.', firstDot + 1)
							 | 
						||
| 
								 | 
							
								  var major = version.slice(0, firstDot)
							 | 
						||
| 
								 | 
							
								  var minor = secondDot === -1
							 | 
						||
| 
								 | 
							
								    ? version.slice(firstDot + 1)
							 | 
						||
| 
								 | 
							
								    : version.slice(firstDot + 1, secondDot)
							 | 
						||
| 
								 | 
							
								  var patch = secondDot === -1
							 | 
						||
| 
								 | 
							
								    ? 'x'
							 | 
						||
| 
								 | 
							
								    : version.slice(secondDot + 1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // check existence of major node
							 | 
						||
| 
								 | 
							
								  var majorNode = this.tree.children[major]
							 | 
						||
| 
								 | 
							
								  if (majorNode == null) return this
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // if minor is the wildcard, then remove the full major node
							 | 
						||
| 
								 | 
							
								  if (minor === 'x') {
							 | 
						||
| 
								 | 
							
								    this.tree.removeChild(major)
							 | 
						||
| 
								 | 
							
								    return this
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // check existence of minor node
							 | 
						||
| 
								 | 
							
								  var minorNode = majorNode.children[minor]
							 | 
						||
| 
								 | 
							
								  if (minorNode == null) return this
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // if patch is the wildcard, then remove the full minor node
							 | 
						||
| 
								 | 
							
								  // and also the major if there are no more children
							 | 
						||
| 
								 | 
							
								  if (patch === 'x') {
							 | 
						||
| 
								 | 
							
								    this.tree.children[major].removeChild(minor)
							 | 
						||
| 
								 | 
							
								    if (this.tree.children[major].length === 0) {
							 | 
						||
| 
								 | 
							
								      this.tree.removeChild(major)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return this
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // check existence of patch node
							 | 
						||
| 
								 | 
							
								  var patchNode = minorNode.children[patch]
							 | 
						||
| 
								 | 
							
								  if (patchNode == null) return this
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // Specific delete
							 | 
						||
| 
								 | 
							
								  this.tree
							 | 
						||
| 
								 | 
							
								    .children[major]
							 | 
						||
| 
								 | 
							
								    .children[minor]
							 | 
						||
| 
								 | 
							
								    .removeChild(patch)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // check if the minor node has no more children, if so removes it
							 | 
						||
| 
								 | 
							
								  // same for the major node
							 | 
						||
| 
								 | 
							
								  if (this.tree.children[major].children[minor].length === 0) {
							 | 
						||
| 
								 | 
							
								    this.tree.children[major].removeChild(minor)
							 | 
						||
| 
								 | 
							
								    if (this.tree.children[major].length === 0) {
							 | 
						||
| 
								 | 
							
								      this.tree.removeChild(major)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return this
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SemVerStore.prototype.empty = function () {
							 | 
						||
| 
								 | 
							
								  this.tree = new Node()
							 | 
						||
| 
								 | 
							
								  return this
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function getMax (arr) {
							 | 
						||
| 
								 | 
							
								  var l = arr.length
							 | 
						||
| 
								 | 
							
								  var max = arr[0]
							 | 
						||
| 
								 | 
							
								  for (var i = 1; i < l; i++) {
							 | 
						||
| 
								 | 
							
								    if (arr[i] > max) {
							 | 
						||
| 
								 | 
							
								      max = arr[i]
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return max
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function Node (prefix, children, store) {
							 | 
						||
| 
								 | 
							
								  this.prefix = Number(prefix) || 0
							 | 
						||
| 
								 | 
							
								  this.children = children || null
							 | 
						||
| 
								 | 
							
								  this.childrenPrefixes = children ? Object.keys(children) : []
							 | 
						||
| 
								 | 
							
								  this.store = store || null
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Node.prototype.getChild = function (prefix) {
							 | 
						||
| 
								 | 
							
								  if (this.children === null) return null
							 | 
						||
| 
								 | 
							
								  if (prefix === 'x') {
							 | 
						||
| 
								 | 
							
								    var max = getMax(this.childrenPrefixes)
							 | 
						||
| 
								 | 
							
								    return this.children[max]
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return this.children[prefix] || null
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Node.prototype.addChild = function (node) {
							 | 
						||
| 
								 | 
							
								  this.children = this.children || {}
							 | 
						||
| 
								 | 
							
								  var child = this.getChild(node.prefix)
							 | 
						||
| 
								 | 
							
								  if (child === null) {
							 | 
						||
| 
								 | 
							
								    this.children[node.prefix] = node
							 | 
						||
| 
								 | 
							
								    this.childrenPrefixes.push(node.prefix)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return child || node
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Node.prototype.removeChild = function (prefix) {
							 | 
						||
| 
								 | 
							
								  if (prefix === 'x') {
							 | 
						||
| 
								 | 
							
								    this.children = null
							 | 
						||
| 
								 | 
							
								    this.childrenPrefixes = []
							 | 
						||
| 
								 | 
							
								    return this
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  if (this.children[prefix] !== undefined) {
							 | 
						||
| 
								 | 
							
								    prefix = Number(prefix)
							 | 
						||
| 
								 | 
							
								    delete this.children[prefix]
							 | 
						||
| 
								 | 
							
								    this.childrenPrefixes.splice(
							 | 
						||
| 
								 | 
							
								      this.childrenPrefixes.indexOf(prefix), 1
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  return this
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Node.prototype.setStore = function (store) {
							 | 
						||
| 
								 | 
							
								  this.store = store
							 | 
						||
| 
								 | 
							
								  return this
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Object.defineProperty(Node.prototype, 'length', {
							 | 
						||
| 
								 | 
							
								  get: function () {
							 | 
						||
| 
								 | 
							
								    return this.childrenPrefixes.length
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = SemVerStore
							 |