data-primals-engine 1.6.5 → 1.7.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.
- package/README.md +160 -113
- package/client/index.js +3 -0
- package/client/package-lock.json +8121 -8824
- package/client/package.json +10 -3
- package/client/src/AssistantChat.jsx +369 -362
- package/client/src/DataEditor.jsx +383 -383
- package/client/src/DataLayout.jsx +54 -20
- package/client/src/ModelList.jsx +280 -280
- package/client/src/ViewSwitcher.scss +0 -31
- package/client/src/constants.js +81 -100
- package/client/src/contexts/CommandContext.jsx +274 -259
- package/client/vite.config.js +30 -30
- package/doc/AI-assistance.md +93 -0
- package/doc/Advanced-workflows.md +90 -0
- package/doc/Event-system.md +79 -0
- package/doc/Packs-gallery.md +73 -0
- package/package.json +30 -16
- package/src/constants.js +1 -1
- package/src/core.js +487 -477
- package/src/defaultModels.js +1 -1
- package/src/email.js +0 -2
- package/src/engine.js +342 -335
- package/src/filter.js +348 -343
- package/src/migrate.js +1 -1
- package/src/modules/assistant/assistant.js +30 -20
- package/src/modules/data/data.backup.js +4 -4
- package/src/modules/data/data.js +311 -302
- package/src/modules/data/data.operations.js +79 -64
- package/src/modules/data/data.relations.js +2 -1
- package/src/modules/data/data.scheduling.js +1 -1
- package/src/modules/mongodb.js +16 -8
- package/src/modules/user.js +0 -1
- package/src/modules/workflow.js +1828 -1815
- package/src/packs.js +5701 -5697
- package/src/profiles.js +19 -0
- package/swagger-en.yml +3390 -3385
- package/swagger-fr.yml +3385 -3380
- package/test/assistant.test.js +2 -2
- package/test/data.backup.integration.test.js +3 -1
- package/test/data.history.integration.test.js +0 -1
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
optionsSanitizer,
|
|
25
25
|
searchRequestTimeout
|
|
26
26
|
} from "../../constants.js";
|
|
27
|
-
import {anonymizeText, getFieldValueHash, getUserId, isDemoUser, isLocalUser} from "../../data.js";
|
|
27
|
+
import {anonymizeText, encryptValue, getFieldValueHash, getUserId, isDemoUser, isLocalUser} from "../../data.js";
|
|
28
28
|
import sanitizeHtml from "sanitize-html";
|
|
29
29
|
import {importJobs, modelsCache, runCryptoWorkerTask, runImportExportWorker} from "./data.core.js";
|
|
30
30
|
import {
|
|
@@ -71,7 +71,7 @@ const IMPORT_CHUNK_DELAY_MS = 1000; // Délai en millisecondes entre le traiteme
|
|
|
71
71
|
|
|
72
72
|
export const dataTypes = {
|
|
73
73
|
object: {
|
|
74
|
-
|
|
74
|
+
validate: (value, field) => {
|
|
75
75
|
return value === null || isPlainObject(value);
|
|
76
76
|
}
|
|
77
77
|
},
|
|
@@ -112,7 +112,13 @@ export const dataTypes = {
|
|
|
112
112
|
const ml = Math.min(Math.max(field.maxlength, 0), m);
|
|
113
113
|
return value === null || typeof value === 'string' && (!ml || value.length <= ml)
|
|
114
114
|
},
|
|
115
|
-
anonymize: anonymizeText
|
|
115
|
+
anonymize: anonymizeText,
|
|
116
|
+
filter: async (value, field) => {
|
|
117
|
+
if (field.encrypted && value) {
|
|
118
|
+
return encryptValue(value);
|
|
119
|
+
}
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
116
122
|
},
|
|
117
123
|
code: {
|
|
118
124
|
validate: (value, field) => {
|
|
@@ -142,8 +148,12 @@ export const dataTypes = {
|
|
|
142
148
|
const ml = Math.min(Math.max(field.maxlength, 0), m);
|
|
143
149
|
return value === null || typeof value === 'string' && (!ml || value.length <= ml)
|
|
144
150
|
},
|
|
145
|
-
filter: async (value) => {
|
|
146
|
-
|
|
151
|
+
filter: async (value, field) => {
|
|
152
|
+
const sanitized = sanitizeHtml(value, optionsSanitizer);
|
|
153
|
+
if (field.encrypted && sanitized) {
|
|
154
|
+
return encryptValue(sanitized);
|
|
155
|
+
}
|
|
156
|
+
return sanitized;
|
|
147
157
|
},
|
|
148
158
|
anonymize: anonymizeText
|
|
149
159
|
},
|
|
@@ -152,7 +162,7 @@ export const dataTypes = {
|
|
|
152
162
|
if (value === null)
|
|
153
163
|
return true;
|
|
154
164
|
const m = Config.Get('maxStringLength', maxStringLength);
|
|
155
|
-
const ml = Math.min(Math.max(field.maxlength, 0),
|
|
165
|
+
const ml = Math.min(Math.max(field.maxlength, 0), m);
|
|
156
166
|
// La valeur peut être une chaîne de caractères...
|
|
157
167
|
if (typeof value === 'string') {
|
|
158
168
|
return !ml || value.length <= ml;
|
|
@@ -850,7 +860,7 @@ export const insertData = async (modelName, data, files, user, triggerWorkflow =
|
|
|
850
860
|
return {success: true, data: firstInsertedDoc, insertedIds: insertedIds.map(id => id.toString())};
|
|
851
861
|
|
|
852
862
|
} catch (error) { // Attrape les erreurs de permission ou de pushDataUnsecure
|
|
853
|
-
logger
|
|
863
|
+
logger?.error(`[insertData] Main error during insertion process for model ${modelName}: ${error.message}`, error.stack);
|
|
854
864
|
// Renvoyer une structure d'erreur cohérente
|
|
855
865
|
return {
|
|
856
866
|
success: false,
|
|
@@ -1474,7 +1484,7 @@ const internalEditOrPatchData = async (modelName, filter, data, files, user, isP
|
|
|
1474
1484
|
};
|
|
1475
1485
|
|
|
1476
1486
|
} catch (error) {
|
|
1477
|
-
logger
|
|
1487
|
+
logger?.error("Erreur lors de la mise à jour de la ressource :", error);
|
|
1478
1488
|
return {success: false, error: error.message};
|
|
1479
1489
|
}
|
|
1480
1490
|
};
|
|
@@ -1716,9 +1726,10 @@ export const deleteData = async (modelName, filter, user = {}, triggerWorkflow,
|
|
|
1716
1726
|
} else {
|
|
1717
1727
|
logger.info(`[deleteData] No documents to delete for user ${user?.username} after permission checks or matching criteria.`);
|
|
1718
1728
|
}
|
|
1719
|
-
|
|
1720
1729
|
const res = { success: true, deletedCount };
|
|
1721
1730
|
|
|
1731
|
+
if (!modelNameToInvalidate)
|
|
1732
|
+
return res;
|
|
1722
1733
|
// --- CORRECTION ---
|
|
1723
1734
|
// The event payload must match what the history listener expects: { modelName, user, before }.
|
|
1724
1735
|
// 'documentsToDelete' contains the full documents before they were deleted.
|
|
@@ -1845,7 +1856,6 @@ export const searchData = async (query, user) => {
|
|
|
1845
1856
|
// Vérifier si les données sont en cache
|
|
1846
1857
|
const cachedData = searchCache.get(cacheKey);
|
|
1847
1858
|
if (cachedData) {
|
|
1848
|
-
console.log('Cache hit for key:', cacheKey);
|
|
1849
1859
|
return cachedData;
|
|
1850
1860
|
}
|
|
1851
1861
|
|
|
@@ -3090,7 +3100,6 @@ export const exportData = async (options, user) => {
|
|
|
3090
3100
|
* Installs pack models and data for a user or globally.
|
|
3091
3101
|
* Can accept either a pack ID (to install from database) or a direct pack JSON object.
|
|
3092
3102
|
*
|
|
3093
|
-
* @param {object} logger - Logger instance
|
|
3094
3103
|
* @param {string|object} packIdentifier - Either pack ID (string) or pack JSON object
|
|
3095
3104
|
* @param {object|null} user - User object (if installing for user) or null (for global install)
|
|
3096
3105
|
* @param {string} [lang='en'] - Language code for localized data
|
|
@@ -3099,7 +3108,6 @@ export const exportData = async (options, user) => {
|
|
|
3099
3108
|
export async function installPack(packIdentifier, user = null, lang = 'en', options = {}) {
|
|
3100
3109
|
let pack;
|
|
3101
3110
|
const packsCollection = getCollection('packs');
|
|
3102
|
-
|
|
3103
3111
|
// Determine if we're working with an ID or direct pack object
|
|
3104
3112
|
if (typeof packIdentifier === 'string') {
|
|
3105
3113
|
let p;
|
|
@@ -3139,12 +3147,19 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3139
3147
|
throw new Error('Invalid pack identifier - must be either pack ID string or pack object');
|
|
3140
3148
|
}
|
|
3141
3149
|
|
|
3150
|
+
// Vérifier si le pack est déjà installé pour cet utilisateur
|
|
3151
|
+
const existingPack = await packsCollection.findOne({ name: pack.name, _user: user?.username });
|
|
3152
|
+
if (existingPack) {
|
|
3153
|
+
logger?.warn(`Pack '${pack.name}' is already installed for user '${user?.username}'. Skipping installation.`);
|
|
3154
|
+
return { success: true, summary: {}, errors: [], modifiedCount: 0 };
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3142
3157
|
const username = user ? user.username : null;
|
|
3143
3158
|
const logPrefix = username
|
|
3144
3159
|
? `Installing pack '${pack.name}' for user '${username}'`
|
|
3145
3160
|
: `Installing pack '${pack.name}' globally`;
|
|
3146
3161
|
|
|
3147
|
-
logger
|
|
3162
|
+
logger?.info(`--- ${logPrefix} ---`);
|
|
3148
3163
|
|
|
3149
3164
|
const summary = {
|
|
3150
3165
|
models: {installed: [], skipped: [], failed: []},
|
|
@@ -3159,9 +3174,8 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3159
3174
|
if (Array.isArray(pack.models)) {
|
|
3160
3175
|
// For user installs, check existing models
|
|
3161
3176
|
const existingModels = user
|
|
3162
|
-
? await modelsCollection.find({_user: username}).toArray()
|
|
3177
|
+
? await modelsCollection.find({_user: user.username}).toArray()
|
|
3163
3178
|
: await modelsCollection.find({_user: {$exists: false}}).toArray();
|
|
3164
|
-
|
|
3165
3179
|
const existingModelNames = existingModels.map(m => m.name);
|
|
3166
3180
|
|
|
3167
3181
|
for (let i = 0; i < pack.models.length; i++) {
|
|
@@ -3170,8 +3184,9 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3170
3184
|
const modelName = typeof modelOrName === 'string' ? modelOrName : modelOrName?.name;
|
|
3171
3185
|
if (!modelName) throw new Error('Model definition in pack is missing a name.');
|
|
3172
3186
|
|
|
3173
|
-
|
|
3174
|
-
|
|
3187
|
+
const r = typeof user?.username === 'string' && await modelsCollection.findOne({name: modelName, _user: user.username || /.*/});
|
|
3188
|
+
if (r ) {
|
|
3189
|
+
logger?.debug(`[Model Install] Skipping '${modelName}': already exists`);
|
|
3175
3190
|
summary.models.skipped.push(modelName);
|
|
3176
3191
|
continue;
|
|
3177
3192
|
}
|
|
@@ -3198,7 +3213,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3198
3213
|
await modelsCollection.insertOne(preparedModel);
|
|
3199
3214
|
summary.models.installed.push(modelName);
|
|
3200
3215
|
} catch (e) {
|
|
3201
|
-
logger
|
|
3216
|
+
logger?.error(e);
|
|
3202
3217
|
const modelName = typeof modelOrName === 'string' ? modelOrName : modelOrName?.name || 'unknown';
|
|
3203
3218
|
errors.push(`Failed to install model '${modelName}': ${e.message}`);
|
|
3204
3219
|
summary.models.failed.push(modelName);
|
|
@@ -3209,8 +3224,8 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3209
3224
|
// --- PHASE 2: DATA INSTALLATION ---
|
|
3210
3225
|
const dataToInstall = {...pack.data?.all, ...pack.data?.[lang]};
|
|
3211
3226
|
if (!dataToInstall || Object.keys(dataToInstall).length === 0) {
|
|
3212
|
-
logger
|
|
3213
|
-
return {success:
|
|
3227
|
+
logger?.warn(`Pack '${pack.name}' has no data to install.`);
|
|
3228
|
+
return {success: errors.length === 0, summary, errors, modifiedCount: 0};
|
|
3214
3229
|
}
|
|
3215
3230
|
|
|
3216
3231
|
// Process link references (same as original)
|
|
@@ -3243,49 +3258,49 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3243
3258
|
const documents = dataToInstall[modelName];
|
|
3244
3259
|
if (documents.length === 0) continue;
|
|
3245
3260
|
|
|
3246
|
-
|
|
3247
|
-
|
|
3261
|
+
try {
|
|
3262
|
+
const docsToInsert = [];
|
|
3263
|
+
const modelDefForHash = await getModel(modelName, user);
|
|
3248
3264
|
|
|
3249
|
-
|
|
3250
|
-
|
|
3265
|
+
for (const docSource of documents) {
|
|
3266
|
+
let docForInsert = {...docSource};
|
|
3251
3267
|
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3268
|
+
// Clear $link fields for first pass
|
|
3269
|
+
for (const key in docForInsert) {
|
|
3270
|
+
if (isPlainObject(docForInsert[key]) && docForInsert[key].$link) {
|
|
3271
|
+
docForInsert[key] = null;
|
|
3272
|
+
}
|
|
3256
3273
|
}
|
|
3257
|
-
}
|
|
3258
3274
|
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3275
|
+
const tempId = docForInsert._temp_pack_id;
|
|
3276
|
+
delete docForInsert._id;
|
|
3277
|
+
delete docForInsert._temp_pack_id;
|
|
3262
3278
|
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
docForInsert._model = modelName;
|
|
3266
|
-
docForInsert._hash = getFieldValueHash(modelDefForHash, docForInsert);
|
|
3279
|
+
if (user) docForInsert._user = username;
|
|
3267
3280
|
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
_hash: docForInsert._hash,
|
|
3271
|
-
_model: modelName
|
|
3272
|
-
};
|
|
3281
|
+
docForInsert._model = modelName;
|
|
3282
|
+
docForInsert._hash = getFieldValueHash(modelDefForHash, docForInsert);
|
|
3273
3283
|
|
|
3274
|
-
|
|
3275
|
-
|
|
3284
|
+
// Check for existing document
|
|
3285
|
+
const existingQuery = {
|
|
3286
|
+
_hash: docForInsert._hash,
|
|
3287
|
+
_model: modelName
|
|
3288
|
+
};
|
|
3276
3289
|
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3290
|
+
if (docForInsert._env) existingQuery._env = docForInsert._env;
|
|
3291
|
+
if (user) existingQuery._user = username;
|
|
3292
|
+
|
|
3293
|
+
const existingDoc = await collection.findOne(existingQuery, {projection: {_id: 1}});
|
|
3294
|
+
if (existingDoc) {
|
|
3295
|
+
tempIdToNewIdMap[tempId] = existingDoc._id;
|
|
3296
|
+
summary.datas.skipped++;
|
|
3297
|
+
} else {
|
|
3298
|
+
docForInsert._temp_pack_id_for_mapping = tempId;
|
|
3299
|
+
docsToInsert.push(docForInsert);
|
|
3300
|
+
}
|
|
3284
3301
|
}
|
|
3285
|
-
}
|
|
3286
3302
|
|
|
3287
|
-
|
|
3288
|
-
try {
|
|
3303
|
+
if (docsToInsert.length > 0) {
|
|
3289
3304
|
const finalDocsToInsert = docsToInsert.map(d => {
|
|
3290
3305
|
const doc = {...d};
|
|
3291
3306
|
delete doc._temp_pack_id_for_mapping;
|
|
@@ -3303,22 +3318,22 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3303
3318
|
tempIdToNewIdMap[doc._temp_pack_id_for_mapping] = result.insertedIds[index];
|
|
3304
3319
|
}
|
|
3305
3320
|
});
|
|
3306
|
-
} catch (e) {
|
|
3307
|
-
summary.datas.failed += docsToInsert.length;
|
|
3308
|
-
errors.push(`Error inserting batch for ${modelName}: ${e.message}`);
|
|
3309
|
-
logger.error(`[Pack Install] Error on insertMany for model ${modelName}:`, e);
|
|
3310
3321
|
}
|
|
3322
|
+
} catch (e) {
|
|
3323
|
+
summary.datas.failed += documents.length;
|
|
3324
|
+
errors.push(`Error processing model ${modelName}: ${e.message}`);
|
|
3325
|
+
logger?.error(`[Pack Install] Error processing model ${modelName}:`, e);
|
|
3311
3326
|
}
|
|
3312
3327
|
}
|
|
3313
3328
|
|
|
3314
3329
|
// --- PASS 2: REFERENCE LINKING ---
|
|
3315
|
-
logger
|
|
3330
|
+
logger?.info(`[Pack Install] Starting Pass 2: Linking ${linkQueue.length} references`);
|
|
3316
3331
|
for (const linkOp of linkQueue) {
|
|
3317
3332
|
const {sourceTempId, sourceModelName, fieldName, linkSelector} = linkOp;
|
|
3318
3333
|
const sourceId = tempIdToNewIdMap[sourceTempId];
|
|
3319
3334
|
|
|
3320
3335
|
if (!sourceId) {
|
|
3321
|
-
logger
|
|
3336
|
+
logger?.warn(`[LINK FAILED] Could not find newly inserted document for temp ID ${sourceTempId}. Skipping link.`);
|
|
3322
3337
|
continue;
|
|
3323
3338
|
}
|
|
3324
3339
|
|
|
@@ -3330,7 +3345,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3330
3345
|
const fieldDef = sourceModelDef.fields.find(f => f.name === fieldName);
|
|
3331
3346
|
|
|
3332
3347
|
if (!fieldDef) {
|
|
3333
|
-
logger
|
|
3348
|
+
logger?.warn(`[LINK FAILED] Field '${fieldName}' not found in source model '${sourceModelName}'`);
|
|
3334
3349
|
errors.push(`[LINK FAILED] Field '${fieldName}' not found in source model '${sourceModelName}'`);
|
|
3335
3350
|
summary.datas.failed++;
|
|
3336
3351
|
continue;
|
|
@@ -3344,7 +3359,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3344
3359
|
|
|
3345
3360
|
if (!targetDocs || targetDocs.length === 0) {
|
|
3346
3361
|
const errorMsg = `[LINK FAILED] No target found for ${JSON.stringify(linkSelector)}`;
|
|
3347
|
-
logger
|
|
3362
|
+
logger?.warn(errorMsg);
|
|
3348
3363
|
errors.push(errorMsg);
|
|
3349
3364
|
summary.datas.failed++;
|
|
3350
3365
|
continue;
|
|
@@ -3363,7 +3378,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3363
3378
|
|
|
3364
3379
|
} catch (e) {
|
|
3365
3380
|
const errorMsg = `[LINK CRITICAL] Error linking ${sourceModelName}.${fieldName}: ${e.message}`;
|
|
3366
|
-
logger
|
|
3381
|
+
logger?.error(errorMsg, e.stack);
|
|
3367
3382
|
errors.push(errorMsg);
|
|
3368
3383
|
summary.datas.failed++;
|
|
3369
3384
|
}
|
|
@@ -3372,7 +3387,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3372
3387
|
if (options.installForUser && user?.username) {
|
|
3373
3388
|
if (pack.name)
|
|
3374
3389
|
await packsCollection.deleteOne({name: pack.name, _user: user.username});
|
|
3375
|
-
logger
|
|
3390
|
+
logger?.info(`--- Creating pack '${pack.name}' for user... ---`);
|
|
3376
3391
|
const packToCreate = {...pack, _id: undefined, private: true, _user: user.username};
|
|
3377
3392
|
await packsCollection.insertOne(packToCreate);
|
|
3378
3393
|
}
|
|
@@ -3383,7 +3398,7 @@ export async function installPack(packIdentifier, user = null, lang = 'en', opti
|
|
|
3383
3398
|
}
|
|
3384
3399
|
|
|
3385
3400
|
const modifiedCount = summary.datas.inserted + summary.datas.updated;
|
|
3386
|
-
logger
|
|
3401
|
+
logger?.info(`--- ${logPrefix} completed ---`);
|
|
3387
3402
|
return {
|
|
3388
3403
|
success: errors.length === 0,
|
|
3389
3404
|
summary,
|
|
@@ -581,7 +581,8 @@ export const checkHash = async (me, model, hash, excludeId = null) => {
|
|
|
581
581
|
const query = {
|
|
582
582
|
_model: model.name,
|
|
583
583
|
_hash: hash,
|
|
584
|
-
...(excludeId && {_id: {$ne: new ObjectId(excludeId)}})
|
|
584
|
+
...(excludeId && {_id: {$ne: new ObjectId(excludeId)}}),
|
|
585
|
+
_user: me.username
|
|
585
586
|
};
|
|
586
587
|
|
|
587
588
|
console.log("Query being executed:", JSON.stringify(query, null, 2));
|
|
@@ -21,7 +21,7 @@ export function onInit(defaultEngine) {
|
|
|
21
21
|
|
|
22
22
|
export const cancelAlerts = async (user) => {
|
|
23
23
|
|
|
24
|
-
const datasCollection = getCollection('datas'); // Alerts are in the global collection
|
|
24
|
+
const datasCollection = getCollection(Config.Get('dataCollection', 'datas')); // Alerts are in the global collection
|
|
25
25
|
|
|
26
26
|
// 1. Fetch the latest state of the alert
|
|
27
27
|
const alertDocs = await datasCollection.find({_user: user.username, _model: 'alert'}).toArray();
|
package/src/modules/mongodb.js
CHANGED
|
@@ -3,31 +3,36 @@ import {Logger} from "../gameObject.js";
|
|
|
3
3
|
import {MongoDatabase} from "../engine.js";
|
|
4
4
|
import {ObjectId} from "mongodb";
|
|
5
5
|
import {isLocalUser} from "../data.js";
|
|
6
|
+
import {Event} from "../events.js";
|
|
7
|
+
import {Config} from "../config.js";
|
|
6
8
|
|
|
7
9
|
export let modelsCollection, datasCollection, filesCollection, packsCollection;
|
|
8
10
|
|
|
9
11
|
export {ObjectId};
|
|
10
12
|
|
|
11
|
-
let engine, logger
|
|
13
|
+
let engine, logger, currentDb
|
|
14
|
+
|
|
12
15
|
let colls= [];
|
|
13
16
|
export async function onInit(defaultEngine) {
|
|
14
17
|
engine = defaultEngine;
|
|
15
18
|
logger = engine.getComponent(Logger);
|
|
16
19
|
|
|
20
|
+
currentDb = MongoDatabase();
|
|
17
21
|
modelsCollection = getCollection("models");
|
|
18
|
-
datasCollection = getCollection(
|
|
22
|
+
datasCollection = getCollection(Config.Get('dataCollection', 'datas'));
|
|
19
23
|
filesCollection = getCollection("files");
|
|
20
24
|
packsCollection = getCollection("packs");
|
|
21
25
|
|
|
22
|
-
colls = await
|
|
26
|
+
colls = await currentDb.listCollections().toArray();
|
|
23
27
|
|
|
28
|
+
await Event.Trigger("OnDatabaseLoaded", "system", "calls", engine)
|
|
24
29
|
logger.info("MongoDB collections loaded.");
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
export const getCollections= async (forceRefresh)=>{
|
|
28
33
|
if( !forceRefresh )
|
|
29
34
|
return colls;
|
|
30
|
-
colls = await
|
|
35
|
+
colls = await currentDb.listCollections().toArray();
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
export const createCollection = async (coll)=>{
|
|
@@ -35,7 +40,7 @@ export const createCollection = async (coll)=>{
|
|
|
35
40
|
if( found){
|
|
36
41
|
return getCollection(coll);
|
|
37
42
|
}
|
|
38
|
-
return await
|
|
43
|
+
return await currentDb.createCollection(coll);
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
export const isObjectId = (id) => {
|
|
@@ -44,15 +49,18 @@ export const isObjectId = (id) => {
|
|
|
44
49
|
|
|
45
50
|
|
|
46
51
|
export const getCollection = (str) => {
|
|
47
|
-
return
|
|
52
|
+
return currentDb.collection(str);
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
export const getDatabase = () => {
|
|
56
|
+
return currentDb;
|
|
57
|
+
}
|
|
51
58
|
|
|
52
59
|
// New function to determine the collection name for a user
|
|
53
60
|
export const getUserCollectionName = async (user) => {
|
|
54
61
|
const feat = await engine.userProvider.hasFeature(user, 'indexes');
|
|
55
|
-
|
|
62
|
+
const dataCollectionName = Config.Get('dataCollection', 'datas');
|
|
63
|
+
return feat ? (isLocalUser(user) ? `${dataCollectionName}_${user._user}` :`${dataCollectionName}_${user.username}` ) : dataCollectionName;
|
|
56
64
|
};
|
|
57
65
|
|
|
58
66
|
|