cnpm / cnpmjs.org

@@ -0,0 +1,49 @@
Loading
1 +
'use strict';
2 +
3 +
const config = require('../config');
4 +
const packageService = require('./package');
5 +
6 +
// replace bug version and set deprecated property for cli tooltip
7 +
exports.hotfix = function* (rows) {
8 +
  if (!config.enableBugVersion) {
9 +
    return;
10 +
  }
11 +
  let row = rows[0];
12 +
  if (!row) {
13 +
    return;
14 +
  }
15 +
  // https://github.com/cnpm/bug-versions/blob/master/package.json#L118
16 +
  // "bug-versions": {
17 +
  //   "gifsicle": {
18 +
  //     "5.3.0": {
19 +
  //       "version": "5.2.1",
20 +
  //       "reason": "https://github.com/imagemin/gifsicle-bin/issues/133"
21 +
  //     }
22 +
  //   },
23 +
  const moduleRow = yield packageService.getLatestModule('bug-versions');
24 +
  if (!moduleRow) {
25 +
    return;
26 +
  }
27 +
  const bugVersions = moduleRow.package['bug-versions'];
28 +
  const bugs = bugVersions && bugVersions[row.package.name];
29 +
  if (!bugs) {
30 +
    return;
31 +
  }
32 +
33 +
  const existsVerionsMap = {};
34 +
  for (row of rows) {
35 +
    existsVerionsMap[row.package.version] = row.package;
36 +
  }
37 +
38 +
  for (row of rows) {
39 +
    const bug = bugs[row.package.version];
40 +
    if (bug && bug.version && existsVerionsMap[bug.version]) {
41 +
      const packageJSON = JSON.parse(JSON.stringify(existsVerionsMap[bug.version]));
42 +
      const hotfixDeprecated = `[WARNING] Use ${bug.version} instead of ${row.package.version}, reason: ${bug.reason}`;
43 +
      packageJSON.deprecated = row.package.deprecated ? `${row.package.deprecated} (${hotfixDeprecated})` : hotfixDeprecated;
44 +
      // don't change version
45 +
      packageJSON.version = row.package.version;
46 +
      Object.assign(row.package, packageJSON);
47 +
    }
48 +
  }
49 +
};

@@ -4,6 +4,7 @@
Loading
4 4
var utility = require('utility');
5 5
var packageService = require('../../../services/package');
6 6
var blocklistService = require('../../../services/blocklist');
7 +
var bugVersionService = require('../../../services/bug_version');
7 8
var common = require('../../../lib/common');
8 9
var SyncModuleWorker = require('../../sync_module_worker');
9 10
var config = require('../../../config');
@@ -29,27 +30,20 @@
Loading
29 30
 */
