express5-valid 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +314 -0
  2. package/dist/arg-error.d.mts +12 -0
  3. package/dist/arg-error.d.ts +12 -0
  4. package/dist/arg-error.d.ts.map +1 -0
  5. package/dist/index.d.mts +11 -0
  6. package/dist/index.d.ts +11 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +884 -0
  9. package/dist/index.js.map +7 -0
  10. package/dist/index.mjs +851 -0
  11. package/dist/index.mjs.map +7 -0
  12. package/dist/middleware.d.mts +10 -0
  13. package/dist/middleware.d.ts +10 -0
  14. package/dist/middleware.d.ts.map +1 -0
  15. package/dist/router.d.mts +14 -0
  16. package/dist/router.d.ts +14 -0
  17. package/dist/router.d.ts.map +1 -0
  18. package/dist/types.d.mts +17 -0
  19. package/dist/types.d.ts +17 -0
  20. package/dist/types.d.ts.map +1 -0
  21. package/dist/valid-array.d.mts +28 -0
  22. package/dist/valid-array.d.ts +28 -0
  23. package/dist/valid-array.d.ts.map +1 -0
  24. package/dist/valid-base.d.mts +20 -0
  25. package/dist/valid-base.d.ts +20 -0
  26. package/dist/valid-base.d.ts.map +1 -0
  27. package/dist/valid-boolean.d.mts +14 -0
  28. package/dist/valid-boolean.d.ts +14 -0
  29. package/dist/valid-boolean.d.ts.map +1 -0
  30. package/dist/valid-date.d.mts +22 -0
  31. package/dist/valid-date.d.ts +22 -0
  32. package/dist/valid-date.d.ts.map +1 -0
  33. package/dist/valid-enum.d.mts +15 -0
  34. package/dist/valid-enum.d.ts +15 -0
  35. package/dist/valid-enum.d.ts.map +1 -0
  36. package/dist/valid-error-handler.d.mts +4 -0
  37. package/dist/valid-error-handler.d.ts +4 -0
  38. package/dist/valid-error-handler.d.ts.map +1 -0
  39. package/dist/valid-number.d.mts +27 -0
  40. package/dist/valid-number.d.ts +27 -0
  41. package/dist/valid-number.d.ts.map +1 -0
  42. package/dist/valid-object.d.mts +16 -0
  43. package/dist/valid-object.d.ts +16 -0
  44. package/dist/valid-object.d.ts.map +1 -0
  45. package/dist/valid-string.d.mts +32 -0
  46. package/dist/valid-string.d.ts +32 -0
  47. package/dist/valid-string.d.ts.map +1 -0
  48. package/package.json +70 -0
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # express5-valid
2
+
3
+ Librairie de validation type-safe pour Express.js 5.0+
4
+
5
+ Compatible Node.js 18+
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install express5-valid express@^5.0.0
11
+ ```
12
+
13
+ ## Publication npm
14
+
15
+ Checklist minimale avant de publier :
16
+
17
+ ```bash
18
+ npm whoami
19
+ npm run prepublishOnly
20
+ npm pack --dry-run
21
+ ```
22
+
23
+ Publication :
24
+
25
+ ```bash
26
+ npm version patch
27
+ npm publish
28
+ ```
29
+
30
+ Si le nom du package est déjà pris sur npm, il faudra le renommer dans package.json avant publication.
31
+
32
+ ## Configuration
33
+
34
+ ```typescript
35
+ import express from 'express';
36
+ import { validMiddleware, validErrorHandler } from 'express5-valid';
37
+
38
+ const app = express();
39
+ app.use(express.json());
40
+ app.use(validMiddleware); // Doit être ajouté avant les routes
41
+
42
+ // Vos routes ici
43
+
44
+ app.use(validErrorHandler); // Le gestionnaire d'erreurs doit être en dernier
45
+ app.listen(3000);
46
+ ```
47
+
48
+ ### Utilisation avec JsonRouter (optionnel)
49
+
50
+ ```typescript
51
+ import { createJsonRouter } from 'express5-valid';
52
+
53
+ const api = createJsonRouter();
54
+ api.post('/users', handler);
55
+ app.use(api.router);
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Types de Validation
61
+
62
+ ### String
63
+
64
+ Accès : `body('field').string` ou `params('field').string`
65
+
66
+ | Paramètre | Type | Description |
67
+ |-----------|------|-------------|
68
+ | `.required` | getter | Le champ est obligatoire |
69
+ | `.nullable` | getter | Autorise les valeurs null |
70
+ | `.default(value)` | method | Valeur par défaut si undefined |
71
+ | `.minLength(n)` | method | Longueur minimale |
72
+ | `.maxLength(n)` | method | Longueur maximale |
73
+ | `.pattern(regex)` | method | Validation par expression régulière |
74
+ | `.email` | getter | Valide le format email |
75
+ | `.url` | getter | Valide le format URL (http/https) |
76
+ | `.trim` | getter | Supprime les espaces |
77
+ | `.lowercase` | getter | Convertit en minuscules |
78
+ | `.uppercase` | getter | Convertit en majuscules |
79
+ | `.oneOf(values)` | method | Doit être dans la liste de valeurs |
80
+ | `.value` | getter | Extrait la valeur validée |
81
+
82
+ **Exemple :**
83
+ ```typescript
84
+ const name = body('name').string.required.trim.minLength(2).maxLength(50).value;
85
+ const email = body('email').string.email.value;
86
+ ```
87
+
88
+ ---
89
+
90
+ ### Number
91
+
92
+ Accès : `body('field').number` ou `params('field').number`
93
+
94
+ | Paramètre | Type | Description |
95
+ |-----------|------|-------------|
96
+ | `.required` | getter | Le champ est obligatoire |
97
+ | `.nullable` | getter | Autorise les valeurs null |
98
+ | `.default(value)` | method | Valeur par défaut si undefined |
99
+ | `.min(n)` | method | Valeur minimale (inclusive) |
100
+ | `.max(n)` | method | Valeur maximale (inclusive) |
101
+ | `.between(min, max)` | method | Raccourci pour min et max |
102
+ | `.integer` | getter | Doit être un entier |
103
+ | `.positive` | getter | Doit être > 0 |
104
+ | `.negative` | getter | Doit être < 0 |
105
+ | `.oneOf(values)` | method | Doit être dans la liste de valeurs |
106
+ | `.value` | getter | Extrait la valeur validée |
107
+
108
+ **Exemple :**
109
+ ```typescript
110
+ const age = body('age').number.required.positive.integer.between(1, 150).value;
111
+ const price = body('price').number.max(9999.99).value;
112
+ ```
113
+
114
+ ---
115
+
116
+ ### Boolean
117
+
118
+ Accès : `body('field').boolean` ou `params('field').boolean`
119
+
120
+ | Paramètre | Type | Description |
121
+ |-----------|------|-------------|
122
+ | `.required` | getter | Le champ est obligatoire |
123
+ | `.nullable` | getter | Autorise les valeurs null |
124
+ | `.default(value)` | method | Valeur par défaut si undefined |
125
+ | `.value` | getter | Extrait la valeur validée |
126
+
127
+ **Parsing :** Accepte boolean, 'true'/'false' (string), ou 1/0
128
+
129
+ **Exemple :**
130
+ ```typescript
131
+ const active = body('active').boolean.required.value;
132
+ const isAdmin = body('isAdmin').boolean.default(false).value;
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Date
138
+
139
+ Accès : `body('field').date` ou `params('field').date`
140
+
141
+ | Paramètre | Type | Description |
142
+ |-----------|------|-------------|
143
+ | `.required` | getter | Le champ est obligatoire |
144
+ | `.nullable` | getter | Autorise les valeurs null |
145
+ | `.default(value)` | method | Valeur par défaut si undefined |
146
+ | `.min(date)` | method | Doit être après cette date |
147
+ | `.max(date)` | method | Doit être avant cette date |
148
+ | `.past` | getter | Doit être dans le passé |
149
+ | `.future` | getter | Doit être dans le futur |
150
+ | `.value` | getter | Extrait la valeur validée |
151
+
152
+ **Parsing :** Accepte Date, string ISO, ou number (timestamp)
153
+
154
+ **Exemple :**
155
+ ```typescript
156
+ const birthDate = body('birthDate').date.required.past.value;
157
+ const eventDate = body('eventDate').date.future.value;
158
+ ```
159
+
160
+ ---
161
+
162
+ ### Array
163
+
164
+ Accès : `body('field').array` ou `params('field').array`
165
+
166
+ | Paramètre | Type | Description |
167
+ |-----------|------|-------------|
168
+ | `.required` | getter | Le champ est obligatoire |
169
+ | `.nullable` | getter | Autorise les valeurs null |
170
+ | `.default(value)` | method | Valeur par défaut si undefined |
171
+ | `.minLength(n)` | method | Longueur minimale du tableau |
172
+ | `.maxLength(n)` | method | Longueur maximale du tableau |
173
+ | `.ofNumbers(config?)` | method | Valide un tableau de nombres |
174
+ | `.ofStrings(config?)` | method | Valide un tableau de strings |
175
+ | `.ofBooleans()` | method | Valide un tableau de booléens |
176
+ | `.ofObjects(validator)` | method | Valide un tableau d'objets |
177
+ | `.value` | getter | Extrait la valeur validée |
178
+
179
+ #### Options pour ofNumbers
180
+
181
+ | Option | Type | Description |
182
+ |--------|------|-------------|
183
+ | `min` | number | Valeur minimale par élément |
184
+ | `max` | number | Valeur maximale par élément |
185
+ | `integer` | boolean | Doit être des entiers |
186
+ | `positive` | boolean | Doit être > 0 |
187
+ | `negative` | boolean | Doit être < 0 |
188
+
189
+ #### Options pour ofStrings
190
+
191
+ | Option | Type | Description |
192
+ |--------|------|-------------|
193
+ | `minLength` | number | Longueur minimale par élément |
194
+ | `maxLength` | number | Longueur maximale par élément |
195
+ | `pattern` | RegExp | Regex par élément |
196
+ | `email` | boolean | Doit être des emails valides |
197
+ | `url` | boolean | Doit être des URLs valides |
198
+ | `trim` | boolean | Supprime les espaces par élément |
199
+
200
+ **Exemple :**
201
+ ```typescript
202
+ const numbers = body('items').array.ofNumbers({ min: 1, max: 100 }).minLength(1).value;
203
+ const emails = body('emails').array.ofStrings({ email: true }).value;
204
+ const tags = body('tags').array.ofStrings({ minLength: 2, trim: true }).value;
205
+ ```
206
+
207
+ ---
208
+
209
+ ### Enum
210
+
211
+ Accès : `body('field').enum(allowedValues)` ou `params('field').enum(allowedValues)`
212
+
213
+ | Paramètre | Type | Description |
214
+ |-----------|------|-------------|
215
+ | `.required` | getter | Le champ est obligatoire |
216
+ | `.nullable` | getter | Autorise les valeurs null |
217
+ | `.default(value)` | method | Valeur par défaut si undefined |
218
+ | `.value` | getter | Extrait la valeur validée |
219
+
220
+ **Exemple :**
221
+ ```typescript
222
+ const status = body('status').enum(['pending', 'approved', 'rejected']).required.value;
223
+ const priority = body('priority').enum([1, 2, 3, 4, 5]).value;
224
+ ```
225
+
226
+ ---
227
+
228
+ ### Object
229
+
230
+ Accès : `body('field').object(validator)` ou `params('field').object(validator)`
231
+
232
+ | Paramètre | Type | Description |
233
+ |-----------|------|-------------|
234
+ | `.required` | getter | Le champ est obligatoire |
235
+ | `.nullable` | getter | Autorise les valeurs null |
236
+ | `.default(value)` | method | Valeur par défaut si undefined |
237
+ | `.value` | getter | Extrait la valeur validée |
238
+
239
+ **Exemple :**
240
+ ```typescript
241
+ import { validArgument } from 'express5-valid';
242
+
243
+ const profile = body('profile').object((obj) => {
244
+ return {
245
+ firstName: validArgument(obj, 'firstName').string.required.value,
246
+ lastName: validArgument(obj, 'lastName').string.required.value,
247
+ age: validArgument(obj, 'age').number.positive.value,
248
+ };
249
+ }).required.value;
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Codes d'Erreur
255
+
256
+ | Code | Description | Types concernés |
257
+ |------|-------------|-----------------|
258
+ | `REQUIRED` | Champ manquant | Tous |
259
+ | `NOT_NULLABLE` | La valeur est null | Tous |
260
+ | `INVALID_TYPE` | Type de données incorrect | Tous |
261
+ | `MIN_LENGTH` | String trop courte | String |
262
+ | `MAX_LENGTH` | String trop longue | String |
263
+ | `MIN_VALUE` | Nombre en dessous du minimum | Number |
264
+ | `MAX_VALUE` | Nombre au dessus du maximum | Number |
265
+ | `NOT_INTEGER` | Nombre décimal fourni | Number |
266
+ | `NOT_POSITIVE` | N'est pas > 0 | Number |
267
+ | `NOT_NEGATIVE` | N'est pas < 0 | Number |
268
+ | `INVALID_EMAIL` | Format email invalide | String |
269
+ | `INVALID_URL` | Format URL invalide | String |
270
+ | `NOT_IN_LIST` | Valeur absente de la liste | String, Number, Enum |
271
+ | `PATTERN_MISMATCH` | Regex échouée | String |
272
+ | `ARRAY_MIN_LENGTH` | Tableau trop court | Array |
273
+ | `ARRAY_MAX_LENGTH` | Tableau trop long | Array |
274
+ | `ARRAY_ELEMENT` | Validation d'élément échouée | Array |
275
+ | `DATE_MIN` | Date avant le minimum | Date |
276
+ | `DATE_MAX` | Date après le maximum | Date |
277
+ | `DATE_NOT_PAST` | Date pas dans le passé | Date |
278
+ | `DATE_NOT_FUTURE` | Date pas dans le futur | Date |
279
+ | `INVALID_DATE` | Date non parsable | Date |
280
+
281
+ ---
282
+
283
+ ## Exemple Complet
284
+
285
+ ```typescript
286
+ import express from 'express';
287
+ import { body, params, createJsonRouter, validMiddleware,
288
+ validErrorHandler, validArgument } from 'express5-valid';
289
+
290
+ const app = express();
291
+ app.use(express.json());
292
+ app.use(validMiddleware);
293
+
294
+ const api = createJsonRouter();
295
+
296
+ api.post('/users', () => {
297
+ const name = body('name').string.required.trim.minLength(2).value;
298
+ const email = body('email').string.email.value;
299
+ const age = body('age').number.positive.integer.value;
300
+ const roles = body('roles').array.ofStrings().value;
301
+
302
+ return { name, email, age, roles };
303
+ });
304
+
305
+ api.get('/users/:id', () => {
306
+ const id = params('id').number.required.positive.value;
307
+ return { id };
308
+ });
309
+
310
+ app.use(api.router);
311
+ app.use(validErrorHandler);
312
+
313
+ app.listen(3000);
314
+ ```
@@ -0,0 +1,12 @@
1
+ export interface ErrorParams {
2
+ [key: string]: unknown;
3
+ }
4
+ export default class ArgError extends Error {
5
+ field: string;
6
+ code: string;
7
+ details: string;
8
+ params: ErrorParams;
9
+ constructor(field: string, code: string, details: string, params?: ErrorParams);
10
+ get msg(): string;
11
+ }
12
+ //# sourceMappingURL=arg-error.d.ts.map
@@ -0,0 +1,12 @@
1
+ export interface ErrorParams {
2
+ [key: string]: unknown;
3
+ }
4
+ export default class ArgError extends Error {
5
+ field: string;
6
+ code: string;
7
+ details: string;
8
+ params: ErrorParams;
9
+ constructor(field: string, code: string, details: string, params?: ErrorParams);
10
+ get msg(): string;
11
+ }
12
+ //# sourceMappingURL=arg-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arg-error.d.ts","sourceRoot":"","sources":["../src/arg-error.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,KAAK;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;gBAER,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,WAAgB;IAQlF,IAAI,GAAG,IAAI,MAAM,CAEhB;CACJ"}
@@ -0,0 +1,11 @@
1
+ import ArgError from "./arg-error";
2
+ import ValidBase from "./valid-base";
3
+ export { ArgError };
4
+ export { validMiddleware } from "./middleware";
5
+ export { default as validErrorHandler } from "./valid-error-handler";
6
+ export { createJsonRouter, type JsonRouter } from "./router";
7
+ export type { NumberArrayConfig, StringArrayConfig } from "./types";
8
+ export declare function body(name: string): ValidBase;
9
+ export declare function params(name: string): ValidBase;
10
+ export declare function validArgument(obj: Record<string, unknown>, name: string): ValidBase;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import ArgError from "./arg-error";
2
+ import ValidBase from "./valid-base";
3
+ export { ArgError };
4
+ export { validMiddleware } from "./middleware";
5
+ export { default as validErrorHandler } from "./valid-error-handler";
6
+ export { createJsonRouter, type JsonRouter } from "./router";
7
+ export type { NumberArrayConfig, StringArrayConfig } from "./types";
8
+ export declare function body(name: string): ValidBase;
9
+ export declare function params(name: string): ValidBase;
10
+ export declare function validArgument(obj: Record<string, unknown>, name: string): ValidBase;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,aAAa,CAAC;AACnC,OAAO,SAAS,MAAM,cAAc,CAAC;AAGrC,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEpE,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAY5C;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAG9C;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAEnF"}