Exemple #1
0
  Manifest.getManifest = (user, repo, opts, cb) => {
    if (!cb) {
      cb = opts
      opts = {}
    }

    opts = opts || {}

    const manifestKey = createManifestKey(user, repo, opts)
    const batchKey = manifestKey + (opts.authToken || '')

    if (batch.exists(batchKey)) {
      return batch.push(batchKey, cb)
    }

    batch.push(batchKey, cb)

    db.get(manifestKey, (err, manifest) => {
      if (err && !err.notFound) return batch.call(batchKey, (cb) => cb(copy(err)))

      if (!opts.noCache && manifest && !manifest.private && manifest.expires > Date.now()) {
        console.log('Using cached manifest', manifestKey, manifest.data.name, manifest.data.version)
        return batch.call(batchKey, (cb) => cb(null, manifest.data))
      }

      const gh = github.getInstance(opts.authToken)
      const ghOpts = {owner: user, repo, path: (opts.path ? opts.path + '/' : '') + 'package.json'}

      // Add "ref" options if ref is set. Otherwise use default branch.
      if (opts.ref) {
        ghOpts.ref = opts.ref
      }

      if (manifest) {
        ghOpts.headers = { 'If-None-Match': manifest.etag }
      }

      gh.repos.getContent(ghOpts, (err, resp) => {
        if (err) {
          if (err.code === '504' && !opts.noCache && manifest && !manifest.private) {
            console.log('Using expired cached manifest', manifestKey, manifest.data.name, manifest.data.version)
            return batch.call(batchKey, (cb) => cb(null, manifest.data))
          }

          console.error('Failed to get package.json', user, repo, opts.path, opts.ref, err)
          return batch.call(batchKey, (cb) => cb(copy(err)))
        }

        if (!opts.noCache && manifest && manifest.expires > Date.now()) {
          console.log('Using cached private manifest', manifest.data.name, manifest.data.version, opts.ref)
          return batch.call(batchKey, (cb) => cb(null, manifest.data))
        }

        if (!opts.noCache && manifest && resp.meta && resp.meta.status === '304 Not Modified') {
          console.log('Using unmodified manifest', manifest.data.name, manifest.data.version, opts.ref)

          manifest.expires = moment().add(moment.duration({ hours: 1 })).valueOf()

          return db.put(manifestKey, manifest, (err) => {
            if (err) return batch.call(batchKey, (cb) => cb(copy(err)))
            batch.call(batchKey, (cb) => cb(null, manifest.data))
          })
        }

        let data

        try {
          // JSON.parse will barf with a SyntaxError if the body is ill.
          const buffer = Buffer.from(resp.data.content, resp.data.encoding)
          data = JSON.parse(buffer.toString().trim())
        } catch (err) {
          console.error('Failed to parse package.json', resp, err)
          return batch.call(batchKey, (cb) => {
            const content = resp && resp.data && resp.data.content
            cb(new Error('Failed to parse package.json: ' + content))
          })
        }

        if (!data) {
          console.error('Empty package.json')
          return batch.call(batchKey, (cb) => cb(new Error('Empty package.json')))
        }

        console.log('Got manifest', data.name, data.version, opts.ref)

        if (!opts.authToken) {
          // There was no authToken so MUST be public
          onGetRepo(null, {'private': false})
        } else {
          // Get repo info so we can determine private/public status
          gh.repos.get({user: user, repo: repo}, onGetRepo)
        }

        function onGetRepo (err, repoData) {
          if (err) {
            console.error('Failed to get repo data', user, repo, err)
            return batch.call(batchKey, (cb) => cb(copy(err)))
          }

          const oldManifest = manifest

          data.ref = opts.ref
          manifest = {
            data,
            etag: resp.meta.etag,
            private: repoData.private,
            expires: moment().add(moment.duration({ hours: 1 })).valueOf()
          }

          db.put(manifestKey, manifest, (err) => {
            if (err) {
              console.error('Failed to save manifest', manifestKey, err)
              return batch.call(batchKey, (cb) => cb(copy(err)))
            }

            console.log('Cached at', manifestKey)

            batch.call(batchKey, (cb) => cb(null, manifest.data))

            if (!oldManifest) {
              Manifest.emit('retrieve', manifest.data, user, repo, opts.path, opts.ref, repoData.private)
            } else {
              const oldDependencies = oldManifest ? oldManifest.data.dependencies : {}
              const oldDevDependencies = oldManifest ? oldManifest.data.devDependencies : {}
              const oldPeerDependencies = oldManifest ? oldManifest.data.peerDependencies : {}
              const oldOptionalDependencies = oldManifest ? oldManifest.data.optionalDependencies : {}

              let diffs

              if (Manifest.listenerCount('dependenciesChange')) {
                diffs = depDiff(oldDependencies, data.dependencies)

                if (diffs.length) {
                  Manifest.emit('dependenciesChange', diffs, manifest.data, user, repo, opts.path, opts.ref, repoData.private)
                }
              }

              if (Manifest.listenerCount('devDependenciesChange')) {
                diffs = depDiff(oldDevDependencies, data.devDependencies)

                if (diffs.length) {
                  Manifest.emit('devDependenciesChange', diffs, manifest.data, user, repo, opts.path, opts.ref, repoData.private)
                }
              }

              if (Manifest.listenerCount('peerDependenciesChange')) {
                diffs = depDiff(oldPeerDependencies, data.peerDependencies)

                if (diffs.length) {
                  Manifest.emit('peerDependenciesChange', diffs, manifest.data, user, repo, opts.path, opts.ref, repoData.private)
                }
              }

              if (Manifest.listenerCount('optionalDependenciesChange')) {
                diffs = depDiff(oldOptionalDependencies, data.optionalDependencies)

                if (diffs.length) {
                  Manifest.emit('optionalDependenciesChange', diffs, manifest.data, user, repo, opts.path, opts.ref, repoData.private)
                }
              }
            }
          })
        }
      })
    })
  }
Exemple #2
0
 }).on('data', (data) => {
   data.value.expires = Date.now()
   batch.push({type: 'put', key: data.key, value: data.value})
 }).on('end', () => {