import { Injectable } from '@nestjs/common'; import { Request } from 'express'; @Injectable() export class FormUtilityService { public emailRegex = /^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z0-9](-*\.?[a-zA-Z0-9])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/; public passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\w\W]{8,}$/; public usernameRegex = /^[a-zA-Z0-9_\-.]{3,26}$/; /** * Merge array of objects into single object * @param flash Array of objects * @returns Merged object */ public mergeObjectArray(flash: Record[]): Record { return flash.reduce>( (obj, item) => ({ ...obj, ...item }), {}, ); } /** * Trim values of specified keys of an object * @param entry Object * @param fields Fields to strip spaces from * @returns Object with trimmed values */ public trimmed(entry: T, fields: string[]): T { return fields.reduce( (object, key) => ({ ...object, [key]: object[key]?.trim() }), entry, ); } /** * Strip keys from an object * @param object Object to strip * @param keys Keys to strip from the object * @returns Stripped object */ public stripObject(object: T, keys: string[]): T { return keys.reduce((obj, field) => { delete obj[field]; return obj; }, object); } /** * Pluck keys from an object * @param object Object to pluck * @param keys Keys to pluck from the object * @returns Plucked object */ public pluckObject(object: T, keys: string[]): Partial { return Object.keys(object).reduce>((obj, field) => { if (keys.includes(field)) { obj[field] = object[field]; } return obj; }, {}); } /** * Strip keys from an object array * @param array Object array to strip * @param keys Keys to strip from the object array * @returns Stripped object */ public stripObjectArray(array: T[], keys: string[]): T[] { return array.map((object) => this.stripObject(object, keys)); } /** * Pluck keys from an object array * @param array Object array to pluck * @param keys Keys to pluck from the object array * @returns Plucked object */ public pluckObjectArray(array: T[], keys: string[]): Partial[] { return array.map((object) => this.pluckObject(object, keys)); } /** * Include CSRF token, messages and prefilled form values for a template with a form * @param req Express request * @param additional Additional data to pass * @returns Template locals */ public populateTemplate( req: Request, additional: Record = {}, ): Record { const message = req.flash('message')[0] || {}; const form = this.mergeObjectArray( (req.flash('form') as Record[]) || [], ); return { path: req.originalUrl, csrf: req.csrfToken(), message, form, ...additional, }; } }