data-primals-engine 1.2.2 → 1.2.4

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 (54) hide show
  1. package/CONTRIBUTING.md +91 -0
  2. package/README.md +33 -17
  3. package/client/src/App.jsx +0 -5
  4. package/client/src/ConditionBuilder.scss +34 -1
  5. package/client/src/ConditionBuilder2.jsx +179 -53
  6. package/client/src/ContentView.jsx +0 -3
  7. package/client/src/CronBuilder.jsx +0 -1
  8. package/client/src/CronPartBuilder.jsx +0 -2
  9. package/client/src/DashboardView.jsx +0 -5
  10. package/client/src/DataEditor.jsx +8 -211
  11. package/client/src/DataLayout.jsx +0 -1
  12. package/client/src/DataTable.jsx +1 -3
  13. package/client/src/Field.jsx +0 -5
  14. package/client/src/FlexBuilder.jsx +1 -1
  15. package/client/src/ModelCreatorField.jsx +1 -5
  16. package/client/src/RTE.jsx +1 -6
  17. package/client/src/RTETrans.jsx +0 -2
  18. package/client/src/RelationField.jsx +1 -1
  19. package/client/src/RelationValue.jsx +1 -2
  20. package/client/src/TourSpotlight.jsx +0 -2
  21. package/client/src/constants.js +1 -1
  22. package/client/src/filter.js +87 -0
  23. package/client/src/hooks/data.js +1 -3
  24. package/client/src/hooks/useTutorials.jsx +0 -1
  25. package/package.json +3 -3
  26. package/server.js +2 -2
  27. package/src/constants.js +2 -2
  28. package/src/defaultModels.js +1 -14
  29. package/src/email.js +9 -7
  30. package/src/engine.js +60 -20
  31. package/src/events.js +1 -1
  32. package/src/filter.js +221 -0
  33. package/src/index.js +1 -1
  34. package/src/middlewares/middleware-mongodb.js +0 -1
  35. package/src/modules/assistant.js +1 -3
  36. package/src/modules/bucket.js +3 -4
  37. package/src/modules/{data.js → data/data.js} +42 -59
  38. package/src/modules/data/index.js +1 -0
  39. package/src/modules/file.js +1 -1
  40. package/src/modules/mongodb.js +0 -1
  41. package/src/modules/user.js +1 -1
  42. package/src/modules/workflow.js +299 -133
  43. package/src/packs.js +249 -8
  44. package/test/data.backup.integration.test.js +7 -5
  45. package/test/data.integration.test.js +8 -6
  46. package/test/events.test.js +1 -1
  47. package/test/file.test.js +11 -17
  48. package/test/import_export.integration.test.js +38 -27
  49. package/test/model.integration.test.js +20 -21
  50. package/test/user.test.js +32 -25
  51. package/test/vm.test.js +51 -0
  52. package/test/workflow.integration.test.js +22 -14
  53. package/test/workflow.robustness.test.js +19 -9
  54. package/src/modules/test +0 -147
@@ -543,19 +543,6 @@ export const defaultModels = {
543
543
  { name: 'createdAt', type: 'datetime', required: true }
544
544
  ]
545
545
  },
546
- campaign: {
547
- name: 'campaign',
548
- "description": "",
549
- fields: [
550
- { name: 'name', type: 'string_t', required: true },
551
- { name: 'description', type: 'richtext' },
552
- { name: 'startDate', type: 'datetime' },
553
- { name: 'endDate', type: 'datetime' },
554
- { name: 'type', type: 'enum', items: ['email', 'sms', 'advertisement', 'promotion'] },
555
- { name: 'status', type: 'enum', items: ['planified', 'in_progress', 'finished', 'cancelled'] },
556
- { name: 'budget', type: 'number' }
557
- ]
558
- },
559
546
  review: {
560
547
  name: "review",
561
548
  "description": "",
@@ -1014,7 +1001,7 @@ export const defaultModels = {
1014
1001
  { name: 'owner', type: 'relation', relation: 'user', required: false },
1015
1002
  { name: 'startedAt', type: 'datetime', required: true, hint: "Timestamp when the workflow run began." },
1016
1003
  { name: 'completedAt', type: 'datetime', hint: "Timestamp when the workflow run finished (successfully or failed)." },
1017
- { name: 'error', type: 'string', maxlength: 4096, hint: "Error message if the workflow run failed." }
1004
+ { name: 'log', type: 'string', maxlength: 4096, hint: "Error message if the workflow run failed." }
1018
1005
  ]
1019
1006
  },
