blob: 680e4e345afa7c8c4c64422f65aa508a967b8a05 [file] [log] [blame]
import { OffsetUnits } from './enums';
import { IssueEvent } from './types';
/**
* Format a string array into a list
* @param strArray string array
* @returns string that represents a list
*
* @example
* > toListStr(['a', 'b'])
* - a
* - b
*/
export function formatStrArray(strArray: (string | undefined)[]): string {
if (strArray.length === 0) {
return '';
}
return strArray.map(s => `- ${s}`).join('\n') + '\n';
}
/**
* Validate an enum value
* @param name name of the variable to check
* @param val value to check
* @param enumObj enum object
*
* @example
* > enum CD {
* C = 'c',
* D = 'd',
* }
* > validateEnums('a', 'b', CD)
* Uncaught Error: `a` must be one of ['c', 'd'], but got 'b'
*/
export function validateEnum<T>(
name: T,
val: T,
enumObj: { [key: string]: T },
): never | void {
const values = Object.values(enumObj);
if (!values.includes(val)) {
const wrap = (s: T): string => `'${s}'`;
const joined = values.map(wrap).join(', ');
throw new Error(
`\`${name}\` must be one of [${joined}], but got ${wrap(val)}`,
);
}
}
/**
* Parse a offset string
* @param offset offset string (e.g. '1M')
* @returns [value, unit]
*
* @example
* > parseOffsetString('1M')
* [ 1, 'M' ]
*/
export function parseOffsetString(offsetStr: string): [number, OffsetUnits] {
const chars = Object.values(OffsetUnits).join('');
const pattern = `^(\\d+)([${chars}])$`;
const m = new RegExp(pattern).exec(offsetStr);
if (m === null) {
throw Error(`"${offsetStr}" doesn't match "${pattern}"`);
}
const value = parseInt(m[1] as string);
const unit = m[2] as OffsetUnits;
return [value, unit];
}
/**
* Get a offset date
* @param date base date
* @param value time value
* @param unit time unit (must be one of ['H', 'D', 'M'])
* @returns offset date
*
* @example
* > const d = new Date('2020-10-10T10:10:10.000Z')
* > getOffsetDate(d, '1H').toISOString()
* '2020-10-10T09:10:10.000Z'
*
* > getOffsetDate(d, '1D').toISOString()
* '2020-10-09T10:10:10.000Z'
*
* > getOffsetDate(d, '1M').toISOString()
* '2020-09-10T10:10:10.000Z'
*/
export function getOffsetDate(
date: Date,
value: number,
unit: OffsetUnits,
): never | Date {
const copied = new Date(date);
switch (unit) {
case OffsetUnits.HOUR: {
copied.setHours(copied.getHours() - value);
return copied;
}
case OffsetUnits.DAY: {
copied.setDate(copied.getDate() - value);
return copied;
}
case OffsetUnits.MONTH: {
copied.setMonth(copied.getMonth() - value);
return copied;
}
default: {
throw Error('Should not reach here');
}
}
}
/**
* Check if a given event is a label event
* @param event issue event
* @returns true if `event` is a label event otherwise false
*/
export function isLabelEvent(event: IssueEvent): boolean {
return ['labeled', 'unlabeled'].includes(event.event);
}
/**
* Check if a given event is created by a user
* @param event issue event
* @returns true if a given event is created by a user otherwise false
*/
export function isCreatedByUser(event: IssueEvent): boolean {
return event.actor.login === 'pr-bot-test';
}
/**
* Remove duplicates in an array
* @param array array that may contain duplicates
* @returns unique array
*/
export function removeDuplicates<T>(array: T[]): T[] {
return [...new Set(array)];
}