Skip to content

Commit 2656323

Browse files
committed
feat: Enhance keys and toPlainAndCrush functions with detailed JSDoc comments for improved documentation
1 parent d510734 commit 2656323

File tree

2 files changed

+131
-13
lines changed

2 files changed

+131
-13
lines changed

apps/api/src/_common/functions/is-cli.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'node:path'
22
import { Abstract, DynamicModule, ForwardReference, Provider, Type } from '@nestjs/common'
3+
import { isArray } from 'radash'
34

45
/**
56
* Vérifie si le point d'entrée actuel est le mode console.
@@ -69,7 +70,7 @@ export function useOnCli<
6970
| (string | symbol | Function | Provider | DynamicModule | Promise<DynamicModule> | ForwardReference<any> | Abstract<any>),
7071
>(items: T | T[]): T[] {
7172
if (isConsoleEntrypoint()) {
72-
return items instanceof Array ? items : [items]
73+
return isArray(items) ? items : [items]
7374
}
7475
return []
7576
}
Lines changed: 129 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,144 @@
1-
import { objectify, isObject, isArray, get } from 'radash';
2-
import { ClassTransformOptions, instanceToPlain } from 'class-transformer';
1+
import { objectify, isObject, isArray, get } from 'radash'
2+
import { ClassTransformOptions, instanceToPlain } from 'class-transformer'
33

4+
/**
5+
* Extrait récursivement tous les chemins de propriétés d'un objet sous forme de notation à points.
6+
*
7+
* Parcourt un objet ou tableau de manière récursive pour générer la liste complète
8+
* des chemins d'accès aux propriétés en notation pointée (ex: "user.address.city").
9+
*
10+
* @template TValue Type de l'objet à analyser
11+
* @param {TValue} value - Objet dont extraire les chemins de propriétés
12+
* @returns {string[]} Tableau des chemins en notation pointée
13+
*
14+
* @description
15+
* Comportement selon le type de données :
16+
* - Objet : Parcourt récursivement toutes les propriétés
17+
* - Tableau de primitives : Retourne les chemins sans indices
18+
* - Tableau d'objets : Inclut les indices numériques dans les chemins
19+
* - Valeur primitive : Retourne le chemin complet
20+
* - Valeur nulle/undefined : Retourne un tableau vide
21+
*
22+
* @example
23+
* ```typescript
24+
* const data = {
25+
* user: {
26+
* name: 'John',
27+
* address: {
28+
* city: 'Paris',
29+
* zip: '75001'
30+
* }
31+
* },
32+
* tags: ['admin', 'user']
33+
* };
34+
*
35+
* const paths = keys(data);
36+
* // Retourne: [
37+
* // 'user.name',
38+
* // 'user.address.city',
39+
* // 'user.address.zip',
40+
* // 'tags'
41+
* // ]
42+
*
43+
* const arrayData = {
44+
* items: [
45+
* { id: 1, name: 'Item 1' },
46+
* { id: 2, name: 'Item 2' }
47+
* ]
48+
* };
49+
*
50+
* const arrayPaths = keys(arrayData);
51+
* // Retourne: [
52+
* // 'items.0.id',
53+
* // 'items.0.name',
54+
* // 'items.1.id',
55+
* // 'items.1.name'
56+
* // ]
57+
* ```
58+
*/
459
export const keys = <TValue extends object>(value: TValue): string[] => {
5-
if (!value) return [];
60+
if (!value) return []
61+
662
const getKeys = (nested: any, paths: string[]): string[] => {
763
if (isObject(nested)) {
8-
return Object.entries(nested).flatMap(([k, v]) => getKeys(v, [...paths, k]));
64+
return Object.entries(nested).flatMap(([k, v]) => getKeys(v, [...paths, k]))
965
}
66+
1067
if (isArray(nested)) {
1168
if (nested.length > 0 && ['string', 'number', 'boolean'].includes(typeof nested[0])) {
12-
return nested.flatMap((item) => getKeys(item, paths));
69+
return nested.flatMap((item) => getKeys(item, paths))
1370
}
14-
return nested.flatMap((item, i) => getKeys(item, [...paths, `${i}`]));
71+
72+
return nested.flatMap((item, i) => getKeys(item, [...paths, `${i}`]))
1573
}
16-
return [paths.join('.')];
17-
};
18-
return getKeys(value, []);
19-
};
2074

75+
return [paths.join('.')]
76+
}
77+
78+
return getKeys(value, [])
79+
}
80+
81+
/**
82+
* Convertit un objet ou une instance de classe en objet plat avec notation pointée.
83+
*
84+
* Cette fonction transforme d'abord l'objet en plain object (via class-transformer),
85+
* puis "écrase" la structure imbriquée en un objet plat où les clés utilisent
86+
* la notation à points pour représenter les chemins d'accès.
87+
*
88+
* @template TValue Type de l'objet à transformer
89+
* @param {TValue} value - Objet ou instance de classe à aplatir
90+
* @param {ClassTransformOptions} [options] - Options de transformation class-transformer
91+
* @returns {object} Objet plat avec clés en notation pointée
92+
*
93+
* @description
94+
* Processus de transformation :
95+
* 1. Conversion de l'instance en plain object (supprime les méthodes, applique @Expose/@Exclude)
96+
* 2. Extraction de tous les chemins de propriétés
97+
* 3. Création d'un nouvel objet avec clés en notation pointée
98+
*
99+
* Cas d'usage typiques :
100+
* - Préparation de données pour des systèmes de recherche
101+
* - Export de données en format CSV/Excel
102+
* - Indexation dans des bases de données NoSQL
103+
* - Comparaison de structures complexes
104+
*
105+
* @example
106+
* ```typescript
107+
* class User {
108+
* name: string;
109+
* address: {
110+
* city: string;
111+
* zip: string;
112+
* };
113+
* }
114+
*
115+
* const user = new User();
116+
* user.name = 'John Doe';
117+
* user.address = { city: 'Paris', zip: '75001' };
118+
*
119+
* const flat = toPlainAndCrush(user);
120+
* // Retourne: {
121+
* // 'name': 'John Doe',
122+
* // 'address.city': 'Paris',
123+
* // 'address.zip': '75001'
124+
* // }
125+
*
126+
* // Avec options class-transformer
127+
* const flatExcluded = toPlainAndCrush(user, {
128+
* excludeExtraneousValues: true
129+
* });
130+
*
131+
* // Utilisation pour la recherche
132+
* const searchIndex = toPlainAndCrush(complexObject);
133+
* Object.entries(searchIndex).forEach(([key, value]) => {
134+
* indexer.add(key, value);
135+
* });
136+
* ```
137+
*/
21138
export const toPlainAndCrush = <TValue extends object>(value: TValue, options?: ClassTransformOptions): object => {
22139
return objectify(
23140
keys(instanceToPlain(value, options)),
24141
(k) => k,
25142
(k) => get(value, k),
26-
);
27-
};
143+
)
144+
}

0 commit comments

Comments
 (0)