date-fns#parse TypeScript Examples

The following examples show how to use date-fns#parse. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: queryCovid19Data.ts    From covid19-trend-map with Apache License 2.0 6 votes vote down vote up
getBiggestWeeklyIncrease = (data: Covid19CasesByTimeFeature[]) => {
    let featureWithBiggestWeeklyIncrease = data[0];
    let biggestWeeklyIncrease = Number.NEGATIVE_INFINITY;

    const dateForFirstFeature = parse(
        data[0].attributes.dt,
        'yyyy-MM-dd',
        new Date()
    );

    const dayForFirstFeature = getISODay(dateForFirstFeature);

    for (let i = 0, len = data.length; i < len; i++) {
        let dayOfWeek = (i % 7) + dayForFirstFeature;

        dayOfWeek = dayOfWeek > 7 ? dayOfWeek - 7 : dayOfWeek;

        if (dayOfWeek === 1) {
            const { Confirmed } = data[i].attributes;

            const feature7DaysAgo = i - 6 >= 0 ? data[i - 6] : data[0];

            const weeklyIncrease =
                Confirmed - feature7DaysAgo.attributes.Confirmed;

            if (weeklyIncrease > biggestWeeklyIncrease) {
                biggestWeeklyIncrease = weeklyIncrease;
                featureWithBiggestWeeklyIncrease = data[i];
            }
        }
    }

    const dateWithBiggestWeeklyIncrease =
        featureWithBiggestWeeklyIncrease.attributes.dt; //parse(featureWithBiggestWeeklyIncrease.attributes.dt, 'yyyy-MM-dd', new Date())

    return dateWithBiggestWeeklyIncrease; //format(dateWithBiggestWeeklyIncrease, 'MMMM dd, yyyy');
}
Example #2
Source File: make-monthly-stat.ts    From merged-pr-stat with MIT License 6 votes vote down vote up
async function main(): Promise<void> {
  program.requiredOption("--start <yyyy/MM>").requiredOption("--end <yyyy/MM>").requiredOption("--query <query>");

  program.parse(process.argv);

  const startDate = parse(program.start, "yyyy/MM", new Date());
  const endDate = parse(program.end, "yyyy/MM", new Date());
  const query = program.query as string;

  const allStats = [];
  for (let start = startDate; start <= endDate; start = addMonths(start, 1)) {
    const end = add(start, { months: 1, seconds: -1 });
    console.error(format(start, "yyyy-MM-dd HH:mm:ss"));
    console.error(format(end, "yyyy-MM-dd HH:mm:ss"));

    const stdout = execFileSync(
      "merged-pr-stat",
      ["--start", start.toISOString(), "--end", end.toISOString(), "--query", query],
      { encoding: "utf8" }
    );
    const result = {
      startDate: format(start, "yyyy-MM-dd HH:mm:ss"),
      endDate: format(end, "yyyy-MM-dd HH:mm:ss"),
      ...JSON.parse(stdout),
    };
    allStats.push(result);
  }
  process.stdout.write(csvStringify(allStats, { header: true }));
}
Example #3
Source File: ngx-mat-datefns-date-adapter.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
parse(value: any, parseFormat: any): Date | null {
    if (value) {
      if (typeof value === 'string') {
        if (this.options?.useUtc) {
          const d = parse(value.trim(), parseFormat, new Date(), {
            locale: this._dateFnsLocale,
          });
          return zonedTimeToUtc(d, UTC_TIMEZONE);
        }
        return parse(value.trim(), parseFormat, new Date(), {
          locale: this._dateFnsLocale,
        });
      }
      if (typeof value === 'number') {
        return toDate(value);
      }
      if (value instanceof Date) {
        return this.clone(value as Date);
      }
      return null;
    }
    return null;
  }
Example #4
Source File: Result.ts    From covid19-graphql with MIT License 6 votes vote down vote up
resolvers: ResultResolvers = {
  date(parent, { format: dateFormat }) {
    if (!dateFormat) {
      return parent.date
    } else {
      return format(parse(parent.date, "yyyy-M-d", new Date()), dateFormat)
    }
  }
}
Example #5
Source File: dateUtils.tsx    From symphony-ui-toolkit with Apache License 2.0 6 votes vote down vote up
export function autocompleteDate(value: string, format: string, locale: Locale): Date {
  if (!value) {
    return null;
  }
  const date = parse(value, format, new Date(), { locale: locale });
  // If year not typed, take the current year
  if (!isValid(date)) {
    // regex: remove -yyyy, yyyy-, /yyyy, yyyy/, .yyyy, ...
    const autocompletedDate = parse(
      value,
      format.replace(/[\W]?y{4}[\W]?/, ''),
      new Date(),
      {
        locale: locale,
      }
    );
    return autocompletedDate;
  }
  return date;
}
Example #6
Source File: CashGraphService.ts    From cashcash-desktop with MIT License 6 votes vote down vote up
private formatExternalTooltip(
        params: object | any[],
        accountMap: Map<number, CashAccount>,
        currencyMap: Map<number, CashCurrency>,
        useOriginalCurrency: boolean = false,
        merged: boolean = false,
    ): string {
        const amountField = useOriginalCurrency ? 'originalAmount' : 'amount';
        const currencyField = useOriginalCurrency ? 'originalCurrencyId' : 'currencyId';
        let output: string = '';
        if (Array.isArray(params)) {
            if (params.length > 0) {
                const dateParsed = parse(
                    params[0].data.transactionDate,
                    'yyyy-MM',
                    DateUtils.newDate(),
                );
                const dateString = DateUtils.formatHumanMonth(dateParsed);
                const dateStringWithUpperCase = StringUtils.toUpperCaseFirstLetter(dateString);
                output += `<strong>${dateStringWithUpperCase}</strong> : <br/>`;
            }
            for (const param of params.sort((a, b) => b.data[amountField] - a.data[amountField])) {
                const item: GraphSplit = param.data;
                if (item[amountField] !== 0) {
                    const account: CashAccount = accountMap.get(+item.accountId)!;
                    const accountName = merged ? '' : account.name;
                    const amountString = PrintUtils.printAmount(
                        '' + item[amountField],
                        +item[currencyField],
                        currencyMap,
                    );
                    output += `${param.marker} ${StringUtils.escapeHtml(
                        accountName,
                    )} ${amountString}<br/>`;
                }
            }
        }
        return output;
    }
