Skip to content

Commit

Permalink
Add helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Jérémy ACHAIN committed Nov 19, 2023
1 parent a98650e commit 0586380
Show file tree
Hide file tree
Showing 36 changed files with 338 additions and 79 deletions.
8 changes: 8 additions & 0 deletions lib/helpers/array.helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { KeyValue, ValueKey } from '../models/index.js';
export declare abstract class ArrayHelper {
static sortBy<T>(array: T[], field: string): T[];
static unique<T>(array: T[]): T[];
static recordToList<T extends string, U>(record: Record<T, U>): KeyValue<string, U>[];
static listToRecord<T extends {
[K in keyof T]: string | number;
}, K extends keyof T>(array: T[], selector: K): Record<T[K], T>;
static enumToArray<V extends ValueKey = ValueKey, K extends ValueKey = ValueKey>(enumValue: Record<V, K>): KeyValue<K, V>[];
}
//# sourceMappingURL=array.helper.d.ts.map
2 changes: 1 addition & 1 deletion lib/helpers/array.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/helpers/date.helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export declare abstract class DateHelper {
static seconds(date?: Date): number;
static dayStart(date?: Date): Date;
static dayEnd(date?: Date): Date;
static calcHoursAfter(date: string | Date): number;
}
//# sourceMappingURL=date.helper.d.ts.map
2 changes: 1 addition & 1 deletion lib/helpers/date.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/helpers/document.helper.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export declare abstract class DocumentHelper {
static getTraverseChildren(elem: Element): Element[];
}
//# sourceMappingURL=document.helper.d.ts.map
1 change: 1 addition & 0 deletions lib/helpers/document.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/helpers/enum.helper.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export declare abstract class EnumHelper {
static enumToRegex(enumValue: any): RegExp;
}
//# sourceMappingURL=enum.helper.d.ts.map
1 change: 1 addition & 0 deletions lib/helpers/enum.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions lib/helpers/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './array.helper.js';
export * from './console.helper.js';
export * from './date.helper.js';
export * from './document.helper.js';
export * from './enum.helper.js';
export * from './math.helper.js';
export * from './object.helper.js';
export * from './string.helper.js';
Expand Down
2 changes: 1 addition & 1 deletion lib/helpers/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/helpers/math.helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { ValueKey } from '../models/index.js';
export declare abstract class MathHelper {
static parseInt(value: ValueKey): number;
static clamp(value: number, min: number, max: number): number;
static round(value: number, decimal?: number): number;
static floor(value: number, decimal?: number): number;
static sum(numbers: number[]): number;
static distance(lat1: number, lon1: number, lat2: number, lon2: number, unit?: string): number;
}
//# sourceMappingURL=math.helper.d.ts.map
2 changes: 1 addition & 1 deletion lib/helpers/math.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/helpers/object.helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AnyValue, GenericValueRecord } from '../models/index.js';
export declare abstract class ObjectHelper {
static hasStringIndex<T = AnyValue>(value: unknown): value is GenericValueRecord<T>;
static objectToRecord<V>(object: any): Record<string, V>;
}
//# sourceMappingURL=object.helper.d.ts.map
2 changes: 1 addition & 1 deletion lib/helpers/object.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/helpers/string.helper.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export declare abstract class StringHelper {
static stringify(value: unknown): string;
static slugify: (str?: string) => string;
}
//# sourceMappingURL=string.helper.d.ts.map
2 changes: 1 addition & 1 deletion lib/helpers/string.helper.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/index.min.mjs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/models/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './console.const.js';
export * from './console.interface.js';
export * from './key-value.interface.js';
export * from './value.const.js';
export * from './value.type.js';
//# sourceMappingURL=index.d.ts.map
2 changes: 1 addition & 1 deletion lib/models/index.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions lib/models/key-value.interface.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export declare interface KeyValue<K, V> {
key: K;
value: V;
}
//# sourceMappingURL=key-value.interface.d.ts.map
1 change: 1 addition & 0 deletions lib/models/key-value.interface.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion lib/tools/smart-map.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { ValueKey } from '../models/index.js';
import { KeyValue, ValueKey } from '../models/index.js';
export declare class SmartMap<V, K extends ValueKey = string> extends Map<K, V> {
private readonly _keys;
private readonly _values;
constructor(entries?: [K, V][]);
static fromRecord<K extends ValueKey, V>(record: Record<K, V>): SmartMap<V, K>;
static fromKeyValues<K extends ValueKey, V = string>(keyValues: KeyValue<K, V>[]): SmartMap<V, K>;
static fromEnum<E extends Record<ValueKey, any>, K = keyof E, V = E[keyof E]>(enumValue: E): SmartMap<V, string>;
get(key: K): V;
set(key: K, value: V): this;
getKeys(): K[];
getValues(): V[];
toRecord(): Record<K, V>;
toKeyValues(): KeyValue<K, V>[];
map(predicate: (value: V, index: K, indexNumber: number) => V): V[];
each(predicate: (value: V, index: K, indexNumber: number) => void): void;
find(predicate: (value: V, index: K, indexNumber: number) => boolean): V | undefined;
Expand Down
2 changes: 1 addition & 1 deletion lib/tools/smart-map.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@alkemist/smart-tools",
"version": "1.0.6",
"version": "1.1.10",
"description": "Smart tools",
"main": "lib/index.min.mjs",
"type": "module",
Expand Down
42 changes: 42 additions & 0 deletions src/helpers/array.helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
import { StringHelper } from './string.helper.js';
import { KeyValue, ValueKey } from '../models/index.js';

export abstract class ArrayHelper {
static sortBy<T>(array: T[], field: string): T[] {
return array.sort((a: any, b: any) => {
const aValue = StringHelper.slugify(a[field]!);
const bValue = StringHelper.slugify(b[field]!);
return (aValue > bValue) ? 1 : ((bValue > aValue) ? -1 : 0);
});
}

static unique<T>(array: T[]) {
return array.filter((value, index, array) => array.indexOf(value) === index)
}

static recordToList<T extends string, U>(record: Record<T, U>): KeyValue<string, U>[] {
return Object.entries<U>(record).map(([ t, u ]: [ string, U ]) => ({
key: t,
value: u as U
}));
}

static listToRecord<
T extends { [K in keyof T]: string | number },
K extends keyof T
>(array: T[], selector: K): Record<T[K], T> {
return array.reduce(
(acc, item) => {
acc[item[selector]] = item;
return acc;
}, {} as Record<T[K], T>
)
}

static enumToArray<V extends ValueKey = ValueKey, K extends ValueKey = ValueKey>(enumValue: Record<V, K>): KeyValue<K, V>[] {
// Enum is a inversed record
const values = Object.keys(enumValue) as V[];

return values.map((value: V) => {
const key = enumValue[value] as K;
return { key, value }
});
}
}
24 changes: 24 additions & 0 deletions src/helpers/date.helper.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
export abstract class DateHelper {
static seconds(date: Date = new Date()) {
return Math.round(date.getTime() / 1000);
}

static dayStart(date: Date = new Date()) {
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
return date;
}

static dayEnd(date: Date = new Date()) {
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
date.setMilliseconds(59);
return date;
}

static calcHoursAfter(date: string | Date): number {
const dateTime = (new Date()).getTime();
const lastUpdatedTime = new Date(date).getTime();
return Math.abs(Math.round((dateTime - lastUpdatedTime) / (1000 * 60 * 60)));
}
}
18 changes: 18 additions & 0 deletions src/helpers/document.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export abstract class DocumentHelper {
static getTraverseChildren(elem: Element): Element[] {
const children = [];
const elementsToCheck: Element[] = [ elem ];

while (elementsToCheck.length > 0) {
const currentElement = elementsToCheck.pop() as HTMLElement;
children.push(currentElement);

for (let i = 0; i < currentElement.children.length; i++) {
elementsToCheck.push(currentElement.children[i]);
}
}

// console.log("traverseChildren", children);
return children;
}
}
6 changes: 6 additions & 0 deletions src/helpers/enum.helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export abstract class EnumHelper {
static enumToRegex(enumValue: any): RegExp {
const keys = Object.keys(enumValue);
return new RegExp(keys.join('|'));
}
}
2 changes: 2 additions & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './array.helper.js';
export * from './console.helper.js';
export * from './date.helper.js';
export * from './document.helper.js';
export * from './enum.helper.js';
export * from './math.helper.js';
export * from './object.helper.js';
export * from './string.helper.js';
Expand Down
39 changes: 39 additions & 0 deletions src/helpers/math.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,43 @@ export abstract class MathHelper {
}
return parseInt(value);
}

