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
						
					
					
				| '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
 |