@mlagie/sql-connector 2.0.7 → 2.0.9

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.
@@ -1,241 +0,0 @@
1
- const generateCondition = require('../src/utils/generateCondition');
2
- const { Schema } = require('../src/models/Schema');
3
-
4
- describe('Utils - generateCondition.js', () => {
5
- test('Devrait générer une chaîne classique de conditions WHERE (isUpdate = false)', () => {
6
- const filter = { status: 'active', age: 18 };
7
- const result = generateCondition(filter, false);
8
- expect(result).toBe("`status` = 'active' AND `age` = 18");
9
- });
10
-
11
- test('Devrait générer une chaîne d\'assignations SET (isUpdate = true)', () => {
12
- const data = { email: 'test@test.com', updated: 1 };
13
- const result = generateCondition(data, true);
14
- expect(result).toBe("`email` = 'test@test.com' , `updated` = 1");
15
- });
16
-
17
- test('Devrait générer un opérateur IN lorsqu\'une valeur est un tableau', () => {
18
- const filter = { id: [1, 2, 3] };
19
- const result = generateCondition(filter, false);
20
- expect(result).toBe('`id` IN (1, 2, 3)');
21
- });
22
-
23
- test('Devrait générer "IS NULL" pour les filtres et conserver l\'assignation brute en cas d\'Update', () => {
24
- expect(generateCondition({ deletedAt: null }, false)).toBe('`deletedAt` IS NULL');
25
- expect(generateCondition({ deletedAt: null }, true)).toBe('`deletedAt` = NULL');
26
- });
27
-
28
- test('Devrait convertir une chaîne date ISO au format MySQL si spécifiée dans le Schéma', () => {
29
- const schema = new Schema({
30
- publishedAt: { type: Date }
31
- });
32
- const filter = { publishedAt: '2026-07-03T15:00:00.000Z' };
33
- const result = generateCondition(filter, false, schema);
34
- expect(result).toBe("`publishedAt` = '2026-07-03 15:00:00'");
35
- });
36
-
37
- test('Devrait nettoyer les guillemets de protection d\'une chaîne de caractères', () => {
38
- const filter = { name: '"Alice"' };
39
- expect(generateCondition(filter, false)).toBe("`name` = 'Alice'");
40
- });
41
-
42
- test("generateCondition utilise les champs unique du schema", () => {
43
- const result = generateCondition(
44
- { email: "john@test.fr" },
45
- false,
46
- {
47
- schemaDict: {
48
- email: {
49
- unique: true
50
- }
51
- }
52
- }
53
- );
54
-
55
- expect(result).toContain("email");
56
- });
57
-
58
- test("generateCondition génère un IN pour les champs uniques tableau", () => {
59
- const result = generateCondition(
60
- { email: ["a@test.fr", "b@test.fr"] },
61
- false,
62
- {
63
- schemaDict: {
64
- email: {
65
- unique: true
66
- }
67
- }
68
- }
69
- );
70
-
71
- expect(result).toContain("IN");
72
- });
73
-
74
- test("generateCondition génère un JSON_CONTAINS pour objet unique", () => {
75
- const result = generateCondition(
76
- {
77
- metadata: {
78
- role: "admin"
79
- }
80
- },
81
- false,
82
- {
83
- schemaDict: {
84
- metadata: {
85
- unique: true
86
- }
87
- }
88
- }
89
- );
90
-
91
- expect(result).toContain("JSON_CONTAINS");
92
- });
93
-
94
- test("generateCondition génère IS NULL pour champ unique", () => {
95
- const result = generateCondition(
96
- { email: null },
97
- false,
98
- {
99
- schemaDict: {
100
- email: {
101
- unique: true
102
- }
103
- }
104
- }
105
- );
106
-
107
- expect(result).toContain("IS NULL");
108
- });
109
-
110
- test("generateCondition convertit une date ISO sur champ unique", () => {
111
- const result = generateCondition(
112
- {
113
- created_at: "2025-01-01T10:00:00Z"
114
- },
115
- false,
116
- {
117
- schemaDict: {
118
- created_at: {
119
- unique: true
120
- }
121
- }
122
- }
123
- );
124
-
125
- expect(result).toContain("2025-01-01 10:00:00");
126
- });
127
-
128
- test("generateCondition update JSON", () => {
129
- const result = generateCondition(
130
- {
131
- metadata: {
132
- role: "admin"
133
- }
134
- },
135
- true
136
- );
137
-
138
- expect(result).toContain("=");
139
- expect(result).not.toContain("JSON_CONTAINS");
140
- });
141
-
142
- test("generateCondition filtre JSON", () => {
143
- const result = generateCondition(
144
- {
145
- metadata: {
146
- role: "admin"
147
- }
148
- },
149
- false
150
- );
151
-
152
- expect(result).toContain("JSON_CONTAINS");
153
- });
154
-
155
- test("generateCondition retourne une condition simple", () => {
156
- const result = generateCondition(
157
- { id: 42 },
158
- false
159
- );
160
-
161
- expect(result).toContain("42");
162
- });
163
-
164
- test("generateCondition retire les guillemets doubles entourant une valeur", () => {
165
- const result = generateCondition(
166
- { name: '"john"' },
167
- false,
168
- {
169
- schemaDict: {
170
- name: {
171
- unique: true
172
- }
173
- }
174
- }
175
- );
176
-
177
- expect(result).toContain("john");
178
- expect(result).not.toContain('"john"');
179
- });
180
-
181
- test("generateCondition utilise JSON_CONTAINS avec une chaîne JSON", () => {
182
- const result = generateCondition(
183
- {
184
- metadata: '{"role":"admin"}'
185
- },
186
- false,
187
- {
188
- schemaDict: {
189
- metadata: {
190
- unique: true
191
- }
192
- }
193
- }
194
- );
195
-
196
- expect(result).toContain("JSON_CONTAINS");
197
- });
198
-
199
- test("generateCondition détecte une chaîne JSON", () => {
200
- const result = generateCondition({
201
- metadata: '{"role":"admin"}'
202
- });
203
-
204
- expect(result).toContain("JSON_CONTAINS");
205
- });
206
-
207
- test("generateCondition supporte fieldDef.type string", () => {
208
- generateCondition(
209
- {
210
- created_at: "2025-01-01T10:00:00Z"
211
- },
212
- false,
213
- {
214
- schemaDict: {
215
- created_at: {
216
- type: "Date"
217
- }
218
- }
219
- }
220
- );
221
- });
222
-
223
- test("generateCondition convertit une date ISO pour un champ Date", () => {
224
- const result = generateCondition(
225
- {
226
- created_at: "2025-01-01T10:00:00Z"
227
- },
228
- false,
229
- {
230
- schemaDict: {
231
- created_at: {
232
- type: Date
233
- }
234
- }
235
- }
236
- );
237
-
238
- expect(result).toContain("2025-01-01 10:00:00");
239
- });
240
-
241
- });
@@ -1,22 +0,0 @@
1
- const mockExecute = jest.fn();
2
- const mockEnd = jest.fn((callback) => { if (callback) callback(null); });
3
-
4
- const mockPool = {
5
- promise: () => ({
6
- execute: mockExecute
7
- }),
8
- end: mockEnd
9
- };
10
-
11
- jest.mock('mysql2', () => {
12
- // Le require est fait à l'intérieur du callback au moment de l'exécution
13
- const mysql2Actual = jest.requireActual('mysql2');
14
-
15
- return {
16
- createPool: jest.fn(() => mockPool),
17
- escape: mysql2Actual.escape,
18
- escapeId: mysql2Actual.escapeId
19
- };
20
- });
21
-
22
- module.exports = { mockExecute, mockEnd, mockPool };
@@ -1,48 +0,0 @@
1
- const { getSafe, setSafe } = require('../src/utils/security/safe');
2
-
3
- describe('Utils - safe.js', () => {
4
- describe('getSafe', () => {
5
- test('Devrait lire une propriété existante valide', () => {
6
- const obj = { name: 'Alice' };
7
- expect(getSafe(obj, 'name')).toBe('Alice');
8
- });
9
-
10
- test('Devrait renvoyer undefined pour une propriété absente', () => {
11
- const obj = { name: 'Alice' };
12
- expect(getSafe(obj, 'age')).toBeUndefined();
13
- });
14
-
15
- test('Devrait bloquer l’accès aux propriétés interdites (Pollution de Prototype)', () => {
16
- const obj = {};
17
- expect(getSafe(obj, '__proto__')).toBeUndefined();
18
- expect(getSafe(obj, 'constructor')).toBeUndefined();
19
- expect(getSafe(obj, 'prototype')).toBeUndefined();
20
- });
21
-
22
- test('Devrait gérer un objet null ou indéfini sans lever d’erreur', () => {
23
- expect(getSafe(null, 'name')).toBeUndefined();
24
- expect(getSafe(undefined, 'name')).toBeUndefined();
25
- });
26
- });
27
-
28
- describe('setSafe', () => {
29
- test('Devrait assigner une valeur à une clé valide', () => {
30
- const obj = {};
31
- const result = setSafe(obj, 'age', 30);
32
- expect(result).toBe(true);
33
- expect(obj.age).toBe(30);
34
- });
35
-
36
- test('Devrait refuser d’assigner des clés interdites et renvoyer false', () => {
37
- const obj = {};
38
- expect(setSafe(obj, '__proto__', { polluted: true })).toBe(false);
39
- expect(setSafe(obj, 'constructor', {})).toBe(false);
40
- expect(setSafe(obj, 'prototype', {})).toBe(false);
41
- expect(obj.__proto__.polluted).toBeUndefined();
42
- });
43
-
44
- test('Devrait renvoyer false si l’objet cible n’est pas valide', () => {
45
- expect(setSafe(null, 'key', 'val')).toBe(false);
46
- });
47
- });
48
- });
package/tests/sql.test.js DELETED
@@ -1,62 +0,0 @@
1
- const { escapeIdentifier, escapeIdentifierList, escapeValue, escapeOrderDirection } = require('../src/utils/sql');
2
-
3
- describe('Utils - sql.js', () => {
4
- describe('escapeIdentifier', () => {
5
- test('Devrait renvoyer "*" inchangé', () => {
6
- expect(escapeIdentifier('*')).toBe('*');
7
- });
8
-
9
- test('Devrait formater un identifiant simple avec des backticks', () => {
10
- expect(escapeIdentifier('users')).toBe('`users`');
11
- });
12
-
13
- test('Devrait nettoyer les backticks existants (normalisation)', () => {
14
- expect(escapeIdentifier('`users`')).toBe('`users`');
15
- });
16
-
17
- test('Devrait gérer les identifiants composites sépares par un point', () => {
18
- expect(escapeIdentifier('users.id')).toBe('`users`.`id`');
19
- expect(escapeIdentifier('users.*')).toBe('`users`.*');
20
- });
21
-
22
- test('Devrait lever une erreur si l’identifiant n’est pas une chaîne de caractères ou vide', () => {
23
- expect(() => escapeIdentifier('')).toThrow('Invalid SQL identifier');
24
- expect(() => escapeIdentifier(null)).toThrow('Invalid SQL identifier');
25
- });
26
-
27
- test('Devrait lever une erreur en cas de tentative d’injection de caractères non autorisés', () => {
28
- expect(() => escapeIdentifier('users; DROP TABLE users;')).toThrow('Invalid SQL identifier');
29
- expect(() => escapeIdentifier('users-table')).toThrow('Invalid SQL identifier');
30
- expect(() => escapeIdentifier('users.id;--')).toThrow('Invalid SQL identifier');
31
- });
32
- });
33
-
34
- describe('escapeIdentifierList', () => {
35
- test('Devrait joindre et échapper une liste d’identifiants', () => {
36
- expect(escapeIdentifierList(['id', 'email'])).toBe('`id`, `email`');
37
- });
38
- });
39
-
40
- describe('escapeValue', () => {
41
- test('Devrait déléguer l’échappement de valeurs de manière sécurisée', () => {
42
- expect(escapeValue("John's")).toBe("'John\\'s'");
43
- expect(escapeValue(42)).toBe('42');
44
- });
45
- });
46
-
47
- describe('escapeOrderDirection', () => {
48
- test('Devrait normaliser en majuscule ASC et DESC', () => {
49
- expect(escapeOrderDirection('asc')).toBe('ASC');
50
- expect(escapeOrderDirection('DESC')).toBe('DESC');
51
- });
52
-
53
- test('Devrait retourner ASC par défaut si null ou undefined', () => {
54
- expect(escapeOrderDirection(null)).toBe('ASC');
55
- expect(escapeOrderDirection(undefined)).toBe('ASC');
56
- });
57
-
58
- test('Devrait lever une erreur pour toute direction invalide', () => {
59
- expect(() => escapeOrderDirection('INJECTION;')).toThrow('Invalid SQL sort direction');
60
- });
61
- });
62
- });
@@ -1,16 +0,0 @@
1
- const { sqlTypeMap } = require('../src/utils/sqlTypeMap');
2
-
3
- describe('Utils - sqlTypeMap.js', () => {
4
- test('Devrait posséder les correspondances de types standards indispensables', () => {
5
- expect(sqlTypeMap.String).toBe('VARCHAR');
6
- expect(sqlTypeMap.Number).toBe('INT');
7
- expect(sqlTypeMap.Boolean).toBe('BOOLEAN');
8
- expect(sqlTypeMap.Date).toBe('DATETIME');
9
- expect(sqlTypeMap.Object).toBe('JSON');
10
- });
11
-
12
- test('Devrait retourner les valeurs temporelles par défaut configurées', () => {
13
- expect(sqlTypeMap.Now).toBe('NOW()');
14
- expect(sqlTypeMap.CurrentTimestamp).toBe('CURRENT_TIMESTAMP');
15
- });
16
- });