Example #7
Source File: health-kit-helper.spec.ts    From nyxo-app with GNU General Public License v3.0 6 votes vote down vote up
expectedNight: Night = {
  id: 'test-id-1234',
  sourceId: 'nyxo',
  sourceName: 'nyxo',
  value: Value.InBed,
  startDate: parse(
    '2020-04-12 01:00:00 +0300',
    'yyyy-MM-dd kk:mm:SS XX',
    new Date()
  ).toISOString(),
  endDate: parse(
    '2020-04-12 08:00:00 +0300',
    'yyyy-MM-dd kk:mm:SS XX',
    new Date()
  ).toISOString(),
  totalDuration: 420
}
Example #8
Source File: time.ts    From nyxo-app with GNU General Public License v3.0 6 votes vote down vote up
getTitle = (): { title: string; subtitle: string } => {
  const timeFormat = 'HH:mm:ss'
  const now = new Date()
  if (
    isWithinInterval(now, {
      start: parse('04:00:00', timeFormat, new Date()),
      end: parse('11:59:59', timeFormat, new Date())
    })
  ) {
    return { title: 'Good Morning', subtitle: 'MORNING_SUBTITLE' }
  }
  if (
    isWithinInterval(now, {
      start: parse('12:00:00', timeFormat, new Date()),
      end: parse('16:59:59', timeFormat, new Date())
    })
  ) {
    return { title: 'Good Afternoon', subtitle: 'AFTERNOON_SUBTITLE' }
  }
  if (
    isWithinInterval(now, {
      start: parse('17:00:00', timeFormat, new Date()),
      end: parse('20:59:59', timeFormat, new Date())
    })
  ) {
    return { title: 'Good Evening', subtitle: 'EVENING_SUBTITLE' }
  }
  return { title: 'Good Night', subtitle: 'NIGHT_SUBTITLE' }
}
Example #9
Source File: index.tsx    From firetable with Apache License 2.0 6 votes vote down vote up
config: IFieldConfig = {
  type: FieldType.date,
  name: "Date",
  dataType: "firebase.firestore.Timestamp",
  initialValue: null,
  initializable: true,
  icon: <DateIcon />,
  description:
    "Date displayed and input by default as YYYY/MM/DD or input using a picker module.",
  TableCell: withHeavyCell(BasicCell, TableCell),
  TableEditor: NullEditor,
  SideDrawerField,
  settings: Settings,
  csvImportParser: (value, config) =>
    parse(value, config?.format ?? DATE_FORMAT, new Date()),
  csvExportFormatter: (value: any, config?: any) =>
    format(value.toDate(), config?.format ?? DATE_FORMAT),
}
Example #10
Source File: WeekTimeline.tsx    From life-calendar with MIT License 5 votes vote down vote up
parseDate = (dateStr: string) => parse(dateStr, 'yyyy-MM-dd', new Date())
Example #11
Source File: index.ts    From react-native-scroll-bottom-sheet with MIT License 5 votes vote down vote up
createMockData = () => {
  const elementsByDate: {
    [key: string]: ListItemData[];
  } = {};
  const today = new Date();
  Array.from({ length: 200 }).forEach((_, index) => {
    const date = format(
      subDays(today, generateRandomIntFromInterval(0, 30)),
      'yyyy LL d'
    );
    const amount = (generateRandomIntFromInterval(100, 10000) / 100).toFixed(2);
    const randomEntry = {
      id: String(index),
      title: Faker.commerce.productName(),
      subtitle: Faker.commerce.productMaterial(),
      amount,
      iconColor: `rgb(${generateRandomIntFromInterval(
        0,
        255
      )}, ${generateRandomIntFromInterval(
        0,
        255
      )}, ${generateRandomIntFromInterval(0, 255)})`,
    };
    if (Array.isArray(elementsByDate[date])) {
      elementsByDate[date].push(randomEntry);
    } else {
      elementsByDate[date] = [randomEntry];
    }
  });

  return Object.entries(elementsByDate)
    .map(([key, data]) => ({
      title: key,
      data,
    }))
    .sort((a, b) => {
      return (
        parse(b.title, 'yyyy LL d', new Date()).getTime() -
        parse(a.title, 'yyyy LL d', new Date()).getTime()
      );
    })
    .map(item => ({
      ...item,
      title: format(parse(item.title, 'yyyy LL d', new Date()), 'ccc d MMM'),
    }));
}
Example #12
Source File: EditForm.tsx    From frontend with MIT License 5 votes vote down vote up
parseDateString = (value: string, originalValue: string) => {
  const parsedDate = isDate(originalValue)
    ? originalValue
    : parse(originalValue, formatString, new Date())

  return parsedDate
}
Example #13
Source File: CreateForm.tsx    From frontend with MIT License 5 votes vote down vote up
parseDateString = (value: string, originalValue: string) => {
  const parsedDate = isDate(originalValue)
    ? originalValue
    : parse(originalValue, formatString, new Date())

  return parsedDate
}
Example #14
Source File: CampaignForm.tsx    From frontend with MIT License 5 votes vote down vote up
parseDateString = (value: string, originalValue: string) => {
  const parsedDate = isDate(originalValue)
    ? originalValue
    : parse(originalValue, formatString, new Date())

  return parsedDate
}
Example #15
Source File: UpdateBirthdayModal.tsx    From frontend with MIT License 5 votes vote down vote up
parseDateString = (value: string, originalValue: string) => {
  const parsedDate = isDate(originalValue)
    ? originalValue
    : parse(originalValue, formatString, new Date())

  return parsedDate
}
Example #16
Source File: dates.ts    From office-booker with MIT License 5 votes vote down vote up
dateStartOfWeek = (date: string) => {
  const start = startOfWeek(parse(date, 'yyyy-MM-dd', new Date()), { weekStartsOn: 1 });
  const adjustedToUTC = subMinutes(start, start.getTimezoneOffset());
  return format(adjustedToUTC, 'yyyy-MM-dd');
}
Example #17
Source File: dategrid.test.ts    From calendar-hack with MIT License 5 votes vote down vote up
dparse = (s: string) => parse(s, 'MM/dd/yyyy', new Date())
Example #18
Source File: CashGraphService.ts    From cashcash-desktop with MIT License 5 votes vote down vote up
private formatInOutTooltip(
        params: object | any[],
        accountMap: Map<number, CashAccount>,
        currencyMap: Map<number, CashCurrency>,
        useOriginalCurrency: boolean = false,
        merged: boolean = false,
    ): string {
        const amountField = useOriginalCurrency ? 'originalAmount' : 'amount';
        const currencyField = useOriginalCurrency ? 'originalCurrencyId' : 'currencyId';
        let output: string = '';
        if (Array.isArray(params)) {
            if (params.length > 0) {
                const dateParsed = parse(
                    params[0].data.transactionDate,
                    'yyyy-MM',
                    DateUtils.newDate(),
                );
                const dateString = DateUtils.formatHumanMonth(dateParsed);
                const dateStringWithUpperCase = StringUtils.toUpperCaseFirstLetter(dateString);
                output += `<strong>${dateStringWithUpperCase}</strong> : <br/>`;
            }
            let deltaAmount = 0;
            let deltaCurrencyId = 0;
            for (const param of params) {
                const item: GraphSplit = param.data;
                const accountName = param.seriesName;
                const amountString = PrintUtils.printAmount(
                    '' + item[amountField],
                    +item[currencyField],
                    currencyMap,
                );
                if (accountName === InOutType.IN) {
                    deltaAmount += item[amountField];
                } else {
                    deltaAmount -= item[amountField];
                }
                deltaCurrencyId = item[currencyField];
                // tslint:disable-next-line:max-line-length
                output += `${param.marker} ${StringUtils.escapeHtml(
                    i18n.t(accountName).toString(),
                )} ${amountString}<br/>`;
            }
            const deltaString = PrintUtils.printAmount(
                '' + deltaAmount,
                +deltaCurrencyId,
                currencyMap,
            );
            output += `Delta ${deltaString}<br/>`;
        }
        return output;
    }