static clamp(value: number, min: number, max: number) {
return Math.min(Math.max(min, value), max);
}

static round(value: number, decimal: number = 2) {
return Math.round(value * Math.pow(10, decimal)) / Math.pow(10, decimal);
}

static floor(value: number, decimal: number = 2) {
return Math.floor(value * Math.pow(10, decimal)) / Math.pow(10, decimal);
}

static sum(numbers: number[]) {
return numbers.reduce((s, c) => s + c, 0)
}

/**
* @param lat1
* @param lon1
* @param lat2
* @param lon2
* @param unit 'M' is statute miles (default), 'K' is kilometers, 'N' is nautical miles
* https://www.movable-type.co.uk/scripts/latlong.html
*/
static distance(lat1: number, lon1: number, lat2: number, lon2: number, unit = "K") {
const R = 6371e3; // metres
const φ1 = lat1 * Math.PI / 180; // φ, λ in radians
const φ2 = lat2 * Math.PI / 180;
const Δφ = (lat2 - lat1) * Math.PI / 180;
const Δλ = (lon2 - lon1) * Math.PI / 180;

const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

return R * c; // in metres
}
}
19 changes: 13 additions & 6 deletions src/helpers/object.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import { TypeHelper } from './type.helper.js';
import { AnyValue, GenericValueRecord, PrimitiveClassNames } from '../models/index.js';

