data-primals-engine 1.0.6 → 1.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-primals-engine",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "data-primals-engine is the package responsible from handling large amount of data in a practical and performant way. It can handle large amount of data in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation.",
5
5
  "main": "src/engine.js",
6
6
  "type": "module",
package/server.js CHANGED
@@ -13,11 +13,20 @@ const bench = GameObject.Create("Benchmark");
13
13
  const timer = bench.addComponent(BenchmarkTool);
14
14
  timer.start();
15
15
 
16
- const engine = Engine.Create();
16
+
17
+ const engine = await Engine.Create();
18
+
19
+ if (process.argv.length === 3) {
20
+ let arg = process.argv[2];
21
+ if( arg === 'reset-models'){
22
+ console.log("resetting models");
23
+ await engine.resetModels();
24
+ }
25
+ }
17
26
 
18
27
  const port = process.env.PORT || 7633;
19
28
  engine.start(port, async (r) => {
20
29
  const logger = engine.getComponent(Logger);
21
-
30
+ console.log("Server started on port" + port);
22
31
  timer.stop();
23
32
  });
package/src/constants.js CHANGED
@@ -2,24 +2,6 @@ export const dbName = "engine";
2
2
 
3
3
  export const cookiesSecret = 'hoaivuymzovyoznllmafivpzaovphlejvalwjvelfhqochakfesv';
4
4
 
