UNPKG

bananareporter

Version:

Easily generate a report from multiple sources

142 lines (141 loc) 6.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GithubIntegration = exports.GithubConfig = void 0; const base_1 = require("./base"); // import {Axios} from 'axios' const common_1 = require("../util/common"); const zod_1 = require("zod"); const axios_1 = require("axios"); const dayjs = require("dayjs"); const logger_1 = require("../util/logger"); const objectPath = require("object-path"); exports.GithubConfig = zod_1.z.object({ committerUsername: zod_1.z.string().min(1), /** * needed only if you want to access commits * made to private repositories */ token: zod_1.z.string().min(1).optional(), filters: zod_1.z.array(zod_1.z.object({ on: zod_1.z.string().min(1), regex: zod_1.z.string().min(1), })).nonempty().optional(), domain: zod_1.z.string().optional().default('api.github.com'), apiVersion: zod_1.z.string().startsWith('2').optional().default('2022-11-28'), protocol: zod_1.z.union([zod_1.z.literal('http'), zod_1.z.literal('https')]).optional().default('https'), // TODO should be extended from a base integration from: common_1.zIsoString.optional(), to: common_1.zIsoString.optional(), delay: zod_1.z.number().min(0).optional(), }); class GithubIntegration extends base_1.IntegrationBase { constructor(_rawConfig, bananaReporterConfig) { var _a, _b, _c; super(_rawConfig, bananaReporterConfig); logger_1.logger.debug('github integration'); this.config = exports.GithubConfig.parse(_rawConfig); logger_1.logger.debug('github integration config', this.config); this.bananaReporterConfig = bananaReporterConfig; this.delayToUse = (_a = this.config.delay) !== null && _a !== void 0 ? _a : this.bananaReporterConfig.delay; logger_1.logger.debug(`github integration delayToUse ${this.delayToUse}`); this.dateRange = { from: (_b = this.config.from) !== null && _b !== void 0 ? _b : this.bananaReporterConfig.from, to: (_c = this.config.to) !== null && _c !== void 0 ? _c : this.bananaReporterConfig.to, }; logger_1.logger.debug('github integration dateRange', this.dateRange); const baseURL = `${this.config.protocol}://${this.config.domain}`; logger_1.logger.debug(`github integration baseURL ${baseURL}`); this.httpClient = axios_1.default.create({ baseURL, headers: { Authorization: this.config.token ? `Bearer ${this.config.token}` : undefined, 'X-GitHub-Api-Version': this.config.apiVersion, Accept: 'application/vnd.github+json', }, timeout: 35000, }); } async httpRequest(path, config) { logger_1.logger.debug(`github integration http request ${path}`, config); const res = await this.httpClient(path, { ...config, }); return res.data; } async fetchData() { let page = 1; let commitList = []; while (page > 0) { logger_1.logger.debug(`github integration working on ${page}`); /* eslint-disable no-await-in-loop */ const commits = await this.getUserCommits(this.config.committerUsername, { from: this.dateRange.from, to: this.dateRange.to, page, }); // no more data, break loop if (commits.items.length === 0) { logger_1.logger.debug('github integration no more commits to process'); break; } // eslint-disable-next-line unicorn/prefer-spread commitList = commitList.concat(commits.items); logger_1.logger.debug(`github integration commitList ${commitList.length} (added ${commits.items.length} commits)`); page += 1; await (0, common_1.delay)(this.delayToUse); } // format data to common obj for (const filter of this.config.filters || []) { const targetKey = filter.on; commitList = commitList.filter(c => { const regex = new RegExp(filter.regex); const value = objectPath.get(c, targetKey); if (typeof value === 'undefined') { const errorMsg = `while filtering commit ${c.sha} unable to find the key ${targetKey} in the commit's object (available keys: ${Object.keys(c).join(',')})`; logger_1.logger.error(errorMsg); throw new Error(errorMsg); } return regex.test(value); }); } const formattedData = commitList.map(e => this.toBananaReporterObj(e)); return formattedData; } async getUserCommits(username, options) { var _a; const fromDate = dayjs(options.from); const toDate = dayjs(options.to); const from = fromDate.format('YYYY-MM-DD'); const to = toDate.format('YYYY-MM-DD'); logger_1.logger.debug(`github integration getUserCommits from ${from} to ${to}`); const page = (_a = options.page) !== null && _a !== void 0 ? _a : 1; const url = '/search/commits'; const commits = await this.httpRequest(url, { params: { q: `committer:${username} committer-date:${from}..${to}`, sort: 'asc', // eslint-disable-next-line camelcase per_page: 100, page, }, }); return commits; } toBananaReporterObj(rawData) { const projectId = rawData.repository.id; const projectName = rawData.repository.name; const description = `${rawData.commit.message} git:${rawData.sha.slice(0, 7)}`; return { id: rawData.sha, date: rawData.commit.committer.date, username: rawData.commit.committer.name, description, projectId: String(projectId), projectName, type: GithubIntegration.type, __raw: this.bananaReporterConfig.includeRawObject ? rawData : undefined, }; } } exports.GithubIntegration = GithubIntegration; GithubIntegration.type = base_1.SourceType.Enum.github;