export abstract class ObjectHelper {
static hasStringIndex<T = AnyValue>(value: unknown): value is GenericValueRecord<T> {
return TypeHelper.isEvaluable(value)
&& typeof value === "object"
&& [ ...PrimitiveClassNames, "Array" ]
.indexOf(TypeHelper.getPrototypeOf(value).constructor.name) === -1;
}
static hasStringIndex<T = AnyValue>(value: unknown): value is GenericValueRecord<T> {
return TypeHelper.isEvaluable(value)
&& typeof value === "object"
&& [ ...PrimitiveClassNames, "Array" ]
.indexOf(TypeHelper.getPrototypeOf(value).constructor.name) === -1;
}

static objectToRecord<V>(object: any) {
return Object.entries(object).reduce((result, [ key, value ]) => {
result[key] = value as V;
return result;
}, {} as Record<string, V>)
}
}
48 changes: 38 additions & 10 deletions src/helpers/string.helper.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
import { TypeHelper } from './type.helper.js';

export abstract class StringHelper {
static stringify(value: unknown): string {
if (TypeHelper.isEvaluable(value)) {
if (typeof value.toString !== undefined
|| TypeHelper.isSymbol(value)
) {
return value.toString();
}
return value + "";
}
return value === null ? "null" : "undefined";
static stringify(value: unknown): string {
if (TypeHelper.isEvaluable(value)) {
if (typeof value.toString !== undefined
|| TypeHelper.isSymbol(value)
) {
return value.toString();
}
return value + "";
}
return value === null ? "null" : "undefined";
}

static slugify = function (str?: string) {
if (!str) {
return '';
}

str = str.trim().replace(/^\s+|\s+$/g, '');

// Make the string lowercase
str = str.toLowerCase();

// Remove accents, swap ñ for n, etc
const from = 'ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆÍÌÎÏŇÑÓÖÒÔÕØŘŔŠŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇíìîïňñóöòôõøðřŕšťúůüùûýÿžþÞĐđßÆa·/_,:;';
const to = 'AAAAAACCCDEEEEEEEEIIIINNOOOOOORRSTUUUUUYYZaaaaaacccdeeeeeeeeiiiinnooooooorrstuuuuuyyzbBDdBAa------';
for (let i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}

// Remove invalid chars
str = str.replace(/[^a-z0-9 -]/g, '')
// Collapse whitespace and replace by -
.replace(/\s+/g, '-')
// Collapse dashes
.replace(/-+/g, '-');

return str;
};

}
Loading

0 comments on commit 0586380

Please sign in to comment.