Example #19
Source File: Datepicker.tsx    From atlas with GNU General Public License v3.0 5 votes vote down vote up
DatepickerComponent: React.ForwardRefRenderFunction<HTMLInputElement, DatepickerProps> = (
  { name, value, required, error, disabled, helperText, onChange, onBlur },
  ref
) => {
  const [rawValue, setRawValue] = useState<string>()

  useEffect(() => {
    if (value && isValid(value)) {
      setRawValue(format(value, DATE_FORMAT))
    } else if (!value) {
      setRawValue('')
    }
  }, [value])

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value
    setRawValue(value)

    const parsedDate = value ? parse(e.target.value, DATE_FORMAT, new Date()) : null
    onChange(parsedDate)
  }

  return (
    <NumberFormat
      value={rawValue}
      getInputRef={ref}
      customInput={TextField}
      name={name}
      format="##/##/####"
      placeholder="DD / MM / YYYY"
      mask={['D', 'D', 'M', 'M', 'Y', 'Y', 'Y', 'Y']}
      helperText={helperText}
      error={error}
      required={required}
      disabled={disabled}
      onChange={handleChange}
      onBlur={onBlur}
    />
  )
}
Example #20
Source File: TimeUtils.ts    From UUI with MIT License 5 votes vote down vote up
export function tryParseTimeFromString(dateString: string) {
  const result = parse(dateString, DEFAULT_TIME_FORMAT_TOKEN, getZeroDate())
  if (isNaN(result.getTime())) throw new Error('time_string_parse_failed');
  return result
}
Example #21
Source File: DateUtils.ts    From UUI with MIT License 5 votes vote down vote up
export function tryParseDateFromString(dateString: string) {
  const result = parse(dateString, DEFAULT_DATE_FORMAT_TOKEN, getZeroDate())
  if (isNaN(result.getTime())) throw new Error('date_string_parse_failed');
  return result
}
Example #22
Source File: DateTimeUtils.ts    From UUI with MIT License 5 votes vote down vote up
export function tryParseDateTimeFromString(dateString: string) {
  const result = parse(dateString, DEFAULT_DATETIME_FORMAT_TOKEN, getZeroDate())
  if (isNaN(result.getTime())) throw new Error('date_string_parse_failed');
  return result
}
Example #23
Source File: createBooking.ts    From office-booker with MIT License 4 votes vote down vote up
createBooking = async (
  config: Config,
  currentUser: User,
  request: CreateBooking | RestoreBooking
): Promise<Booking> => {
  const isAuthorised =
    request.user === currentUser.email ||
    currentUser.permissions.canManageAllBookings ||
    currentUser.permissions.officesCanManageBookingsFor.find(
      (office) => office.id === request.office.id
    ) !== undefined;

  if (!isAuthorised) {
    throw new Forbidden();
  }

  const parsed = parse(request.date, 'yyyy-MM-dd', new Date());
  if (Number.isNaN(parsed.getTime())) {
    throw new HttpError({
      internalMessage: `Invalid date format: ${request.date}`,
      status: 400,
      httpMessage: 'Invalid date format',
    });
  }

  if (!getAvailableDates(config).includes(request.date)) {
    throw new HttpError({
      internalMessage: `Date out of range: ${request.date}`,
      status: 400,
      httpMessage: 'Date out of range',
    });
  }

  const requestedOffice = config.officeQuotas.find((office) => office.id === request.office.id);
  if (!requestedOffice) {
    throw new HttpError({
      internalMessage: `Office not found: ${request.office}`,
      status: 400,
      httpMessage: 'Office not found',
    });
  }

  const configureSendNotification = async () => {
    const { fromAddress, notificationToAddress, reasonToBookRequired } = config;
    if (!notificationToAddress) {
      return async () => {};
    }

    //get the user from db
    const dbUser = await getUser(config, request.user.toLocaleLowerCase());
    if (dbUser.autoApproved) {
      return async () => {};
    }

    if (fromAddress === undefined) {
      throw Error(`Missing required env parameters for reason notifications: FROM_ADDRESS`);
    }
    if (reasonToBookRequired && !request.reasonToBook) {
      throw new HttpError({
        httpMessage: `Invalid reason to book given`,
        status: 400,
        internalMessage: `No reason to book provided`,
      });
    }
    const reasonToBook = request.reasonToBook ? request.reasonToBook : 'No reason provided';
    return async () => {
      if (config.env !== 'test') {
        await sendNotificationEmail(
          notificationToAddress,
          fromAddress,
          request.date,
          request.user,
          requestedOffice.name,
          reasonToBook
        );
      }
    };
  };

  const sendNotificationIfRequired = await configureSendNotification();

  // Id date as a direct string
  const id = requestedOffice.id + '_' + request.date.replace(/-/gi, '');
  const newBooking = <BookingsModel>{
    id,
    parking: request.parking ?? false,
    officeId: requestedOffice.id,
    date: request.date,
    user: request.user,
    ...('created' in request ? { id: request.id, created: request.created } : {}),
  };

  const userEmail = newBooking.user.toLocaleLowerCase();
  const startOfWeek = dateStartOfWeek(newBooking.date);

  const officeBookings = await getOfficeBookings(config, requestedOffice.name, [newBooking.date]);
  const isQuotaExceeded = officeBookings[0]?.bookingCount >= requestedOffice.quota;
  const isParkingExceeded =
    newBooking.parking && officeBookings[0]?.parkingCount >= requestedOffice.parkingQuota;
  if (isQuotaExceeded || isParkingExceeded) {
    const whichExceeded =
      isQuotaExceeded && isParkingExceeded
        ? 'Office and parking quota'
        : isQuotaExceeded
        ? 'Office quota'
        : 'Office parking quota';
    throw new HttpError({
      internalMessage: `${whichExceeded} has exceeded for ${requestedOffice.name} on date: ${newBooking.date}`,
      status: 409,
      httpMessage: `${whichExceeded} exceeded`,
    });
  }

  audit('1:IncrementingOfficeBookingCount', { newBooking, startOfWeek, currentUser });
  const officeBookedSuccessfully = await incrementOfficeBookingCount(
    config,
    requestedOffice,
    newBooking.date,
    newBooking.parking
  );

  if (!officeBookedSuccessfully) {
    const parkingInternalMessageAddition = newBooking.parking
      ? ` or parking quota of ${requestedOffice.parkingQuota}`
      : '';
    const parkingMessageAddition = newBooking.parking ? ` or parking quota` : '';

    throw new HttpError({
      internalMessage: `Office quota of ${requestedOffice.quota}${parkingInternalMessageAddition} has exceeded for ${requestedOffice.name} on date: ${newBooking.date}`,
      status: 409,
      httpMessage: `Office quota${parkingMessageAddition} exceeded`,
    });
  }

  audit('2:IncrementingUserBookingCount');
  const dbUser = await getUser(config, userEmail);
  const userBookedSuccessfully = await incrementUserBookingCount(
    config,
    userEmail,
    dbUser.quota,
    startOfWeek
  );

  if (!userBookedSuccessfully) {
    audit('2.1:DecrementingOfficeBookingCount');
    await decrementOfficeBookingCount(
      config,
      requestedOffice.id,
      newBooking.date,
      newBooking.parking
    );
    throw new HttpError({
      internalMessage: `User quota of ${dbUser.quota} has exceeded for ${userEmail} on date: ${newBooking.date}`,
      status: 409,

      httpMessage: 'User quota exceeded',
    });
  }

  audit('3:CreatingBooking');
  const createdBooking = await dbCreate(config, newBooking);
  if (createdBooking === undefined) {
    try {
      audit('3.1:DecremetingUserBookingCount');
      await decrementUserBookingCount(config, newBooking.user, startOfWeek);
      audit('3.1:DecremetingOfficeBookingCount');
      await decrementOfficeBookingCount(
        config,
        requestedOffice.id,
        newBooking.date,
        newBooking.parking
      );
      throw new HttpError({
        internalMessage: `Duplicate booking found for ${userEmail} on date: ${newBooking.date}`,
        status: 409,
        httpMessage: `Can't have multiple bookings per day`,
      });
    } catch (err) {
      if (err instanceof HttpError) {
        throw err;
      }
      throw new HttpError({
        internalMessage: `Failed while rollowing back duplicate booking found for ${userEmail} on date: ${newBooking.date}\n${err.message}`,
        level: 'ERROR',
        status: 409,
        httpMessage: `Can't have multiple bookings per day`,
      });
    }
  }

  audit('4:Completed');
  await sendNotificationIfRequired();
  return mapBooking(config, createdBooking);
}
Example #24
Source File: app.ts    From office-booker with MIT License 4 votes vote down vote up
configureApp = (config: Config) => {
  const getAuthUser = (res: Response) => getUser(config, getAuthUserEmail(res));
  const validateEmail = (email: string) => {
    if (config.validEmailMatch !== undefined && !config.validEmailMatch.test(email)) return false;
    if (!isValidEmail(email)) return false;
    return true;
  };

  const normaliseEmail = (email: string) =>
    config.caseSensitiveEmail === true ? email : email.toLocaleLowerCase();

  const app = express();
  app.use(express.urlencoded({ extended: true }));
  app.use(express.json());
  if (config.env !== 'test') {
    app.use(morgan('combined'));
  }

  app.use(async (req, res, next) => {
    res.locals.env = config.env;
    next();
  });

  if (config.env !== 'local' && config.env !== 'test') {
    app.set('trust proxy', true);
  }

  app.get('/api/config', (req, res, next) => {
    try {
      const clientConfig = {
        version: '2.1.0',
        showTestBanner: config.showTestBanner,
        auth:
          config.authConfig.type === 'cognito'
            ? {
                type: 'cognito',
                region: config.authConfig.region,
                userPoolId: config.authConfig.cognitoUserPoolId,
                webClientId: config.authConfig.cognitoClientId,
              }
            : { type: 'test' },
        emailRegex: config.validEmailMatch?.source,
        advancedBookingDays: config.advanceBookingDays,
        reasonToBookRequired: config.reasonToBookRequired,
      };
      return res.set('Cache-Control', 'public, max-age=3600').json(clientConfig);
    } catch (err) {
      return next(err);
    }
  });

  app.post('/api/selftest', async (req, res, next) => {
    try {
      if (config.selfTestKey === undefined || config.selfTestKey.length < 20) {
        throw new NotFound('Self test key not set or less than 20 characters');
      }
      if (config.selfTestUser === undefined || !validateEmail(config.selfTestUser)) {
        throw new NotFound('Self test user not set or not a valid email address');
      }
      if (req.headers.bearer !== config.selfTestKey) {
        throw new Forbidden(`Incorrect self-test key`);
      }
      const testUserEmail = normaliseEmail(config.selfTestUser);
      const office = getOffice(config, config.officeQuotas[0].id);
      const user = await getUser(config, testUserEmail);
      const bookings = mapBookings(config, await getUserBookings(config, testUserEmail));
      return res.json({ office, user, bookings });
    } catch (error) {
      return next(error);
    }
  });

  app.use((req, res, next) => {
    if (config.readonly) {
      if (req.method === 'GET' || req.method === 'OPTIONS' || req.method === 'HEAD') {
        return next();
      } else {
        return next(
          new HttpError({ httpMessage: 'Service currently in read-only mode', status: 503 })
        );
      }
    }
    return next();
  });

  app.post('/api/users', async (req, res, next) => {
    try {
      const body = req.body;
      if (!isRegisterBody(body)) {
        throw new HttpError({ httpMessage: 'Bad Request', status: 400 });
      }
      const normalisedEmail = normaliseEmail(body.email);
      if (!isValidEmail(normalisedEmail)) {
        throw new HttpError({ httpMessage: 'Email not valid', status: 400 });
      }
      await registerUser(config, normalisedEmail);
      return res.sendStatus(204);
    } catch (err) {
      return next(err);
    }
  });

  configureAuth(config, app);

  app.get('/api/offices', async (_req, res, next) => {
    try {
      return res.json(config.officeQuotas);
    } catch (err) {
      return next(err);
    }
  });

  app.get('/api/offices/:officeId', async (req, res, next) => {
    try {
      const officeId = req.params.officeId;
      const office = await getOffice(config, officeId);
      return res.json(office);
    } catch (err) {
      return next(err);
    }
  });

  app.get('/api/users', async (req, res, next) => {
    try {
      const quota = req.query.quota?.toString();
      const role: string | undefined = req.query?.role?.toString();
      const filterQuota = quota?.toLocaleLowerCase() === 'custom';
      const autoApproved = req.query?.autoApproved?.toString() === 'true';
      const emailPrefix = req.query.emailPrefix?.toString().toLowerCase();
      const paginationToken = req.query.paginationToken?.toString();
      const authUser = await getAuthUser(res);
      if (!authUser.permissions.canViewUsers) {
        throw new Forbidden(`${authUser.email} attempted to list users`);
      }
      const users = await queryUsers(config, {
        customQuota: filterQuota,
        roleName: role,
        emailPrefix,
        autoApproved,
        paginationToken,
      });
      return res.json(users);
    } catch (err) {
      return next(err);
    }
  });

  app.get('/api/users/:email', async (req, res, next) => {
    try {
      // Anyone can fetch themselves.
      // Admins can fetch anyone.
      const userEmail = normaliseEmail(req.params.email);
      if (!validateEmail(userEmail)) {
        throw new NotFound(`Not a valid email address: ${userEmail}`);
      }
      const authUser = await getAuthUser(res);
      if (userEmail !== authUser.email && !authUser.permissions.canViewUsers) {
        throw new Forbidden(`${authUser.email} attempted to get another user`);
      }
      const userState = await getUser(config, userEmail);
      return res.json(userState);
    } catch (err) {
      return next(err);
    }
  });

  app.put('/api/users/:email', async (req, res, next) => {
    try {
      const userEmail = normaliseEmail(req.params.email);
      if (!validateEmail(userEmail)) {
        throw new NotFound(`Not a valid email address: ${userEmail}`);
      }
      const putBody = req.body;
      if (!isPutUserBody(putBody)) {
        throw new HttpError({ httpMessage: 'Bad Request', status: 400 });
      }
      const authUser = await getAuthUser(res);
      if (!authUser.permissions.canEditUsers) {
        throw new Forbidden(`${authUser.email} is not a system admin`);
      }

      const updatedUser = await putUser(config, authUser, userEmail, putBody);
      return res.json(updatedUser);
    } catch (err) {
      return next(err);
    }
  });

  app.get('/api/bookings', async (req, res, next) => {
    try {
      const parseEmail = (): { email?: string } => {
        const userEmail = req.query.user as unknown;
        if (typeof userEmail === 'undefined') {
          return {};
        }
        if (typeof userEmail !== 'string') {
          throw new HttpError({ httpMessage: 'Invalid email type', status: 400 });
        }
        const email = normaliseEmail(userEmail);
        if (!validateEmail(email)) {
          throw new HttpError({ httpMessage: 'Invalid email', status: 400 });
        }
        return { email };
      };

      const parseOffice = (): { office?: OfficeQuota } => {
        const officeQuery = req.query.office as unknown;
        if (typeof officeQuery === 'undefined') {
          return {};
        }
        if (typeof officeQuery !== 'string') {
          throw new HttpError({ httpMessage: 'Invalid office type', status: 400 });
        }
        const office = config.officeQuotas.find((o) => o.id === officeQuery);
        if (office === undefined) {
          throw new HttpError({ httpMessage: 'Unknown office query', status: 400 });
        }
        return { office };
      };

      const parseDate = (): { date?: string } => {
        const date = req.query.date as unknown;
        if (typeof date === 'undefined') {
          return {};
        }
        if (typeof date !== 'string') {
          throw new HttpError({ httpMessage: 'Invalid date type', status: 400 });
        }
        const parsedDate = parse(date, 'yyyy-MM-dd', new Date());
        if (Number.isNaN(parsedDate.getTime())) {
          throw new HttpError({ httpMessage: 'Invalid date', status: 400 });
        }
        return { date };
      };

      const parsedQuery = { ...parseEmail(), ...parseOffice(), ...parseDate() };

      const authUser = await getAuthUser(res);

      const bookings = await queryBookings(config, authUser, parsedQuery);
      return res.json(bookings);
    } catch (err) {
      return next(err);
    }
  });

  app.post('/api/bookings/', async (req, res, next) => {
    try {
      const newBooking = req.body;
      if (!isCreateBooking(newBooking)) {
        throw new HttpError({ httpMessage: `Bad request body`, status: 400 });
      }
      if (!validateEmail(newBooking.user)) {
        throw new HttpError({ httpMessage: `Invalid user email address`, status: 400 });
      }
      newBooking.user = normaliseEmail(newBooking.user);
      const authUser = await getAuthUser(res);
      const result = await createBooking(config, authUser, {
        date: newBooking.date,
        office: newBooking.office,
        user: newBooking.user,
        parking: newBooking.parking,
        reasonToBook: newBooking.reasonToBook,
      });
      return res.json(result);
    } catch (err) {
      return next(err);
    }
  });

  app.delete('/api/bookings/:id', async (req, res, next) => {
    try {
      const userQuery = req.query.user as unknown;
      const bookingId = req.params.id;
      const userEmail = (() => {
        switch (typeof userQuery) {
          case 'string':
            return normaliseEmail(userQuery);
          case 'undefined':
            return undefined;
          default:
            throw new HttpError({ httpMessage: 'Bad request', status: 400 });
        }
      })();
      if (userEmail !== undefined && !validateEmail(userEmail)) {
        throw new HttpError({ httpMessage: 'Bad request - invalid email', status: 400 });
      }

      const authUser = await getAuthUser(res);

      await deleteBooking(config, authUser, {
        id: bookingId,
        email: userEmail ?? authUser.email,
      });
      return res.sendStatus(204);
    } catch (err) {
      return next(err);
    }
  });

  app.get('/api/stats', async (req, res) => {
    const authUser = await getAuthUser(res);
    if (!authUser.permissions.canViewAdminPanel) {
      throw new Unauthorized();
    }

    const stats = await getStats(config, authUser);
    return res.json(stats);
  });

  app.all('/api/*', (req, res) => {
    return res.status(404).json({
      message: 'Not Found',
    });
  });

  app.use((error: Error, req: Request, res: Response, _next: NextFunction) => {
    if (error instanceof HttpError) {
      return errorResponse(req, res, {
        body: { message: error.httpMessage },
        status: error.status,
        error,
        level: error.level,
      });
    }
    // todo: get env to check for prod deploy
    return errorResponse(req, res, {
      error,
      body: { message: 'Something went wrong. We are looking into it.' },
    });
  });

  return app;
}
Example #25
Source File: WeekTimeline.tsx    From life-calendar with MIT License 4 votes vote down vote up
transformData = (data: any = { events: [] }) => {
  const _data = JSON.parse(JSON.stringify(data));

  let firstEvent: any = {
    ...DefaultData.events[0],
    _date: parseDate(DefaultData.events[0].date)
  }; // default 1st event (as the "base" event)
  _data.events = _data.events || [];

  // for each item, calculate and append more properties:
  _data.events = _data.events.map((item: any, idx: number) => {
    item._date = parseDate(item.date);
    if (idx === 0) {
      firstEvent = { ...item };
      item._weekNum = 0;
    } else {
      item._weekNum = differenceInWeeks(item._date, firstEvent._date);
    }
    return item;
  });
  // append "Today" to the _data.events (as the last event)
  const now = new Date();
  _data.events.push({
    title: `Today`,
    type: 0,
    date: format(now, 'yyyy-MM-dd'),
    _date: now,
    _weekNum: differenceInWeeks(now, firstEvent._date)
  });

  const firstYear = getYear(firstEvent._date);
  let markedWeeks = []; // highlighted boxes - [0, 52, 104, ...] for 90 years
  let weeks = 0;
  for (let i = 0; i < 90; i += 1) {
    const year = firstYear + i;
    weeks = weeks + (isLeapYear(year) ? 52.28571 : 52.14286);

    let markedWeek = Math.round(weeks);
    // adjust for better alignment (because of Math.round and leap years)
    markedWeek++;
    if (
      [
        4,
        5,
        6,
        11,
        12,
        13,
        18,
        19,
        20,
        25,
        26,
        27,
        32,
        33,
        34,
        39,
        40,
        41,
        46,
        47,
        48,
        53,
        54,
        55,
        60,
        61,
        62,
        67,
        68,
        69,
        74,
        75,
        76,
        81,
        82,
        83,
        88,
        89,
        90
      ].indexOf(i + 1) >= 0
    ) {
      markedWeek = markedWeek - 1;
    }
    markedWeeks.push(markedWeek); // TODO: rounding leads to inaccurate box position
  }
  // console.log('markedWeeks', markedWeeks);

  return [_data, markedWeeks];
}
Example #26
Source File: type_transformation.ts    From Deep-Lynx with MIT License 4 votes vote down vote up
// convertValue will return a Conversion on successful or unsuccessful conversion, and null
    // on values that need no conversion
    static convertValue(dataType: string, value: any, date_conversion_format?: string): Conversion | null {
        if (typeof value === 'undefined' || value === null || value === 'null') {
            return new Conversion({original_value: value, errors: 'unable to convert value, value is null or undefined'});
        }

        switch (dataType) {
            case 'number': {
                if (typeof value === 'number') {
                    return null;
                }

                const convertedValue = parseInt(value, 10);
                if (isNaN(convertedValue)) {
                    return new Conversion({original_value: value, errors: 'unable to convert value to number'});
                }

                return convertedValue % 1 === 0
                    ? new Conversion({original_value: value, converted_value: Math.floor(convertedValue)})
                    : new Conversion({original_value: value, converted_value: convertedValue});
            }

            case 'float': {
                if (typeof value === 'number') {
                    return null;
                }

                const convertedValue = parseFloat(value);
                if (isNaN(convertedValue)) {
                    return new Conversion({original_value: value, errors: 'unable to convert value to float'});
                }

                return convertedValue % 1 === 0
                    ? new Conversion({original_value: value, converted_value: Math.floor(convertedValue)})
                    : new Conversion({original_value: value, converted_value: convertedValue});
            }

            case 'number64': {
                if (typeof value === 'string') {
                    return null;
                }

                return new Conversion({original_value: value, converted_value: String(value)});
            }

            case 'float64': {
                if (typeof value === 'string') {
                    return null;
                }

                return new Conversion({original_value: value, converted_value: String(value)});
            }

            // because dates can be formatted in various ways, all we can really do for conversion is to
            // set it to string - Deep Lynx only checks to see if dates are strings currently
            case 'date': {
                if (value instanceof Date) {
                    return new Conversion({original_value: value, converted_value: value.toISOString()});
                }

                // if it's a number we assume we're dealing with unix time
                if (typeof value === 'number') {
                    return new Conversion({original_value: value, converted_value: toDate(value).toISOString()});
                }

                if (typeof value === 'string') {
                    try {
                        const convertedDate = date_conversion_format ? parse(value, date_conversion_format, new Date()) : new Date(value);
                        return new Conversion({original_value: value, converted_value: convertedDate.toISOString()});
                    } catch (e) {
                        return new Conversion({original_value: value, errors: `unable to convert value to date using format string: ${e}`});
                    }
                }

                return new Conversion({original_value: value, errors: 'unable to convert value to date, value is not string or number'});
            }

            case 'string': {
                if (typeof value === 'string') {
                    return null;
                }

                return new Conversion({original_value: value, converted_value: String(value)});
            }

            case 'boolean': {
                if (typeof value === 'boolean') {
                    return null;
                }

                if (typeof value === 'string') {
                    return new Conversion({
                        original_value: value,
                        converted_value: value.includes('true') || value.includes('TRUE') || value.includes('True') || value.includes('1'),
                    });
                }

                // only 1 dictates true here
                if (typeof value === 'number') {
                    const converted_value = value === 1;
                    return new Conversion({original_value: value, converted_value});
                }

                // anything else dictates failure
                return new Conversion({original_value: value, errors: 'unable to convert boolean, must be a boolean, string, or number to attempt conversion'});
            }

            // enumerations are currently string only values
            case 'enumeration': {
                if (typeof value === 'string') {
                    return null;
                }
                return new Conversion({original_value: value, converted_value: String(value)});
            }

            // files are generally filenames or URLs - as such, convert to string
            case 'file': {
                if (typeof value === 'string') {
                    return null;
                }
                return new Conversion({original_value: value, converted_value: String(value)});
            }

            case 'list': {
                if (Array.isArray(value)) {
                    return null;
                }
                return new Conversion({original_value: value, converted_value: [value]});
            }

            // covers the "unknown" type where no conversion is necessary
            default: {
                return null;
            }
        }
    }