30 31
module.exports = function* list() {
31 32
  const name = this.params.name || this.params[0];
32 -
  // sync request will contain this query params
33 -
  let noCache = this.query.cache === '0';
34 -
  if (!noCache) {
35 -
    const ua = this.headers['user-agent'] || '';
36 -
    // old sync client will request with these user-agent
37 -
    if (ua.indexOf('npm_service.cnpmjs.org/') !== -1) {
38 -
      noCache = true;
39 -
    }
40 -
  }
33 +
  const isSyncWorkerRequest = common.isSyncWorkerRequest(this);
41 34
  const isJSONPRequest = this.query.callback;
42 -
  let cacheKey;
35 +
  let cacheKey = '';
43 36
  let needAbbreviatedMeta = false;
44 37
  let abbreviatedMetaType = 'application/vnd.npm.install-v1+json';
45 38
  if (config.enableAbbreviatedMetadata && this.accepts([ 'json', abbreviatedMetaType ]) === abbreviatedMetaType) {
46 39
    needAbbreviatedMeta = true;
47 -
    if (cache && !isJSONPRequest) {
40 +
    // don't cache result on sync request
41 +
    if (cache && !isJSONPRequest && !isSyncWorkerRequest) {
48 42
      cacheKey = `list-${name}-v1`;
49 43
    }
50 44
  }
51 -
52 -
  if (cacheKey && !noCache) {
45 +
  
46 +
  if (cacheKey) {
53 47
    const values = yield cache.hmget(cacheKey, 'etag', 'body');
54 48
    if (values && values[0] && values[1]) {
55 49
      this.body = values[1];
@@ -112,14 +106,14 @@
Loading
112 106
    var rows = yield packageService.listModuleAbbreviatedsByName(name);
113 107
    rows = filterBlockVerions(rows, blocks);
114 108
    if (rows.length > 0) {
115 -
      yield handleAbbreviatedMetaRequest(this, name, modifiedTime, tags, rows, cacheKey);
109 +
      yield handleAbbreviatedMetaRequest(this, name, modifiedTime, tags, rows, cacheKey, isSyncWorkerRequest);
116 110
      return;
117 111
    }
118 112
    var fullRows = yield packageService.listModulesByName(name);
119 113
    fullRows = filterBlockVerions(fullRows, blocks);
120 114
    if (fullRows.length > 0) {
121 115
      // no abbreviated meta rows, use the full meta convert to abbreviated meta
122 -
      yield handleAbbreviatedMetaRequestWithFullMeta(this, name, modifiedTime, tags, fullRows);
116 +
      yield handleAbbreviatedMetaRequestWithFullMeta(this, name, modifiedTime, tags, fullRows, isSyncWorkerRequest);
123 117
      return;
124 118
    }
125 119
  }
@@ -228,6 +222,9 @@
Loading
228 222
      createdTime = t;
229 223
    }
230 224
  }
225 +
  if (!isSyncWorkerRequest) {
226 +
    yield bugVersionService.hotfix(rows);
227 +
  }
231 228
232 229
  if (modifiedTime && createdTime) {
233 230
    var ts = {
@@ -303,8 +300,9 @@
Loading
303 300
  }
304 301
};
305 302
306 -
function* handleAbbreviatedMetaRequest(ctx, name, modifiedTime, tags, rows, cacheKey) {
307 -
  debug('show %s got %d rows, %d tags, modifiedTime: %s', name, rows.length, tags.length, modifiedTime);
303 +
function* handleAbbreviatedMetaRequest(ctx, name, modifiedTime, tags, rows, cacheKey, isSyncWorkerRequest) {
304 +
  debug('show %s got %d rows, %d tags, modifiedTime: %s, cacheKey: %s, isSyncWorkerRequest: %s',
305 +
    name, rows.length, tags.length, modifiedTime, cacheKey, isSyncWorkerRequest);
308 306
  const isJSONPRequest = ctx.query.callback;
309 307
  var latestMod = null;
310 308
  // set tags
@@ -335,6 +333,10 @@
Loading
335 333
      modifiedTime = row.gmt_modified;
336 334
    }
337 335
  }
336 +
  // don't use bug-versions hotfix on sync request
337 +
  if (!isSyncWorkerRequest) {
338 +
    yield bugVersionService.hotfix(rows);
339 +
  }
338 340
339 341
  if (!latestMod) {
340 342
    latestMod = rows[0];
@@ -388,9 +390,9 @@
Loading
388 390
  }
389 391
}
390 392
391 -
function* handleAbbreviatedMetaRequestWithFullMeta(ctx, name, modifiedTime, tags, rows) {
392 -
  debug('show %s got %d rows, %d tags',
393 -
    name, rows.length, tags.length);
393 +
function* handleAbbreviatedMetaRequestWithFullMeta(ctx, name, modifiedTime, tags, rows, isSyncWorkerRequest) {
394 +
  debug('show %s got %d rows, %d tags, isSyncWorkerRequest: %s',
395 +
    name, rows.length, tags.length, isSyncWorkerRequest);
394 396
  var latestMod = null;
395 397
  // set tags
396 398
  var distTags = {};
@@ -440,12 +442,16 @@
Loading
440 442
    common.setDownloadURL(pkg, ctx);
441 443
442 444
    versions[pkg.version] = pkg;
445 +
    row.package = pkg;
443 446
    allVersionString += pkg.version + ',';
444 447
445 448
    if ((!distTags.latest && !latestMod) || distTags.latest === pkg.version) {
446 449
      latestMod = row;
447 450
    }
448 451
  }
452 +
  if (!isSyncWorkerRequest) {
453 +
    yield bugVersionService.hotfix(rows);
454 +
  }
449 455
450 456
  if (!latestMod) {
451 457
    latestMod = rows[0];

@@ -290,6 +290,9 @@
Loading
290 290
  // enable package or package version block list, must create package_version_blocklist table in database
291 291
  enableBlockPackageVersion: false,
292 292
293 +
  // enable bug version hotfix by https://github.com/cnpm/bug-versions
294 +
  enableBugVersion: false,
295 +
293 296
  // global hook function: function* (envelope) {}
294 297
  // envelope format please see https://github.com/npm/registry/blob/master/docs/hooks/hooks-payload.md#payload
295 298
  globalHook: null,
@@ -339,6 +342,7 @@
Loading
339 342
  });
340 343
341 344
  config.enableBlockPackageVersion = true;
345 +
  config.enableBugVersion = true;
342 346
}
343 347
344 348
if (process.env.NODE_ENV !== 'test') {

@@ -128,3 +128,16 @@
Loading
128 128
    return AuthorizeType.BEARER;
129 129
  }
