verdaccio一些api

之前搭建了一个私有NPM来管理组内的一些依赖包,今天无意中看到了一些verdaccio的请求,搜了下网上,好像没有文章说明,那就自己动手扒一扒……

获取所有可见列表

2021-03-12T06:43:12.png

代码:src\api\web\endpoint\package.ts

route.get('/packages', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
  storage.getLocalDatabase(async function(err, packages): Promise<void> {
    if (err) {
      throw err;
    }

    async function processPackages(packages: PackcageExt[] = []): Promise<any> {
      const permissions: PackcageExt[] = [];
      const packgesCopy = packages.slice();
      for (const pkg of packgesCopy) {
        const pkgCopy = { ...pkg };
        pkgCopy.author = formatAuthor(pkg.author);
        try {
          if (await checkAllow(pkg.name, req.remote_user)) {
            if (config.web) {
              pkgCopy.author.avatar = generateGravatarUrl(pkgCopy.author.email, config.web.gravatar);
            }
            if (!_.isNil(pkgCopy.dist) && !_.isNull(pkgCopy.dist.tarball)) {
              pkgCopy.dist.tarball = getLocalRegistryTarballUri(pkgCopy.dist.tarball, pkg.name, req, config.url_prefix);
            }
            permissions.push(pkgCopy);
          }
        } catch (err) {
          logger.logger.error({ name: pkg.name, error: err }, 'permission process for @{name} has failed: @{error}');
          throw err;
        }
      }

      return permissions;
    }

    const { web } = config;
    // @ts-ignore
    const order: boolean = config.web ? getOrder(web.sort_packages) : true;

    next(sortByName(await processPackages(packages), order));
  });
});

获取依赖信息

2021-03-12T06:40:02.png

代码:src\api\web\endpoint\package.ts

route.get('/sidebar/(@:scope/)?:package', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
  const packageName: string = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;

  storage.getPackage({
    name: packageName,
    uplinksLook: true,
    keepUpLinkData: true,
    req,
    callback: function(err: Error, info: $SidebarPackage): void {
      if (_.isNil(err)) {
        const {v} = req.query;
        let sideBarInfo: any = _.clone(info);
        sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(info, req, config.url_prefix).versions;
        if (isVersionValid(info, v)) {
          // @ts-ignore
          sideBarInfo.latest = sideBarInfo.versions[v];
          sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
          } else {
            sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest];
            if (sideBarInfo?.latest) {
              sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author);
            } else {
              res.status(HTTP_STATUS.NOT_FOUND);
              res.end();
              return;
            }
          }
          sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo);
          if (config.web) {
            sideBarInfo = addGravatarSupport(sideBarInfo, config.web.gravatar);
          } else {
            sideBarInfo = addGravatarSupport(sideBarInfo);
          }
          next(sideBarInfo);
        } else {
          res.status(HTTP_STATUS.NOT_FOUND);
          res.end();
        }
      }
  });
});

获取依赖的README

2021-03-12T06:51:39.png

代码:src\api\web\endpoint\package.ts

route.get('/package/readme/(@:scope/)?:package/:version?', can('access'), function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
  const packageName = req.params.scope ? addScope(req.params.scope, req.params.package) : req.params.package;

  storage.getPackage({
    name: packageName,
    uplinksLook: true,
    req,
    callback: function(err, info): void {
      if (err) {
        return next(err);
      }

      res.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.TEXT_PLAIN);
      next(parseReadme(info.name, info.readme));
    },
  });
});

搜索依赖包

2021-03-12T06:55:26.png

代码:src\api\web\endpoint\search.ts

route.get('/search/:anything', function(req: $RequestExtend, res: $ResponseExtend, next: $NextFunctionVer): void {
  const results: any = Search.query(req.params.anything);
  // FUTURE: figure out here the correct type
  const packages: any[] = [];

  const getPackageInfo = function(i): void {
    storage.getPackage({
      name: results[i].ref,
      uplinksLook: false,
      callback: (err, entry: Package): void => {
        if (!err && entry) {
          auth.allow_access({ packageName: entry.name }, req.remote_user, function(err, allowed): void {
            if (err || !allowed) {
              return;
            }

            packages.push(entry.versions[entry[DIST_TAGS].latest]);
          });
        }

        if (i >= results.length - 1) {
          next(packages);
        } else {
          getPackageInfo(i + 1);
        }
      },
    });
  };

  if (results.length) {
    getPackageInfo(0);
  } else {
    next([]);
  }
});

已有 3 条评论

  1. 回复

    羡慕会技术的大佬,像我不会的只能仰望了。

    1. 王叨叨 王叨叨 [作者]
      回复

      打开调试工具,一点一点就找到了

  2. 回复

    对新手太有用了

添加新评论