1020
1007
  dashboard:{
package/src/email.js CHANGED
@@ -6,12 +6,12 @@ import {emailDefaultConfig} from "./constants.js";
6
6
 
7
7
  // Le transporteur par défaut, utilisé si aucune config spécifique n'est fournie.
8
8
  const defaultTransporter = nodemailer.createTransport({
9
- host: "mail.smtp2go.com",
10
- port: 587,
9
+ host: process.env.SMTP_HOST,
10
+ port: process.env.SMTP_PORT || 587,
11
11
  secure: false,
12
12
  auth: {
13
- user: process.env.MAIL_USER,
14
- pass: process.env.MAIL_PASS
13
+ user: process.env.SMTP_USER,
14
+ pass: process.env.SMTP_PASS
15
15
  }
16
16
  });
17
17
 
@@ -52,7 +52,9 @@ export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl =
52
52
  // Choisir le transporteur à utiliser
53
53
  const transporter = smtpConfig ? createTransporter(smtpConfig||emailDefaultConfig) : defaultTransporter;
54
54
 
55
- if (tpl === null) tpl = Event.Trigger("sendEmail:template", "system", "calls", data, lang);
55
+ Event.Listen("OnEmailTemplate", (data, lang) => data.content, "event", "system");
56
+
57
+ if (tpl === null) tpl = Event.Trigger("OnEmailTemplate", "event", "system", data, lang);
56
58
  let html = tpl;
57
59
  try {
58
60
  html = juice(tpl);
@@ -73,9 +75,9 @@ export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl =
73
75
 
74
76
  try {
75
77
  await Promise.all(sendPromises);
76
- console.log(`Email(s) envoyé(s) avec succès à: ${emails.join(', ')}`);
78
+ console.log(`Email(s) sent successfully to : ${emails.join(', ')}`);
77
79
  } catch (error) {
78
- console.error("Erreur lors de l'envoi d'un ou plusieurs emails :", error);
80
+ console.error("Error when sending to one ore more emails :", error);
79
81
  // Vous pouvez relancer l'erreur si vous voulez que l'appelant la gère
80
82
  throw error;
81
83
  }
package/src/engine.js CHANGED
@@ -13,13 +13,15 @@ import {
13
13
  import http from "http";
14
14
  import cookieParser from "cookie-parser";
15
15
  import requestIp from 'request-ip';
16
- import {createModel, deleteModels, getModels, validateModelStructure} from "./modules/data.js";
16
+ import {createModel, deleteModels, getModels, installAllPacks, validateModelStructure} from "./modules/data/data.js";
17
17
  import {defaultModels} from "./defaultModels.js";
18
18
  import {DefaultUserProvider} from "./providers.js";
19
19
  import formidableMiddleware from 'express-formidable';
20
20
  import sirv from "sirv";
21
21
  import * as tls from "node:tls";
22
22
  import {Event} from "./events.js";
23
+ import path from "node:path";
24
+ import {isPathRelativeTo, isValidPath} from "./core.js";
23
25
 
24
26
  // Constants
25
27
  const isProduction = process.env.NODE_ENV === 'production'
@@ -49,23 +51,35 @@ const isTlsActive = !(!process.env.TLS || ["0", "false"].includes(process.env.TL
49
51
  const clientOptions = {
50
52
  maxPoolSize: databasePoolSize
51
53
  };
52
- // On ajoute les options TLS si elles sont activées
54
+
55
+ // We add TLS options if enabled
53
56
  if (isTlsActive) {
54
57
  clientOptions.tls = true;
55
- // Chemin vers le certificat de l'autorité de certification (pour faire confiance au serveur)
56
- if (process.env.CA_CERT) {
57
- clientOptions.tlsCAFile = process.env.CA_CERT;
58
- }
59
- // Chemin vers le certificat et la clé du CLIENT (pour que le serveur vous fasse confiance)
60
- if (process.env.CERT_KEY) {
61
- clientOptions.tlsCertificateKeyFile = process.env.CERT_KEY;
58
+
59
+ // is mTLS ? (client certificate required instead of password)
60
+ if (process.env.CERT) {
61
+ clientOptions.secureContext = tls.createSecureContext({
62
+ ca: fs.readFileSync(process.env.CA_CERT),
63
+ cert: fs.readFileSync(process.env.CERT),
64
+ key: fs.readFileSync(process.env.CERT_KEY)
65
+ });
66
+ }else {
67
+ // Path to the authority certificate
68
+ if (process.env.CA_CERT) {
69
+ clientOptions.tlsCAFile = process.env.CA_CERT;
70
+ }
71
+ // Path to the certificate key
72
+ if (process.env.CERT_KEY) {
73
+ clientOptions.tlsCertificateKeyFile = process.env.CERT_KEY;
74
+ }
62
75
  }
63
- // Options pour le développement (à utiliser avec prudence)
64
76
  if (tlsAllowInvalidCertificates) {
65
77
  clientOptions.tlsAllowInvalidCertificates = true;
78
+ console.warn("🚨 [SECURITY WARNING] tlsAllowInvalidCertificates is ON. Server certificate will not be validated.");
66
79
  }
67
80
  if (tlsAllowInvalidHostnames) {
68
81
  clientOptions.tlsAllowInvalidHostnames = true;
82
+ console.warn("🚨 [SECURITY WARNING] tlsAllowInvalidHostnames is ON. Server hostname will not be validated.");
69
83
  }
70
84
  }
71
85
 
@@ -143,18 +157,44 @@ export const Engine = {
143
157
  }
144
158
  };
145
159
 
146
- await Promise.all(Config.Get('modules', []).map(async module => {
160
+ await Promise.all(Config.Get('modules', []).map(async moduleIdentifier => {
147
161
  try {
148
- if( fs.existsSync(module) ){
149
- return await importModule(module);
150
- }else {
151
- return await importModule('./modules/' + module + ".js");
162
+ let moduleDir;
163
+ const moduleName = path.basename(moduleIdentifier);
164
+
165
+ const directPath = path.resolve(moduleIdentifier);
166
+ let isDir = fs.existsSync(directPath) && fs.statSync(directPath).isDirectory();
167
+ if (isDir) {
168
+ moduleDir = directPath;
169
+ if (!fs.existsSync(moduleDir) || !fs.statSync(moduleDir).isDirectory()) {
170
+ logger.warn(`Le dossier du module est introuvable pour l'identifiant : '${moduleIdentifier}'. Chemin cherché : '${moduleDir}'.`);
171
+ return null;
172
+ }
173
+ } else {
174
+ moduleDir = path.resolve('./src/modules', moduleIdentifier);
175
+ }
176
+
177
+ let moduleEntryPoint;
178
+ const jsPath = moduleDir+'.js';
179
+ const indexJsPath = path.join(moduleDir, 'index.js');
180
+ const moduleJsPath = path.join(moduleDir, `${moduleName}.js`);
181
+
182
+ if (fs.existsSync(jsPath)) {
183
+ moduleEntryPoint = 'file://'+jsPath;
184
+ } else if (fs.existsSync(indexJsPath)) {
185
+ moduleEntryPoint = 'file://'+indexJsPath;
186
+ } else if (fs.existsSync(moduleJsPath)) {
187
+ moduleEntryPoint = 'file://'+moduleJsPath;
152
188
  }
153
- } catch (e){
154
- logger.info('ERROR at loading module '+ module, e.stack);
189
+
190
+ return await importModule(moduleEntryPoint);
191
+ } catch (e) {
192
+ logger.error(`Échec du chargement du module '${moduleIdentifier}':`, e.stack);
193
+ return null;
155
194
  }
156
- })).then(async e => {
157
- engine._modules = e;
195
+ })).then(async results => {
196
+ // On filtre les modules qui n'ont pas pu être chargés
197
+ engine._modules = results.filter(Boolean);
158
198
  return Promise.resolve();
159
199
  });
160
200
 
@@ -175,6 +215,7 @@ export const Engine = {
175
215
  server.listen(port);
176
216
 
177
217
  await setupInitialModels();
218
+ await installAllPacks();
178
219
 
179
220
  if (cb)
180
221
  await cb();
@@ -238,4 +279,3 @@ export const Engine = {
238
279
  return engine;
239
280
  }
240
281
  }
241
-
package/src/events.js CHANGED
@@ -60,7 +60,7 @@ export const Event = {
60
60
  }
61
61
  return ret;
62
62
  },
63
- Listen: (name = "", callback = () => {}, system = "priority", layer = "medium") => {
63
+ Listen: (name = "", callback, system = "priority", layer = "medium") => {
64
64
  const validSystems = Object.keys(eventLayerSystems); // Récupération des clés pour une vérification plus performante
65
65
  if (!validSystems.includes(system)) {
66
66
  throw new Error(`System '${system}' does not exist. Valid systems are: ${validSystems.join(', ')}`); // Message d'erreur plus informatif
package/src/filter.js ADDED
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Evaluates a single condition against form data.
3
+ * @param {object} currentModelDef - The definition of the current model.
4
+ * @param {object} condition - The condition to evaluate.
5
+ * @param {object} formData - The form data.
6
+ * @param {object[]} allModels - An array of all model definitions.
7
+ * @param {object} user - The current user.
8
+ * @returns {boolean} - True if the condition is met, false otherwise.
9
+ */
10
+ const evaluateSingleCondition = (currentModelDef, condition, formData, allModels, user) => {
11
+ // Condition est directement un filtre MongoDB, donc on l'applique
12
+ // en utilisant les opérateurs et les valeurs qu'il contient.
13
+
14
+ if (!condition || typeof condition !== 'object') {
15
+ console.warn("[Client Eval] Condition is not an object:", condition);
16
+ return true; // Permissive default
17
+ }
18
+
19
+ // Si la condition est de la forme {field: value}, on la transforme en {$eq: value}
20
+ if (!Object.keys(condition)[0].startsWith('$') && typeof condition[Object.keys(condition)[0]] !== 'object') {
21
+ const fieldName = Object.keys(condition)[0];
22
+ const value = condition[fieldName];
23
+ return evaluateSingleCondition(currentModelDef, {[fieldName]: {$eq: value}}, formData, allModels, user);
24
+ }
25
+
26
+ // Gestion des opérateurs d'agrégation (commencent par $)
27
+ const operator = Object.keys(condition)[0];
28
+ if (operator === '$eq' && Array.isArray(condition[operator])) {
29
+ // Cas spécial pour {$eq: ['$field', value]}
30
+ const [fieldPath, expectedValue] = condition[operator];
31
+ if (typeof fieldPath === 'string' && fieldPath.startsWith('$')) {
32
+ const fieldName = fieldPath.substring(1); // Enlève le $ devant
33
+ return formData[fieldName] == expectedValue;
34
+ }
35
+ }
36
+
37
+ // Si la condition contient des opérateurs logiques, on les gère ici
38
+ if (condition.$and || condition.$or || condition.$not || condition.$nor) {
39
+ console.warn("[Client Eval] Condition logique détectée dans evaluateSingleCondition, ce n'est pas attendu. Devrait être géré par isConditionMet.");
40
+ return true; // Permissive default
41
+ }
42
+
43
+ if (condition.$find) {
44
+ const fieldName = Object.keys(condition)[0];
45
+ const fieldValue = formData[fieldName];
46
+ const findCondition = condition.$find;
47
+
48
+ if (!Array.isArray(fieldValue)) return false;
49
+
50
+ return fieldValue.some(item => {
51
+ // Gestion spéciale pour la syntaxe $eq: ["$$this.field", value]
52
+ if (findCondition.$eq && Array.isArray(findCondition.$eq)) {
53
+ const [fieldPath, value] = findCondition.$eq;
54
+ if (fieldPath.startsWith("$$this.")) {
55
+ const fieldToCheck = fieldPath.replace("$$this.", "");
56
+ return item[fieldToCheck] == value;
57
+ }
58
+ }
59
+
60
+ // Sinon, évaluation normale
61
+ const tempData = { ...item };
62
+ return evaluateSingleCondition(currentModelDef, findCondition, tempData, allModels, user);
63
+ });
64
+ }
65
+
66
+ // Si la condition contient un opérateur $exists, on le gère ici
67
+ if (condition.$exists !== undefined) {
68
+ const fieldName = Object.keys(condition)[0]; // Récupérer le nom du champ
69
+ const shouldExist = condition.$exists; // Récupérer la valeur de $exists (true ou false)
70
+ const exists = Object.prototype.hasOwnProperty.call(formData, fieldName) && formData[fieldName] !== undefined && formData[fieldName] !== null;
71
+ return exists === shouldExist;
72
+ }
73
+
74
+ // Si la condition contient un opérateur $find, on le gère ici
75
+ if (condition.$find) {
76
+ // Récupérer le nom du champ
77
+ const fieldName = Object.keys(condition)[0];
78
+ const fieldValue = formData[fieldName];
79
+ try {
80
+ // Assuming evaluateSingleCondition handles $find
81
+ return evaluateSingleCondition(currentModelDef, condition.$find, formData, allModels, user);
82
+ } catch (error) {
83
+ console.error("Error evaluating $find condition:", condition, error);
84
+ return false;
85
+ }
86
+ }
87
+
88
+ // Récupérer le nom du champ et la condition
89
+ const fieldName = Object.keys(condition)[0];
90
+ const fieldValue = condition[fieldName];
91
+
92
+ // Récupérer la définition du champ
93
+ const fieldDef = currentModelDef?.fields.find(f => f.name === fieldName);
94
+
95
+ // Si la définition du champ n'est pas trouvée, on retourne true
96
+ if (!fieldDef) {
97
+ console.warn(`[Client Eval] Field definition not found for field: ${fieldName}`);
98
+ return true; // Permissive default
99
+ }
100
+
101
+ let targetValue = formData[fieldName];
102
+ let processedConditionValue = fieldValue;
103
+
104
+ // 1. Handle $exists (on the first field)
105
+ // 2. Convert condition value based on operator's expected input type
106
+ const fieldType = fieldDef?.type; // Type of the first field
107
+
108
+ try {
109
+ processedConditionValue = convertValueType(fieldValue, fieldType);
110
+ } catch (e) {
111
+ logClientEvalWarning(`Error converting value type: ${e.message}`, condition);
112
+ return false;
113
+ }
114
+
115
+ return evaluateComparison(fieldValue, targetValue, processedConditionValue, condition);
116
+
117
+ function logClientEvalWarning(message, details) {
118
+ console.warn(`[Client Eval] ${message}:`, details);
119
+ }
120
+
121
+ function convertValueType(value, inputType) {
122
+ switch (inputType) {
123
+ case 'number':
124
+ const numValue = parseFloat(value);
125
+ if (isNaN(numValue)) {
126
+ throw new Error(`Invalid number value: ${value}`);
127
+ }
128
+ return numValue;
129
+ case 'boolean':
130
+ return String(value).toLowerCase() === 'true';
131
+ case 'csv':
132
+ return String(value).split(',').map(item => item.trim()).filter(Boolean);
133
+ case 'text':
134
+ default:
135
+ return String(value);
136
+ }
137
+ }
138
+
139
+ function evaluateComparison(operator, targetValue, processedConditionValue, condition) {
140
+ try {
141
+ switch (typeof operator === 'object' ? Object.keys(operator)[0] : null) {
142
+ case '$eq': return targetValue == processedConditionValue;
143
+ case '$ne': return targetValue != processedConditionValue;
144
+ case '$gt': return targetValue > processedConditionValue;
145
+ case '$lt': return targetValue < processedConditionValue;
146
+ case '$gte': return targetValue >= processedConditionValue;
147
+ case '$lte': return targetValue <= processedConditionValue;
148
+ case '$regex':
149
+ if (typeof targetValue !== 'string') return false;
150
+ if (typeof processedConditionValue !== 'string') return false;
151
+ try {
152
+ const regex = new RegExp(processedConditionValue, 'i');
153
+ return regex.test(targetValue);
154
+ } catch (e) {
155
+ logClientEvalWarning(`Invalid regex pattern: ${processedConditionValue}`, condition);
156
+ return false;
157
+ }
158
+ case '$in':
159
+ return Array.isArray(processedConditionValue) && processedConditionValue.includes(String(targetValue));
160
+ case '$nin':
161
+ return !Array.isArray(processedConditionValue) || !processedConditionValue.includes(String(targetValue));
162
+ default:
163
+ logClientEvalWarning(`Unhandled operator in client evaluation logic: ${operator}`, condition);
164
+ return true; // Permissive default
165
+ }
166
+ } catch (evalError) {
167
+ logClientEvalWarning(`Error during client condition evaluation: ${operator}, targetValue=${targetValue}, processedConditionValue=${processedConditionValue}`, condition);
168
+ return false;
169
+ }
170
+ }
171
+ };
172
+
173
+ export const isConditionMet = (model, cond, formData, allModels, user) => {
174
+ const condition = cond;
175
+
176
+ if (!condition) return true;
177
+
178
+ // Cas 1: Condition simple {field: value} → transformée en {field: {$eq: value}}
179
+ if (typeof condition === 'object' && !Array.isArray(condition)) {
180
+ const keys = Object.keys(condition);
181
+ if (keys.length === 1 && !keys[0].startsWith('$') &&
182
+ typeof condition[keys[0]] !== 'object') {
183
+ const simpleCondition = {
184
+ [keys[0]]: {$eq: condition[keys[0]]}
185
+ };
186
+ return evaluateSingleCondition(model, simpleCondition, formData, allModels, user);
187
+ }
188
+ }
189
+
190
+ // Cas 2: Opérateurs logiques ($and, $or, $not, $nor)
191
+ if (condition.$and && Array.isArray(condition.$and)) {
192
+ if (condition.$and.length === 0) return true;
193
+ return condition.$and.every(sub => isConditionMet(model, sub, formData, allModels, user));
194
+ }
195
+
196
+ if (condition.$or && Array.isArray(condition.$or)) {
197
+ if (condition.$or.length === 0) return false;
198
+ return condition.$or.some(sub => isConditionMet(model, sub, formData, allModels, user));
199
+ }
200
+
201
+ if (condition.$not) {
202
+ return !isConditionMet(model, condition.$not, formData, allModels, user);
203
+ }
204
+
205
+ if (condition.$nor && Array.isArray(condition.$nor)) {
206
+ if (condition.$nor.length === 0) return true;
207
+ return !condition.$nor.some(sub => isConditionMet(model, sub, formData, allModels, user));
208
+ }
209
+
210
+ // Cas 3: Syntaxe d'agrégation {$eq: ['$field', value]}
211
+ if (Object.keys(condition).length === 1) {
212
+ const operator = Object.keys(condition)[0];
213
+ if (operator.startsWith('$') && operator !== '$find' &&
214
+ Array.isArray(condition[operator])) {
215
+ return evaluateSingleCondition(model, condition, formData, allModels, user);
216
+ }
217
+ }
218
+
219
+ // Cas 4: Tous les autres cas (conditions normales avec opérateurs)
220
+ return evaluateSingleCondition(model, condition, formData, allModels, user);
221
+ };
package/src/index.js CHANGED
@@ -10,6 +10,6 @@ export { UserProvider } from './providers.js';
10
10
 
11
11
  // --- Database & Data Modules ---
12
12
  export { datasCollection, filesCollection, modelsCollection, packsCollection } from './modules/mongodb.js';
13
- export { searchData, insertData, editData, exportData, importData, scheduleAlerts, cancelAlerts, validateModelStructure, installPack, jobDumpUserData, loadFromDump, dumpUserData, validateRestoreRequest, patchData, deleteData, createModel, editModel, deleteModels, getModel, getModels } from './modules/data.js';
13
+ export { searchData, insertData, editData, exportData, importData, scheduleAlerts, cancelAlerts, validateModelStructure, installPack, jobDumpUserData, loadFromDump, dumpUserData, validateRestoreRequest, patchData, deleteData, createModel, editModel, deleteModels, getModel, getModels } from './modules/data/index.js';
14
14
 
15
15
 
@@ -60,7 +60,6 @@ function _sanitize(target, options) {
60
60
 
61
61
  if( (key === 'regex' && obj.input) || key === '$regex' ){
62
62
  obj[key] = new RegExp(val, "ui");
63
- console.log('regex san', obj[key]);
64
63
  }
65
64
  else if (!wl.includes(key) && regex.test(key)) {
66
65
  isSanitized = true;
@@ -1,11 +1,9 @@
1
- // server/src/modules/assistant.js
2
-
3
1
  import { getCollectionForUser, modelsCollection } from "./mongodb.js";
4
2
  import { Logger } from "../gameObject.js";
5
3
  import { ChatOpenAI } from "@langchain/openai";
6
4
  import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
7
5
  import { HumanMessage, SystemMessage } from "@langchain/core/messages";
8
- import {searchData, patchData, deleteData, insertData} from "./data.js";
6
+ import {searchData, patchData, deleteData, insertData} from "./data/index.js";
9
7
  import { getDataAsString } from "../data.js";
10
8
  import i18n from "../../src/i18n.js";
11
9
  import {generateLimiter} from "./user.js";
@@ -3,7 +3,7 @@ import AWS from "aws-sdk";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import {decryptValue, encryptValue} from "../data.js";
6
- import {loadFromDump, validateRestoreRequest} from "./data.js";
6
+ import {loadFromDump, validateRestoreRequest} from "./data/index.js";
7
7
  import {Logger} from "../gameObject.js";
8
8
  import {middlewareAuthenticator, userInitiator} from "./user.js";
9
9
  import {awsDefaultConfig, maxBytesPerSecondThrottleData} from "../constants.js";
@@ -117,7 +117,6 @@ export async function getUserS3Config(user) {
117
117
  bucketName: userConfig.bucketName || defaultConfig.bucketName
118
118
  };
119
119
  }
120
- console.log({defaultConfig})
121
120
  return defaultConfig;
122
121
  }
123
122
  const getS3Client = (s3Config) => {
@@ -212,9 +211,9 @@ export const deleteFromS3 = async (s3Config, remoteFilename) => {
212
211
 
213
212
  try {
214
213
  await s3.deleteObject(params).promise();
215
- console.log(`Fichier supprimé avec succès de S3 : ${bucketPath}`);
214
+ console.log(`File successfully removed from S3 : ${bucketPath}`);
216
215
  } catch (err) {
217
- console.error("Erreur lors de la suppression sur S3 :", err);
216
+ console.error("Error when deleting S3 file :", err);
218
217
  throw err;
219
218
  }
220
219
  };