5
-
6
- export const langs = {
7
- fr: "Français",
8
- en: "English",
9
- ar: "عربي",
10
- fa: "فارسی",
11
- it: "Italiano",
12
- es: "Español",
13
- el: "Ελληνικά",
14
- de: "Deutsch",
15
- cs: "Čeština",
16
- sv: "Svenska",
17
- pt: "Português",
18
- ja: "日本語",
19
- zh: "简体中文",
20
- ru: "Русский",
21
- };
22
-
23
5
  export const availableLangs = [
24
6
  "en",
25
7
  "fa",
@@ -138,7 +120,7 @@ metaModels['common'] = { load: ['contact', 'location', 'request'] };
138
120
  metaModels['personal'] = { load: ['budget', 'imageGallery'] };
139
121
  metaModels['users'] = { load: ['permission', 'role', 'user', 'token'], 'require': ['i18n', 'common'] };
140
122
  metaModels['i18n'] = { load: ['translation','lang']};
141
- metaModels['website'] = { load: ['webpage', 'content', 'taxonomy', 'contact', 'resource'], 'require': ['i18n'] };
123
+ metaModels['website'] = { load: ['webpage', 'content', 'taxonomy', 'contact', 'event', 'resource'], 'require': ['i18n'] };
142
124
  metaModels['messaging'] = { load: ['alert','ticket', 'message', 'channel'], 'require': ['i18n'] };
143
125
  metaModels['eshopping'] = { load: [
144
126
  'order', 'currency', 'product', 'productVariant', 'discount', 'cart', 'cartItem',
@@ -148,67 +130,7 @@ metaModels['eshopping'] = { load: [
148
130
  metaModels['workflow'] = { load: ['env', 'workflow', 'workflowRun', 'workflowAction', 'workflowStep', 'workflowTrigger']};
149
131
  metaModels['erp'] = { load: [ 'accountingExercise', 'accountingLineItem', 'accountingEntry', 'employee', 'dashboard', 'kpi'] };
150
132
 
151
- export const profiles = {
152
- 'personal': ['contact', 'location', 'imageGallery', 'budget', 'currency', 'taxonomy'], // budget,
153
- 'developer': ['alert','request','webpage', 'content', 'taxonomy', 'resource', 'translation', 'contact', 'location', 'channel', 'lang', 'token', 'message', 'ticket', 'user', 'permission', 'role'],
154
- 'company': ['alert','request','location', 'campaign', 'order', 'currency', 'product', 'cart', 'cartItem', 'invoice', 'messaging', 'user', 'role', 'permission', 'token','translation', 'lang', 'webpage', 'content', 'taxonomy', 'contact', 'resource', 'accountingExercise', 'accountingLineItem', 'accountingEntry', 'employee', 'kpi', 'dashboard'],
155
- 'engineer': ['alert','request','dashboard', 'kpi', 'user', 'role', 'token', 'permission', 'workflow', 'workflowRun', 'workflowStep', "channel", "message", 'workflowAction', 'workflowTrigger']
156
- }
157
-
158
- // Dans ConditionBuilder.jsx ou un fichier de constantes partagé
159
- export const mongoOperators = [
160
- { value: '$eq', label: '==', inputType: 'text' }, // Égal (pour string, number, boolean...)
161
- { value: '$ne', label: '!=', inputType: 'text' }, // Différent
162
- { value: '$gt', label: '>', inputType: 'number' }, // Supérieur (nombre, date)
163
- { value: '$gte', label: '>=', inputType: 'number' }, // Supérieur ou égal à
164
- { value: '$lt', label: '<', inputType: 'number' }, // Inférieur à
165
- { value: '$lte', label: '<=', inputType: 'number' }, // Inférieur ou égal à
166
- { value: '$regex', label: 'contient (regex)', inputType: 'text' }, // Correspondance Regex (pour string)
167
- { value: '$in', label: 'est dans (liste)', inputType: 'csv' }, // Dans un tableau (valeurs séparées par des virgules)
168
- { value: '$nin', label: "n'est pas dans (liste)", inputType: 'csv' }, // Pas dans un tableau
169
- { value: '$exists', label: 'existe', inputType: 'boolean' }, // Le champ existe (true/false)
170
- // { value: '$not', label: 'NON (condition)', inputType: 'condition' }, // Pourrait encapsuler une autre condition
171
- // Ajoutez d'autres opérateurs MongoDB pertinents si besoin ($size, $type, $elemMatch...)
172
- ];
173
133
 
174
134
  export const allowedFields = ['locked', 'hiddenable', 'anonymized', 'condition', 'color', 'index', 'type', 'required', 'hint', 'default', 'validate', 'unique', 'name', 'placeholder', 'asMain'];
175
135
 
176
136
 
177
-
178
- export const MONGO_OPERATORS = {
179
- ADD: { mongo: '$add', label: '+', type: 'numeric', multi: true },
180
- SUBTRACT: { mongo: '$subtract', label: '-', type: 'numeric', multi: false },
181
- MULTIPLY: { mongo: '$multiply', label: '*', type: 'numeric', multi: true },
182
- DIVIDE: { mongo: '$divide', label: '/', type: 'numeric', multi: false },
183
- MODULO: { mongo: '$mod', label: '%', type: 'numeric', multi: false },
184
- POW: { mongo: '$pow', label: 'pow', type: 'numeric', multi: false },
185
- SQRT: { mongo: '$sqrt', label: '√', type: 'numeric', multi: false, unary: true },
186
- ABS: { mongo: '$abs', label: 'abs', type: 'numeric', multi: false, unary: true },
187
- CEIL: { mongo: '$ceil', label: 'ceil', type: 'numeric', multi: false, unary: true },
188
- FLOOR: { mongo: '$floor', label: 'floor', type: 'numeric', multi: false, unary: true },
189
- COS: { mongo: '$cos', label: 'cos', type: 'numeric', multi: false, unary: true },
190
- ACOS: { mongo: '$acos', label: 'acos', type: 'numeric', multi: false, unary: true },
191
- SIN: { mongo: '$sin', label: 'sin', type: 'numeric', multi: false, unary: true },
192
- ASIN: { mongo: '$asin', label: 'asin', type: 'numeric', multi: false, unary: true },
193
- TAN: { mongo: '$tan', label: 'tan', type: 'numeric', multi: false, unary: true },
194
- ATAN: { mongo: '$atan', label: 'atan', type: 'numeric', multi: false, unary: true },
195
- LN: { mongo: '$ln', label: 'ln', type: 'numeric', multi: false, unary: true },
196
- LOG: { mongo: '$log10', label: 'log', type: 'numeric', multi: false, unary: true },
197
-
198
- CONCAT: { mongo: '$concat', label: 'concat', type: 'string', multi: true },
199
-
200
- YEAR: { mongo: '$year', label: 'year', type: 'date', unary: true },
201
- MONTH: { mongo: '$month', label: 'month', type: 'date', unary: true },
202
- WEEK: { mongo: '$week', label: 'week', type: 'date', unary: true },
203
- DAY_OF_MONTH: { mongo: '$dayOfMonth', label: 'day', type: 'date', unary: true },
204
- HOUR: { mongo: '$hour', label: 'hour', type: 'date', unary: true },
205
- MINUTE: { mongo: '$minute', label: 'min', type: 'date', unary: true },
206
- SECOND: { mongo: '$second', label: 'sec', type: 'date', unary: true },
207
- };
208
-
209
- export const OPERAND_TYPES = {
210
- FIELD: 'field',
211
- CONSTANT: 'constant',
212
- PREVIOUS_STEP: 'previousStep',
213
- };
214
-
package/src/data.js CHANGED
@@ -29,8 +29,12 @@ export const isLocalUser = (user) => {
29
29
  return user && user._model === 'user' && typeof(user._user) === 'string' && user._user.trim() !== '';
30
30
  };
31
31
 
32
+ export const isDemoUser = (user) => {
33
+ return /^demo[0-9]{1,2}$/.test(user?.username);
34
+ }
35
+
32
36
  export function getUserHash(user) {
33
- if( /^demo[0-9]{1,2}$/.test(user?.username) ){
37
+ if( isDemoUser(user) ){
34
38
  return user.username;
35
39
  }
36
40
  return user ? (
@@ -419,8 +423,9 @@ export const getFieldValueHash = (model, data) => {
419
423
  * @param {array} allModels - Un tableau contenant les définitions de TOUS les modèles du système.
420
424
  * @returns {string} - La chaîne de caractères représentant la donnée.
421
425
  */
422
- export const getDataAsString = (model, data, t, allModels, extended=false) => {
423
-
426
+ export const getDataAsString = (model, data, tr, allModels, extended=false) => {
427
+ const { t, i18n} = tr;
428
+ const lang = (i18n.resolvedLanguage || i18n.language).split(/[-_]/)?.[0];
424
429
  // Cas de base : si le modèle ou les données sont manquants, on ne peut rien faire.
425
430
  if (!model || !data) {
426
431
  return '';
@@ -464,7 +469,6 @@ export const getDataAsString = (model, data, t, allModels, extended=false) => {
464
469
  const relatedModel = allModels?.find(m => m.name === fieldDef.relation);
465
470
  if (!relatedModel) return `[${fieldDef.relation}]`; // Modnon trouvé
466
471
 
467
- console.log({relatedModel, value});
468
472
  // Si la relation est multiple (un tableau d'objets)
469
473
  if (Array.isArray(value)) {
470
474
  return value
@@ -474,10 +478,16 @@ export const getDataAsString = (model, data, t, allModels, extended=false) => {
474
478
  }
475
479
  // Si la relation est simple (un seul objet)
476
480
  else if (typeof value === 'object') {
477
- console.log({relatedModel, value});
478
481
  return getDataAsString(relatedModel, value, t, allModels); // Appel récursif
479
482
  }
480
483
  }
484
+
485
+ if(fieldDef.type === 'datetime'){
486
+ return new Date(value).toLocaleDateString(lang, {year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric'});
487
+ }
488
+ if(fieldDef.type === 'date'){
489
+ return new Date(value).toLocaleDateString(lang, {year: 'numeric', month: 'numeric', day: 'numeric'});
490
+ }
481
491
  // --- FIN DE LA NOUVELLE LOGIQUE ---
482
492
 
483
493
  // Logique existante pour les autres types de champs
@@ -106,11 +106,11 @@ export const defaultModels = {
106
106
  { name: 'subject', type: 'string' }, // Sujet de la notification (ex: titre de l'email)
107
107
  { name: 'content', type: 'richtext', required: true }, // Contenu du message (localisable)
108
108
  { name: 'channels', type: 'relation', multiple: true, relation: 'channel' }, // Canaux de diffusion (email, SMS, forum, etc.)
109
- { name: 'status', type: 'enum', items: ['en attente', 'envoyée', 'lue', 'échouée'] },
109
+ { name: 'status', type: 'enum', items: ['pending', 'sent', 'read', 'failed'] },
110
110
  { name: 'sentAt', type: 'datetime' },
111
111
  { name: 'readAt', type: 'datetime' },
112
112
  { name: 'type', type: 'string' }, // Type de notification (ex: "commande.miseAJour", "messageForum")
113
- { name: 'priority', type: 'enum', items: ['basse', 'moyenne', 'haute'] },
113
+ { name: 'priority', type: 'enum', items: ['low', 'medium', 'high']},
114
114
  ],
115
115
  },
116
116
  alert: {
@@ -404,7 +404,7 @@ export const defaultModels = {
404
404
  { name: 'invoiceId', type: 'string', required: true, unique: true },
405
405
  { name: 'invoiceDate', type: 'datetime', required: true },
406
406
  { name: 'dueDate', type: 'datetime' },
407
- { name: 'status', type: 'enum', items: ['payée', 'non payée', 'partiellement payée', 'annulée'] },
407
+ { name: 'status', type: 'enum', items: ['paid', 'unpaid', 'partially_paid', 'cancelled'] },
408
408
  ],
409
409
  },
410
410
  userSubscription: {
@@ -418,8 +418,8 @@ export const defaultModels = {
418
418
  { name: 'endDate', type: 'datetime' },
419
419
  { name: 'price', type: 'number', required: true },
420
420
  { name: 'currency', type: 'relation', relation: 'currency', required: true },
421
- { name: 'paymentMethod', type: 'enum', items: ['carte bancaire', 'mandat SEPA'] },
422
- { name: 'status', type: 'enum', items: ['actif', 'inactif', 'annulé', 'expiré', 'en attente'] },
421
+ { name: 'paymentMethod', type: 'enum', items: ['bank_card', 'SEPA_mandate', 'cash', 'check', 'other'] },
422
+ { name: 'status', type: 'enum', items: ['active', 'inactive', 'cancelled', 'expired', 'pending'] },
423
423
  { name: 'billingCycleAnchor', type: 'datetime' },
424
424
  { name: 'nextBillingDate', type: 'datetime' },
425
425
  { name: 'lastBillingDate', type: 'datetime' },
@@ -455,7 +455,7 @@ export const defaultModels = {
455
455
  { name: 'order', type: 'relation', relation: 'order', required: true },
456
456
  { name: 'trackingNumber', type: 'string' },
457
457
  { name: 'carrier', type: 'string' },
458
- { name: 'status', type: 'enum', items: ['en attente', 'en transit', 'livrée', 'problème'] },
458
+ { name: 'status', type: 'enum', items: ['pending', 'in_transit', 'delivered', 'issue'] },
459
459
  { name: 'estimatedDeliveryDate', type: 'datetime' },
460
460
  { name: 'actualDeliveryDate', type: 'datetime' }
461
461
  ],
@@ -476,7 +476,7 @@ export const defaultModels = {
476
476
  { "name": "user", "type": "relation", relation: "user" },
477
477
  { "name": "reason", "type": "string", maxlength: 2048, required: true },
478
478
  { "name": "channel", "type": "relation", relation: 'channel' },
479
- { "name": "status", "type": "enum", items: ["en attente", "approuvé", "remboursé", "refusé"] },
479
+ { "name": "status", "type": "enum", items: ["pending", "approved", "refunded", "refused"] },
480
480
  { name: 'amount', type: 'number', min: 0 },
481
481
  { name: 'currency', type: 'relation', relation: 'currency' },
482
482
  { name: 'refundDate', type: 'datetime' },
@@ -490,7 +490,7 @@ export const defaultModels = {
490
490
  { name: 'product', type: 'relation', relation: 'product', required: true },
491
491
  { name: 'variant', type: 'relation', relation: 'productVariant' },
492
492
  { name: 'quantity', type: 'number', required: true, min: 1 },
493
- { name: 'condition', type: 'enum', items: ['neuf', 'très bon état', 'bon état', 'dégradé', 'endommagé', 'inutilisable'] }
493
+ { name: 'condition', type: 'enum', items: ['new', 'very_good', 'good', 'degraded', 'damaged', 'unusable'] }
494
494
  ],
495
495
  },
496
496
  ticket: {
@@ -504,8 +504,8 @@ export const defaultModels = {
504
504
  { name: 'parent', type: 'relation', relation: 'ticket' },
505
505
  { name: 'subject', type: 'string', required: true },
506
506
  { name: 'message', type: 'richtext', required: true },
507
- { name: 'status', type: 'enum', items: ['ouvert', 'en cours', 'fermé'] },
508
- { name: 'priority', type: 'enum', items: ['basse', 'moyenne', 'haute'] },
507
+ { name: 'status', type: 'enum', items: ['opened', 'in_progress', 'closed'] },
508
+ { name: 'priority', type: 'enum', items: ['low', 'medium', 'high', 'urgent'] },
509
509
  { name: 'assignedTo', type: 'relation', relation: 'user' },
510
510
  { name: 'createdAt', type: 'datetime', required: true }
511
511
  ],
@@ -518,8 +518,8 @@ export const defaultModels = {
518
518
  { name: 'description', type: 'richtext' },
519
519
  { name: 'startDate', type: 'datetime' },
520
520
  { name: 'endDate', type: 'datetime' },
521
- { name: 'type', type: 'enum', items: ['email', 'SMS', 'publicité', 'promotion'] },
522
- { name: 'status', type: 'enum', items: ['planifiée', 'en cours', 'terminée', 'annulée'] },
521
+ { name: 'type', type: 'enum', items: ['email', 'sms', 'advertisement', 'promotion'] },
522
+ { name: 'status', type: 'enum', items: ['planified', 'in_progress', 'finished', 'cancelled'] },
523
523
  { name: 'budget', type: 'number' }
524
524
  ],
525
525
  },
@@ -631,7 +631,7 @@ export const defaultModels = {
631
631
  {
632
632
  "name": "status",
633
633
  "type": "enum",
634
- "items": ["brouillon", "validée", "annulée"],
634
+ "items": ["draft", "validated", "cancelled"],
635
635
  "default": "brouillon"
636
636
  },
637
637
  {
@@ -1283,5 +1283,117 @@ export const defaultModels = {
1283
1283
  hint: "Pièces jointes (reçus, factures)."
1284
1284
  },
1285
1285
  ]
1286
+ },
1287
+ event: {
1288
+ "name": "event",
1289
+ "description": "A model for managing events, conferences, meetups, and gatherings.",
1290
+ "fields": [
1291
+ {
1292
+ "name": "title",
1293
+ "type": "string",
1294
+ "required": true,
1295
+ "asMain": true,
1296
+ "hint": "The title of the event"
1297
+ },
1298
+ {
1299
+ "name": "description",
1300
+ "type": "richtext_t",
1301
+ "hint": "A detailed description of the event, including agenda, speakers, and other relevant information."
1302
+ },
1303
+ {
1304
+ "name": "startDate",
1305
+ "type": "datetime",
1306
+ "required": true,
1307
+ "hint": "The starting date and time of the event"
1308
+ },
1309
+ {
1310
+ "name": "endDate",
1311
+ "type": "datetime",
1312
+ "required": true,
1313
+ "hint": "The ending date and time of the event"
1314
+ },
1315
+ {
1316
+ "name": "location",
1317
+ "type": "relation",
1318
+ "relation": "location",
1319
+ "hint": "The venue or location where the event will be held. This could be a physical address or an online meeting link."
1320
+ },
1321
+ {
1322
+ "name": "categories",
1323
+ "type": "relation",
1324
+ "relation": "taxonomy",
1325
+ "multiple": true,
1326
+ "hint": "Categories or tags associated with the event (e.g., \"conference\", \"workshop\", \"music\", \"technology\")."
1327
+ },
1328
+ {
1329
+ "name": "organizer",
1330
+ "type": "relation",
1331
+ "relation": "contact",
1332
+ "hint": "The name of the organization or individual hosting the event."
1333
+ },
1334
+ {
1335
+ "name": "isOnline",
1336
+ "type": "boolean",
1337
+ "default": false,
1338
+ "hint": "Whether the event is online or in-person."
1339
+ },
1340
+ {
1341
+ "name": "eventUrl",
1342
+ "type": "url",
1343
+ "hint": "A link to the official event webpage or registration page."
1344
+ },
1345
+ {
1346
+ "name": "imageUrl",
1347
+ "type": "file",
1348
+ "hint": "URL of the event image or banner."
1349
+ },
1350
+ {
1351
+ "name": "status",
1352
+ "type": "enum",
1353
+ "items": [
1354
+ "scheduled",
1355
+ "ongoing",
1356
+ "completed",
1357
+ "cancelled",
1358
+ "postponed"
1359
+ ],
1360
+ "hint": "The current status of the event."
1361
+ },
1362
+ {
1363
+ "name": "capacity",
1364
+ "type": "number",
1365
+ "hint": "The maximum number of attendees allowed for the event."
1366
+ },
1367
+ {
1368
+ "name": "price",
1369
+ "type": "number",
1370
+ "hint": "The price of admission, if applicable."
1371
+ },
1372
+ {
1373
+ "name": "currency",
1374
+ "type": "relation",
1375
+ "relation": "currency",
1376
+ "hint": "The currency for the price (e.g., USD, EUR)."
1377
+ },
1378
+ {
1379
+ "name": "registrationDeadline",
1380
+ "type": "datetime",
1381
+ "hint": "The date by which attendees must register for the event."
1382
+ },
1383
+ {
1384
+ "name": "attendees",
1385
+ "type": "relation",
1386
+ "relation": "contact",
1387
+ "multiple": true,
1388
+ "hint": "A relation to the contacts attending the event"
1389
+ },
1390
+ {
1391
+ "name": "sponsors",
1392
+ "type": "relation",
1393
+ "relation": "contact",
1394
+ "multiple": true,
1395
+ "hint": "List of sponsors or partners involved in the event."
1396
+ }
1397
+ ]
1286
1398
  }
1287
1399
  };
package/src/email.js CHANGED
@@ -2,6 +2,8 @@ import { translations } from "data-primals-engine/i18n";
2
2
  import process from "node:process";
3
3
  import nodemailer from "nodemailer";
4
4
  import juice from "juice";
5
+ import {event_trigger} from "./core.js";
6
+ import {emailDefaultConfig} from "./constants.js";
5
7
 
6
8
  // Le transporteur par défaut, utilisé si aucune config spécifique n'est fournie.
7
9
  const defaultTransporter = nodemailer.createTransport({
package/src/engine.js CHANGED
@@ -4,14 +4,11 @@ import fs from 'node:fs'
4
4
  import express from 'express'
5
5
  import {MongoClient as InternalMongoClient} from 'mongodb'
6
6
  import process from "process";
7
- import multipart from 'connect-multiparty';
8
- import path from 'node:path';
9
- import bodyParser from "body-parser";
10
- import {cookiesSecret, dbName, install, maxDataSize} from "./constants.js";
7
+ import {cookiesSecret, dbName} from "./constants.js";
11
8
  import http from "http";
12
9
  import cookieParser from "cookie-parser";
13
10
  import requestIp from 'request-ip';
14
- import {createModel, getModels, installAllPacks, validateModelStructure} from "./modules/data.js";
11
+ import {createModel, deleteModels, getModels, validateModelStructure} from "./modules/data.js";
15
12
  import {defaultModels} from "./defaultModels.js";
16
13
  import {DefaultUserProvider} from "./providers.js";
17
14
  import formidableMiddleware from 'express-formidable';
@@ -28,9 +25,10 @@ export const MongoDatabase = MongoClient.db(dbName);
28
25
 
29
26
 
30
27
  export const Engine = {
31
- Create: (options) => {
28
+ Create: async (options) => {
32
29
  const engine = GameObject.Create("Engine");
33
30
  console.log("Creating engine", Config.Get('modules'));
31
+ engine.addComponent(Logger);
34
32
 
35
33
  engine.userProvider = new DefaultUserProvider(engine);
36
34
 
@@ -39,9 +37,8 @@ export const Engine = {
39
37
  engine.getComponent(Logger).info(`Custom UserProvider '${providerInstance.constructor.name}' has been set.`);
40
38
  };
41
39
 
42
- var app = express();
43
-
44
- // Allows you to set port in the project properties.
40
+ const app = express();
41
+ // Allows you to set port in the project properties.
45
42
  app.set('port', process.env.PORT || 3000);
46
43
  app.set('engine', engine);
47
44
 
@@ -50,7 +47,7 @@ export const Engine = {
50
47
  uploadDir: process.cwd()+'/uploads/tmp',
51
48
  multiples: true, // req.files to be arrays of files
52
49
  }));
53
- app.use(cookieParser(isProduction ? cookiesSecret : 'secret'));
50
+ app.use(cookieParser(process.env.COOKIES_SECRET || cookiesSecret));
54
51
  app.use(requestIp.mw())
55
52
 
56
53
  engine.use = (...args) => {
@@ -75,10 +72,38 @@ export const Engine = {
75
72
  return engine._modules.find(m => m.module === module);
76
73
  };
77
74
 
75
+
76
+ const logger = engine.getComponent(Logger);
77
+
78
+ const importModule = async (module) => {
79
+ const moduleA = await import(module);
80
+ if (moduleA.onInit){
81
+ await moduleA.onInit(engine);
82
+ return {...moduleA, module};
83
+ }else {
84
+ const mod = moduleA.default();
85
+ await mod?.onInit(engine);
86
+ return { ...mod, module};
87
+ }
88
+ };
89
+
90
+ await Promise.all(Config.Get('modules').map(async module => {
91
+ try {
92
+ if( fs.existsSync(module)){
93
+ return await importModule(module);
94
+ }else {
95
+ return await importModule('./modules/' + module + ".js");
96
+ }
97
+ } catch (e){
98
+ console.log('ERROR at loading module '+ module + ' in /modules dir.'+ e);
99
+ }
100
+ })).then(async e => {
101
+ engine._modules = e;
102
+ return Promise.resolve();
103
+ });
78
104
  let server;
79
105
  engine.start = async (port, cb) =>{
80
106
  // Use connect method to connect to the server
81
- await MongoClient.connect();
82
107
 
83
108
  // Start http server
84
109
  server = http.createServer(app);
@@ -91,37 +116,11 @@ export const Engine = {
91
116
 
92
117
  server.listen(port);
93
118
 
94
- const importModule = async (module) => {
95
- const moduleA = await import(module);
96
- if (moduleA.onInit){
97
- await moduleA.onInit(engine);
98
- return {...moduleA, module};
99
- }else {
100
- const mod = moduleA.default();
101
- await mod?.onInit(engine);
102
- return { ...mod, module};
103
- }
104
- };
105
-
106
- await Promise.all(Config.Get('modules').map(async module => {
107
- try {
108
- if( fs.existsSync(module)){
109
- return await importModule(module);
110
- }else {
111
- return await importModule('./modules/' + module + ".js");
112
- }
113
- } catch (e){
114
- console.log('ERROR at loading module '+ module + ' in /modules dir.'+ e);
115
- }
116
- })).then(async e => {
117
- engine._modules = e;
118
- if (cb)
119
- return await cb();
120
- return Promise.resolve();
121
- });
122
-
123
119
  await setupInitialModels();
124
120
 
121
+ if (cb)
122
+ await cb();
123
+
125
124
  process.on('uncaughtException', function (exception) {
126
125
  console.error(exception);
127
126
  fs.appendFile('issues.txt', JSON.stringify({ code: exception.code, message: exception.message, stack: exception.stack }), function (err) {
@@ -132,17 +131,14 @@ export const Engine = {
132
131
  process.exit(0);
133
132
  });
134
133
  }
135
- engine.addComponent(Logger);
136
134
 
137
135
  engine.stop = async () => {
138
136
  await server.close();
139
137
  };
140
138
 
141
- const logger = engine.getComponent(Logger);
142
-
143
139
  async function setupInitialModels() {
144
- logger.info("Validation des structures de modèles et insertion");
145
- const ms = Object.values(Config.Get('defaultModels', []));
140
+ logger.info("Validating structures of default models...");
141
+ const ms = Object.values(Config.Get('defaultModels', defaultModels));
146
142
 
147
143
  let dbModels = await getModels();
148
144
 
@@ -155,13 +151,15 @@ export const Engine = {
155
151
  model.locked = true;
156
152
  const r = await createModel(model);
157
153
  dbModels.push({...model, _id: r.insertedId });
158
- }
159
- else
160
- logger.info('Model loaded (' + model.name + ')', {});
154
+ logger.info('Model inserted (' + model.name + ')');
155
+ }else
156
+ logger.info('Model loaded (' + model.name + ')');
161
157
  }
162
158
  logger.info("All models loaded.");
163
159
  }
164
-
160
+ engine.resetModels = async () => {
161
+ await deleteModels();
162
+ };
165
163
  return engine;
166
164
  }
167
165
  }
package/src/gameObject.js CHANGED
@@ -70,23 +70,21 @@ export class UsableBehaviour extends Behaviour {
70
70
 
71
71
  use() {
72
72
  Event.Trigger("GameObject.UsableBehavior.use", "system", "calls", this);
73
- // Logique d'utilisation (exemple)
74
- console.log(this.gameObject.name + " a été utilisé !");
75
73
  }
76
74
  }
77
75
 
78
- const pilote = GameObject.Create("Pilote");
76
+ const mainDriver = GameObject.Create("MainDrivers");
79
77
 
80
78
  // Exemple d'attachement de comportements
81
- pilote.addComponent(MovableBehaviour, 10);
82
- pilote.addComponent(UsableBehaviour);
79
+ mainDriver.addComponent(MovableBehaviour, 10);
80
+ mainDriver.addComponent(UsableBehaviour);
83
81
 
84
82
  // Accéder et utiliser les composants
85
- const movable = pilote.getComponent(MovableBehaviour);
83
+ const movable = mainDriver.getComponent(MovableBehaviour);
86
84
  if (movable) {
87
85
  movable.update();
88
86
  }
89
- const usable = pilote.getComponent(UsableBehaviour);
87
+ const usable = mainDriver.getComponent(UsableBehaviour);
90
88
  if (usable) {
91
89
  usable.use();
92
90
  }