Example #27
Source File: CashGraphService.ts    From cashcash-desktop with MIT License 4 votes vote down vote up
async generateActivityGraph(
        parameters: TransactionParameters,
        splitList: GraphSplitExtended[],
        accountMap: Map<number, CashAccount>,
        currencyMap: Map<number, CashCurrency>,
    ): Promise<EChartOption> {
        // Filter
        const graphSplitList = GraphUtils.keepOneTransaction(splitList);
        let activitySplitList = GraphUtils.convertToActivitySplit(graphSplitList);
        activitySplitList = GraphUtils.reduceByDay(activitySplitList);

        const serieListTemplate = {
            type: 'heatmap',
            coordinateSystem: 'calendar',
            itemStyle: {
                normal: {
                    color: '#ddb926',
                },
            },
            label: {
                normal: {
                    show: true,
                    formatter: '{b}',
                },
            },
        };

        const calendarTemplate: EChartOption.Calendar = {
            width: '80%',
            left: 'center',
            range: [
                DateUtils.formatDate(parameters.transactionDateFrom!),
                DateUtils.formatDate(parameters.transactionDateTo!),
            ],
            splitLine: {
                show: true,
                lineStyle: {
                    color: '#c1c1c1',
                    width: 1,
                    type: 'solid',
                },
            },
            itemStyle: {
                borderWidth: 5,
                borderColor: '#fff',
            },
            yearLabel: {
                formatter: isSameYear(
                    parameters.transactionDateFrom!,
                    parameters.transactionDateTo!,
                )
                    ? '{start}'
                    : '{start} - {end}',
            },
            dayLabel: {
                align: 'right',
                firstDay: 1, // start on Monday
                nameMap: i18n.locale === 'en' ? 'en' : ['D', 'L', 'M', 'M', 'J', 'V', 'S'],
            },
        };

        const visualMapTemplate: EChartOption.VisualMap = {
            calculable: true,
            orient: 'horizontal',
            left: 'center',
            textStyle: {
                color: '#000',
                fontWeight: 'bold',
            },
            realtime: false,
        };
        return {
            series: [
                {
                    ...serieListTemplate,
                    calendarIndex: 0,
                    name: 'by amount',
                    data: activitySplitList.map((o) => [o.stringTransactionDate, o.amount]),
                },
                {
                    ...serieListTemplate,
                    calendarIndex: 1,
                    name: 'by nb of transactions',
                    data: activitySplitList.map((o) => [
                        o.stringTransactionDate,
                        o.nbOfTransactions,
                    ]),
                },
            ],
            tooltip: {
                position: 'top',
                formatter: (p: any) => {
                    const value =
                        p.seriesName === 'by amount'
                            ? PrintUtils.printAmount(
                                  '' + p.data[1],
                                  +activitySplitList[0].currencyId,
                                  currencyMap,
                              )
                            : p.data[1];
                    const dateParsed = parse(p.data[0], 'yyyy-MM-dd', new Date());
                    const dateString = DateUtils.formatHumanDate(dateParsed);
                    const dateStringWithUpperCase = StringUtils.toUpperCaseFirstLetter(dateString);
                    return dateStringWithUpperCase + ': ' + value;
                },
            },
            visualMap: [
                {
                    ...visualMapTemplate,
                    top: 20,
                    seriesIndex: 0,
                    max:
                        activitySplitList.length > 0
                            ? _.maxBy(activitySplitList, (o) => o.amount)!.amount
                            : 0,
                    text: ['', i18n.t('Amount per day').toString()],
                    formatter:
                        activitySplitList.length > 0
                            ? '{value}' + currencyMap.get(splitList[0].currencyId)!.symbol
                            : '{value}',
                },
                {
                    ...visualMapTemplate,
                    top: 270,
                    seriesIndex: 1,
                    max:
                        activitySplitList.length > 0
                            ? _.maxBy(activitySplitList, (o) => o.nbOfTransactions)!
                                  .nbOfTransactions
                            : 0,
                    text: ['', i18n.t('Number of transactions per day').toString()],
                },
            ],
            calendar: [
                {
                    ...calendarTemplate,
                    top: 90,
                },
                {
                    ...calendarTemplate,
                    top: 340,
                },
            ],
            color: GraphUtils.getDefaultColorPalette(),
        };
    }