@cofondateurauchomage/libs 1.1.134 → 1.1.136
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.
- package/build/api.validate.js +24 -11
- package/build/regex.d.ts +6 -0
- package/build/regex.js +37 -1
- package/build/utils/objectUtils.d.ts +5 -0
- package/build/utils/objectUtils.js +11 -0
- package/package.json +1 -1
package/build/api.validate.js
CHANGED
|
@@ -22,21 +22,33 @@ const zVisibility = zod_1.z.enum(const_1.VISIBILITIES);
|
|
|
22
22
|
const zName = zod_1.z.string().regex(regex_1.RGX.Name.regex);
|
|
23
23
|
const zStrMax50 = zod_1.z.string().max(50);
|
|
24
24
|
const zStrMax1000 = zod_1.z.string().max(1000);
|
|
25
|
-
const zLinkedin = zod_1.z
|
|
25
|
+
const zLinkedin = zod_1.z
|
|
26
|
+
.string()
|
|
27
|
+
.refine((s) => (0, regex_1.normalizeLinkedInUrl)(s) !== null, {
|
|
28
|
+
message: regex_1.RGX.Linkedin.message,
|
|
29
|
+
})
|
|
30
|
+
.transform((s) => (0, regex_1.normalizeLinkedInUrl)(s));
|
|
26
31
|
const zTel = zod_1.z.string().regex(regex_1.RGX.Tel.regex);
|
|
32
|
+
/**
|
|
33
|
+
* Optionnel sur un schéma string qui rejette `""` (ex. `.regex()` ou contrainte équivalente).
|
|
34
|
+
* Les simples `z.string()` / `z.string().max()` acceptent déjà la chaîne vide.
|
|
35
|
+
*/
|
|
36
|
+
function optionalStr(schema) {
|
|
37
|
+
return zod_1.z.union([schema, zod_1.z.literal("")]).optional();
|
|
38
|
+
}
|
|
27
39
|
const zSkillsRequired = zod_1.z.array(zSkill).min(1).max(2);
|
|
28
40
|
const zSkillsOptional = zod_1.z.array(zSkill).min(1).max(2).optional();
|
|
29
41
|
const contactCreate = {
|
|
30
42
|
email: zod_1.z.string(),
|
|
31
43
|
emailProspect: zod_1.z.string(),
|
|
32
|
-
tel: zTel
|
|
33
|
-
linkedin: zLinkedin
|
|
44
|
+
tel: optionalStr(zTel),
|
|
45
|
+
linkedin: optionalStr(zLinkedin),
|
|
34
46
|
website: zod_1.z.string().optional(),
|
|
35
47
|
newsletterMarketing: zod_1.z.boolean().optional(),
|
|
36
48
|
};
|
|
37
49
|
const contactUpdate = {
|
|
38
|
-
tel: zTel
|
|
39
|
-
linkedin: zLinkedin
|
|
50
|
+
tel: optionalStr(zTel),
|
|
51
|
+
linkedin: optionalStr(zLinkedin),
|
|
40
52
|
website: zod_1.z.string().optional(),
|
|
41
53
|
};
|
|
42
54
|
const projectBody = {
|
|
@@ -170,8 +182,8 @@ const schemasForAllRoutes = {
|
|
|
170
182
|
}),
|
|
171
183
|
updateProspect: zod_1.z.object({
|
|
172
184
|
name: zStrMax50.optional(),
|
|
173
|
-
lastName: zName
|
|
174
|
-
firstName: zName
|
|
185
|
+
lastName: optionalStr(zName),
|
|
186
|
+
firstName: optionalStr(zName),
|
|
175
187
|
description: zStrMax1000.optional(),
|
|
176
188
|
status: zProjectStatus.optional(),
|
|
177
189
|
status_detail: zStrMax1000.optional(),
|
|
@@ -182,7 +194,7 @@ const schemasForAllRoutes = {
|
|
|
182
194
|
skills: zSkillsOptional,
|
|
183
195
|
yearsOfExperience: zod_1.z.number().min(0).max(100).optional(),
|
|
184
196
|
availability: zAvailabilityWithNeverMind.optional(),
|
|
185
|
-
city: zName
|
|
197
|
+
city: optionalStr(zName),
|
|
186
198
|
invest: zod_1.z.number().min(0).max(1_000_000).optional(),
|
|
187
199
|
partner: zStrMax1000.optional(),
|
|
188
200
|
partner_swanbase: zod_1.z.boolean().optional(),
|
|
@@ -192,8 +204,8 @@ const schemasForAllRoutes = {
|
|
|
192
204
|
bestStrength: zStrMax1000.optional(),
|
|
193
205
|
projectStatus: zod_1.z.array(zProjectStatusWithNeverMind).optional(),
|
|
194
206
|
email: zod_1.z.string(),
|
|
195
|
-
tel: zTel
|
|
196
|
-
linkedin: zLinkedin
|
|
207
|
+
tel: optionalStr(zTel),
|
|
208
|
+
linkedin: optionalStr(zLinkedin),
|
|
197
209
|
website: zod_1.z.string().optional(),
|
|
198
210
|
}),
|
|
199
211
|
createReaction: zod_1.z.object({
|
|
@@ -246,10 +258,11 @@ function validateBodyForO(route, body) {
|
|
|
246
258
|
throwFromZodError(parsed.error);
|
|
247
259
|
}
|
|
248
260
|
const input = body;
|
|
261
|
+
const data = parsed.data;
|
|
249
262
|
const result = {};
|
|
250
263
|
for (const key of Object.keys(schema.shape)) {
|
|
251
264
|
if (input[key] !== undefined) {
|
|
252
|
-
result[key] =
|
|
265
|
+
result[key] = data[key];
|
|
253
266
|
}
|
|
254
267
|
}
|
|
255
268
|
return result;
|
package/build/regex.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accepte plusieurs formes d’URL profil LinkedIn et renvoie toujours
|
|
3
|
+
* `https://www.linkedin.com/.../` (slash final, sans query/hash).
|
|
4
|
+
* Retourne `null` si l’URL n’est pas un profil LinkedIn valide.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeLinkedInUrl(raw: string): string | null;
|
|
1
7
|
export declare const RGX: {
|
|
2
8
|
Date: {
|
|
3
9
|
regex: RegExp;
|
package/build/regex.js
CHANGED
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RGX = void 0;
|
|
4
|
+
exports.normalizeLinkedInUrl = normalizeLinkedInUrl;
|
|
4
5
|
const regex = {
|
|
5
6
|
date: /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))$/,
|
|
6
7
|
email: /^[\w.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
|
|
7
|
-
|
|
8
|
+
/** Saisie tolérante (schéma / attribut HTML). La valeur canonique est produite par `normalizeLinkedInUrl`. */
|
|
9
|
+
linkedin: /^(https?:\/\/)?(www\.)?([\w-]+\.)?linkedin\.com\/(pub|in|profile)\/.+$/i,
|
|
8
10
|
name: /^(?=.*[A-Za-zÜ-ü])[A-Za-zÜ-ü\s\-]{1,50}$/,
|
|
9
11
|
tel: /^([+][1-9]{2,3}[ .\-]?)?[0-9]{1,3}([ .\-]?[0-9]{2,3}){3,6}$/,
|
|
10
12
|
};
|
|
11
13
|
const pattern = (regex) => String(regex).replace("/^", "").replace("$/", "");
|
|
14
|
+
/**
|
|
15
|
+
* Accepte plusieurs formes d’URL profil LinkedIn et renvoie toujours
|
|
16
|
+
* `https://www.linkedin.com/.../` (slash final, sans query/hash).
|
|
17
|
+
* Retourne `null` si l’URL n’est pas un profil LinkedIn valide.
|
|
18
|
+
*/
|
|
19
|
+
function normalizeLinkedInUrl(raw) {
|
|
20
|
+
const trimmed = raw.trim();
|
|
21
|
+
if (!trimmed)
|
|
22
|
+
return null;
|
|
23
|
+
let href = trimmed;
|
|
24
|
+
if (!/^https?:\/\//i.test(href)) {
|
|
25
|
+
href = `https://${href}`;
|
|
26
|
+
}
|
|
27
|
+
let url;
|
|
28
|
+
try {
|
|
29
|
+
url = new URL(href);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const hn = url.hostname.toLowerCase();
|
|
35
|
+
const validHost = hn === "linkedin.com" ||
|
|
36
|
+
hn === "www.linkedin.com" ||
|
|
37
|
+
/^[\w-]+\.linkedin\.com$/i.test(hn);
|
|
38
|
+
if (!validHost)
|
|
39
|
+
return null;
|
|
40
|
+
if (!/^\/(in|pub|profile)\/.+/i.test(url.pathname)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const path = url.pathname.endsWith("/")
|
|
44
|
+
? url.pathname
|
|
45
|
+
: `${url.pathname}/`;
|
|
46
|
+
return `https://www.linkedin.com${path}`;
|
|
47
|
+
}
|
|
12
48
|
exports.RGX = {
|
|
13
49
|
Date: {
|
|
14
50
|
regex: regex.date,
|
|
@@ -28,5 +28,10 @@ type WithoutNull<T> = {
|
|
|
28
28
|
[K in keyof T as IsNull<T[K]> extends true ? never : K]: Exclude<T[K], null>;
|
|
29
29
|
};
|
|
30
30
|
export declare function removeNull<T extends Record<string, any>>(obj: T): WithoutNull<T>;
|
|
31
|
+
type IsUndefined<T> = T extends undefined ? true : false;
|
|
32
|
+
type WithoutUndefined<T> = {
|
|
33
|
+
[K in keyof T as IsUndefined<T[K]> extends true ? never : K]: Exclude<T[K], undefined>;
|
|
34
|
+
};
|
|
35
|
+
export declare function removeUndefined<T extends Record<string, any>>(obj: T): WithoutUndefined<T>;
|
|
31
36
|
export declare function deepEqual<T>(obj1: T, obj2: T): boolean;
|
|
32
37
|
export {};
|
|
@@ -7,6 +7,7 @@ exports.typedObjectEntries = typedObjectEntries;
|
|
|
7
7
|
exports.isObject = isObject;
|
|
8
8
|
exports.cleanObject = cleanObject;
|
|
9
9
|
exports.removeNull = removeNull;
|
|
10
|
+
exports.removeUndefined = removeUndefined;
|
|
10
11
|
exports.deepEqual = deepEqual;
|
|
11
12
|
const arrayUtils_1 = require("./arrayUtils");
|
|
12
13
|
/**
|
|
@@ -66,6 +67,16 @@ function removeNull(obj) {
|
|
|
66
67
|
}
|
|
67
68
|
return acc;
|
|
68
69
|
}
|
|
70
|
+
function removeUndefined(obj) {
|
|
71
|
+
const acc = {};
|
|
72
|
+
for (const [key, value] of typedObjectEntries(obj)) {
|
|
73
|
+
const cleanedValue = isObject(value) ? removeUndefined(value) : value;
|
|
74
|
+
if (cleanedValue !== undefined) {
|
|
75
|
+
acc[key] = cleanedValue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return acc;
|
|
79
|
+
}
|
|
69
80
|
function deepEqual(obj1, obj2) {
|
|
70
81
|
if (obj1 === obj2) {
|
|
71
82
|
return true;
|