]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/cache/caching-client.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / lib / cache / caching-client.js
diff --git a/org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/cache/caching-client.js b/org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/cache/caching-client.js
new file mode 100644 (file)
index 0000000..a2c7c5f
--- /dev/null
@@ -0,0 +1,218 @@
+module.exports = CachingRegistryClient
+
+var path = require("path")
+  , fs = require("graceful-fs")
+  , url = require("url")
+  , assert = require("assert")
+  , inherits = require("util").inherits
+
+var RegistryClient = require("npm-registry-client")
+  , npm = require("../npm.js")
+  , log = require("npmlog")
+  , getCacheStat = require("./get-stat.js")
+  , cacheFile = require("npm-cache-filename")
+  , mkdirp = require("mkdirp")
+  , rimraf = require("rimraf")
+  , chownr = require("chownr")
+  , writeFile = require("write-file-atomic")
+
+function CachingRegistryClient (config) {
+  RegistryClient.call(this, adaptConfig(config))
+
+  this._mapToCache = cacheFile(config.get("cache"))
+
+  // swizzle in our custom cache invalidation logic
+  this._request = this.request
+  this.request  = this._invalidatingRequest
+  this.get      = get
+}
+inherits(CachingRegistryClient, RegistryClient)
+
+CachingRegistryClient.prototype._invalidatingRequest = function (uri, params, cb) {
+  var client = this
+  this._request.call(this, uri, params, function () {
+    var args = arguments
+
+    var method = params.method
+    if (method !== "HEAD" && method !== "GET") {
+      var invalidated = client._mapToCache(uri)
+      // invalidate cache
+      //
+      // This is irrelevant for commands that do etag / last-modified caching,
+      // but ls and view also have a timed cache, so this keeps the user from
+      // thinking that it didn't work when it did.
+      // Note that failure is an acceptable option here, since the only
+      // result will be a stale cache for some helper commands.
+      log.verbose("request", "invalidating", invalidated, "on", method)
+      return rimraf(invalidated, function () {
+        cb.apply(undefined, args)
+      })
+    }
+
+    cb.apply(undefined, args)
+  })
+}
+
+function get (uri, params, cb) {
+  assert(typeof uri === "string", "must pass registry URI to get")
+  assert(params && typeof params === "object", "must pass params to get")
+  assert(typeof cb === "function", "must pass callback to get")
+
+  var parsed = url.parse(uri)
+  assert(
+    parsed.protocol === "http:" || parsed.protocol === "https:",
+    "must have a URL that starts with http: or https:"
+  )
+
+  var cacheBase = cacheFile(npm.config.get("cache"))(uri)
+  var cachePath = path.join(cacheBase, ".cache.json")
+
+  // If the GET is part of a write operation (PUT or DELETE), then
+  // skip past the cache entirely, but still save the results.
+  if (uri.match(/\?write=true$/)) {
+    log.verbose("get", "GET as part of write; not caching result")
+    return get_.call(this, uri, cachePath, params, cb)
+  }
+
+  var client = this
+  fs.stat(cachePath, function (er, stat) {
+    if (!er) {
+      fs.readFile(cachePath, function (er, data) {
+        try {
+          data = JSON.parse(data)
+        }
+        catch (ex) {
+          data = null
+        }
+
+        params.stat = stat
+        params.data = data
+
+        get_.call(client, uri, cachePath, params, cb)
+      })
+    }
+    else {
+      get_.call(client, uri, cachePath, params, cb)
+    }
+  })
+}
+
+function get_ (uri, cachePath, params, cb) {
+  var staleOk = params.staleOk === undefined ? false : params.staleOk
+    , timeout = params.timeout === undefined ? -1 : params.timeout
+    , data    = params.data
+    , stat    = params.stat
+    , etag
+    , lastModified
+
+  timeout = Math.min(timeout, npm.config.get("cache-max") || 0)
+  timeout = Math.max(timeout, npm.config.get("cache-min") || -Infinity)
+  if (process.env.COMP_CWORD !== undefined &&
+      process.env.COMP_LINE  !== undefined &&
+      process.env.COMP_POINT !== undefined) {
+    timeout = Math.max(timeout, 60000)
+  }
+
+  if (data) {
+    if (data._etag) etag = data._etag
+    if (data._lastModified) lastModified = data._lastModified
+
+    if (stat && timeout && timeout > 0) {
+      if ((Date.now() - stat.mtime.getTime())/1000 < timeout) {
+        log.verbose("get", uri, "not expired, no request")
+        delete data._etag
+        delete data._lastModified
+        return cb(null, data, JSON.stringify(data), { statusCode : 304 })
+      }
+
+      if (staleOk) {
+        log.verbose("get", uri, "staleOk, background update")
+        delete data._etag
+        delete data._lastModified
+        process.nextTick(
+          cb.bind(null, null, data, JSON.stringify(data), { statusCode : 304 } )
+        )
+        cb = function () {}
+      }
+    }
+  }
+
+  var options = {
+    etag         : etag,
+    lastModified : lastModified,
+    follow       : params.follow,
+    auth         : params.auth
+  }
+  this.request(uri, options, function (er, remoteData, raw, response) {
+    // if we get an error talking to the registry, but we have it
+    // from the cache, then just pretend we got it.
+    if (er && cachePath && data && !data.error) {
+      er = null
+      response = { statusCode: 304 }
+    }
+
+    if (response) {
+      log.silly("get", "cb", [response.statusCode, response.headers])
+      if (response.statusCode === 304 && (etag || lastModified)) {
+        remoteData = data
+        log.verbose(etag ? "etag" : "lastModified", uri+" from cache")
+      }
+    }
+
+    data = remoteData
+    if (!data) er = er || new Error("failed to fetch from registry: " + uri)
+
+    if (er) return cb(er, data, raw, response)
+
+    saveToCache(cachePath, data, saved)
+
+    // just give the write the old college try.  if it fails, whatever.
+    function saved () {
+      delete data._etag
+      delete data._lastModified
+      cb(er, data, raw, response)
+    }
+
+    function saveToCache (cachePath, data, saved) {
+      log.verbose("get", "saving", data.name, "to", cachePath)
+      getCacheStat(function (er, st) {
+        mkdirp(path.dirname(cachePath), function (er, made) {
+          if (er) return saved()
+
+          writeFile(cachePath, JSON.stringify(data), function (er) {
+            if (er) return saved()
+
+            chownr(made || cachePath, st.uid, st.gid, saved)
+          })
+        })
+      })
+    }
+  })
+}
+
+function adaptConfig (config) {
+  return {
+    proxy : {
+      http         : config.get("proxy"),
+      https        : config.get("https-proxy"),
+      localAddress : config.get("local-address")
+    },
+    ssl : {
+      certificate : config.get("cert"),
+      key         : config.get("key"),
+      ca          : config.get("ca"),
+      strict      : config.get("strict-ssl")
+    },
+    retry : {
+      retries    : config.get("fetch-retries"),
+      factor     : config.get("fetch-retry-factor"),
+      minTimeout : config.get("fetch-retry-mintimeout"),
+      maxTimeout : config.get("fetch-retry-maxtimeout")
+    },
+    userAgent  : config.get("user-agent"),
+    log        : log,
+    defaultTag : config.get("tag"),
+    couchToken : config.get("_token"),
+    maxSockets : config.get('maxsockets')
+  }
+}