130 130
};
131 +
132 +
exports.isSyncWorkerRequest = function (ctx) {
133 +
  // sync request will contain this query params
134 +
  let isSyncWorkerRequest = ctx.query.cache === '0';
135 +
  if (!isSyncWorkerRequest) {
136 +
    const ua = ctx.headers['user-agent'] || '';
137 +
    // old sync client will request with these user-agent
138 +
    if (ua.indexOf('npm_service.cnpmjs.org/') !== -1) {
139 +
      isSyncWorkerRequest = true;
140 +
    }
141 +
  }
142 +
  return isSyncWorkerRequest;
143 +
};

@@ -530,7 +530,7 @@
Loading
530 530
531 531
  let realRegistry = registry;
532 532
  // get from npm, don't cache
533 -
  const packageUrl = '/' + name.replace('/', '%2f') + '?sync_timestamp=' + Date.now();
533 +
  const packageUrl = '/' + name.replace('/', '%2f') + '?cache=0&sync_timestamp=' + Date.now();
534 534
  try {
535 535
    var result = yield npmSerivce.request(packageUrl, { registry: registry });
536 536
    pkg = result.data;
@@ -1553,6 +1553,12 @@
Loading
1553 1553
  var username = this.username;
1554 1554
  var downurl = sourcePackage.dist.tarball;
1555 1555
  var urlobj = urlparse(downurl);
1556 +
  // let cnpmjs.org registry know this request send from sync worker
1557 +
  if (downurl.indexOf('?') > 0) {
1558 +
    downurl = `${downurl}&cache=0&sync_timestamp=${Date.now()}`;
1559 +
  } else {
1560 +
    downurl = `${downurl}?cache=0&sync_timestamp=${Date.now()}`;
1561 +
  }
1556 1562
  var filename = path.basename(urlobj.pathname);
1557 1563
  var filepath = common.getTarballFilepath(sourcePackage.name, sourcePackage.version, filename);
1558 1564
  var ws = fs.createWriteStream(filepath);

@@ -25,7 +25,6 @@
Loading
25 25
    filename = `${scope}/${filename}`;
26 26
  }
27 27
28 -
29 28
  var version = filename.slice(name.length + 1, -4);
30 29
  // can not get dist
31 30
  var url = null;
Files Coverage
common 67.39%
controllers 86.13%
middleware 94.34%
models 89.96%
routes 100.00%
servers 90.91%
services 91.07%
sync 89.61%
config/index.js 76.47%
lib/common.js 88.46%
Project Totals (100 files) 87.76%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading