Merge branch 'main' into aggregation

This commit is contained in:
rijkvanzanten
2021-06-11 21:00:02 -04:00
3 changed files with 106 additions and 1 deletions

View File

@@ -0,0 +1,95 @@
import {
addYears,
subWeeks,
subYears,
addWeeks,
subMonths,
addMonths,
subDays,
addDays,
subHours,
addHours,
subMinutes,
addMinutes,
subSeconds,
addSeconds,
addMilliseconds,
subMilliseconds,
} from 'date-fns';
import { clone } from 'lodash';
/**
* Adjust a given date by a given change in duration. The adjustment value uses the exact same syntax
* and logic as Vercel's `ms`.
*
* The conversion is lifted straight from `ms`.
*/
export function adjustDate(date: Date, adjustment: string) {
date = clone(date);
const subtract = adjustment.startsWith('-');
if (subtract || adjustment.startsWith('+')) {
adjustment = adjustment.substring(1);
}
const match =
/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|months?|mth|mo|years?|yrs?|y)?$/i.exec(
adjustment
);
if (!match) {
return;
}
const amount = parseFloat(match[1]);
const type = (match[2] || 'days').toLowerCase();
switch (type) {
case 'years':
case 'year':
case 'yrs':
case 'yr':
case 'y':
return subtract ? subYears(date, amount) : addYears(date, amount);
case 'months':
case 'month':
case 'mth':
case 'mo':
return subtract ? subMonths(date, amount) : addMonths(date, amount);
case 'weeks':
case 'week':
case 'w':
return subtract ? subWeeks(date, amount) : addWeeks(date, amount);
case 'days':
case 'day':
case 'd':
return subtract ? subDays(date, amount) : addDays(date, amount);
case 'hours':
case 'hour':
case 'hrs':
case 'hr':
case 'h':
return subtract ? subHours(date, amount) : addHours(date, amount);
case 'minutes':
case 'minute':
case 'mins':
case 'min':
case 'm':
return subtract ? subMinutes(date, amount) : addMinutes(date, amount);
case 'seconds':
case 'second':
case 'secs':
case 'sec':
case 's':
return subtract ? subSeconds(date, amount) : addSeconds(date, amount);
case 'milliseconds':
case 'millisecond':
case 'msecs':
case 'msec':
case 'ms':
return subtract ? subMilliseconds(date, amount) : addMilliseconds(date, amount);
default:
return undefined;
}
}

View File

@@ -1,5 +1,6 @@
import { Accountability, Filter } from '../types';
import { toArray } from '../utils/to-array';
import { adjustDate } from './adjust-date';
import { deepMap } from './deep-map';
export function parseFilter(filter: Filter, accountability: Accountability | null): any {
@@ -13,7 +14,14 @@ export function parseFilter(filter: Filter, accountability: Accountability | nul
else return toArray(val);
}
if (val === '$NOW') return new Date();
if (val.startsWith('$NOW')) {
if (val.includes('(') && val.includes(')')) {
const adjustment = val.match(/\(([^)]+)\)/)?.[1];
return adjustDate(new Date(), adjustment);
}
return new Date();
}
if (val === '$CURRENT_USER') return accountability?.user || null;
if (val === '$CURRENT_ROLE') return accountability?.role || null;

View File

@@ -138,3 +138,5 @@ In addition to static values, you can also filter against _dynamic_ values using
- `$CURRENT_USER` — The primary key of the currently authenticated user
- `$CURRENT_ROLE` — The primary key of the role for the currently authenticated user
- `$NOW` — The current timestamp
- `$NOW(<adjustment>)` - The current timestamp plus/minus a given distance, for example `$NOW(-1 year)`,
`$NOW(+2 hours)`